Decompiled source of ModernizationPortFullAuto v0.9.4
BepInEx/plugins/ModernizationPort/ModernizationPort.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using DM; using HarmonyLib; using Landfall.TABS; using Landfall.TABS.UnitPlacement; using Microsoft.CodeAnalysis; using ModernizationPort; using ModernizationPort.Legacy; using TFBGames; using TMPro; using UModLoader; using UnityEngine; using UnityEngine.AI; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyFileVersion("0.9.4.0")] [assembly: AssemblyTitle("modernization port by lil zalupa")] [assembly: AssemblyProduct("modernization port by lil zalupa")] [assembly: AssemblyCompany("lilzalupa")] [assembly: AssemblyVersion("0.9.4.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace UModLoader { public static class ULoader { internal static ContentDatabase Content; internal static LandfallContentDatabase Native; internal static readonly List<UnitBlueprint> CreatedUnits = new List<UnitBlueprint>(); internal static readonly List<Faction> CreatedFactions = new List<Faction>(); internal static readonly Dictionary<DatabaseID, string> Names = new Dictionary<DatabaseID, string>(); private static Dictionary<string, string> language; private const int ModId = 1459449901; public static Dictionary<string, Dictionary<string, object>> VDic { get; private set; } public static Dictionary<string, Dictionary<string, Dictionary<string, object>>> MDic { get; private set; } internal static void Prepare(ContentDatabase content) { Content = content; Native = content.LandfallContentDatabase; VDic = new Dictionary<string, Dictionary<string, object>>(); string[] array = new string[6] { "blueprints", "weapons", "clothes", "moves", "bases", "explosions" }; foreach (string key in array) { VDic.Add(key, new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase)); } MDic = new Dictionary<string, Dictionary<string, Dictionary<string, object>>> { { "Modernization", new Dictionary<string, Dictionary<string, object>> { { "blueprints", new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase) }, { "factions", new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase) } } } }; language = Localizer.GetLanguage((Language)0); foreach (UnitBlueprint unitBlueprint in Native.GetUnitBlueprints()) { Add("blueprints", unitBlueprint.Entity.Name, unitBlueprint); if (language.TryGetValue(unitBlueprint.Entity.Name, out var value)) { Add("blueprints", value, unitBlueprint); } } Index("weapons", Native.GetWeapons()); Index("clothes", Native.GetCharacterProps()); Index("moves", Native.GetCombatMoves()); Index("bases", Native.GetUnitBases()); foreach (GameObject projectile in Native.GetProjectiles()) { if (Object.op_Implicit((Object)(object)projectile)) { Add("projectiles-unused", ((Object)projectile).name, projectile); } } Explosion[] array2 = Resources.FindObjectsOfTypeAll<Explosion>(); foreach (Explosion val in array2) { if (Object.op_Implicit((Object)(object)val)) { Add("explosions", ((Object)((Component)val).gameObject).name, ((Component)val).gameObject); } } Alias("blueprints", "CavalryKnight", "Cavalry", "Cavalry Knight"); NativeTemplateAdapter.Apply(); string[] array3 = (from pair in RequiredTemplates.Items where !VDic[pair[0]].ContainsKey(pair[1]) select pair[0] + "/" + pair[1]).ToArray(); if (array3.Length != 0) { throw new MissingMemberException("Vanilla templates unavailable: " + string.Join(", ", array3)); } PortPlugin.Info("Template preflight complete: " + RequiredTemplates.Items.Length + " required names resolved."); } private static void Index(string category, IEnumerable<GameObject> objects) { foreach (GameObject @object in objects) { if (!Object.op_Implicit((Object)(object)@object)) { continue; } Add(category, ((Object)@object).name, @object); Component[] componentsInChildren = @object.GetComponentsInChildren<Component>(true); foreach (Component obj in componentsInChildren) { IDatabaseEntity val = (IDatabaseEntity)(object)((obj is IDatabaseEntity) ? obj : null); if (val != null && val.Entity != null) { Add(category, val.Entity.Name, @object); if (language.TryGetValue(val.Entity.Name, out var value)) { Add(category, value, @object); } } } } } private static void Add(string category, string key, object value) { if (string.IsNullOrEmpty(key) || !VDic.TryGetValue(category, out var value2)) { return; } key = key.Replace("(Clone)", "").Trim(); if (!value2.ContainsKey(key)) { value2.Add(key, value); } string text = key; bool flag; do { flag = false; string[] array = new string[7] { "CP_", "P_", "W_", "WP_", "Move_", "E_", "B_" }; foreach (string text2 in array) { if (text.StartsWith(text2, StringComparison.OrdinalIgnoreCase)) { text = text.Substring(text2.Length); flag = true; break; } } } while (flag); if (!value2.ContainsKey(text)) { value2.Add(text, value); } string key2 = text.Replace(" ", ""); if (!value2.ContainsKey(key2)) { value2.Add(key2, value); } string key3 = key.Replace(" ", ""); if (!value2.ContainsKey(key3)) { value2.Add(key3, value); } } internal static void Alias(string category, string key, params string[] alternatives) { Dictionary<string, object> dictionary = VDic[category]; if (dictionary.ContainsKey(key)) { return; } foreach (string key2 in alternatives) { if (dictionary.TryGetValue(key2, out var value)) { dictionary.Add(key, value); break; } } } private static int StableId(string text) { uint num = 2166136261u; foreach (char c in text) { num ^= c; num *= 16777619; } return (int)(num & 0x7FFFFFFF); } internal static void Identity(IDatabaseEntity owner, string kind, string name) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) DatabaseEntity val = owner.Entity.ShallowCopy(); val.GUID = new DatabaseID(1459449901, StableId(kind + "/" + name)); val.Name = name; AccessTools.Field(typeof(DatabaseEntity), "m_unlockKey").SetValue(val, ""); AccessTools.Field(((object)owner).GetType(), "m_entity").SetValue(owner, val); Names.Add(val.GUID, name); } internal static void Register(IDatabaseEntity entity, Object obj, string field) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) IDictionary dictionary = (IDictionary)AccessTools.Field(typeof(LandfallContentDatabase), field).GetValue(Native); IDictionary dictionary2 = (IDictionary)AccessTools.Field(((object)Content.AssetLoader).GetType(), "m_nonStreamableAssets").GetValue(Content.AssetLoader); if (dictionary.Contains(entity.Entity.GUID) || dictionary2.Contains(entity.Entity.GUID)) { throw new InvalidOperationException("Modernization ID already registered: " + entity.Entity.Name); } dictionary.Add(entity.Entity.GUID, obj); try { dictionary2.Add(entity.Entity.GUID, obj); } catch { dictionary.Remove(entity.Entity.GUID); throw; } } internal static void Rollback() { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) if (Content == null) { return; } IDictionary dictionary = (IDictionary)AccessTools.Field(((object)Content.AssetLoader).GetType(), "m_nonStreamableAssets").GetValue(Content.AssetLoader); foreach (UnitBlueprint createdUnit in CreatedUnits) { ((IDictionary)AccessTools.Field(typeof(LandfallContentDatabase), "m_unitBlueprints").GetValue(Native)).Remove(createdUnit.Entity.GUID); dictionary.Remove(createdUnit.Entity.GUID); Object.Destroy((Object)(object)createdUnit); } foreach (Faction createdFaction in CreatedFactions) { ((IDictionary)AccessTools.Field(typeof(LandfallContentDatabase), "m_factions").GetValue(Native)).Remove(createdFaction.Entity.GUID); dictionary.Remove(createdFaction.Entity.GUID); Object.Destroy((Object)(object)createdFaction); } CreatedUnits.Clear(); CreatedFactions.Clear(); Names.Clear(); } } public static class UFunctions { public static string AssemName() { return "Modernization"; } public static string ModNamify(string name) { return "Modernization/" + name; } public static string ModName(DatabaseEntity entity) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (entity == null || !ULoader.Names.TryGetValue(entity.GUID, out var value)) { if (entity != null) { return entity.Name; } return ""; } return ModNamify(value); } public static Faction CreateFaction(string name, UnitBlueprint[] units, Sprite icon) { Faction val = Object.Instantiate<Faction>(ULoader.Native.GetFactions().First((Faction x) => Object.op_Implicit((Object)(object)x) && x.m_displayFaction)); ULoader.Identity((IDatabaseEntity)(object)val, "faction", name); ((Object)val).name = "Modernization/" + name; val.Units = (UnitBlueprint[])(((object)units) ?? ((object)new UnitBlueprint[0])); val.m_displayFaction = true; val.index = ULoader.Native.GetFactions().Count(); if (Object.op_Implicit((Object)(object)icon)) { val.Entity.SetSpriteIcon(icon); } ULoader.Register((IDatabaseEntity)(object)val, (Object)(object)val, "m_factions"); ULoader.CreatedFactions.Add(val); ULoader.MDic[AssemName()]["factions"].Add(name, val); return val; } public static UnitBlueprint CreateUnit(string name, UnitBlueprint original, Faction faction, Sprite icon) { UnitBlueprint val = Object.Instantiate<UnitBlueprint>(original); ULoader.Identity((IDatabaseEntity)(object)val, "unit", name); ((Object)val).name = "Modernization/" + name; if (Object.op_Implicit((Object)(object)original.voiceBundle)) { val.voiceBundle = Object.Instantiate<VoiceBundle>(original.voiceBundle); ((Object)val.voiceBundle).hideFlags = (HideFlags)52; } val.SetNoCustomRider(); if (Object.op_Implicit((Object)(object)icon)) { val.Entity.SetSpriteIcon(icon); } ULoader.Register((IDatabaseEntity)(object)val, (Object)(object)val, "m_unitBlueprints"); ULoader.CreatedUnits.Add(val); ULoader.MDic[AssemName()]["blueprints"].Add(name, val); List<UnitBlueprint> list = faction.Units.ToList(); list.Add(val); faction.Units = list.ToArray(); return val; } } public sealed class UPool { private static UPool instance; private readonly Dictionary<string, GameObject> objects = new Dictionary<string, GameObject>(StringComparer.OrdinalIgnoreCase); private readonly GameObject root; public static UPool MyPool => instance ?? (instance = new UPool()); private UPool() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown root = new GameObject("Modernization prefab pool"); root.SetActive(false); ((Object)root).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)root); } public GameObject AddObject(string name, GameObject original, bool clone = true, HideFlags flags = (HideFlags)52) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) GameObject val = (clone ? Object.Instantiate<GameObject>(original, root.transform) : original); val.transform.SetParent(root.transform, false); ((Object)val).name = "Modernization/" + name; ((Object)val).hideFlags = flags; objects.Add(name, val); return val; } public GameObject GetObject(string name) { return objects[name]; } internal GameObject ClonePrivate(GameObject original) { GameObject obj = Object.Instantiate<GameObject>(original, root.transform); ((Object)obj).hideFlags = (HideFlags)52; return obj; } } public enum TriggerType { OnStart, OnTimer, OnGround } public sealed class USpawner : MonoBehaviour { public UnitBlueprint[] unitsToSpawn; public int u_numOfObjects = 1; public float u_startDelay; public float u_cd; public TriggerType u_triggerType; private bool triggered; private Vector3 previous; private void Start() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) previous = ((Component)this).transform.position; if (u_triggerType != TriggerType.OnGround) { Begin(); } } private void Update() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) if (!triggered && u_triggerType == TriggerType.OnGround) { Vector3 position = ((Component)this).transform.position; Vector3 val = position - previous; RaycastHit val2 = default(RaycastHit); if (((Vector3)(ref val)).sqrMagnitude > 0.0001f && Physics.Raycast(previous, ((Vector3)(ref val)).normalized, ref val2, ((Vector3)(ref val)).magnitude + 0.05f) && !Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<Unit>())) { Begin(); } else if (Physics.Raycast(position, Vector3.down, ref val2, 0.3f) && !Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<Unit>())) { Begin(); } previous = position; } } private void OnCollisionEnter(Collision collision) { if (u_triggerType == TriggerType.OnGround && !Object.op_Implicit((Object)(object)((Component)collision.collider).GetComponentInParent<Unit>())) { Begin(); } } private void OnTriggerEnter(Collider collider) { if (u_triggerType == TriggerType.OnGround && !Object.op_Implicit((Object)(object)((Component)collider).GetComponentInParent<Unit>())) { Begin(); } } private void Begin() { if (!triggered) { triggered = true; ((MonoBehaviour)this).StartCoroutine(Spawn()); } } private IEnumerator Spawn() { if (u_startDelay > 0f) { yield return (object)new WaitForSeconds(u_startDelay); } if (unitsToSpawn == null || unitsToSpawn.Length == 0) { yield break; } TeamHolder componentInParent = ((Component)this).GetComponentInParent<TeamHolder>(); Unit componentInParent2 = ((Component)this).GetComponentInParent<Unit>(); Team team = (Team)((!Object.op_Implicit((Object)(object)componentInParent)) ? (Object.op_Implicit((Object)(object)componentInParent2) ? ((int)componentInParent2.data.team) : 0) : ((int)componentInParent.team)); for (int i = 0; i < Math.Min(u_numOfObjects, 64); i++) { if (!Object.op_Implicit((Object)(object)this)) { break; } if (!Object.op_Implicit((Object)(object)((Component)this).gameObject)) { break; } UnitBlueprint val = unitsToSpawn[i % unitsToSpawn.Length]; if (Object.op_Implicit((Object)(object)val)) { PortRuntime.SpawnNative(val, ((Component)this).transform.position, ((Component)this).transform.rotation, team); } if (u_cd > 0f) { yield return (object)new WaitForSeconds(u_cd); } } } } } namespace ModernizationPort { public sealed class PortVisual : MonoBehaviour { } public static class PinaCollada { internal sealed class Model { internal Mesh Mesh; internal Material[] Materials; } internal static readonly Dictionary<string, Model> Models = new Dictionary<string, Model>(StringComparer.OrdinalIgnoreCase); internal static readonly Dictionary<string, Texture2D> Textures = new Dictionary<string, Texture2D>(StringComparer.OrdinalIgnoreCase); internal static readonly Dictionary<string, SoundEffectInstance> Sounds = new Dictionary<string, SoundEffectInstance>(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary<string, Sprite> Sprites = new Dictionary<string, Sprite>(StringComparer.OrdinalIgnoreCase); private static bool loaded; private static int Count(BinaryReader r, int maximum = 20000000) { int num = r.ReadInt32(); if (num < 0 || num > maximum) { throw new InvalidDataException("Invalid asset count: " + num); } return num; } private static string String(BinaryReader r) { int num = Count(r, 65536); byte[] array = r.ReadBytes(num); if (array.Length != num) { throw new EndOfStreamException(); } return Encoding.UTF8.GetString(array); } private static Vector3[] Vectors3(BinaryReader r) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) Vector3[] array = (Vector3[])(object)new Vector3[Count(r)]; for (int i = 0; i < array.Length; i++) { array[i] = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); } return array; } private static Vector2[] Vectors2(BinaryReader r) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) Vector2[] array = (Vector2[])(object)new Vector2[Count(r)]; for (int i = 0; i < array.Length; i++) { array[i] = new Vector2(r.ReadSingle(), r.ReadSingle()); } return array; } private static byte[] Bytes(BinaryReader r, int count) { byte[] array = r.ReadBytes(count); if (array.Length != count) { throw new EndOfStreamException(); } return array; } public static void EnsureLoaded() { //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Expected O, but got Unknown //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Expected O, but got Unknown //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Expected O, but got Unknown //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Unknown result type (might be due to invalid IL or missing references) //IL_03a1: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Expected O, but got Unknown //IL_045f: Unknown result type (might be due to invalid IL or missing references) //IL_0464: Unknown result type (might be due to invalid IL or missing references) //IL_046b: Unknown result type (might be due to invalid IL or missing references) //IL_0470: Unknown result type (might be due to invalid IL or missing references) //IL_0488: Expected O, but got Unknown if (loaded) { return; } using (FileStream stream = File.OpenRead(Path.Combine(Path.GetDirectoryName(typeof(PinaCollada).Assembly.Location), "Modernization.assets.gz"))) { using GZipStream input = new GZipStream(stream, CompressionMode.Decompress); using BinaryReader binaryReader = new BinaryReader(input); if (Encoding.ASCII.GetString(Bytes(binaryReader, 8)) != "MODPORT1") { throw new InvalidDataException("Incorrect Modernization resources."); } int num = Count(binaryReader, 1000); Shader val = Shader.Find("Standard"); if (!Object.op_Implicit((Object)(object)val)) { val = Shader.Find("Diffuse"); } if (!Object.op_Implicit((Object)(object)val)) { Material val2 = ((IEnumerable<Material>)Resources.FindObjectsOfTypeAll<Material>()).FirstOrDefault((Func<Material, bool>)((Material x) => Object.op_Implicit((Object)(object)x) && Object.op_Implicit((Object)(object)x.shader) && x.HasProperty("_Color") && ((Object)x.shader).name.IndexOf("UI", StringComparison.OrdinalIgnoreCase) < 0)); if (Object.op_Implicit((Object)(object)val2)) { val = val2.shader; } } if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("A material shader is unavailable."); } Color color = default(Color); for (int num2 = 0; num2 < num; num2++) { string text = String(binaryReader); Mesh val3 = new Mesh { name = "Modernization/" + text, hideFlags = (HideFlags)52 }; Vector3[] array = Vectors3(binaryReader); if (array.Length > 65535) { val3.indexFormat = (IndexFormat)1; } val3.vertices = array; Vector3[] array2 = Vectors3(binaryReader); if (array2.Length != 0) { val3.normals = array2; } Vector2[] array3 = Vectors2(binaryReader); if (array3.Length != 0) { val3.uv = array3; } int num3 = (val3.subMeshCount = Count(binaryReader, 1000)); for (int num5 = 0; num5 < num3; num5++) { int[] array4 = new int[Count(binaryReader)]; for (int num6 = 0; num6 < array4.Length; num6++) { array4[num6] = binaryReader.ReadInt32(); } val3.SetTriangles(array4, num5, false); } val3.RecalculateBounds(); if (array2.Length == 0) { val3.RecalculateNormals(); } Material[] array5 = (Material[])(object)new Material[Count(binaryReader, 1000)]; for (int num7 = 0; num7 < array5.Length; num7++) { ((Color)(ref color))..ctor(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); Material val4 = new Material(val) { name = "Modernization/" + text + "/" + num7, hideFlags = (HideFlags)52, color = color }; val4.SetFloat("_Glossiness", 0.12f); array5[num7] = val4; } Models.Add(text, new Model { Mesh = val3, Materials = array5.Take(RuntimeCompatibilityRules.MaterialSlots(num3, array5.Length)).ToArray() }); } num = Count(binaryReader, 1000); for (int num8 = 0; num8 < num; num8++) { string text2 = String(binaryReader); byte[] array6 = Bytes(binaryReader, Count(binaryReader)); Texture2D val5 = new Texture2D(2, 2, (TextureFormat)4, false) { name = "Modernization/" + text2, hideFlags = (HideFlags)52, filterMode = (FilterMode)0 }; if (!ImageConversion.LoadImage(val5, array6)) { throw new InvalidDataException("Invalid texture: " + text2); } Textures.Add(text2, val5); } num = Count(binaryReader, 1000); for (int num9 = 0; num9 < num; num9++) { string text3 = String(binaryReader); SoundEffectInstance val6 = new SoundEffectInstance { soundRef = text3 }; val6.volume = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); val6.pitch = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); val6.maxInstances = binaryReader.ReadInt32(); val6.cooldown = binaryReader.ReadSingle(); val6.spatialBlend = binaryReader.ReadSingle(); val6.reverbZoneMix = binaryReader.ReadSingle(); val6.minDistance = binaryReader.ReadSingle(); val6.maxDistance = binaryReader.ReadSingle(); val6.lengthInMeasures = binaryReader.ReadInt32(); val6.transitionMeasures = new int[Count(binaryReader, 1000)]; for (int num10 = 0; num10 < val6.transitionMeasures.Length; num10++) { val6.transitionMeasures[num10] = binaryReader.ReadInt32(); } val6.clipTypes = (SoundEffectVariations[])(object)new SoundEffectVariations[Count(binaryReader, 1000)]; for (int num11 = 0; num11 < val6.clipTypes.Length; num11++) { SoundEffectVariations val7 = new SoundEffectVariations { materialType = (MaterialType)binaryReader.ReadInt32(), clips = (AudioClip[])(object)new AudioClip[Count(binaryReader, 1000)] }; for (int num12 = 0; num12 < val7.clips.Length; num12++) { string text4 = String(binaryReader); int num13 = binaryReader.ReadInt32(); int num14 = binaryReader.ReadInt32(); int num15 = binaryReader.ReadInt32(); int num16 = Count(binaryReader); if (num16 != num14 * num15 || num13 <= 0 || num15 < 1 || num15 > 2) { throw new InvalidDataException("Invalid audio: " + text4); } float[] array7 = new float[num16]; byte[] array8 = Bytes(binaryReader, checked(num16 * 4)); Buffer.BlockCopy(array8, 0, array7, 0, array8.Length); AudioClip val8 = AudioClip.Create("Modernization/" + text4, num14, num15, num13, false); ((Object)val8).hideFlags = (HideFlags)52; if (!val8.SetData(array7, 0)) { throw new InvalidDataException("Could not create audio: " + text4); } val7.clips[num12] = val8; } val6.clipTypes[num11] = val7; } Sounds.Add(text3, val6); } if (Encoding.ASCII.GetString(Bytes(binaryReader, 8)) != "ENDPORT1" || binaryReader.BaseStream.ReadByte() != -1) { throw new InvalidDataException("Incomplete resource package."); } } Alias(Sounds, "artileryfire", "artillery"); loaded = true; PortPlugin.Info("Original resources ready: " + Models.Count + " models, " + Textures.Count + " images, 29 sound sets."); } private static void Alias<T>(Dictionary<string, T> items, string name, string original) { if (!items.ContainsKey(name) && items.ContainsKey(original)) { items.Add(name, items[original]); } } private static string Key(string path) { int num = path.LastIndexOf('/'); if (num >= 0) { return path.Substring(num + 1); } return path; } public static Sprite GetSprite(string path, int? size = null, FilterMode filter = (FilterMode)0) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) EnsureLoaded(); string text = Key(path); if (Sprites.TryGetValue(text, out var value)) { return value; } if (!Textures.TryGetValue(text, out var value2)) { throw new KeyNotFoundException("Original icon missing: " + path); } ((Texture)value2).filterMode = filter; value = Sprite.Create(value2, new Rect(0f, 0f, (float)((Texture)value2).width, (float)((Texture)value2).height), new Vector2(0.5f, 0.5f), (float)(size ?? 100)); ((Object)value).name = "Modernization/" + text; ((Object)value).hideFlags = (HideFlags)52; Sprites.Add(text, value); return value; } private static GameObject Attach(Transform parent, string path, float scale, Vector3? rotation, Vector3? position, string name) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_00a1: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown EnsureLoaded(); string key = Key(path); if (!Models.TryGetValue(key, out var value)) { throw new KeyNotFoundException("Original mesh missing: " + path); } GameObject val = new GameObject(name); val.AddComponent<PortVisual>(); val.transform.SetParent(parent, false); val.transform.localPosition = (Vector3)(((??)position) ?? Vector3.zero); val.transform.localRotation = Quaternion.Euler((Vector3)(((??)rotation) ?? Vector3.zero)); val.transform.localScale = Vector3.one * scale; val.AddComponent<MeshFilter>().sharedMesh = value.Mesh; ((Renderer)val.AddComponent<MeshRenderer>()).sharedMaterials = value.Materials; val.layer = ((Component)parent).gameObject.layer; return val; } public static void SetMeshRenderers(GameObject go, bool enabled) { Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if (!Object.op_Implicit((Object)(object)((Component)val).GetComponentInParent<PortVisual>())) { val.enabled = enabled; } } } public static void SetStaticMesh(GameObject go, string path, float scale, Vector3? rotation = null, Vector3? position = null, string name = "PinaCollada Mesh Object") { SetMeshRenderers(go, enabled: false); Attach(go.transform, path, scale, rotation, position, name); } public static void SetStaticMeshToBone(GameObject go, string path, float scale, Vector3? rotation, Vector3? position, string name, GearType gear, EquipType equip) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Invalid comparison between Unknown and I4 //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Invalid comparison between Unknown and I4 SetMeshRenderers(go, enabled: false); UnitRig val = go.GetComponentInParent<UnitRig>(); if (!Object.op_Implicit((Object)(object)val)) { val = ((Component)go.transform.root).GetComponentInChildren<UnitRig>(); } if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("Native unit rig missing: " + path); } Transform val2 = default(Transform); Transform val3 = default(Transform); val.GetBonesForEquip(gear, ref val2, ref val3); if (!Object.op_Implicit((Object)(object)val2) && !Object.op_Implicit((Object)(object)val3)) { throw new InvalidOperationException("Native attachment bone missing: " + path); } if (Object.op_Implicit((Object)(object)val2) && ((int)equip == 0 || (int)equip == 1 || !Object.op_Implicit((Object)(object)val3))) { Attach(val2, path, scale, rotation, position, name); } if (Object.op_Implicit((Object)(object)val3) && (Object)(object)val3 != (Object)(object)val2 && ((int)equip == 0 || (int)equip == 2)) { Attach(val3, path, scale, rotation, position, name); } } } internal sealed class DiscordInviteController : MonoBehaviour { private static bool shownThisLaunch; private ConfigEntry<bool> setting; private DiscordInviteWindow window; private float stableSince = -1f; private float nextPoll; internal void Init(ConfigEntry<bool> entry) { setting = entry; setting.SettingChanged += OnSettingChanged; ((Behaviour)this).enabled = setting.Value && !shownThisLaunch; } private void Update() { if (Time.unscaledTime < nextPoll) { return; } nextPoll = Time.unscaledTime + 0.25f; MainMenuButtons val = Object.FindObjectOfType<MainMenuButtons>(); bool flag = Object.op_Implicit((Object)(object)val) && ((Behaviour)val).isActiveAndEnabled; if (!flag) { stableSince = -1f; return; } if (stableSince < 0f) { stableSince = Time.unscaledTime; } if (!InviteSchedule.ShouldShow(setting.Value, shownThisLaunch, flag, Time.unscaledTime - stableSince)) { return; } shownThisLaunch = true; ((Behaviour)this).enabled = false; try { window = DiscordInviteWindow.Create(); } catch (Exception exception) { PortPlugin.Report("Discord invitation window", exception); } } private void OnSettingChanged(object sender, EventArgs args) { if (!setting.Value && Object.op_Implicit((Object)(object)window)) { window.Close(); } ((Behaviour)this).enabled = setting.Value && !shownThisLaunch; } private void OnDestroy() { if (setting != null) { setting.SettingChanged -= OnSettingChanged; } if (Object.op_Implicit((Object)(object)window)) { window.Close(); } } } internal sealed class DiscordInviteWindow : MonoBehaviour { private static readonly FieldInfo Locale = AccessTools.Field(typeof(Localizer), "m_locale"); private static Sprite rounded; private RectTransform panel; private TextMeshProUGUI title; private TextMeshProUGUI body; private TextMeshProUGUI hint; private TextMeshProUGUI joinLabel; private TextMeshProUGUI closeLabel; private bool registered; private bool closing; private int reportedLanguage = -1; internal static DiscordInviteWindow Create() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Modernization Discord invite", new Type[1] { typeof(RectTransform) }); Canvas obj = val.AddComponent<Canvas>(); obj.renderMode = (RenderMode)0; obj.sortingOrder = 30000; CanvasScaler obj2 = val.AddComponent<CanvasScaler>(); obj2.uiScaleMode = (ScaleMode)1; obj2.referenceResolution = new Vector2(1920f, 1080f); obj2.matchWidthOrHeight = 0.5f; val.AddComponent<GraphicRaycaster>(); if (!Object.op_Implicit((Object)(object)EventSystem.current)) { GameObject val2 = new GameObject("Modernization invite events"); val2.transform.SetParent(val.transform, false); val2.AddComponent<EventSystem>(); val2.AddComponent<StandaloneInputModule>(); } DiscordInviteWindow discordInviteWindow = val.AddComponent<DiscordInviteWindow>(); discordInviteWindow.Build(); return discordInviteWindow; } private static Sprite Rounded() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)rounded)) { return rounded; } Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false) { name = "Modernization/invite-rounded", hideFlags = (HideFlags)52, wrapMode = (TextureWrapMode)1 }; Color32[] array = (Color32[])(object)new Color32[1024]; for (int i = 0; i < 32; i++) { for (int j = 0; j < 32; j++) { float num = Mathf.Max(new float[3] { (float)(10 - j) - 0.5f, (float)j + 0.5f - 22f, 0f }); float num2 = Mathf.Max(new float[3] { (float)(10 - i) - 0.5f, (float)i + 0.5f - 22f, 0f }); float num3 = Mathf.Clamp01(10f - Mathf.Sqrt(num * num + num2 * num2) + 0.5f); array[i * 32 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)(num3 * 255f)); } } val.SetPixels32(array); val.Apply(false, true); rounded = Sprite.Create(val, new Rect(0f, 0f, 32f, 32f), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, new Vector4(10f, 10f, 10f, 10f)); ((Object)rounded).name = "Modernization/invite-rounded"; ((Object)rounded).hideFlags = (HideFlags)52; return rounded; } private static RectTransform Child(string name, Transform parent) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); return (RectTransform)val.transform; } private static Image Box(RectTransform target, Color colour) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) Image obj = ((Component)target).gameObject.AddComponent<Image>(); obj.sprite = Rounded(); obj.type = (Type)1; ((Graphic)obj).color = colour; return obj; } private static TextMeshProUGUI Label(string name, Transform parent, float size, Color colour, FontStyles style) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI obj = ((Component)Child(name, parent)).gameObject.AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj).fontSize = size; ((Graphic)obj).color = colour; ((TMP_Text)obj).fontStyle = style; ((TMP_Text)obj).alignment = (TextAlignmentOptions)514; ((TMP_Text)obj).enableWordWrapping = true; ((TMP_Text)obj).overflowMode = (TextOverflowModes)0; ((Graphic)obj).raycastTarget = false; return obj; } private Button MakeButton(string name, Transform parent, Color colour, out TextMeshProUGUI label, Action onClick) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Expected O, but got Unknown //IL_0137: Unknown result type (might be due to invalid IL or missing references) RectTransform val = Child(name, parent); Image targetGraphic = Box(val, colour); Button obj = ((Component)val).gameObject.AddComponent<Button>(); ((Selectable)obj).targetGraphic = (Graphic)(object)targetGraphic; ColorBlock colors = ((Selectable)obj).colors; ((ColorBlock)(ref colors)).normalColor = new Color(0.9f, 0.9f, 0.9f, 1f); ((ColorBlock)(ref colors)).highlightedColor = Color.white; ((ColorBlock)(ref colors)).pressedColor = new Color(0.75f, 0.75f, 0.75f, 1f); ((ColorBlock)(ref colors)).selectedColor = ((ColorBlock)(ref colors)).highlightedColor; ((ColorBlock)(ref colors)).fadeDuration = 0.08f; ((Selectable)obj).colors = colors; ((UnityEvent)obj.onClick).AddListener((UnityAction)delegate { onClick(); }); VerticalLayoutGroup obj2 = ((Component)val).gameObject.AddComponent<VerticalLayoutGroup>(); ((LayoutGroup)obj2).padding = new RectOffset(12, 12, 9, 9); ((LayoutGroup)obj2).childAlignment = (TextAnchor)4; bool childControlWidth = (((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true); ((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = childControlWidth; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false; LayoutElement obj3 = ((Component)val).gameObject.AddComponent<LayoutElement>(); obj3.minHeight = 44f; obj3.preferredWidth = 10f; obj3.flexibleWidth = 1f; label = Label("Label", (Transform)(object)val, 19f, Color.white, (FontStyles)1); return obj; } private void Build() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_00cf: 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) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Expected O, but got Unknown //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Expected O, but got Unknown //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Unknown result type (might be due to invalid IL or missing references) //IL_03a1: Unknown result type (might be due to invalid IL or missing references) //IL_03bf: Unknown result type (might be due to invalid IL or missing references) //IL_03c4: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Unknown result type (might be due to invalid IL or missing references) //IL_03fb: Unknown result type (might be due to invalid IL or missing references) //IL_041b: Unknown result type (might be due to invalid IL or missing references) //IL_0429: Unknown result type (might be due to invalid IL or missing references) //IL_0434: Unknown result type (might be due to invalid IL or missing references) //IL_0446: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Expected O, but got Unknown //IL_048a: Unknown result type (might be due to invalid IL or missing references) //IL_04a1: Unknown result type (might be due to invalid IL or missing references) //IL_04ca: Unknown result type (might be due to invalid IL or missing references) //IL_04f6: Unknown result type (might be due to invalid IL or missing references) //IL_0500: Expected O, but got Unknown panel = Child("Panel", ((Component)this).transform); RectTransform obj = panel; RectTransform obj2 = panel; RectTransform obj3 = panel; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(1f, 0f); obj3.pivot = val; Vector2 anchorMin = (obj2.anchorMax = val); obj.anchorMin = anchorMin; panel.anchoredPosition = new Vector2(-40f, 40f); panel.sizeDelta = new Vector2(440f, 180f); Box(panel, new Color(0.11f, 0.12f, 0.14f, 0.96f)); Outline obj4 = ((Component)panel).gameObject.AddComponent<Outline>(); ((Shadow)obj4).effectColor = new Color(1f, 1f, 1f, 0.12f); ((Shadow)obj4).effectDistance = new Vector2(1.5f, -1.5f); Shadow obj5 = ((Component)panel).gameObject.AddComponent<Shadow>(); obj5.effectColor = new Color(0f, 0f, 0f, 0.45f); obj5.effectDistance = new Vector2(0f, -5f); VerticalLayoutGroup obj6 = ((Component)panel).gameObject.AddComponent<VerticalLayoutGroup>(); ((LayoutGroup)obj6).padding = new RectOffset(22, 22, 18, 18); ((HorizontalOrVerticalLayoutGroup)obj6).spacing = 8f; ((LayoutGroup)obj6).childAlignment = (TextAnchor)1; bool childControlWidth = (((HorizontalOrVerticalLayoutGroup)obj6).childControlHeight = true); ((HorizontalOrVerticalLayoutGroup)obj6).childControlWidth = childControlWidth; ((HorizontalOrVerticalLayoutGroup)obj6).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)obj6).childForceExpandHeight = false; ContentSizeFitter obj7 = ((Component)panel).gameObject.AddComponent<ContentSizeFitter>(); obj7.verticalFit = (FitMode)2; obj7.horizontalFit = (FitMode)0; title = Label("Title", (Transform)(object)panel, 26f, Color.white, (FontStyles)1); ((TMP_Text)title).margin = new Vector4(34f, 0f, 34f, 0f); body = Label("Description", (Transform)(object)panel, 19f, new Color(0.86f, 0.88f, 0.92f, 1f), (FontStyles)0); hint = Label("Hint", (Transform)(object)panel, 14f, new Color(0.62f, 0.65f, 0.7f, 1f), (FontStyles)0); RectTransform val3 = Child("Buttons", (Transform)(object)panel); HorizontalLayoutGroup obj8 = ((Component)val3).gameObject.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj8).spacing = 12f; ((LayoutGroup)obj8).padding = new RectOffset(0, 0, 6, 0); childControlWidth = (((HorizontalOrVerticalLayoutGroup)obj8).childControlHeight = true); ((HorizontalOrVerticalLayoutGroup)obj8).childControlWidth = childControlWidth; ((HorizontalOrVerticalLayoutGroup)obj8).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)obj8).childForceExpandHeight = true; MakeButton("Join Discord", (Transform)(object)val3, Color32.op_Implicit(new Color32((byte)88, (byte)101, (byte)242, byte.MaxValue)), out joinLabel, OpenDiscord); MakeButton("Close", (Transform)(object)val3, new Color(0.25f, 0.27f, 0.31f, 1f), out closeLabel, Close); RectTransform val4 = Child("Close cross", (Transform)(object)panel); ((Component)val4).gameObject.AddComponent<LayoutElement>().ignoreLayout = true; ((Vector2)(ref val))..ctor(1f, 1f); val4.pivot = val; anchorMin = (val4.anchorMax = val); val4.anchorMin = anchorMin; val4.anchoredPosition = new Vector2(-10f, -10f); val4.sizeDelta = new Vector2(32f, 32f); Image targetGraphic = Box(val4, new Color(1f, 1f, 1f, 0f)); Button obj9 = ((Component)val4).gameObject.AddComponent<Button>(); ((Selectable)obj9).targetGraphic = (Graphic)(object)targetGraphic; ColorBlock colors = ((Selectable)obj9).colors; ((ColorBlock)(ref colors)).normalColor = new Color(1f, 1f, 1f, 0f); ((ColorBlock)(ref colors)).highlightedColor = new Color(1f, 1f, 1f, 0.14f); ((ColorBlock)(ref colors)).pressedColor = new Color(1f, 1f, 1f, 0.24f); ((ColorBlock)(ref colors)).selectedColor = ((ColorBlock)(ref colors)).normalColor; ((Selectable)obj9).colors = colors; ((UnityEvent)obj9.onClick).AddListener(new UnityAction(Close)); float[] array = new float[2] { 45f, -45f }; foreach (float num in array) { RectTransform obj10 = Child("Line", (Transform)(object)val4); obj10.sizeDelta = new Vector2(18f, 2.5f); ((Transform)obj10).localRotation = Quaternion.Euler(0f, 0f, num); Image obj11 = ((Component)obj10).gameObject.AddComponent<Image>(); ((Graphic)obj11).color = new Color(0.8f, 0.82f, 0.86f, 1f); ((Graphic)obj11).raycastTarget = false; } Refresh(); Localizer.RegisterCallback((MonoBehaviour)(object)this, new UpdateText(Refresh)); registered = true; } private static TMP_FontAsset FallbackFont() { TMP_FontAsset defaultFontAsset = TMP_Settings.defaultFontAsset; if (!Object.op_Implicit((Object)(object)defaultFontAsset)) { return Resources.FindObjectsOfTypeAll<TMP_FontAsset>().FirstOrDefault(); } return defaultFontAsset; } private void Refresh() { if (closing || !Object.op_Implicit((Object)(object)panel)) { return; } int num = ((!(Locale == null)) ? Convert.ToInt32(Locale.GetValue(null)) : 0); TMP_FontAsset font = Localizer.GetCurrentFont(0); if (!Object.op_Implicit((Object)(object)font)) { font = FallbackFont(); } Func<char, bool> fontHas = (char c) => !Object.op_Implicit((Object)(object)font) || font.HasCharacter(c, true, true); InviteText inviteText = InviteText.For(num).FitToFont(fontHas); if (inviteText == null) { inviteText = InviteText.English.FitToFont(fontHas) ?? InviteText.English; if (reportedLanguage != num) { reportedLanguage = num; PortPlugin.Warn("Discord invitation: the game font lacks glyphs for language " + num + "; English text is shown."); } } TextMeshProUGUI[] array = (TextMeshProUGUI[])(object)new TextMeshProUGUI[5] { title, body, hint, joinLabel, closeLabel }; foreach (TextMeshProUGUI val in array) { if (Object.op_Implicit((Object)(object)font)) { ((TMP_Text)val).font = font; } ((TMP_Text)val).isRightToLeftText = inviteText.RightToLeft; } ((TMP_Text)title).text = inviteText.Title; ((TMP_Text)body).text = inviteText.Body; ((TMP_Text)hint).text = inviteText.Hint; ((TMP_Text)joinLabel).text = inviteText.Join; ((TMP_Text)closeLabel).text = inviteText.Close; LayoutRebuilder.ForceRebuildLayoutImmediate(panel); } private void Update() { if (Input.GetKeyDown((KeyCode)27)) { Close(); } } private void OpenDiscord() { Application.OpenURL("https://discord.gg/8AtrRHEPAT"); Close(); } internal void Close() { if (!closing) { closing = true; EventSystem current = EventSystem.current; if (Object.op_Implicit((Object)(object)current) && Object.op_Implicit((Object)(object)current.currentSelectedGameObject) && current.currentSelectedGameObject.transform.IsChildOf(((Component)this).transform)) { current.SetSelectedGameObject((GameObject)null); } Object.Destroy((Object)(object)((Component)this).gameObject); } } private void OnDestroy() { closing = true; if (registered) { Localizer.UnregisterCallback((MonoBehaviour)(object)this); registered = false; } } } internal sealed class InviteText { internal const string Url = "https://discord.gg/8AtrRHEPAT"; internal readonly string Code; internal readonly string Language; internal readonly string Title; internal readonly string Body; internal readonly string Join; internal readonly string Close; internal readonly string Hint; internal readonly bool RightToLeft; internal static readonly InviteText English = new InviteText("LANG_EN_US", "English", "Join us on Discord!", "Mod news, updates and discussions — on our server.", "Join Discord", "Close", "Joining is optional · Esc to close"); internal static readonly InviteText[] ByLanguage = new InviteText[9] { English, new InviteText("LANG_FR", "Français", "Rejoins-nous sur Discord\u00a0!", "Actus du mod, mises à jour et discussions — sur notre serveur.", "Rejoindre Discord", "Fermer", "Facultatif · Échap pour fermer"), new InviteText("LANG_IT", "Italiano", "Unisciti a noi su Discord!", "Novità della mod, aggiornamenti e discussioni — sul nostro server.", "Entra su Discord", "Chiudi", "Facoltativo · Esc per chiudere"), new InviteText("LANG_DE", "Deutsch", "Komm auf unseren Discord!", "Mod-News, Updates und Diskussionen — auf unserem Server.", "Discord beitreten", "Schließen", "Beitritt freiwillig · Esc zum Schließen"), new InviteText("LANG_ES", "Español", "¡Únete a nuestro Discord!", "Noticias del mod, actualizaciones y debates — en nuestro servidor.", "Unirse a Discord", "Cerrar", "Es opcional · Esc para cerrar"), new InviteText("LANG_PT_BR", "Português (Brasil)", "Entre no nosso Discord!", "Novidades do mod, atualizações e discussões — no nosso servidor.", "Entrar no Discord", "Fechar", "É opcional · Esc para fechar"), new InviteText("LANG_RU", "Русский", "Присоединяйся в Discord!", "Новости мода, обновления и обсуждения — на нашем сервере.", "Зайти в Discord", "Закрыть", "Вступать необязательно · Esc — закрыть"), new InviteText("LANG_CH", "简体中文", "加入我们的 Discord!", "模组新闻、更新和讨论——尽在我们的服务器。", "加入 Discord", "关闭", "加入为可选 · 按 Esc 关闭"), new InviteText("LANG_JA", "日本語", "Discordに参加しよう!", "MODのニュース、アップデート、ディスカッションは私たちのサーバーで。", "Discordに参加", "閉じる", "参加は任意です · Escで閉じる") }; private static readonly Dictionary<char, string> Substitutes = new Dictionary<char, string> { { '—', "-" }, { '–', "-" }, { '·', "|" }, { '\u00a0', " " }, { '!', "!" }, { '、', ", " }, { '。', ". " }, { '¡', "" } }; internal string[] Fields => new string[5] { Title, Body, Join, Close, Hint }; private InviteText(string code, string language, string title, string body, string join, string close, string hint, bool rightToLeft = false) { Code = code; Language = language; Title = title; Body = body; Join = join; Close = close; Hint = hint; RightToLeft = rightToLeft; } internal static InviteText For(int language) { if (language < 0 || language >= ByLanguage.Length) { return English; } InviteText inviteText = ByLanguage[language]; string[] fields = inviteText.Fields; for (int i = 0; i < fields.Length; i++) { if (string.IsNullOrEmpty(fields[i])) { return English; } } return inviteText; } internal static string FitToFont(string text, Func<char, bool> fontHas) { if (string.IsNullOrEmpty(text)) { return text; } StringBuilder stringBuilder = new StringBuilder(text.Length); foreach (char c in text) { if (c == ' ' || c == '\n' || fontHas(c)) { stringBuilder.Append(c); continue; } if (Substitutes.TryGetValue(c, out var value)) { bool flag = true; string text2 = value; foreach (char c2 in text2) { if (c2 != ' ' && !fontHas(c2)) { flag = false; } } if (flag) { stringBuilder.Append(value); continue; } } return null; } return stringBuilder.ToString().Trim(); } internal InviteText FitToFont(Func<char, bool> fontHas) { string[] array = new string[5]; string[] fields = Fields; for (int i = 0; i < fields.Length; i++) { array[i] = FitToFont(fields[i], fontHas); if (array[i] == null) { return null; } } return new InviteText(Code, Language, array[0], array[1], array[2], array[3], array[4], RightToLeft); } } internal static class InviteSchedule { internal const float MenuSettleSeconds = 1.5f; internal static bool ShouldShow(bool enabledInConfig, bool shownThisLaunch, bool mainMenuActive, float menuStableSeconds) { if (enabledInConfig && !shownThisLaunch && mainMenuActive) { return menuStableSeconds >= 1.5f; } return false; } } internal static class NativeTemplateAdapter { internal static void Apply() { TemplateCompatibility.Apply(ULoader.VDic, Valid, Replacement, delegate(TemplateAlias rule, object value) { GameObject val = (GameObject)((value is GameObject) ? value : null); PortPlugin.Info(Object.op_Implicit((Object)(object)val) ? ("Template resolved: " + rule.Category + "/" + rule.LegacyName + " -> " + ((Object)val).name) : ("Optional footwear omitted: " + rule.Category + "/" + rule.LegacyName)); }); } private static bool Valid(TemplateAlias rule, object value) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Invalid comparison between Unknown and I4 GameObject val = (GameObject)((value is GameObject) ? value : null); if (!Object.op_Implicit((Object)(object)val)) { return false; } switch (rule.Role) { case TemplateRole.Ranged: return Object.op_Implicit((Object)(object)val.GetComponent<RangeWeapon>()); case TemplateRole.Melee: return Object.op_Implicit((Object)(object)val.GetComponent<MeleeWeapon>()); case TemplateRole.Shoes: { CharacterItem componentInChildren2 = val.GetComponentInChildren<CharacterItem>(true); if (Object.op_Implicit((Object)(object)componentInChildren2)) { return (int)componentInChildren2.GearT == 9; } return false; } case TemplateRole.Shield: { if (!Object.op_Implicit((Object)(object)val.GetComponent<Weapon>()) || Object.op_Implicit((Object)(object)val.GetComponent<RangeWeapon>())) { return false; } if (Object.op_Implicit((Object)(object)val.GetComponentInChildren<ShieldWobble>(true))) { return true; } WeaponItem componentInChildren = val.GetComponentInChildren<WeaponItem>(true); if (!HasShieldName(((Object)val).name)) { if (Object.op_Implicit((Object)(object)componentInChildren) && ((CharacterItem)componentInChildren).Entity != null) { return HasShieldName(((CharacterItem)componentInChildren).Entity.Name); } return false; } return true; } default: return false; } } private static bool HasShieldName(string name) { if (name != null) { return name.IndexOf("shield", StringComparison.OrdinalIgnoreCase) >= 0; } return false; } private static object Replacement(TemplateAlias rule) { string[] units = rule.Units; for (int i = 0; i < units.Length; i++) { UnitBlueprint unit = NativeUnit(units[i]); GameObject val = FromUnit(rule, unit); if (Object.op_Implicit((Object)(object)val)) { return val; } } if (rule.Role == TemplateRole.Shoes) { return (from p in ULoader.Native.GetCharacterProps() where Valid(rule, p) select p).OrderBy<GameObject, string>((GameObject p) => ((Object)p).name, StringComparer.Ordinal).FirstOrDefault(); } if (rule.LegacyName == "Thrower_WheelBarrowApple") { units = new string[2] { "SpearThrower", "Musketeer" }; foreach (string name in units) { GameObject val2 = FromUnit(rule, NativeUnit(name)); if (Object.op_Implicit((Object)(object)val2)) { return val2; } } } return null; } private static UnitBlueprint NativeUnit(string name) { if (!TemplateCompatibility.TryFind(ULoader.VDic["blueprints"], name, out var value)) { return null; } return (UnitBlueprint)((value is UnitBlueprint) ? value : null); } private static GameObject FromUnit(TemplateAlias rule, UnitBlueprint unit) { if (!Object.op_Implicit((Object)(object)unit)) { return null; } if (rule.Role == TemplateRole.Shoes) { return ((IEnumerable<GameObject>)(((object)unit.m_props) ?? ((object)new GameObject[0]))).FirstOrDefault((Func<GameObject, bool>)((GameObject p) => Valid(rule, p))); } return Weapons(unit, new HashSet<UnitBlueprint>()).FirstOrDefault((Func<GameObject, bool>)((GameObject p) => Valid(rule, p))); } private static IEnumerable<GameObject> Weapons(UnitBlueprint unit, HashSet<UnitBlueprint> seen) { if (!Object.op_Implicit((Object)(object)unit) || !seen.Add(unit)) { yield break; } if (Object.op_Implicit((Object)(object)unit.LeftWeapon)) { yield return unit.LeftWeapon; } if (Object.op_Implicit((Object)(object)unit.RightWeapon)) { yield return unit.RightWeapon; } UnitBlueprint[] array = (UnitBlueprint[])(((object)unit.UnitRiders) ?? ((object)new UnitBlueprint[0])); foreach (UnitBlueprint unit2 in array) { foreach (GameObject item in Weapons(unit2, seen)) { yield return item; } } if (!Object.op_Implicit((Object)(object)unit.UnitBase)) { yield break; } Weapon[] componentsInChildren = unit.UnitBase.GetComponentsInChildren<Weapon>(true); foreach (Weapon val in componentsInChildren) { if (Object.op_Implicit((Object)(object)val)) { yield return ((Component)val).gameObject; } } } } [AttributeUsage(AttributeTargets.Class)] internal sealed class DiagnosticPatchAttribute : Attribute { } internal static class PortDiagnostics { private static readonly DiagnosticGate gate = new DiagnosticGate(200); internal static string Name(Unit unit) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)unit)) { return "?"; } UnitBlueprint unitBlueprint = unit.unitBlueprint; if (Object.op_Implicit((Object)(object)unitBlueprint) && unitBlueprint.Entity != null && ULoader.Names.TryGetValue(unitBlueprint.Entity.GUID, out var value)) { return value; } return ((Object)unit).name; } internal static void Info(Unit unit, string issue, string detail) { string text = gate.Admit(Name(unit), issue, detail); if (text != null) { PortPlugin.Info(text); } } internal static void Warn(Unit unit, string issue, string detail) { string text = gate.Admit(Name(unit), issue, detail); if (text != null) { PortPlugin.Warn(text); } } internal static void Failure(string method, IEnumerable<Unit> units, Exception exception) { if (exception == null) { return; } try { Unit[] array = units.Where(PortRuntime.Owns).Distinct().ToArray(); if (array.Length != 0) { string unit = string.Join(", ", array.Select(Name).ToArray()); string text = gate.Admit(unit, method + " threw " + exception.GetType().Name, exception.ToString()); if (text != null) { PortPlugin.Error(text); } } } catch (Exception exception2) { PortPlugin.Report("Diagnostics for " + method, exception2); } } internal static Unit Of(Component component) { if (!Object.op_Implicit((Object)(object)component)) { return null; } return component.GetComponentInParent<Unit>(); } internal static Unit Of(DataHandler data) { if (!Object.op_Implicit((Object)(object)data)) { return null; } return data.unit; } } [HarmonyPatch(typeof(BlockMove), "GetAcceptableRigs")] internal static class BlockMoveAnchorHook { private static readonly FieldInfo Handler = AccessTools.Field(typeof(BlockMove), "weaponHandler"); private static readonly FieldInfo Rigs = AccessTools.Field(typeof(BlockMove), "acceptableRigs"); private static bool Prefix(BlockMove __instance) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown Unit val = PortDiagnostics.Of((Component)(object)__instance); if (!PortRuntime.Owns(val)) { return true; } WeaponHandler val2 = (WeaponHandler)Handler.GetValue(__instance); List<Rigidbody> list = (List<Rigidbody>)Rigs.GetValue(__instance); bool meleeRight = Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val2.rightWeapon) && Object.op_Implicit((Object)(object)((Component)val2.rightWeapon).GetComponent<MeleeWeapon>()); bool meleeLeft = Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val2.leftWeapon) && Object.op_Implicit((Object)(object)((Component)val2.leftWeapon).GetComponent<MeleeWeapon>()); bool hasLeftHand = Object.op_Implicit((Object)(object)((Component)((Component)__instance).transform.root).GetComponentInChildren<HandLeft>()); if (!RuntimeCompatibilityRules.NeedsBlockAnchor(Object.op_Implicit((Object)(object)val2), meleeRight, meleeLeft, list?.Count ?? 0, hasLeftHand)) { return true; } Rigidbody val3 = (Object.op_Implicit((Object)(object)val.data) ? val.data.mainRig : null); if (!Object.op_Implicit((Object)(object)val3) || list == null) { PortDiagnostics.Warn(val, "BlockMove has neither hands nor a main rigidbody", ((Object)__instance).name); return true; } list.Add(val3); PortDiagnostics.Info(val, "BlockMove anchored to the vehicle body because its base has no hands", ((Object)__instance).name); return false; } } [HarmonyPatch] [DiagnosticPatch] internal static class MountFailureReport { private static IEnumerable<MethodBase> TargetMethods() { yield return AccessTools.Method(typeof(Mount), "Update", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(Mount), "EnterMount", (Type[])null, (Type[])null); } private static void Finalizer(Exception __exception, Mount __instance, MethodBase __originalMethod) { if (__exception != null) { List<Unit> units = new List<Unit> { PortDiagnostics.Of((Component)(object)__instance), PortDiagnostics.Of(Object.op_Implicit((Object)(object)__instance) ? __instance.OtherData : null) }; PortDiagnostics.Failure("Mount." + __originalMethod.Name, units, __exception); } } } [HarmonyPatch(typeof(DodgeMove), "DoMove", new Type[] { typeof(Rigidbody), typeof(Rigidbody), typeof(DataHandler) })] [DiagnosticPatch] internal static class DodgeMoveFailureReport { private static void Finalizer(Exception __exception, DodgeMove __instance) { if (__exception != null) { PortDiagnostics.Failure("DodgeMove.DoMove", (IEnumerable<Unit>)(object)new Unit[1] { PortDiagnostics.Of((Component)(object)__instance) }, __exception); } } } [HarmonyPatch] [DiagnosticPatch] internal static class DodgeSequenceFailureReport { private static FieldInfo owner; private static MethodBase TargetMethod() { Type type = typeof(DodgeMove).GetNestedTypes(BindingFlags.NonPublic).Single((Type t) => t.Name.StartsWith("<DoMoveSequence>")); owner = AccessTools.Field(type, "<>4__this"); return AccessTools.Method(type, "MoveNext", (Type[])null, (Type[])null); } private static void Finalizer(Exception __exception, object __instance) { if (__exception != null) { DodgeMove component = (DodgeMove)((owner == null) ? null : /*isinst with value type is only supported in some contexts*/); PortDiagnostics.Failure("DodgeMove.DoMoveSequence", (IEnumerable<Unit>)(object)new Unit[1] { PortDiagnostics.Of((Component)(object)component) }, __exception); } } } [HarmonyPatch(typeof(BlockMove), "ProjectileBlock")] [DiagnosticPatch] internal static class BlockMoveFailureReport { private static void Finalizer(Exception __exception, BlockMove __instance) { if (__exception != null) { PortDiagnostics.Failure("BlockMove.ProjectileBlock", (IEnumerable<Unit>)(object)new Unit[1] { PortDiagnostics.Of((Component)(object)__instance) }, __exception); } } } [HarmonyPatch(typeof(UnitPlacementBrush), "RemoveUnitInternal")] [DiagnosticPatch] internal static class RemoveUnitFailureReport { private static void Finalizer(Exception __exception, Unit unit) { if (__exception == null) { return; } List<Unit> list = new List<Unit> { unit }; RiderHolder val = (Object.op_Implicit((Object)(object)unit) ? ((Component)unit).GetComponent<RiderHolder>() : null); if (Object.op_Implicit((Object)(object)val) && val.riders != null) { foreach (GameObject rider in val.riders) { if (Object.op_Implicit((Object)(object)rider)) { list.Add(rider.GetComponent<Unit>()); } } } PortDiagnostics.Failure("UnitPlacement.RemoveUnitInternal", list, __exception); } } [HarmonyPatch] [DiagnosticPatch] internal static class CharacterMovementFailureReport { private static bool Prepare() { return AccessTools.TypeByName("CharacterMovement") != null; } private static IEnumerable<MethodBase> TargetMethods() { Type type = AccessTools.TypeByName("CharacterMovement"); string[] array = new string[3] { "Start", "Update", "FixedUpdate" }; foreach (string text in array) { MethodInfo methodInfo = AccessTools.Method(type, text, (Type[])null, (Type[])null); if (methodInfo != null) { yield return methodInfo; } } } private static void Finalizer(Exception __exception, MonoBehaviour __instance, MethodBase __originalMethod) { if (__exception != null) { PortDiagnostics.Failure("CharacterMovement." + __originalMethod.Name, (IEnumerable<Unit>)(object)new Unit[1] { PortDiagnostics.Of((Component)(object)__instance) }, __exception); } } } [BepInPlugin("modernization.port.bepinex", "modernization port by lil zalupa", "0.9.4")] public sealed class PortPlugin : BaseUnityPlugin { public const string Guid = "modernization.port.bepinex"; public const string Version = "0.9.4"; internal static readonly UManager Manager = new UManager(); private static ManualLogSource log; internal static bool Ready; private bool attempted; private float nextCheck; private static readonly HashSet<string> errors = new HashSet<string>(); internal static void Info(string message) { if (log != null) { log.LogInfo((object)message); } } internal static void Warn(string message) { if (log != null) { log.LogWarning((object)message); } } internal static void Error(string message) { if (log != null) { log.LogError((object)message); } } internal static void Report(string context, Exception exception) { if (log != null && errors.Add(context)) { log.LogError((object)(context + ": " + exception)); } } private void Awake() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown log = ((BaseUnityPlugin)this).Logger; Harmony val = new Harmony("modernization.port.bepinex"); Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(typeof(PortPlugin).Assembly); foreach (Type type in typesFromAssembly) { if (!type.IsDefined(typeof(HarmonyPatch), inherit: false)) { continue; } try { val.CreateClassProcessor(type).Patch(); } catch (Exception exception) { if (type.IsDefined(typeof(DiagnosticPatchAttribute), inherit: false)) { Report("Diagnostic hook " + type.Name + " unavailable", exception); continue; } attempted = true; Report("Could not install native API hook " + type.Name, exception); } } if (!attempted) { Info("modernization port by lil zalupa 0.9.4 loaded; creator: lilzalupa; waiting for native content."); } ConfigEntry<bool> entry = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowDiscordInvite", true, "Show a small Discord invitation once per game launch, after the main menu is ready. Set to false to never show it."); ((Component)this).gameObject.AddComponent<DiscordInviteController>().Init(entry); } private void Update() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Expected O, but got Unknown if (attempted || Time.realtimeSinceStartup < nextCheck) { return; } nextCheck = Time.realtimeSinceStartup + 1f; ContentDatabase val = (ContentDatabase)AccessTools.Field(typeof(ContentDatabase), "m_instance").GetValue(null); if (val == null || val.LandfallContentDatabase == null || !val.LandfallContentDatabase.GetUnitBlueprints().Any() || !val.LandfallContentDatabase.GetFactions().Any((Faction x) => Object.op_Implicit((Object)(object)x) && x.m_displayFaction)) { return; } SoundPlayer service = ServiceLocator.GetService<SoundPlayer>(); if (!Object.op_Implicit((Object)(object)service) || !Object.op_Implicit((Object)(object)service.soundBank)) { return; } attempted = true; try { PinaCollada.EnsureLoaded(); ULoader.Prepare(val); LegacyTemplates.Validate(); Info("Native weapon/base/turning templates ready; registering Modernization factions."); Manager.Init(null); foreach (UnitBlueprint createdUnit in ULoader.CreatedUnits) { Manager.EditBlueprint(createdUnit, ULoader.MDic["Modernization"], null); if (createdUnit.m_props == null) { createdUnit.m_props = (GameObject[])(object)new GameObject[0]; } PropItemData[] propData = createdUnit.m_propData; createdUnit.m_propData = (PropItemData[])(object)new PropItemData[createdUnit.m_props.Length]; for (int num = 0; num < createdUnit.m_propData.Length; num++) { createdUnit.m_propData[num] = (PropItemData)((propData != null && num < propData.Length && propData[num] != null) ? ((object)propData[num]) : ((object)new PropItemData())); } createdUnit.rightProjectile = null; createdUnit.leftProjectile = null; VehicleCompatibility.PrepareBlueprint(createdUnit); } PortRuntime.RegisterSounds(service.soundBank); Ready = true; Info("MODERNIZATION READY: " + ULoader.CreatedUnits.Count + " blueprints, " + ULoader.CreatedFactions.Count + " factions; game MVID=" + typeof(UnitBlueprint).Assembly.ManifestModule.ModuleVersionId); } catch (Exception exception) { Ready = false; ULoader.Rollback(); Report("Modernization initialization rolled back", exception); } } } [HarmonyPatch(typeof(UnitBlueprint), "SetWeapon")] internal static class WeaponHook { private static readonly HashSet<string> gateReports = new HashSet<string>(); private static void Prefix(Unit unit) { if (PortRuntime.Owns(unit)) { PortRuntime.SetIdentity(unit); } } private unsafe static void Postfix(Weapon __result, Unit unit, Team team, HandType handType) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) if (!PortPlugin.Ready || !Object.op_Implicit((Object)(object)__result) || !PortRuntime.Owns(unit)) { return; } string text = Name(unit) + "/" + ((object)(*(HandType*)(&handType))/*cast due to .constrained prefix*/).ToString(); RangeWeapon val = null; try { val = ((Component)__result).GetComponentInChildren<RangeWeapon>(); PortPlugin.Manager.EditWeapons(((Component)__result).gameObject, handType, team, unit, ((Component)__result).GetComponentInChildren<MeleeWeapon>(), val, null); } catch (Exception exception) { PortPlugin.Report("Weapon setup for " + text, exception); } try { PortRuntime.IsolateProjectile(val, unit); PortRuntime.RestoreVisuals(((Component)__result).gameObject); } catch (Exception exception2) { PortPlugin.Report("Visual setup for " + text, exception2); } try { RefreshUnitAttackGate(unit, __result); } catch (Exception exception3) { PortPlugin.Report("Attack gate refresh for " + text, exception3); } } private static string Name(Unit unit) { if (!Object.op_Implicit((Object)(object)unit) || !Object.op_Implicit((Object)(object)unit.unitBlueprint) || unit.unitBlueprint.Entity == null) { return "?"; } return unit.unitBlueprint.Entity.Name; } private static void RefreshUnitAttackGate(Unit unit, Weapon weapon) { if (!Object.op_Implicit((Object)(object)unit)) { return; } WeaponHandler val = unit.WeaponHandler; if (!Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)weapon)) { val = ((Component)weapon).GetComponentInParent<WeaponHandler>(); } if (!Object.op_Implicit((Object)(object)val)) { return; } float num = float.PositiveInfinity; if (Object.op_Implicit((Object)(object)val.rightWeapon)) { num = Mathf.Min(num, val.rightWeapon.GetLowestAttackTimeOfWeapons()); } if (Object.op_Implicit((Object)(object)val.leftWeapon)) { num = Mathf.Min(num, val.leftWeapon.GetLowestAttackTimeOfWeapons()); } if (!float.IsNaN(num) && !float.IsInfinity(num) && !(num >= unit.lowestAttackTimeOfWeapons)) { unit.lowestAttackTimeOfWeapons = num; string text = ((Object.op_Implicit((Object)(object)unit.unitBlueprint) && unit.unitBlueprint.Entity != null) ? unit.unitBlueprint.Entity.Name : "?"); if (gateReports.Add(text + "|" + num)) { PortPlugin.Info("[rate-gate] " + text + ": lowestAttackTimeOfWeapons -> " + num); } } } } [HarmonyPatch] internal static class SpawnHook { private static MethodBase TargetMethod() { return typeof(UnitBlueprint).GetMethods().Single((MethodInfo x) => x.Name == "Spawn" && x.GetParameters().Length == 9); } private static void Postfix(UnitBlueprint __instance, Unit unitToSpawn) { if (!PortPlugin.Ready || !PortRuntime.Owns(__instance) || !Object.op_Implicit((Object)(object)unitToSpawn)) { return; } PortRuntime.SetIdentity(unitToSpawn); PortUnitState portUnitState = PortRuntime.Ensure<PortUnitState>(((Component)unitToSpawn).gameObject); if (portUnitState.SpawnConfigured) { return; } portUnitState.SpawnConfigured = true; try { PortPlugin.Manager.CodeOnSpawn(unitToSpawn, null); GameObject[] moves = (GameObject[])(((object)__instance.objectsToSpawnAsChildren) ?? ((object)new GameObject[0])); Transform[] source = ((IEnumerable)((Component)unitToSpawn).transform).Cast<Transform>().ToArray(); HashSet<Transform> used = new HashSet<Transform>(); int i; for (i = 0; i < moves.Length; i++) { if (Object.op_Implicit((Object)(object)moves[i])) { Transform val = ((IEnumerable<Transform>)source).FirstOrDefault((Func<Transform, bool>)((Transform x) => !used.Contains(x) && ((Object)x).name.Replace("(Clone)", "") == ((Object)moves[i]).name)); if (Object.op_Implicit((Object)(object)val)) { used.Add(val); PortPlugin.Manager.EditCombatMoves(((Component)val).gameObject, i, unitToSpawn, null); } } } PortRuntime.RestoreVisuals(((Component)unitToSpawn).gameObject); } catch (Exception exception) { PortPlugin.Report("Abilities for " + __instance.Entity.Name, exception); } } } [HarmonyPatch(typeof(UnitRig), "SpawnProps")] internal static class PropsHook { private static void Prefix(UnitRig __instance) { Unit componentInParent = ((Component)__instance).GetComponentInParent<Unit>(); if (PortPlugin.Ready && PortRuntime.Owns(componentInParent)) { PortRuntime.SetIdentity(componentInParent); PortRuntime.Ensure<PortUnitState>(((Component)componentInParent).gameObject).NextPropIndex = 0; } } } [HarmonyPatch(typeof(UnitRig), "SpawnProp")] internal static class PropHook { private static void Prefix(UnitRig __instance, CharacterItem prop, out int __state) { __state = -1; Unit componentInParent = ((Component)__instance).GetComponentInParent<Unit>(); if (!PortPlugin.Ready || !PortRuntime.Owns(componentInParent) || !Object.op_Implicit((Object)(object)prop)) { return; } PortUnitState portUnitState = PortRuntime.Ensure<PortUnitState>(((Component)componentInParent).gameObject); GameObject[] props = componentInParent.unitBlueprint.m_props; int num = portUnitState.NextPropIndex; while (props != null && num < props.Length) { if ((Object)(object)props[num] == (Object)(object)((Component)prop).gameObject) { __state = num; portUnitState.NextPropIndex = num + 1; break; } num++; } } private static void Postfix(UnitRig __instance, GameObject __result, PropItemData propData, int __state) { if (__state < 0 || !Object.op_Implicit((Object)(object)__result)) { return; } Unit componentInParent = ((Component)__instance).GetComponentInParent<Unit>(); try { PortPlugin.Manager.EditClothes(__result, __result.GetComponent<CharacterItem>(), propData, componentInParent, __state, null); PortRuntime.RestoreVisuals(__result); } catch (Exception exception) { PortPlugin.Report("Clothing for " + componentInParent.unitBlueprint.Entity.Name + "/" + __state, exception); } } } [HarmonyPatch(typeof(Unit), "Start")] internal static class UnitStartHook { private static void Prefix(Unit __instance) { if (PortRuntime.Owns(__instance)) { PortRuntime.SetIdentity(__instance); } } private static void Postfix(Unit __instance) { if (!PortPlugin.Ready || !PortRuntime.Owns(__instance)) { return; } PortUnitState portUnitState = PortRuntime.Ensure<PortUnitState>(((Component)__instance).gameObject); if (portUnitState.AfterSpawnConfigured) { return; } portUnitState.AfterSpawnConfigured = true; try { PortPlugin.Manager.CodeAfterSpawn(__instance, null); PortRuntime.RestoreVisuals(((Component)__instance).gameObject); } catch (Exception exception) { PortPlugin.Report("After-spawn setup for " + __instance.unitBlueprint.Entity.Name, exception); } } } [HarmonyPatch(typeof(RangeWeapon), "SetProjectileStats")] internal static class ProjectileHook { private static void Prefix(RangeWeapon __instance, GameObject spawnedObject) { if (!PortPlugin.Ready || !Object.op_Implicit((Object)(object)spawnedObject)) { return; } Unit val = (Object.op_Implicit((Object)(object)((Weapon)__instance).connectedData) ? ((Weapon)__instance).connectedData.unit : ((Component)__instance).GetComponentInParent<Unit>()); if (!PortRuntime.Owns(val) || Object.op_Implicit((Object)(object)spawnedObject.GetComponent<PortProjectile>())) { return; } spawnedObject.AddComponent<PortProjectile>(); try { PortPlugin.Manager.EditProjectiles(spawnedObject, spawnedObject.GetComponentInChildren<ProjectileHit>(), val, null); PortRuntime.RestoreVisuals(spawnedObject); } catch (Exception exception) { PortPlugin.Report("Projectile setup for " + val.unitBlueprint.Entity.Name, exception); } } } [HarmonyPatch(typeof(RangeWeapon), "Start")] internal static class MagazineStartHook { private static void Postfix(RangeWeapon __instance) { LegacyMagazine component = ((Component)__instance).GetComponent<LegacyMagazine>(); if (Object.op_Implicit((Object)(object)component) && component.StartingAmmo >= 0) { AccessTools.Field(typeof(RangeWeapon), "ammo").SetValue(__instance, component.StartingAmmo); } } } [HarmonyPatch(typeof(RangeWeapon), "Reload")] internal static class ReloadHook { private static void Prefix(RangeWeapon __instance) { PortRuntime.PlayReload(((Component)__instance).GetComponent<LegacyMagazine>()); } } public sealed class LegacyBlueprint { private readonly UnitBlueprint unit; public UnitBlueprint[] Riders { get { return unit.UnitRiders; } set { unit.SetNoCustomRider(); AccessTools.Field(typeof(UnitBlueprint), "Riders").SetValue(unit, value); } } public string VocalRef { get { return unit.VocalRef; } set { if (!Object.op_Implicit((Object)(object)unit.voiceBundle)) { unit.voiceBundle = ScriptableObject.CreateInstance<VoiceBundle>(); } unit.voiceBundle.VocalRef = value; AccessTools.Field(typeof(UnitBlueprint), "vocalPathData").SetValue(unit, null); } } private LegacyBlueprint(UnitBlueprint value) { unit = value; } public static LegacyBlueprint For(UnitBlueprint value) { return new LegacyBlueprint(value); } } public sealed class LegacyMagazine : MonoBehaviour { internal int StartingAmmo = -1; public string ReloadSound; private RangeWeapon Weapon => ((Component)this).GetComponent<RangeWeapon>(); public int InitialAmmo { get { return StartingAmmo; } set { StartingAmmo = value; } } public int Capacity { get { return Weapon.magSize; } set { Weapon.magSize = Math.Max(1, value); } } public float ReloadSeconds { get { return Weapon.reloadTime; } set { Weapon.reloadTime = Math.Max(0f, value); } } public float ShotInterval { get { return ((Weapon)Weapon).internalCooldown; } set { ((Weapon)Weapon).internalCooldown = Math.Max(0.001f, value); } } public static LegacyMagazine For(RangeWeapon weapon) { if (!Object.op_Implicit((Object)(object)weapon)) { throw new ArgumentNullException("weapon"); } return PortRuntime.Ensure<LegacyMagazine>(((Component)weapon).gameObject); } } public static class LegacyTemplates { private static UnitBlueprint Named(params string[] names) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown foreach (string key in names) { if (ULoader.VDic["blueprints"].TryGetValue(key, out var value)) { return (UnitBlueprint)value; } } throw new MissingMemberException("Required vanilla blueprint: " + string.Join(" / ", names)); } public static UnitBlueprint Blueprint(int legacyIndex) { return (UnitBlueprint)(legacyIndex switch { 17 => Named("Healer"), 81 => Named("Valkyrie", "ValkyrieUnit"), _ => throw new NotSupportedException("Unmapped legacy blueprint " + legacyIndex), }); } public static GameObject Base(int legacyIndex) { return (GameObject)(legacyIndex switch { 4 => Named("Wheelbarrow").UnitBase, 12 => Named("CavalryKnight").UnitBase, _ => throw new NotSupportedException("Unmapped legacy base " + legacyIndex), }); } public static GameObject Weapon(int legacyIndex) { UnitBlueprint val = (UnitBlueprint)(legacyIndex switch { 2 => Named("Archer"), 14 => Named("Cannon"), 44 => Named("Musketeer"), 49 => Named("BombThrower", "Bomb Thrower"), 50 => Named("BombCannon", "Bomb Cannon"), 70 => Named("Musketeer"), _ => throw new NotSupportedException("Unmapped legacy weapon " + legacyIndex), }); GameObject val2 = val.RightWeapon; if (!Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val.UnitBase)) { RangeWeapon componentInChildren = val.UnitBase.GetComponentInChildren<RangeWeapon>(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { val2 = ((Component)componentInChildren).gameObject; } } if (!Object.op_Implicit((Object)(object)val2)) { throw new MissingMemberException("Vanilla weapon unavailable: " + val.Entity.Name); } return val2; } internal static void Validate() { int[] array = new int[6] { 2, 14, 44, 49, 50, 70 }; for (int i = 0; i < array.Length; i++) { GameObject val = Weapon(array[i]); if (!Object.op_Implicit((Object)(object)val.GetComponent<RangeWeapon>())) { throw new MissingMemberException("Template is not a ranged weapon: " + ((Object)val).name); } } Base(4); Base(12); Blueprint(17); Blueprint(81); } } public sealed class PortUnitState : MonoBehaviour { internal bool SpawnConfigured; internal bool AfterSpawnConfigured; internal int NextPropIndex; internal readonly List<GameObject> ProjectilePrefabs = new List<GameObject>(); private void OnDestroy() { foreach (GameObject projectilePrefab in ProjectilePrefabs) { if (Object.op_Implicit((Object)(object)projectilePrefab)) { Object.Destroy((Object)(object)projectilePrefab); } } } } public sealed class PortProjectile : MonoBehaviour { } public static class PortRuntime { internal static bool Owns(UnitBlueprint blueprint) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)blueprint) && blueprint.Entity != null) { return ULoader.Names.ContainsKey(blueprint.Entity.GUID); } return false; } internal static bool Owns(Unit unit) { if (Object.op_Implicit((Object)(object)unit)) { return Owns(unit.unitBlueprint); } return false; } internal static void SetIdentity(Unit unit) { if (Owns(unit)) { AccessTools.Field(typeof(Unit), "m_entity").SetValue(unit, unit.unitBlueprint.Entity.ShallowCopy()); } } public static T Ensure<T>(GameObject go) where T : Component { T component = go.GetComponent<T>(); if (!Object.op_Implicit((Object)(object)component)) { return go.AddComponent<T>(); } return component; } public static void SetFootSound(UnitSounds sounds, string path) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)sounds)) { return; } if (string.IsNullOrWhiteSpace(path)) { sounds.FootPathData = null; return; } string[] array = path.Split(new char[1] { '/' }); if (array.Length != 2) { throw new FormatException("Invalid foot sound: " + path); } sounds.FootPathData = new AudioPathData(array[0], array[1], 1f, 1f); } public static void SetConditionalRange(ConditionalEvent move, float range) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Invalid comparison between Unknown and I4 //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Invalid comparison between Unknown and I4 //IL_005b: Unknown result type (might be due to invalid IL or missing references) move.extraRange = 0f; ConditionalEventInstance[] array = (ConditionalEventInstance[])(((object)move.events) ?? ((object)new ConditionalEventInstance[0])); for (int i = 0; i < array.Length; i++) { EventCondition[] array2 = (EventCondition[])(((object)array[i].conditions) ?? ((object)new EventCondition[0])); foreach (EventCondition val in array2) { if ((int)val.conditionType == 1 && (int)val.valueType == 1) { val.value = range; val.rangeType = (RangeType)0; } if ((int)val.conditionType == 0) { val.onlyCountWhenUnitInRange = false; } } } } public static GameObject[] SpawnNative(UnitBlueprint blueprint, Vector3 position, Quaternion rotation, Team team) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) return blueprint.Spawn(position, rotation, team, 1f, (UnitPoolInfo?)null); } internal static void RestoreVisuals(GameObject go) { PortVisual[] componentsInChildren = go.GetComponentsInChildren<PortVisual>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Renderer[] componentsInChildren2 = ((Component)componentsInChildren[i]).GetComponentsInChildren<Renderer>(true); for (int j = 0; j < componentsInChildren2.Length; j++) { componentsInChildren2[j].enabled = true; } } } internal static void IsolateProjectile(RangeWeapon weapon, Unit owner) { if (!Object.op_Implicit((Object)(object)weapon) || !Object.op_Implicit((Object)(object)weapon.ObjectToSpawn)) { return; } GameObject objectToSpawn = weapon.ObjectToSpawn; if (Object.op_Implicit((Object)(object)objectToSpawn.GetComponent<PooledProjectile>())) { GameObject val = UPool.MyPool.ClonePrivate(objectToSpawn); PooledProjectile[] componentsInChildren = val.GetComponentsInChildren<PooledProjectile>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } PortRuntime.Ensure<PortUnitState>(((Component)owner).gameObject).ProjectilePrefabs.Add(val); weapon.ObjectToSpawn = val; } } internal static void RegisterSounds(SoundBank bank) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Expected O, but got Unknown List<SoundBankCategory> list = ((IEnumerable<SoundBankCategory>)(((object)bank.Categories) ?? ((object)new SoundBankCategory[0]))).ToList(); if (list.Any((SoundBankCategory x) => x.categoryName == "Modernization")) { throw new InvalidOperationException("Another Modernization audio category is already installed."); } SoundBankCategory val = ((IEnumerable<SoundBankCategory>)list).FirstOrDefault((Func<SoundBankCategory, bool>)((SoundBankCategory x) => x.categoryName.IndexOf("weapon", StringComparison.OrdinalIgnoreCase) >= 0)) ?? list.FirstOrDefault(); List<SoundEffectInstance> list2 = new List<SoundEffectInstance>(); foreach (KeyValuePair<string, SoundEffectInstance> sound in PinaCollada.Sounds) { SoundEffectInstance value = sound.Value; SoundEffectInstance val2 = new SoundEffectInstance(); FieldInfo[] fields = typeof(SoundEffectInstance).GetFields(); foreach (FieldInfo fieldInfo in fields) { fieldInfo.SetValue(val2, fieldInfo.GetValue(value)); } val2.soundRef = sound.Key; list2.Add(val2); } list.Add(new SoundBankCategory { categoryName = "Modernization", soundEffects = list2.ToArray(), categoryMixerGroup = val?.categoryMixerGroup, volumeMultiplier = 1f, pitchMultiplier = 1f, minDistanceMultiplier = 1f, maxDistanceMultiplier = 1f }); bank.Categories = list.ToArray(); } internal static void PlayReload(LegacyMagazine magazine) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)magazine) && !string.IsNullOrEmpty(magazine.ReloadSound)) { SoundPlayer service = ServiceLocator.GetService<SoundPlayer>(); if (Object.op_Implicit((Object)(object)service)) { service.PlaySoundEffect(magazine.ReloadSound, 1f, ((Component)magazine).transform.position, (MaterialType)0, (Transform)null, 1f); } } } } internal static class RequiredTemplates { internal static readonly string[][] Items = new string[49][] { new string[2] { "blueprints", "Cannon" }, new string[2] { "blueprints", "CavalryKnight" }, new string[2] { "blueprints", "Clubber" }, new string[2] { "blueprints", "Healer" }, new string[2] { "blueprints", "Musketeer" }, new string[2] { "blueprints", "Wheelbarrow" }, new string[2] { "clothes", "Ancient_Belt001" }, new string[2] { "clothes", "Ancient_Belt004" }, new string[2] { "clothes", "Ancient_ChestArmor003" }, new string[2] { "clothes", "Ancient_Helmet004" }, new string[2] { "clothes", "Ancient_Shirt002" }, new string[2] { "clothes", "Halloween_Archer_Glove002" }, new string[2] { "clothes", "Halloween_Archer_Wrist" }, new string[2] { "clothes", "Medieval_Pants002" }, new string[2] { "clothes", "NinjaShoes001" }, new string[2] { "clothes", "Renaissance_HandGuard" }, new string[2] { "clothes", "Renaissance_Shirt005" }, new string[2] { "explosions", "E_ExplosionBombCannon" }, new string[2] { "explosions", "E_ExplosionSamuraiGiant" }, new string[2] { "moves", "BarrelArmor_ArmLeft" }, new string[2] { "moves", "BarrelArmor_ArmRight" }, new string[2] { "moves", "BarrelArmor_ElbowLeft" }, new string[2] { "moves", "BarrelArmor_ElbowRight" }, new string[2] { "moves", "BarrelArmor_Head" }, new string[2] { "moves", "BarrelArmor_Hip" }, new string[2] { "moves", "BarrelArmor_KneeLeft" }, new string[2] { "moves", "BarrelArmor_KneeRight" }, new string[2] { "moves", "BarrelArmor_LegLeft" }, new string[2] { "moves", "BarrelArmor_LegRight" }, new string[2] { "moves", "BarrelArmor_Torso" }, new string[2] { "moves", "BlockShogun" }, new string[2] { "moves", "CavalryCharge" }, new string[2] { "moves", "Chukonu_Walk" }, new string[2] { "moves", "Fencer_Dodge" }, new string[2] { "moves", "FireBreath" }, new string[2] { "moves", "FireBreath_Wheelbarrow" }, new string[2] { "moves", "MinotaurCharge" }, new string[2] { "moves", "SwordArtParry" }, new string[2] { "moves", "Wings" }, new string[2] { "weapons", "BrawlerAxe" }, new string[2] { "weapons", "Chukonu" }, new string[2] { "weapons", "FanSpear" }, new string[2] { "weapons", "Musket" }, new string[2] { "weapons", "PriestStaff" }, new string[2] { "weapons", "Shield_Tower" }, new string[2] { "weapons", "Stick" }, new string[2] { "weapo