diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..99c8491 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,28 @@ +[*.cs] + +# CA1060: Move pinvokes to native methods class +dotnet_diagnostic.CA1060.severity = none + +# CA1806: Do not ignore method results +dotnet_diagnostic.CA1806.severity = none + +# CA1822: Mark members as static +dotnet_diagnostic.CA1822.severity = none + +# CA1031: Do not catch general exception types +dotnet_diagnostic.CA1031.severity = none + +# CA1724: Type names should not match namespaces +dotnet_diagnostic.CA1724.severity = none + +# CA1034: Nested types should not be visible +dotnet_diagnostic.CA1034.severity = none + +# CA3075: Insecure DTD processing in XML +dotnet_diagnostic.CA3075.severity = none + +# CA3075: Mark assemblies with NeutralResourcesLanguageAttribute +dotnet_diagnostic.CA1824.severity = none + +# CA1303: Do not pass literals as localized parameters +dotnet_diagnostic.CA1303.severity = none diff --git a/App.config b/App.config index d740e88..de27714 100644 --- a/App.config +++ b/App.config @@ -1,6 +1,6 @@ - + - + - \ No newline at end of file + diff --git a/Application.xaml.cs b/Application.xaml.cs index f1585a5..d6a1452 100644 --- a/Application.xaml.cs +++ b/Application.xaml.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Windows; @@ -48,17 +49,20 @@ private void ApplicationStartup(object sender, StartupEventArgs e) if (language == "Russian" || language == "English") Language = language; } - public static string[] CommandLineArgs; + public static IList CommandLineArgs { get; private set; } public static string StartupPath => Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly()?.Location); + private static string _language = ""; public static string Language { + get => _language; set { + _language = value; var newDict = new ResourceDictionary { Source = new Uri($"Languages/{value}.xaml", UriKind.Relative) }; - var oldDict = (from d in Current.Resources.MergedDictionaries where d.Source != null && d.Source.OriginalString.StartsWith("Languages/") select d).First(); + var oldDict = (from d in Current.Resources.MergedDictionaries where d.Source != null && d.Source.OriginalString.StartsWith("Languages/", StringComparison.OrdinalIgnoreCase) select d).First(); if (oldDict != null) { diff --git a/Core/Animations.cs b/Core/Animations.cs index e7ef8df..7e77a4c 100644 --- a/Core/Animations.cs +++ b/Core/Animations.cs @@ -10,10 +10,10 @@ public static class Animations { public static string[] Initialize() { - if(!File.Exists(Path.Combine(Common.InputPath, "actions.txt"))) return new string[0]; + if(!File.Exists(Path.Combine(Common.InputPath, "actions.txt"))) return Array.Empty(); var fId = new Win32FileReader(Path.Combine(Common.InputPath, "actions.txt")); - var n = Convert.ToInt32(fId.ReadLine()); + var n = Convert.ToInt32(fId.ReadLine(), CultureInfo.GetCultureInfo(1033)); var aAnimations = new string[n]; for (int i = 0; i < n; i++) { @@ -22,7 +22,7 @@ public static string[] Initialize() aAnimations[i] = animation.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[0]; - var j = Convert.ToInt32(animation.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[3]); + var j = Convert.ToInt32(animation.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[3], CultureInfo.GetCultureInfo("en-US")); while (j != 0) { fId.ReadLine(); @@ -38,16 +38,16 @@ public static string DecompileFlags(DWORD dwFlag) { var sbFlag = new StringBuilder(2048); var dwAnimFlagsLength = dwFlag & 0xFF000000; - string[] strAnimFlags = { "acf_synch_with_horse", "acf_align_with_ground", "acf_enforce_lowerbody", "acf_enforce_rightside", "acf_enforce_all", - "acf_parallels_for_look_slope", "acf_lock_camera", "acf_displace_position", "acf_ignore_slope", "acf_thrust", "acf_right_cut", + string[] strAnimFlags = { "acf_synch_with_horse", "acf_align_with_ground", "acf_enforce_lowerbody", "acf_enforce_rightside", "acf_enforce_all", + "acf_lock_rotation", "acf_parallels_for_look_slope", "acf_lock_camera", "acf_displace_position", "acf_ignore_slope", "acf_thrust", "acf_right_cut", "acf_left_cut", "acf_overswing", "acf_rot_vertical_bow", "acf_rot_vertical_sword" }; - DWORD[] dwAnimFlags = { 0x00000001, 0x00000002, 0x00000100, 0x00000200, 0x00000400, 0x00001000, 0x00002000, 0x00004000, 0x00008000, 0x00010000, + DWORD[] dwAnimFlags = { 0x00000001, 0x00000002, 0x00000100, 0x00000200, 0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000, 0x00008000, 0x00010000, 0x00020000, 0x00040000, 0x00080000, 0x00100000, 0x00200000 }; if (dwAnimFlagsLength != 0) { - dwAnimFlagsLength = dwAnimFlagsLength >> 24; + dwAnimFlagsLength >>= 24; dwFlag ^= 0xFF000000; - sbFlag.AppendFormat("acf_anim_length({0})", dwAnimFlagsLength); + sbFlag.AppendFormat(CultureInfo.GetCultureInfo(1033), "acf_anim_length({0})", dwAnimFlagsLength); } for (int f = 0; f < dwAnimFlags.Length; f++) @@ -116,7 +116,7 @@ public static string DecompileSequenceFlags(DWORD dwFlag) { var sbFlag = new StringBuilder(2048); DWORD dwSequenceBlend = dwFlag & 0xFF; - if (dwSequenceBlend != 0) sbFlag.AppendFormat("arf_blend_in_{0}", dwSequenceBlend - 1); + if (dwSequenceBlend != 0) sbFlag.AppendFormat(CultureInfo.GetCultureInfo("en-US"), "arf_blend_in_{0}", dwSequenceBlend - 1); string[] strAnimSequenceFlags = { "arf_make_walk_sound", "arf_make_custom_sound", "arf_two_handed_blade", "arf_lancer", "arf_stick_item_to_left_hand", "arf_cyclic", "arf_use_walk_progress", "arf_use_stand_progress", "arf_use_inv_walk_progress" }; @@ -169,9 +169,9 @@ public static void Decompile() var iActions = fActions.GetInt(); for (int a = 0; a < iActions; a++) { - string strAnimId = fActions.GetWord(); - DWORD dwAnimFlags = fActions.GetDWord(); - DWORD dwMasterAnimFlags = fActions.GetDWord(); + var strAnimId = fActions.GetWord(); + var dwAnimFlags = fActions.GetDWord(); + var dwMasterAnimFlags = fActions.GetDWord(); fSource.WriteLine(" [\"{0}\", {1}, {2},", strAnimId, DecompileFlags(dwAnimFlags), DecompileMasterFlags(dwMasterAnimFlags)); var iAnimSequences = fActions.GetInt(); for (int s = 0; s < iAnimSequences; s++) diff --git a/Core/Caribbean/Skins.cs b/Core/Caribbean/Skins.cs index 46fa25c..cbecf23 100644 --- a/Core/Caribbean/Skins.cs +++ b/Core/Caribbean/Skins.cs @@ -1,4 +1,5 @@ -using System.Globalization; +using System; +using System.Globalization; using System.IO; namespace Decomp.Core.Caribbean @@ -7,7 +8,7 @@ public static class Skins { public static string[] Initialize() { - if (!File.Exists(Path.Combine(Common.InputPath, "skins.txt"))) return new string[0]; + if (!File.Exists(Path.Combine(Common.InputPath, "skins.txt"))) return Array.Empty(); var fId = new Text(Path.Combine(Common.InputPath, "skins.txt")); fId.GetString(); @@ -180,8 +181,8 @@ public static void Decompile() int ixParticleSystem1 = fSkins.GetInt(), ixParticleSystem2 = fSkins.GetInt(); fSource.WriteLine(" {0}, {1},", - ixParticleSystem1 < Common.ParticleSystems.Length ? "psys_" + Common.ParticleSystems[ixParticleSystem1] : ixParticleSystem1.ToString(), - ixParticleSystem2 < Common.ParticleSystems.Length ? "psys_" + Common.ParticleSystems[ixParticleSystem2] : ixParticleSystem2.ToString()); + ixParticleSystem1 < Common.ParticleSystems.Count ? "psys_" + Common.ParticleSystems[ixParticleSystem1] : ixParticleSystem1.ToString(CultureInfo.GetCultureInfo("en-US")), + ixParticleSystem2 < Common.ParticleSystems.Count ? "psys_" + Common.ParticleSystems[ixParticleSystem2] : ixParticleSystem2.ToString(CultureInfo.GetCultureInfo("en-US"))); var iConstraints = fSkins.GetInt(); fSource.Write(" ["); diff --git a/Core/Caribbean/Troops.cs b/Core/Caribbean/Troops.cs index add4370..25bb837 100644 --- a/Core/Caribbean/Troops.cs +++ b/Core/Caribbean/Troops.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Text; @@ -11,7 +12,7 @@ public static class Troops { public static string[] Initialize() { - if (!File.Exists(Path.Combine(Common.InputPath, "troops.txt"))) return new string[0]; + if (!File.Exists(Path.Combine(Common.InputPath, "troops.txt"))) return Array.Empty(); var fId = new Text(Path.Combine(Common.InputPath, "troops.txt")); fId.GetString(); @@ -31,23 +32,21 @@ public static string[] Initialize() return aTroops; } - public static string DecompileCharacterAttribute(DWORD dwAttribute) + public static string DecompileCharacterAttribute(DWORD dwAttribute) => dwAttribute switch { - switch (dwAttribute) - { - case 0: return "ca_strength"; - case 1: return "ca_agility"; - case 2: return "ca_intelligence"; - case 3: return "ca_charisma"; - default: return dwAttribute.ToString(); - } - } + 0 => "ca_strength", + 1 => "ca_agility", + 2 => "ca_intelligence", + 3 => "ca_charisma", + _ => dwAttribute.ToString(CultureInfo.GetCultureInfo("en-US")), + }; + public static string GetScene(DWORD dwScene) { DWORD dwEntry = (dwScene & 0xFFFF0000) >> 16; DWORD dwId = dwScene & 0xFFFF; - return dwId < Common.Scenes.Length ? $"scn_{Common.Scenes[dwId]}|entry({dwEntry})" : $"{dwId}|entry({dwEntry})"; + return dwId < Common.Scenes.Count ? $"scn_{Common.Scenes[(int)dwId]}|entry({dwEntry})" : $"{dwId}|entry({dwEntry})"; } public static string DecompileFlags(DWORD dwFlag) @@ -55,7 +54,7 @@ public static string DecompileFlags(DWORD dwFlag) var sbFlag = new StringBuilder(1024); DWORD dwSkin = dwFlag & 0xF; - if (dwSkin > 0) sbFlag.Append(dwSkin < Common.Skins.Length ? "tf_" + Common.Skins[dwSkin] + "|" : $"{dwSkin}|"); + if (dwSkin > 0) sbFlag.Append(dwSkin < Common.Skins.Count ? "tf_" + Common.Skins[(int)dwSkin] + "|" : $"{dwSkin}|"); if ((dwFlag & 0x7F00000) - 0x7F00000 == 0) { @@ -117,7 +116,7 @@ public static void Decompile() fSource.WriteLine(Header.Standard); fSource.WriteLine(Header.Troops); - for (int s = 0; s < Common.Skins.Length; s++) fSource.WriteLine("tf_" + Common.Skins[s] + " = " + s); + for (int s = 0; s < Common.Skins.Count; s++) fSource.WriteLine("tf_" + Common.Skins[s] + " = " + s); fSource.WriteLine("\r\ntroops = ["); @@ -141,7 +140,7 @@ public static void Decompile() fSource.Write(" {0},", fTroops.GetWord()); // reserved "0" var iFaction = fTroops.GetInt(); - if (iFaction > 0 && iFaction < Common.Factions.Length) + if (iFaction > 0 && iFaction < Common.Factions.Count) fSource.WriteLine(" fac_{0},", Common.Factions[iFaction]); else fSource.WriteLine(" {0},", iFaction); @@ -170,7 +169,7 @@ public static void Decompile() } fSource.WriteLine(" [{0}],", String.Join(",", itemList.Select(item => { - var u = item.Key < Common.Items.Length ? $"itm_{Common.Items[item.Key]}" : $"{item.Key}"; + var u = item.Key < Common.Items.Count ? $"itm_{Common.Items[item.Key]}" : $"{item.Key}"; return item.Value <= 0 || item.Value >= aImods.Count ? u : $"({u}, {aImods[item.Value]})"; }))); @@ -200,7 +199,7 @@ public static void Decompile() for (int q = 0; q < 8; q++) { DWORD dwKnow = 0xF & (dword >> (q << 2)); - if (dwKnow != 0 && (x << 3) + q < Common.Skills.Length) strKnow.Append($"knows_{Common.Skills[(x << 3) + q]}_{dwKnow}|"); + if (dwKnow != 0 && (x << 3) + q < Common.Skills.Count) strKnow.Append($"knows_{Common.Skills[(x << 3) + q]}_{dwKnow}|"); } } if (strKnow.Length == 0) strKnow.Append('0'); else strKnow.Length--; diff --git a/Core/Common.cs b/Core/Common.cs index cc94454..af90271 100644 --- a/Core/Common.cs +++ b/Core/Common.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Globalization; using System.IO; +using System.Linq; using System.Text; using Decomp.Core.Operators; @@ -17,7 +18,7 @@ public enum Mode public static class Common { - public static string ModuleConstantsText = @"from ID_animations import * + public static string ModuleConstantsText { get; set; } = @"from ID_animations import * from ID_factions import * from ID_info_pages import * from ID_items import * @@ -41,7 +42,7 @@ from ID_strings import * from ID_tableau_materials import * from ID_troops import *"; - public static string ModuleConstantsVanillaText = @"from ID_animations import * + public static string ModuleConstantsVanillaText { get; set; } = @"from ID_animations import * from ID_factions import * from ID_items import * from ID_map_icons import * @@ -63,59 +64,87 @@ from ID_strings import * from ID_tableau_materials import * from ID_troops import *"; - public static Mode SelectedMode = Mode.WarbandScriptEnhancer450; + public static Mode SelectedMode { get; set; } = Mode.WarbandScriptEnhancer450; public static bool IsVanillaMode => SelectedMode == Mode.Vanilla; - public static string[] Procedures; - public static string[] QuickStrings; - public static string[] Strings; - public static string[] Items; - public static string[] Troops; - public static string[] Factions; - public static string[] Quests; - public static string[] PTemps; - public static string[] Parties; - public static string[] Menus; - public static string[] Sounds; - public static string[] Skills; - public static string[] Meshes; - public static string[] Variables; - public static string[] DialogStates; - public static string[] Scenes; - public static string[] MissionTemplates; - public static string[] ParticleSystems; - public static string[] SceneProps; - public static string[] MapIcons; - public static string[] Presentations; - public static string[] Tableaus; - public static string[] Animations; - public static string[] Music; - public static string[] Skins; - public static string[] InfoPages; - - public static string GetCommonIdentifier(string prefix, string[] array, int index, bool useQuotes = false) + public static IReadOnlyList Procedures { get; set; } + public static IReadOnlyList QuickStrings { get; set; } + public static IReadOnlyList Strings { get; set; } + public static IReadOnlyList Items { get; set; } + public static IReadOnlyList Troops { get; set; } + public static IReadOnlyList Factions { get; set; } + public static IReadOnlyList Quests { get; set; } + public static IReadOnlyList PTemps { get; set; } + public static IReadOnlyList Parties { get; set; } + public static IReadOnlyList Menus { get; set; } + public static IReadOnlyList Sounds { get; set; } + public static IReadOnlyList Skills { get; set; } + public static IReadOnlyList Meshes { get; set; } + public static IReadOnlyList Variables { get; set; } + public static IReadOnlyList DialogStates { get; set; } + public static IReadOnlyList Scenes { get; set; } + public static IReadOnlyList MissionTemplates { get; set; } + public static IReadOnlyList ParticleSystems { get; set; } + public static IReadOnlyList SceneProps { get; set; } + public static IReadOnlyList MapIcons { get; set; } + public static IReadOnlyList Presentations { get; set; } + public static IReadOnlyList Tableaus { get; set; } + public static IReadOnlyList Animations { get; set; } + public static IReadOnlyList Music { get; set; } + public static IReadOnlyList Skins { get; set; } + public static IReadOnlyList InfoPages { get; set; } + + public static string GetCommonIdentifier(string prefix, IList array, int index, bool useQuotes = false) { - if (index < 0 || index >= array.Length) return index.ToString(CultureInfo.GetCultureInfo("en-US")); + if (array == null) throw new ArgumentNullException(nameof(array)); + if (prefix == null) throw new ArgumentNullException(nameof(prefix)); + + if (index < 0 || index >= array.Count) return index.ToString(CultureInfo.GetCultureInfo("en-US")); var s = prefix + (prefix.Length > 0 && prefix[prefix.Length - 1] == '_' ? "" : "_") + array[index]; return useQuotes ? "\"" + s + "\"" : s; } - public static string GetCommonIdentifier(string prefix, string[] array, ulong index, bool useQuotes = false) + public static string GetCommonIdentifier(string prefix, IList array, ulong index, bool useQuotes = false) + { + if (array == null) throw new ArgumentNullException(nameof(array)); + if (prefix == null) throw new ArgumentNullException(nameof(prefix)); + + if (index >= (ulong)array.Count) return index.ToString(CultureInfo.GetCultureInfo("en-US")); + var s = prefix + (prefix.Length > 0 && prefix[prefix.Length - 1] == '_' ? "" : "_") + + array[(int)index]; + return useQuotes ? "\"" + s + "\"" : s; + } + + public static string GetCommonIdentifier(string prefix, IReadOnlyList array, int index, bool useQuotes = false) { - if (index >= (ulong)array.Length) return index.ToString(CultureInfo.GetCultureInfo("en-US")); + if (array == null) throw new ArgumentNullException(nameof(array)); + if (prefix == null) throw new ArgumentNullException(nameof(prefix)); + + if (index < 0 || index >= array.Count) return index.ToString(CultureInfo.GetCultureInfo("en-US")); var s = prefix + (prefix.Length > 0 && prefix[prefix.Length - 1] == '_' ? "" : "_") + array[index]; return useQuotes ? "\"" + s + "\"" : s; } - public static Dictionary Operators; + public static string GetCommonIdentifier(string prefix, IReadOnlyList array, ulong index, bool useQuotes = false) + { + if (array == null) throw new ArgumentNullException(nameof(array)); + if (prefix == null) throw new ArgumentNullException(nameof(prefix)); + + if (index >= (ulong)array.Count) return index.ToString(CultureInfo.GetCultureInfo("en-US")); + var s = prefix + (prefix.Length > 0 && prefix[prefix.Length - 1] == '_' ? "" : "_") + + array[(int)index]; + return useQuotes ? "\"" + s + "\"" : s; + } + + public static IReadOnlyDictionary Operators { get; set; } public static Operator FindOperator(int operatorCode) => Operators.ContainsKey(operatorCode) ? Operators[operatorCode] : new Operator(operatorCode.ToString(CultureInfo.GetCultureInfo("en-US")), operatorCode); - public static string InputPath; - public static string OutputPath; + public static string InputPath { get; set; } + public static string OutputPath { get; set; } public static string GetParam(ulong lParam) { @@ -124,152 +153,152 @@ public static string GetParam(ulong lParam) { case 1: var iReg = (int)lParam; - return "reg" + Convert.ToString(iReg); + return "reg" + Convert.ToString(iReg, CultureInfo.GetCultureInfo("en-US")); case 2: var iVariable = (int)lParam; - if (iVariable < Variables.Length) + if (iVariable < Variables.Count) return "\"$" + Variables[iVariable] + "\""; return $"0x{lParam:x16}"; case 3: var iString = (int)lParam; - return iString < Strings.Length ? "\"str_" + Strings[iString] + "\"" : $"0x{lParam:x16}"; + return iString < Strings.Count ? "\"str_" + Strings[iString] + "\"" : $"0x{lParam:x16}"; case 4: var iItem = (int)lParam; - return iItem < Items.Length ? "\"itm_" + Items[iItem] + "\"" : $"0x{lParam:x16}"; + return iItem < Items.Count ? "\"itm_" + Items[iItem] + "\"" : $"0x{lParam:x16}"; case 5: var iTroop = (int)lParam; - return iTroop < Troops.Length ? "\"trp_" + Troops[iTroop] + "\"" : $"0x{lParam:x16}"; + return iTroop < Troops.Count ? "\"trp_" + Troops[iTroop] + "\"" : $"0x{lParam:x16}"; case 6: var iFaction = (int)lParam; - return iFaction < Factions.Length ? "\"fac_" + Factions[iFaction] + "\"" : $"0x{lParam:x16}"; + return iFaction < Factions.Count ? "\"fac_" + Factions[iFaction] + "\"" : $"0x{lParam:x16}"; case 7: var iQuest = (int)lParam; - return iQuest < Quests.Length ? "\"qst_" + Quests[iQuest] + "\"" : $"0x{lParam:x16}"; + return iQuest < Quests.Count ? "\"qst_" + Quests[iQuest] + "\"" : $"0x{lParam:x16}"; case 8: var iPTemplate = (int)lParam; - return iPTemplate < PTemps.Length ? "\"pt_" + PTemps[iPTemplate] + "\"" : $"0x{lParam:x16}"; + return iPTemplate < PTemps.Count ? "\"pt_" + PTemps[iPTemplate] + "\"" : $"0x{lParam:x16}"; case 9: var iParty = (int)lParam; - return iParty < Parties.Length ? "\"p_" + Parties[iParty] + "\"" : $"0x{lParam:x16}"; + return iParty < Parties.Count ? "\"p_" + Parties[iParty] + "\"" : $"0x{lParam:x16}"; case 10: var iScene = (int)lParam; - return iScene < Scenes.Length ? "\"scn_" + Scenes[iScene] + "\"" : $"0x{lParam:x16}"; + return iScene < Scenes.Count ? "\"scn_" + Scenes[iScene] + "\"" : $"0x{lParam:x16}"; case 11: var iMTemplate = (int)lParam; - return iMTemplate < MissionTemplates.Length ? "\"mt_" + MissionTemplates[iMTemplate] + "\"" : $"0x{lParam:x16}"; + return iMTemplate < MissionTemplates.Count ? "\"mt_" + MissionTemplates[iMTemplate] + "\"" : $"0x{lParam:x16}"; case 12: var iMenu = (int)lParam; - return iMenu < Menus.Length ? "\"mnu_" + Menus[iMenu] + "\"" : $"0x{lParam:x16}"; + return iMenu < Menus.Count ? "\"mnu_" + Menus[iMenu] + "\"" : $"0x{lParam:x16}"; case 13: var iProcedure = (int)lParam; - return iProcedure < Procedures.Length ? "\"script_" + Procedures[iProcedure] + "\"" : $"0x{lParam:x16}"; + return iProcedure < Procedures.Count ? "\"script_" + Procedures[iProcedure] + "\"" : $"0x{lParam:x16}"; case 14: var iParticle = (int)lParam; - return iParticle < ParticleSystems.Length ? "\"psys_" + ParticleSystems[iParticle] + "\"" : + return iParticle < ParticleSystems.Count ? "\"psys_" + ParticleSystems[iParticle] + "\"" : $"0x{lParam:x16}"; case 15: var iSceneProp = (int)lParam; - return iSceneProp < SceneProps.Length ? "\"spr_" + SceneProps[iSceneProp] + "\"" : $"0x{lParam:x16}"; + return iSceneProp < SceneProps.Count ? "\"spr_" + SceneProps[iSceneProp] + "\"" : $"0x{lParam:x16}"; case 16: var iSound = (int)lParam; - return iSound < Sounds.Length ? "\"snd_" + Sounds[iSound] + "\"" : $"0x{lParam:x16}"; + return iSound < Sounds.Count ? "\"snd_" + Sounds[iSound] + "\"" : $"0x{lParam:x16}"; case 17: - return "\":var" + Convert.ToString((int)lParam) + "\""; + return "\":var" + Convert.ToString((int)lParam, CultureInfo.GetCultureInfo("en-US")) + "\""; case 18: var iIcon = (int)lParam; - return iIcon < MapIcons.Length ? "\"icon_" + MapIcons[iIcon] + "\"" : $"0x{lParam:x16}"; + return iIcon < MapIcons.Count ? "\"icon_" + MapIcons[iIcon] + "\"" : $"0x{lParam:x16}"; case 19: var iSkill = (int)lParam; - return iSkill < Skills.Length ? "\"skl_" + Skills[iSkill] + "\"" : $"0x{lParam:x16}"; + return iSkill < Skills.Count ? "\"skl_" + Skills[iSkill] + "\"" : $"0x{lParam:x16}"; case 20: var iMesh = (int)lParam; - return iMesh < Meshes.Length ? "\"mesh_" + Meshes[iMesh] + "\"" : $"0x{lParam:x16}"; + return iMesh < Meshes.Count ? "\"mesh_" + Meshes[iMesh] + "\"" : $"0x{lParam:x16}"; case 21: var iPresentation = (int)lParam; - return iPresentation < Presentations.Length ? "\"prsnt_" + Presentations[iPresentation] + "\"" : $"0x{lParam:x16}"; + return iPresentation < Presentations.Count ? "\"prsnt_" + Presentations[iPresentation] + "\"" : $"0x{lParam:x16}"; case 22: var iQuickString = (int)lParam; - return iQuickString < QuickStrings.Length ? "\"@" + QuickStrings[iQuickString] + "\"" : $"0x{lParam:x16}"; + return iQuickString < QuickStrings.Count ? "\"@" + QuickStrings[iQuickString] + "\"" : $"0x{lParam:x16}"; case 23: var iTrack = (int)lParam; - return iTrack < Music.Length ? "\"track_" + Music[iTrack] + "\"" : $"0x{lParam:x16}"; + return iTrack < Music.Count ? "\"track_" + Music[iTrack] + "\"" : $"0x{lParam:x16}"; case 24: var iTableau = (int)lParam; - return iTableau < Tableaus.Length ? "\"tableau_" + Tableaus[iTableau] + "\"" : $"0x{lParam:x16}"; + return iTableau < Tableaus.Count ? "\"tableau_" + Tableaus[iTableau] + "\"" : $"0x{lParam:x16}"; case 25: var iAnim = (int)lParam; - return iAnim < Animations.Length ? "\"anim_" + Animations[iAnim] + "\"" : $"0x{lParam:x16}"; + return iAnim < Animations.Count ? "\"anim_" + Animations[iAnim] + "\"" : $"0x{lParam:x16}"; default: return lParam.ToString(CultureInfo.GetCultureInfo("en-US")); } } - public static string GetTriggerParam(double dblParam) + public static string GetTriggerParam(double dblParam) => (int)dblParam switch { - switch ((int)dblParam) - { - case -2: return "ti_on_game_start"; - case -5: return "ti_simulate_battle"; - case -6: return "ti_on_party_encounter"; - case -8: return "ti_question_answered"; - case -15: return "ti_server_player_joined"; - case -16: return "ti_on_multiplayer_mission_end"; - case -19: return "ti_before_mission_start"; - case -20: return "ti_after_mission_start"; - case -21: return "ti_tab_pressed"; - case -22: return "ti_inventory_key_pressed"; - case -23: return "ti_escape_pressed"; - case -24: return "ti_battle_window_opened"; - case -25: return "ti_on_agent_spawn"; - case -26: return "ti_on_agent_killed_or_wounded"; - case -27: return "ti_on_agent_knocked_down"; - case -28: return "ti_on_agent_hit"; - case -29: return "ti_on_player_exit"; - case -30: return "ti_on_leave_area"; - case -40: return "ti_on_scene_prop_init"; - case -42: return "ti_on_scene_prop_hit"; - case -43: return "ti_on_scene_prop_destroy"; - case -44: return "ti_on_scene_prop_use"; - case -45: return "ti_on_scene_prop_is_animating"; - case -46: return "ti_on_scene_prop_animation_finished"; - case -47: return "ti_on_scene_prop_start_use"; - case -48: return "ti_on_scene_prop_cancel_use"; - case -50: return "ti_on_init_item"; - case -51: return "ti_on_weapon_attack"; - case -52: return "ti_on_missile_hit"; - case -53: return "ti_on_item_picked_up"; - case -54: return "ti_on_item_dropped"; - case -55: return "ti_on_agent_mount"; - case -56: return "ti_on_agent_dismount"; - case -57: return "ti_on_item_wielded"; - case -58: return "ti_on_item_unwielded"; - case -60: return "ti_on_presentation_load"; - case -61: return "ti_on_presentation_run"; - case -62: return "ti_on_presentation_event_state_change"; - case -63: return "ti_on_presentation_mouse_enter_leave"; - case -64: return "ti_on_presentation_mouse_press"; - case -70: return "ti_on_init_map_icon"; - case -71: return "ti_on_order_issued"; - case -75: return "ti_on_switch_to_map"; - case -76: return "ti_scene_prop_deformation_finished"; - case -80: return "ti_on_shield_hit"; - case -100: return "ti_on_scene_prop_stepped_on"; - case -101: return "ti_on_init_missile"; - case -102: return "ti_on_agent_turn"; - case -103: return SelectedMode == Mode.WarbandScriptEnhancer450 ? "ti_on_agent_blocked" : "ti_on_shield_hit"; - case -104: return "ti_on_missile_dive"; - case -105: return "ti_on_agent_start_reloading"; - case -106: return "ti_on_agent_end_reloading"; - case -107: return "ti_on_shield_penetrated"; - case 100000000: return "ti_once"; - default: return dblParam.ToString(CultureInfo.GetCultureInfo("en-US")); - } - } + -2 => "ti_on_game_start", + -5 => "ti_simulate_battle", + -6 => "ti_on_party_encounter", + -8 => "ti_question_answered", + -15 => "ti_server_player_joined", + -16 => "ti_on_multiplayer_mission_end", + -19 => "ti_before_mission_start", + -20 => "ti_after_mission_start", + -21 => "ti_tab_pressed", + -22 => "ti_inventory_key_pressed", + -23 => "ti_escape_pressed", + -24 => "ti_battle_window_opened", + -25 => "ti_on_agent_spawn", + -26 => "ti_on_agent_killed_or_wounded", + -27 => "ti_on_agent_knocked_down", + -28 => "ti_on_agent_hit", + -29 => "ti_on_player_exit", + -30 => "ti_on_leave_area", + -40 => "ti_on_scene_prop_init", + -42 => "ti_on_scene_prop_hit", + -43 => "ti_on_scene_prop_destroy", + -44 => "ti_on_scene_prop_use", + -45 => "ti_on_scene_prop_is_animating", + -46 => "ti_on_scene_prop_animation_finished", + -47 => "ti_on_scene_prop_start_use", + -48 => "ti_on_scene_prop_cancel_use", + -50 => "ti_on_init_item", + -51 => "ti_on_weapon_attack", + -52 => "ti_on_missile_hit", + -53 => "ti_on_item_picked_up", + -54 => "ti_on_item_dropped", + -55 => "ti_on_agent_mount", + -56 => "ti_on_agent_dismount", + -57 => "ti_on_item_wielded", + -58 => "ti_on_item_unwielded", + -60 => "ti_on_presentation_load", + -61 => "ti_on_presentation_run", + -62 => "ti_on_presentation_event_state_change", + -63 => "ti_on_presentation_mouse_enter_leave", + -64 => "ti_on_presentation_mouse_press", + -70 => "ti_on_init_map_icon", + -71 => "ti_on_order_issued", + -75 => "ti_on_switch_to_map", + -76 => "ti_scene_prop_deformation_finished", + -80 => "ti_on_shield_hit", + -100 => "ti_on_scene_prop_stepped_on", + -101 => "ti_on_init_missile", + -102 => "ti_on_agent_turn", + -103 => SelectedMode == Mode.WarbandScriptEnhancer450 ? "ti_on_agent_blocked" : "ti_on_shield_hit", + -104 => "ti_on_missile_dive", + -105 => "ti_on_agent_start_reloading", + -106 => "ti_on_agent_end_reloading", + -107 => "ti_on_shield_penetrated", + 100000000 => "ti_once", + _ => dblParam.ToString(CultureInfo.GetCultureInfo("en-US")) + }; public static string GetIndentations(int indentation) => new String(' ', Math.Max(indentation, 0) << 1); public static void PrintStatement(ref Text fInput, ref Win32FileWriter fOutput, int iRecords, string strDefaultIndentation) { + if (fInput == null) throw new ArgumentNullException(nameof(fInput)); + if (fOutput == null) throw new ArgumentNullException(nameof(fOutput)); + var indentations = 0; for (int r = 0; r < iRecords; r++) { @@ -300,7 +329,7 @@ public static void PrintStatement(ref Text fInput, ref Win32FileWriter fOutput, iOpCode == 18 ? GetIndentations(indentations - 1) : GetIndentations(indentations); string strOpCode = null; - if (strPrefixNeg != "" && iOpCode >= 30 && iOpCode <= 32) + if (strPrefixNeg.Length > 0 && iOpCode >= 30 && iOpCode <= 32) { switch (iOpCode) { @@ -333,197 +362,192 @@ public static void PrintStatement(ref Text fInput, ref Win32FileWriter fOutput, } } - public static string GetKey(ulong lKeyCode) + public static string GetKey(ulong lKeyCode) => lKeyCode switch { - switch (lKeyCode) - { - case 0x02: return "key_1"; - case 0x03: return "key_2"; - case 0x04: return "key_3"; - case 0x05: return "key_4"; - case 0x06: return "key_5"; - case 0x07: return "key_6"; - case 0x08: return "key_7"; - case 0x09: return "key_8"; - case 0x0a: return "key_9"; - case 0x0b: return "key_0"; - case 0x1e: return "key_a"; - case 0x30: return "key_b"; - case 0x2e: return "key_c"; - case 0x20: return "key_d"; - case 0x12: return "key_e"; - case 0x21: return "key_f"; - case 0x22: return "key_g"; - case 0x23: return "key_h"; - case 0x17: return "key_i"; - case 0x24: return "key_j"; - case 0x25: return "key_k"; - case 0x26: return "key_l"; - case 0x32: return "key_m"; - case 0x31: return "key_n"; - case 0x18: return "key_o"; - case 0x19: return "key_p"; - case 0x10: return "key_q"; - case 0x13: return "key_r"; - case 0x1f: return "key_s"; - case 0x14: return "key_t"; - case 0x16: return "key_u"; - case 0x2f: return "key_v"; - case 0x11: return "key_w"; - case 0x2d: return "key_x"; - case 0x15: return "key_y"; - case 0x2c: return "key_z"; - case 0x52: return "key_numpad_0"; - case 0x4f: return "key_numpad_1"; - case 0x50: return "key_numpad_2"; - case 0x51: return "key_numpad_3"; - case 0x4b: return "key_numpad_4"; - case 0x4c: return "key_numpad_5"; - case 0x4d: return "key_numpad_6"; - case 0x47: return "key_numpad_7"; - case 0x48: return "key_numpad_8"; - case 0x49: return "key_numpad_9"; - case 0x45: return "key_num_lock"; - case 0xb5: return "key_numpad_slash"; - case 0x37: return "key_numpad_multiply"; - case 0x4a: return "key_numpad_minus"; - case 0x4e: return "key_numpad_plus"; - case 0x9c: return "key_numpad_enter"; - case 0x53: return "key_numpad_period"; - case 0xd2: return "key_insert"; - case 0xd3: return "key_delete"; - case 0xc7: return "key_home"; - case 0xcf: return "key_end"; - case 0xc9: return "key_page_up"; - case 0xd1: return "key_page_down"; - case 0xc8: return "key_up"; - case 0xd0: return "key_down"; - case 0xcb: return "key_left"; - case 0xcd: return "key_right"; - case 0x3b: return "key_f1"; - case 0x3c: return "key_f2"; - case 0x3d: return "key_f3"; - case 0x3e: return "key_f4"; - case 0x3f: return "key_f5"; - case 0x40: return "key_f6"; - case 0x41: return "key_f7"; - case 0x42: return "key_f8"; - case 0x43: return "key_f9"; - case 0x44: return "key_f10"; - case 0x57: return "key_f11"; - case 0x58: return "key_f12"; - case 0x39: return "key_space"; - case 0x01: return "key_escape"; - case 0x1c: return "key_enter"; - case 0x0f: return "key_tab"; - case 0x0e: return "key_back_space"; - case 0x1a: return "key_open_braces"; - case 0x1b: return "key_close_braces"; - case 0x33: return "key_comma"; - case 0x34: return "key_period"; - case 0x35: return "key_slash"; - case 0x2b: return "key_back_slash"; - case 0x0d: return "key_equals"; - case 0x0c: return "key_minus"; - case 0x27: return "key_semicolon"; - case 0x28: return "key_apostrophe"; - case 0x29: return "key_tilde"; - case 0x3a: return "key_caps_lock"; - case 0x2a: return "key_left_shift"; - case 0x36: return "key_right_shift"; - case 0x1d: return "key_left_control"; - case 0x9d: return "key_right_control"; - case 0x38: return "key_left_alt"; - case 0xb8: return "key_right_alt"; - case 0xe0: return "key_left_mouse_button"; - case 0xe1: return "key_right_mouse_button"; - case 0xe2: return "key_middle_mouse_button"; - case 0xe3: return "key_mouse_button_4"; - case 0xe4: return "key_mouse_button_5"; - case 0xe5: return "key_mouse_button_6"; - case 0xe6: return "key_mouse_button_7"; - case 0xe7: return "key_mouse_button_8"; - case 0xee: return "key_mouse_scroll_up"; - case 0xef: return "key_mouse_scroll_down"; - case 0xf0: return "key_xbox_a"; - case 0xf1: return "key_xbox_b"; - case 0xf2: return "key_xbox_x"; - case 0xf3: return "key_xbox_y"; - case 0xf4: return "key_xbox_dpad_up"; - case 0xf5: return "key_xbox_dpad_down"; - case 0xf6: return "key_xbox_dpad_right"; - case 0xf7: return "key_xbox_dpad_left"; - case 0xf8: return "key_xbox_start"; - case 0xf9: return "key_xbox_back"; - case 0xfa: return "key_xbox_rbumber"; - case 0xfb: return "key_xbox_lbumber"; - case 0xfc: return "key_xbox_ltrigger"; - case 0xfd: return "key_xbox_rtrigger"; - case 0xfe: return "key_xbox_rstick"; - case 0xff: return "key_xbox_lstick"; - default: return $"0x{lKeyCode:x}"; - } - } - - public static string GetGameKey(ulong lKeyCode) + 0x02 => "key_1", + 0x03 => "key_2", + 0x04 => "key_3", + 0x05 => "key_4", + 0x06 => "key_5", + 0x07 => "key_6", + 0x08 => "key_7", + 0x09 => "key_8", + 0x0a => "key_9", + 0x0b => "key_0", + 0x1e => "key_a", + 0x30 => "key_b", + 0x2e => "key_c", + 0x20 => "key_d", + 0x12 => "key_e", + 0x21 => "key_f", + 0x22 => "key_g", + 0x23 => "key_h", + 0x17 => "key_i", + 0x24 => "key_j", + 0x25 => "key_k", + 0x26 => "key_l", + 0x32 => "key_m", + 0x31 => "key_n", + 0x18 => "key_o", + 0x19 => "key_p", + 0x10 => "key_q", + 0x13 => "key_r", + 0x1f => "key_s", + 0x14 => "key_t", + 0x16 => "key_u", + 0x2f => "key_v", + 0x11 => "key_w", + 0x2d => "key_x", + 0x15 => "key_y", + 0x2c => "key_z", + 0x52 => "key_numpad_0", + 0x4f => "key_numpad_1", + 0x50 => "key_numpad_2", + 0x51 => "key_numpad_3", + 0x4b => "key_numpad_4", + 0x4c => "key_numpad_5", + 0x4d => "key_numpad_6", + 0x47 => "key_numpad_7", + 0x48 => "key_numpad_8", + 0x49 => "key_numpad_9", + 0x45 => "key_num_lock", + 0xb5 => "key_numpad_slash", + 0x37 => "key_numpad_multiply", + 0x4a => "key_numpad_minus", + 0x4e => "key_numpad_plus", + 0x9c => "key_numpad_enter", + 0x53 => "key_numpad_period", + 0xd2 => "key_insert", + 0xd3 => "key_delete", + 0xc7 => "key_home", + 0xcf => "key_end", + 0xc9 => "key_page_up", + 0xd1 => "key_page_down", + 0xc8 => "key_up", + 0xd0 => "key_down", + 0xcb => "key_left", + 0xcd => "key_right", + 0x3b => "key_f1", + 0x3c => "key_f2", + 0x3d => "key_f3", + 0x3e => "key_f4", + 0x3f => "key_f5", + 0x40 => "key_f6", + 0x41 => "key_f7", + 0x42 => "key_f8", + 0x43 => "key_f9", + 0x44 => "key_f10", + 0x57 => "key_f11", + 0x58 => "key_f12", + 0x39 => "key_space", + 0x01 => "key_escape", + 0x1c => "key_enter", + 0x0f => "key_tab", + 0x0e => "key_back_space", + 0x1a => "key_open_braces", + 0x1b => "key_close_braces", + 0x33 => "key_comma", + 0x34 => "key_period", + 0x35 => "key_slash", + 0x2b => "key_back_slash", + 0x0d => "key_equals", + 0x0c => "key_minus", + 0x27 => "key_semicolon", + 0x28 => "key_apostrophe", + 0x29 => "key_tilde", + 0x3a => "key_caps_lock", + 0x2a => "key_left_shift", + 0x36 => "key_right_shift", + 0x1d => "key_left_control", + 0x9d => "key_right_control", + 0x38 => "key_left_alt", + 0xb8 => "key_right_alt", + 0xe0 => "key_left_mouse_button", + 0xe1 => "key_right_mouse_button", + 0xe2 => "key_middle_mouse_button", + 0xe3 => "key_mouse_button_4", + 0xe4 => "key_mouse_button_5", + 0xe5 => "key_mouse_button_6", + 0xe6 => "key_mouse_button_7", + 0xe7 => "key_mouse_button_8", + 0xee => "key_mouse_scroll_up", + 0xef => "key_mouse_scroll_down", + 0xf0 => "key_xbox_a", + 0xf1 => "key_xbox_b", + 0xf2 => "key_xbox_x", + 0xf3 => "key_xbox_y", + 0xf4 => "key_xbox_dpad_up", + 0xf5 => "key_xbox_dpad_down", + 0xf6 => "key_xbox_dpad_right", + 0xf7 => "key_xbox_dpad_left", + 0xf8 => "key_xbox_start", + 0xf9 => "key_xbox_back", + 0xfa => "key_xbox_rbumber", + 0xfb => "key_xbox_lbumber", + 0xfc => "key_xbox_ltrigger", + 0xfd => "key_xbox_rtrigger", + 0xfe => "key_xbox_rstick", + 0xff => "key_xbox_lstick", + _ => $"0x{lKeyCode:x}" + }; + + public static string GetGameKey(ulong lKeyCode) => lKeyCode switch { - switch (lKeyCode) - { - case 0: return "gk_move_forward"; - case 1: return "gk_move_backward"; - case 2: return "gk_move_left"; - case 3: return "gk_move_right"; - case 4: return "gk_action"; - case 5: return "gk_jump"; - case 6: return "gk_attack"; - case 7: return "gk_defend"; - case 8: return "gk_kick"; - case 9: return "gk_toggle_weapon_mode"; - case 10: return "gk_equip_weapon_1"; - case 11: return "gk_equip_weapon_2"; - case 12: return "gk_equip_weapon_3"; - case 13: return "gk_equip_weapon_4"; - case 14: return "gk_equip_primary_weapon"; - case 15: return "gk_equip_secondary_weapon"; - case 16: return "gk_drop_weapon"; - case 17: return "gk_sheath_weapon"; - case 18: return "gk_leave"; - case 19: return "gk_zoom"; - case 20: return "gk_view_char"; - case 21: return "gk_cam_toggle"; - case 22: return "gk_view_orders"; - case 23: return "gk_order_1"; - case 24: return "gk_order_2"; - case 25: return "gk_order_3"; - case 26: return "gk_order_4"; - case 27: return "gk_order_5"; - case 28: return "gk_order_6"; - case 29: return "gk_everyone_hear"; - case 30: return "gk_infantry_hear"; - case 31: return "gk_archers_hear"; - case 32: return "gk_cavalry_hear"; - case 33: return "gk_group3_hear"; - case 34: return "gk_group4_hear"; - case 35: return "gk_group5_hear"; - case 36: return "gk_group6_hear"; - case 37: return "gk_group7_hear"; - case 38: return "gk_group8_hear"; - case 39: return "gk_reverse_order_group"; - case 40: return "gk_everyone_around_hear"; - case 41: return "gk_mp_message_all"; - case 42: return "gk_mp_message_team"; - case 43: return "gk_character_window"; - case 44: return "gk_inventory_window"; - case 45: return "gk_party_window"; - case 46: return "gk_quests_window"; - case 47: return "gk_game_log_window"; - case 48: return "gk_quick_save"; - case 49: return "gk_crouch"; - case 50: return "gk_order_7"; - case 51: return "gk_order_8"; - default: return $"0x{lKeyCode:x}"; - } - } + 0 => "gk_move_forward", + 1 => "gk_move_backward", + 2 => "gk_move_left", + 3 => "gk_move_right", + 4 => "gk_action", + 5 => "gk_jump", + 6 => "gk_attack", + 7 => "gk_defend", + 8 => "gk_kick", + 9 => "gk_toggle_weapon_mode", + 10 => "gk_equip_weapon_1", + 11 => "gk_equip_weapon_2", + 12 => "gk_equip_weapon_3", + 13 => "gk_equip_weapon_4", + 14 => "gk_equip_primary_weapon", + 15 => "gk_equip_secondary_weapon", + 16 => "gk_drop_weapon", + 17 => "gk_sheath_weapon", + 18 => "gk_leave", + 19 => "gk_zoom", + 20 => "gk_view_char", + 21 => "gk_cam_toggle", + 22 => "gk_view_orders", + 23 => "gk_order_1", + 24 => "gk_order_2", + 25 => "gk_order_3", + 26 => "gk_order_4", + 27 => "gk_order_5", + 28 => "gk_order_6", + 29 => "gk_everyone_hear", + 30 => "gk_infantry_hear", + 31 => "gk_archers_hear", + 32 => "gk_cavalry_hear", + 33 => "gk_group3_hear", + 34 => "gk_group4_hear", + 35 => "gk_group5_hear", + 36 => "gk_group6_hear", + 37 => "gk_group7_hear", + 38 => "gk_group8_hear", + 39 => "gk_reverse_order_group", + 40 => "gk_everyone_around_hear", + 41 => "gk_mp_message_all", + 42 => "gk_mp_message_team", + 43 => "gk_character_window", + 44 => "gk_inventory_window", + 45 => "gk_party_window", + 46 => "gk_quests_window", + 47 => "gk_game_log_window", + 48 => "gk_quick_save", + 49 => "gk_crouch", + 50 => "gk_order_7", + 51 => "gk_order_8", + _ => $"0x{lKeyCode:x}", + }; + public static bool IsStringRegister(ulong lParam) { @@ -567,7 +591,7 @@ public static bool NotParam(ulong lFlags) return lTag == 0; } - public static string GetFaceKey(ulong lFaceKeyCode) => Convert.ToString(lFaceKeyCode); + public static string GetFaceKey(ulong lFaceKeyCode) => Convert.ToString(lFaceKeyCode, CultureInfo.GetCultureInfo("en-US")); public static string DecompileTextFlags(uint dwFlag) { @@ -592,58 +616,47 @@ public static string DecompileTextFlags(uint dwFlag) return sbFlag.ToString(); } - public static string GetAgentClass(ulong lClass) + public static string GetAgentClass(ulong lClass) => lClass switch { - switch (lClass) - { - case 0: - return "grc_infantry"; - case 1: - return "grc_archers"; - case 2: - return "grc_cavalry"; - case 3: - return "grc_infantry"; - case 9: - return "grc_everyone"; - default: - return lClass.ToString(CultureInfo.GetCultureInfo(1033)); - } - } - - public static string GetTeamOrder(ulong lOrder) + 0 => "grc_infantry", + 1 => "grc_archers", + 2 => "grc_cavalry", + 3 => "grc_infantry", + 9 => "grc_everyone", + _ => lClass.ToString(CultureInfo.GetCultureInfo(1033)) + }; + + public static string GetTeamOrder(ulong lOrder) => lOrder switch { - switch (lOrder) - { - case 0: return "mordr_hold"; - case 1: return "mordr_follow"; - case 2: return "mordr_charge"; - case 3: return "mordr_mount"; - case 4: return "mordr_dismount"; - case 5: return "mordr_advance"; - case 6: return "mordr_fall_back"; - case 7: return "mordr_stand_closer"; - case 8: return "mordr_spread_out"; - case 9: return "mordr_use_blunt_weapons"; - case 10: return "mordr_use_melee_weapons"; - case 11: return "mordr_use_ranged_weapons"; - case 12: return "mordr_use_any_weapon"; - case 13: return "mordr_stand_ground"; - case 14: return "mordr_fire_at_my_command"; - case 15: return "mordr_all_fire_now"; - case 16: return "mordr_left_fire_now"; - case 17: return "mordr_middle_fire_now"; - case 18: return "mordr_right_fire_now"; - case 19: return "mordr_fire_at_will"; - case 20: return "mordr_retreat"; - case 21: return "mordr_form_1_row"; - case 22: return "mordr_form_2_row"; - case 23: return "mordr_form_3_row"; - case 24: return "mordr_form_4_row"; - case 25: return "mordr_form_5_row"; - default: return lOrder.ToString(CultureInfo.GetCultureInfo(1033)); - } - } + 0 => "mordr_hold", + 1 => "mordr_follow", + 2 => "mordr_charge", + 3 => "mordr_mount", + 4 => "mordr_dismount", + 5 => "mordr_advance", + 6 => "mordr_fall_back", + 7 => "mordr_stand_closer", + 8 => "mordr_spread_out", + 9 => "mordr_use_blunt_weapons", + 10 => "mordr_use_melee_weapons", + 11 => "mordr_use_ranged_weapons", + 12 => "mordr_use_any_weapon", + 13 => "mordr_stand_ground", + 14 => "mordr_fire_at_my_command", + 15 => "mordr_all_fire_now", + 16 => "mordr_left_fire_now", + 17 => "mordr_middle_fire_now", + 18 => "mordr_right_fire_now", + 19 => "mordr_fire_at_will", + 20 => "mordr_retreat", + 21 => "mordr_form_1_row", + 22 => "mordr_form_2_row", + 23 => "mordr_form_3_row", + 24 => "mordr_form_4_row", + 25 => "mordr_form_5_row", + _ => lOrder.ToString(CultureInfo.GetCultureInfo(1033)), + }; + public static string GetPartyBehavior(ulong lBehavior) { @@ -654,107 +667,86 @@ public static string GetPartyBehavior(ulong lBehavior) return iAIbehaviour <= 11 ? strAIbehaviours[iAIbehaviour] : iAIbehaviour.ToString(CultureInfo.GetCultureInfo("en-US")); } - public static string GetCharacterAttribute(ulong lAttribute) + public static string GetCharacterAttribute(ulong lAttribute) => lAttribute switch { - switch (lAttribute) - { - case 0: - return "ca_strength"; - case 1: - return "ca_agility"; - case 2: - return "ca_intelligence"; - case 3: - return "ca_charisma"; - default: - return lAttribute.ToString(CultureInfo.GetCultureInfo("en-US")); - } - } + 0 => "ca_strength", + 1 => "ca_agility", + 2 => "ca_intelligence", + 3 => "ca_charisma", + _ => lAttribute.ToString(CultureInfo.GetCultureInfo("en-US")), + }; + - public static string GetWeaponProficiency(ulong lProficiency) + public static string GetWeaponProficiency(ulong lProficiency) => lProficiency switch { - switch (lProficiency) - { - case 0: return "wpt_one_handed_weapon"; - case 1: return "wpt_two_handed_weapon"; - case 2: return "wpt_polearm"; - case 3: return "wpt_archery"; - case 4: return "wpt_crossbow"; - case 5: return "wpt_throwing"; - case 6: return "wpt_firearm"; - default: return lProficiency.ToString(CultureInfo.GetCultureInfo("en-US")); - } - } - - public static string GetInventorySlot(ulong lSlot) + 0 => "wpt_one_handed_weapon", + 1 => "wpt_two_handed_weapon", + 2 => "wpt_polearm", + 3 => "wpt_archery", + 4 => "wpt_crossbow", + 5 => "wpt_throwing", + 6 => "wpt_firearm", + _ => lProficiency.ToString(CultureInfo.GetCultureInfo("en-US")), + }; + + public static string GetInventorySlot(ulong lSlot) => lSlot switch { - switch (lSlot) - { - case 0: return "ek_item_0"; - case 1: return "ek_item_1"; - case 2: return "ek_item_2"; - case 3: return "ek_item_3"; - case 4: return "ek_head"; - case 5: return "ek_body"; - case 6: return "ek_foot"; - case 7: return "ek_gloves"; - case 8: return "ek_horse"; - case 9: return "ek_food"; - default: return lSlot.ToString(CultureInfo.GetCultureInfo("en-US")); - } - } + 0 => "ek_item_0", + 1 => "ek_item_1", + 2 => "ek_item_2", + 3 => "ek_item_3", + 4 => "ek_head", + 5 => "ek_body", + 6 => "ek_foot", + 7 => "ek_gloves", + 8 => "ek_horse", + 9 => "ek_food", + _ => lSlot.ToString(CultureInfo.GetCultureInfo("en-US")), + }; - public static string GetTooltip(ulong t) + + public static string GetTooltip(ulong t) => t switch { - switch (t) - { - case 1: return "tooltip_agent"; - case 2: return "tooltip_horse"; - case 3: return "tooltip_my_horse"; - case 5: return "tooltip_container"; - case 6: return "tooltip_door"; - case 7: return "tooltip_item"; - case 8: return "tooltip_leave_area"; - case 9: return "tooltip_prop"; - case 10: return "tooltip_destructible_prop"; - default: return t.ToString(CultureInfo.GetCultureInfo("en-US")); - } - } + 1 => "tooltip_agent", + 2 => "tooltip_horse", + 3 => "tooltip_my_horse", + 5 => "tooltip_container", + 6 => "tooltip_door", + 7 => "tooltip_item", + 8 => "tooltip_leave_area", + 9 => "tooltip_prop", + 10 => "tooltip_destructible_prop", + _ => t.ToString(CultureInfo.GetCultureInfo("en-US")), + }; public static string GetColor(ulong color) { - if (color <= 0xFFFFFFFF && color > 0x00FFFFFF) return "0x" + color.ToString("X8"); - if (color <= 0x00FFFFFF) return "0x" + color.ToString("X6"); - return "0x" + color.ToString("X"); + if (color <= 0xFFFFFFFF && color > 0x00FFFFFF) return "0x" + color.ToString("X8", CultureInfo.GetCultureInfo("en-US")); + if (color <= 0x00FFFFFF) return "0x" + color.ToString("X6", CultureInfo.GetCultureInfo("en-US")); + return "0x" + color.ToString("X", CultureInfo.GetCultureInfo("en-US")); } - public static string GetAlpha(ulong alpha) => String.Concat("0x", alpha <= 0xFF ? alpha.ToString("X2") : alpha.ToString("X")); + public static string GetAlpha(ulong alpha) => String.Concat("0x", alpha <= 0xFF ? alpha.ToString("X2", CultureInfo.GetCultureInfo("en-US")) : alpha.ToString("X", CultureInfo.GetCultureInfo("en-US"))); - public static string DecompileSortMode(ulong sm) + public static string DecompileSortMode(ulong sm) => (sm & 3) switch { - switch (sm & 3) - { - case 0x0: - return "0"; - case 0x1: - return "sort_f_desc"; - case 0x10: - return "sort_f_ci"; - case 0x11: - return "sort_f_ci | sort_f_desc"; - default: - return sm.ToString(); - } - } + 0x0 => "0", + 0x1 => "sort_f_desc", + 0x10 => "sort_f_ci", + 0x11 => "sort_f_ci | sort_f_desc", + _ => sm.ToString(CultureInfo.GetCultureInfo("en-US")), + }; + - public static bool NeedId = true; - public static void GenerateId(string fileOut, string[] content, string prefix = "") + public static bool NeedId { get; set; } = true; + public static void GenerateId(string fileOut, IEnumerable content, string prefix = "") { - if (!NeedId) return; + if (!NeedId || prefix == null || content == null) return; var f = new Win32FileWriter(Path.Combine(OutputPath, fileOut)); if (prefix.Length > 0 && prefix[prefix.Length - 1] != '_') prefix += '_'; - for (int i = 0; i < content.Length; i++) f.WriteLine("{0}{1} = {2}", prefix, content[i], i); + var enumerable = content.ToArray(); + for (int i = 0; i < enumerable.Length; i++) f.WriteLine("{0}{1} = {2}", prefix, enumerable[i], i); f.Close(); - } + } } } diff --git a/Core/Decompiler.cs b/Core/Decompiler.cs index b00d6f5..f04d4fb 100644 --- a/Core/Decompiler.cs +++ b/Core/Decompiler.cs @@ -22,7 +22,8 @@ private static string GetDirectory(this DirectoryNotFoundException exception) return Path.GetDirectoryName(message.Substring(beginPos + 1, endPos - beginPos - 1)); } - public static MainWindow Window; + public static MainWindow Window { get; set; } + private static string Status { set => Window.StatusTextBlock.SetText(value); @@ -32,10 +33,7 @@ private static string Status public static bool Alive => _workThread.IsAlive; - public static void StopDecompilation() - { - _workThread.Abort(); - } + public static void StopDecompilation() => _workThread.Abort(); public static void StartDecompilation() { @@ -206,11 +204,12 @@ private static void InitializePath(out bool isSingleFile) private static void InitializeOpCodes() { //Common.Operations = new Dictionary(); - Common.Operators = new Dictionary(); - + //Common.Operators = new Dictionary(); + var opCodes = new Dictionary(); Window.ModeComboBox.Dispatcher?.Invoke(() => Common.SelectedMode = (Mode)Window.ModeComboBox.SelectedIndex); var operators = Operator.GetCollection(Common.SelectedMode); - foreach (var op in operators) Common.Operators[op.Code] = op; + foreach (var op in operators) opCodes[op.Code] = op; + Common.Operators = opCodes; } private static void InitializeModuleData() @@ -459,7 +458,7 @@ private static void ProcessFullModule() iNumFiles += strModDataFiles.Count(strModDataFile => File.Exists(Path.Combine(Common.InputPath, "Data", strModDataFile))); - var sShadersFile = GetShadersFullFileName(out bool b); + var sShadersFile = GetShadersFullFileName(out var b); if (b && decompileShaders) iNumFiles++; double dblProgressForOneFile = 100.0 / iNumFiles, dblProgress = 0; diff --git a/Core/Dialogs.cs b/Core/Dialogs.cs index 819c4e8..858e0ec 100644 --- a/Core/Dialogs.cs +++ b/Core/Dialogs.cs @@ -1,4 +1,5 @@ -using System.IO; +using System; +using System.IO; using System.Text; using DWORD = System.UInt32; @@ -6,7 +7,7 @@ namespace Decomp.Core { public static class Dialogs { - public static string[] Initialize() => File.Exists(Path.Combine(Common.InputPath, "dialog_states.txt")) ? Win32FileReader.ReadAllLines(Path.Combine(Common.InputPath, "dialog_states.txt")) : new string[0]; + public static string[] Initialize() => File.Exists(Path.Combine(Common.InputPath, "dialog_states.txt")) ? Win32FileReader.ReadAllLines(Path.Combine(Common.InputPath, "dialog_states.txt")) : Array.Empty(); public static void Decompile() { @@ -48,20 +49,20 @@ public static void Decompile() else if (dwPartner != 0) { if ((dwDialogPartner & PARTY_TPL) != 0) - sbDialogPartner.Append(dwPartner < Common.PTemps.Length ? "pt_" + Common.PTemps[dwPartner] + "|" : $"{dwPartner}|"); + sbDialogPartner.Append(dwPartner < Common.PTemps.Count ? "pt_" + Common.PTemps[(int)dwPartner] + "|" : $"{dwPartner}|"); else - sbDialogPartner.Append(dwPartner < Common.Troops.Length ? "trp_" + Common.Troops[dwPartner] + "|" : $"{dwPartner}|"); + sbDialogPartner.Append(dwPartner < Common.Troops.Count ? "trp_" + Common.Troops[(int)dwPartner] + "|" : $"{dwPartner}|"); } DWORD dwOther = (dwDialogPartner & 0xFFF00000) >> 20; if (dwOther != 0) - sbDialogPartner.Append(dwOther < Common.Troops.Length ? "other(trp_" + Common.Troops[dwOther] + ")|" : $"other({dwOther})|"); + sbDialogPartner.Append(dwOther < Common.Troops.Count ? "other(trp_" + Common.Troops[(int)dwOther] + ")|" : $"other({dwOther})|"); if (sbDialogPartner.Length == 0) sbDialogPartner.Append('0'); else sbDialogPartner.Length--; - if (iStartingDialogState < Common.DialogStates.Length) + if (iStartingDialogState < Common.DialogStates.Count) fSource.Write(" [{0}, \"{1}\",\r\n [", sbDialogPartner, Common.DialogStates[iStartingDialogState]); else fSource.Write(" [{0}, {1},\r\n [", sbDialogPartner, iStartingDialogState); @@ -80,7 +81,7 @@ public static void Decompile() fSource.WriteLine(" \"{0}\",", strDialogText.Replace('_', ' ')); int iEndingDialogState = fDialogs.GetInt(); - if (iEndingDialogState < Common.DialogStates.Length) + if (iEndingDialogState < Common.DialogStates.Count) fSource.Write(" \"{0}\",\r\n [", Common.DialogStates[iEndingDialogState]); else fSource.Write(" {0},\r\n [", iEndingDialogState); diff --git a/Core/Factions.cs b/Core/Factions.cs index c4fde40..8775e18 100644 --- a/Core/Factions.cs +++ b/Core/Factions.cs @@ -9,15 +9,15 @@ public static class Factions { public static string[] Initialize() { - if (!File.Exists(Path.Combine(Common.InputPath, "factions.txt"))) return new string[0]; + if (!File.Exists(Path.Combine(Common.InputPath, "factions.txt"))) return Array.Empty(); var fId = new Text(Path.Combine(Common.InputPath, "factions.txt")); fId.GetString(); - var n = Convert.ToInt32(fId.GetString()); + var n = Convert.ToInt32(fId.GetString(), CultureInfo.GetCultureInfo("en-US")); var aFactions = new string[n]; for (int i = 0; i < n; i++) { - string strFacId = fId.GetWord(); + var strFacId = fId.GetWord(); if (strFacId == "0") strFacId = fId.GetWord(); aFactions[i] = strFacId.Remove(0, 4); diff --git a/Core/Flora.cs b/Core/Flora.cs index f4b98be..db7e73c 100644 --- a/Core/Flora.cs +++ b/Core/Flora.cs @@ -1,4 +1,5 @@ -using System.IO; +using System.Globalization; +using System.IO; using System.Text; using DWORD = System.UInt32; using DWORD64 = System.UInt64; @@ -12,11 +13,11 @@ public static class Flora public static string DecompileFlags(DWORD64 dwFlag) { DWORD64 dwDensity = (dwFlag & 0xFFFF00000000) >> 32; - dwFlag = dwFlag & 0xFFFFFFFF; + dwFlag &= 0xFFFFFFFF; var sbFlag = new StringBuilder(2048); - if (dwDensity != 0) sbFlag.AppendFormat("density({0})|", dwDensity); + if (dwDensity != 0) sbFlag.AppendFormat(CultureInfo.GetCultureInfo("en-US"),"density({0})|", dwDensity); string[] strFlags = { "fkf_plain", "fkf_steppe", "fkf_snow", "fkf_desert", "fkf_plain_forest", "fkf_steppe_forest", "fkf_snow_forest", "fkf_desert_forest", "fkf_realtime_ligting", "fkf_point_up", "fkf_align_with_ground", diff --git a/Core/Header.cs b/Core/Header.cs index 49ff2ce..1f751c9 100644 --- a/Core/Header.cs +++ b/Core/Header.cs @@ -2,20 +2,20 @@ { public static class Header { - public static string Standard = @"# -*- coding: UTF-8 -*- + public static string Standard { get; set; } = @"# -*- coding: UTF-8 -*- #################################################################################################################### # Generated by Warband Module Decompiler # All rights of the module belong to their respective owners #################################################################################################################### "; - public static string Shaders = @"// + public static string Shaders { get; set; } = @"// // Generated by Warband Module Decompiler // All rights of the module belong to their respective owners // "; - public static string Meshes = @"from header_meshes import * + public static string Meshes { get; set; } = @"from header_meshes import * #################################################################################################################### # Each mesh record contains the following fields: @@ -36,7 +36,7 @@ public static class Header meshes = ["; - public static string Music = @"from header_music import * + public static string Music { get; set; } = @"from header_music import * #################################################################################################################### # Each track record contains the following fields: # 1) Track id: used for referencing tracks. @@ -49,7 +49,7 @@ public static class Header tracks = ["; - public static string Icons = @"from header_map_icons import * + public static string Icons { get; set; } = @"from header_map_icons import * from module_constants import * from header_operations import * from header_triggers import * @@ -70,7 +70,7 @@ from ID_sounds import * map_icons = ["; - public static string ParticleSystems = @"from header_particle_systems import * + public static string ParticleSystems { get; set; } = @"from header_particle_systems import * #################################################################################################################### # Each particle system contains the following fields: @@ -105,7 +105,7 @@ from ID_sounds import * particle_systems = ["; - public static string Factions = @"from header_factions import * + public static string Factions { get; set; } = @"from header_factions import * #################################################################################################################### # Each faction record contains the following fields: @@ -126,7 +126,7 @@ from ID_sounds import * default_kingdom_relations = [(""outlaws"",-0.05),(""peasant_rebels"", -0.1),(""deserters"", -0.05),(""mountain_bandits"", -0.02),(""forest_bandits"", -0.02)] factions = ["; - public static string Animations = @"from header_common import * + public static string Animations { get; set; } = @"from header_common import * from header_animations import * #################################################################################################################### @@ -213,7 +213,7 @@ from header_animations import * animations = ["; - public static string Scenes = @"from header_common import * + public static string Scenes { get; set; } = @"from header_common import * from header_operations import * from header_triggers import * from header_scenes import * @@ -261,7 +261,7 @@ from module_constants import * scenes = ["; - public static string InfoPages = @"#################################################################################################################### + public static string InfoPages { get; set; } = @"#################################################################################################################### # Each quest record contains the following fields: # 1) Info page id: used for referencing info pages in other files. The prefix ip_ is automatically added before each info page id. # 2) Info page name: Name displayed in the info page screen. @@ -270,7 +270,7 @@ from module_constants import * info_pages = ["; - public static string Postfx = @"from header_postfx import * + public static string Postfx { get; set; } = @"from header_postfx import * #################################################################################################################### # Each postfx_param contains the following fields: @@ -289,11 +289,11 @@ from module_constants import * postfx_params = ["; - public static string Sounds = @"from header_sounds import * + public static string Sounds { get; set; } = @"from header_sounds import * sounds = ["; - public static string Parties = @"from header_common import * + public static string Parties { get; set; } = @"from header_common import * from header_parties import * from ID_troops import * from ID_factions import * @@ -330,7 +330,7 @@ from ID_map_icons import * parties = ["; - public static string PartyTemplates = @"from header_common import * + public static string PartyTemplates { get; set; } = @"from header_common import * from header_parties import * from ID_troops import * from ID_factions import * @@ -358,7 +358,7 @@ from ID_map_icons import * party_templates = ["; - public static string Troops = @"import random + public static string Troops { get; set; } = @"import random from header_common import * from header_items import * @@ -489,7 +489,7 @@ def charisma(v): "; - public static string Skills = @"from header_common import * + public static string Skills { get; set; } = @"from header_common import * from header_skills import * #################################################################################################################### @@ -531,9 +531,9 @@ from header_skills import * skills = ["; - public static string Strings = @"strings = ["; + public static string Strings { get; set; } = @"strings = ["; - public static string Quests = @"from header_quests import * + public static string Quests { get; set; } = @"from header_quests import * #################################################################################################################### # Each quest record contains the following fields: @@ -547,7 +547,7 @@ from header_skills import * quests = ["; - public static string Skins = @"from header_skins import * + public static string Skins { get; set; } = @"from header_skins import * from ID_particle_systems import * #################################################################################################################### # Each skin record contains the following fields: @@ -576,7 +576,7 @@ from ID_particle_systems import * skins = ["; - public static string Scripts = @"from header_common import * + public static string Scripts { get; set; } = @"from header_common import * from header_operations import * from module_constants import * from header_presentations import * @@ -600,7 +600,7 @@ from ID_animations import * scripts = ["; - public static string Presentations = @"from header_common import * + public static string Presentations { get; set; } = @"from header_common import * from header_presentations import * from header_mission_templates import * from ID_meshes import * @@ -619,7 +619,7 @@ import string presentations = ["; - public static string SimpleTriggers = @"from header_common import * + public static string SimpleTriggers { get; set; } = @"from header_common import * from header_operations import * from header_parties import * from header_items import * @@ -640,7 +640,7 @@ from module_constants import * simple_triggers = ["; - public static string Triggers = @"from header_common import * + public static string Triggers { get; set; } = @"from header_common import * from header_operations import * from header_parties import * from header_items import * @@ -666,7 +666,7 @@ from module_constants import * triggers = ["; - public static string SceneProps = @"from header_common import * + public static string SceneProps { get; set; } = @"from header_common import * from header_scene_props import * from header_operations import * from header_triggers import * @@ -685,7 +685,7 @@ import string scene_props = ["; - public static string TableauMaterials = @"from header_common import * + public static string TableauMaterials { get; set; } = @"from header_common import * from ID_animations import * from header_mission_templates import * from header_tableau_materials import * @@ -710,7 +710,7 @@ from module_constants import * tableaus = ["; - public static string Dialogs = @"from header_common import * + public static string Dialogs { get; set; } = @"from header_common import * from header_dialogs import * from header_operations import * from header_parties import * @@ -756,7 +756,7 @@ from module_constants import * dialogs = ["; - public static string Menus = @"from header_game_menus import * + public static string Menus { get; set; } = @"from header_game_menus import * from header_parties import * from header_items import * from header_mission_templates import * @@ -795,7 +795,7 @@ from module_constants import * game_menus = ["; - public static string Items = @"from module_constants import * + public static string Items { get; set; } = @"from module_constants import * from ID_factions import * from header_items import * from header_operations import * @@ -846,7 +846,7 @@ from header_triggers import * # Fauchard (majowski glaive) items = ["; - public static string MissionTemplates = @"from header_common import * + public static string MissionTemplates { get; set; } = @"from header_common import * from header_operations import * from header_mission_templates import * from header_animations import * @@ -885,7 +885,7 @@ from module_constants import * mission_templates = ["; - public static string GroundSpecs = @" + public static string GroundSpecs { get; set; } = @" from module_info import * gtf_overlay = 0x00000001 #deprecated gtf_dusty = 0x00000002 #controls dustiness of the ground for foot dust particle systems @@ -899,7 +899,7 @@ from module_info import * #spec_name, flags, material, uv_scale, multitex_material_name, gtf_has_color->color ground_specs = ["; - public static string Skyboxes = @" + public static string Skyboxes { get; set; } = @" from module_info import * sf_day = 0x00000000 sf_dawn = 0x00000001 @@ -942,7 +942,7 @@ from module_info import * skyboxes = ["; - public static string Flora = @"import string + public static string Flora { get; set; } = @"import string from module_info import * dword = 0x8000000000000000 @@ -985,9 +985,9 @@ def density(g): fauna_kinds = ["; - public static string PhysicsMaterials = "physics_materials = ["; + public static string PhysicsMaterials { get; set; } = "physics_materials = ["; - public static string ImprovedShaders = @"shrf_lo_quality = 0x1000 + public static string ImprovedShaders { get; set; } = @"shrf_lo_quality = 0x1000 shrf_mid_quality = 0x2000 shrf_hi_quality = 0x4000 diff --git a/Core/InfoPages.cs b/Core/InfoPages.cs index 29b0c31..3d5d15f 100644 --- a/Core/InfoPages.cs +++ b/Core/InfoPages.cs @@ -1,4 +1,5 @@ -using System.IO; +using System; +using System.IO; namespace Decomp.Core { @@ -6,7 +7,7 @@ public static class InfoPages { public static string[] Initialize() { - if (!File.Exists(Path.Combine(Common.InputPath, "info_pages.txt"))) return new string[0]; + if (!File.Exists(Path.Combine(Common.InputPath, "info_pages.txt"))) return Array.Empty(); var fId = new Text(Path.Combine(Common.InputPath, "info_pages.txt")); fId.GetString(); diff --git a/Core/Items.cs b/Core/Items.cs index 654265a..e8b24fa 100644 --- a/Core/Items.cs +++ b/Core/Items.cs @@ -13,11 +13,11 @@ public static class Items { public static string[] Initialize() { - if (!File.Exists(Path.Combine(Common.InputPath, "item_kinds1.txt"))) return new string[0]; + if (!File.Exists(Path.Combine(Common.InputPath, "item_kinds1.txt"))) return Array.Empty(); var fId = new Text(Path.Combine(Common.InputPath, "item_kinds1.txt")); fId.GetString(); - var n = Convert.ToInt32(fId.GetString()); + var n = Convert.ToInt32(fId.GetString(), CultureInfo.GetCultureInfo("en-US")); var aItems = new string[n]; for (int i = 0; i < n; i++) { @@ -251,7 +251,7 @@ public static string DecompileFlags(DWORD64 dwFlag, out BYTE bType) switch (bType) { case HEAD_ARMOR_TYPE: strFlag = strFlag.Replace("itp_next_item_as_melee", "itp_civilian").Replace("itp_offset_lance", "itp_fit_to_head").Replace("itp_couchable", "itp_covers_head").Replace("itp_can_penetrate_shield", "itp_doesnt_cover_hair"); break; //head armor - case BODY_ARMOR_TYPE: strFlag = strFlag.Replace("itp_next_item_as_melee", "itp_civilian").Replace("itp_can_penetrate_shield", "itp_covers_legs").Replace("itp_offset_lance", "itp_show_body"); break; //body armor + case BODY_ARMOR_TYPE: strFlag = strFlag.Replace("itp_next_item_as_melee", "itp_civilian").Replace("itp_can_penetrate_shield", "itp_covers_legs").Replace("itp_offset_lance", "itp_show_body").Replace("itp_offset_mortschlag", "itp_covers_hands"); break; //body armor case FOOT_ARMOR_TYPE: strFlag = strFlag.Replace("itp_next_item_as_melee", "itp_civilian"); break; //legs armor case HAND_ARMOR_TYPE: strFlag = strFlag.Replace("itp_next_item_as_melee", "itp_civilian").Replace("itp_offset_lance", "itp_show_left_hand").Replace("itp_couchable", "itp_show_right_hand"); break; //hand armor } @@ -482,7 +482,7 @@ public static void Decompile() int iFactions = fItems.GetInt(); var factionsList = new int[iFactions]; for (int f = 0; f < iFactions; f++) factionsList[f] = fItems.GetInt(); - string strFactionList = String.Join(",", factionsList.Select(f => f >= 0 && f < Common.Factions.Length ? "fac_" + Common.Factions[f] : Convert.ToString(f))); + string strFactionList = String.Join(",", factionsList.Select(f => f >= 0 && f < Common.Factions.Count ? "fac_" + Common.Factions[f] : Convert.ToString(f, CultureInfo.GetCultureInfo("en-US")))); int iTriggers = fItems.GetInt(); if (iTriggers != 0) diff --git a/Core/MapIcons.cs b/Core/MapIcons.cs index c283398..87f40c6 100644 --- a/Core/MapIcons.cs +++ b/Core/MapIcons.cs @@ -9,11 +9,11 @@ public static class MapIcons { public static string[] Initialize() { - if (!File.Exists(Path.Combine(Common.InputPath, "map_icons.txt"))) return new string[0]; + if (!File.Exists(Path.Combine(Common.InputPath, "map_icons.txt"))) return Array.Empty(); var fId = new Text(Path.Combine(Common.InputPath, "map_icons.txt")); fId.GetString(); - var n = Convert.ToInt32(fId.GetString()); + var n = Convert.ToInt32(fId.GetString(), CultureInfo.GetCultureInfo("en-US")); var aMapIcons = new string[n]; for (int i = 0; i < n; i++) { @@ -72,7 +72,7 @@ public static void Decompile() int iSound = fIcons.GetInt(); double dX = fIcons.GetDouble(), dY = fIcons.GetDouble(), dZ = fIcons.GetDouble(); - fSource.Write(" {0}, {1}, {2}, {3}, {4}", dScale.ToString(CultureInfo.GetCultureInfo("en-US")), iSound != 0 ? (iSound < Common.Sounds.Length ? "snd_" + Common.Sounds[iSound] : iSound.ToString()) : "0", + fSource.Write(" {0}, {1}, {2}, {3}, {4}", dScale.ToString(CultureInfo.GetCultureInfo("en-US")), iSound != 0 ? iSound < Common.Sounds.Count ? "snd_" + Common.Sounds[iSound] : iSound.ToString(CultureInfo.GetCultureInfo("en-US")) : "0", dX.ToString(CultureInfo.GetCultureInfo("en-US")), dY.ToString(CultureInfo.GetCultureInfo("en-US")), dZ.ToString(CultureInfo.GetCultureInfo("en-US"))); int iTriggers = fIcons.GetInt(); diff --git a/Core/Menus.cs b/Core/Menus.cs index 0b9b68b..7478656 100644 --- a/Core/Menus.cs +++ b/Core/Menus.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.IO; using System.Text; using DWORD = System.UInt32; @@ -9,11 +10,11 @@ public static class Menus { public static string[] Initialize() { - if (!File.Exists(Path.Combine(Common.InputPath, "menus.txt"))) return new string[0]; + if (!File.Exists(Path.Combine(Common.InputPath, "menus.txt"))) return Array.Empty(); var fId = new Text(Path.Combine(Common.InputPath, "menus.txt")); fId.GetString(); - var n = Convert.ToInt32(fId.GetString()); + var n = Convert.ToInt32(fId.GetString(), CultureInfo.GetCultureInfo("en-US")); var aMenus = new string[n]; for (int i = 0; i < n; i++) { diff --git a/Core/Meshes.cs b/Core/Meshes.cs index e6badc8..5a82e2c 100644 --- a/Core/Meshes.cs +++ b/Core/Meshes.cs @@ -8,10 +8,10 @@ public static class Meshes { public static string[] Initialize() { - if (!File.Exists(Path.Combine(Common.InputPath, "meshes.txt"))) return new string[0]; + if (!File.Exists(Path.Combine(Common.InputPath, "meshes.txt"))) return Array.Empty(); var fId = new Win32FileReader(Path.Combine(Common.InputPath, "meshes.txt")); - var n = Convert.ToInt32(fId.ReadLine()); + var n = Convert.ToInt32(fId.ReadLine(), CultureInfo.GetCultureInfo("en-US")); var aMeshes = new string[n]; for (int i = 0; i < n; i++) { diff --git a/Core/MissionTemplates.cs b/Core/MissionTemplates.cs index 7cf3f87..497b8de 100644 --- a/Core/MissionTemplates.cs +++ b/Core/MissionTemplates.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.IO; using System.Linq; using System.Text; @@ -10,11 +11,11 @@ public static class MissionTemplates { public static string[] Initialize() { - if (!File.Exists(Path.Combine(Common.InputPath, "mission_templates.txt"))) return new string[0]; + if (!File.Exists(Path.Combine(Common.InputPath, "mission_templates.txt"))) return Array.Empty(); var fId = new Text(Path.Combine(Common.InputPath, "mission_templates.txt")); fId.GetString(); - int n = Convert.ToInt32(fId.GetString()); + int n = Convert.ToInt32(fId.GetString(), CultureInfo.GetCultureInfo("en-US")); var aMissionTemplates = new string[n]; for (int i = 0; i < n; i++) { @@ -74,7 +75,7 @@ public static string DecompileSpawnFlags(DWORD dwSpawnFlag) if (dwTeam == 8) sbSpawnFlag.Append("mtef_team_member_2|"); else if (dwTeam != 0) - sbSpawnFlag.AppendFormat("mtef_team_{0}|", dwTeam - 1); + sbSpawnFlag.AppendFormat(CultureInfo.GetCultureInfo("en-US"), "mtef_team_{0}|", dwTeam - 1); string[] strSpawnFlags = { "mtef_enemy_party", "mtef_ally_party", "mtef_scene_source", "mtef_conversation_source", "mtef_visitor_source", "mtef_defenders", "mtef_attackers", "mtef_no_leader", "mtef_no_companions", "mtef_no_regulars", "mtef_infantry_first", @@ -172,7 +173,7 @@ public static void Decompile() else if (iType == 10) strType = "charge_with_ally"; - if (strType != "") + if (strType.Length > 0) fSource.WriteLine(" {0},", strType); else fSource.WriteLine(" {0},", iType); @@ -198,7 +199,7 @@ public static void Decompile() var itemsList = new int[iItems]; for (int j = 0; j < iItems; j++) itemsList[j] = fMissionTemplates.GetInt(); - fSource.WriteLine("{0}]),", String.Join(",", itemsList.Select(t => t < Common.Items.Length && t > -1 ? $"itm_{Common.Items[t]}" : t.ToString()))); + fSource.WriteLine("{0}]),", String.Join(",", itemsList.Select(t => t < Common.Items.Count && t > -1 ? $"itm_{Common.Items[t]}" : t.ToString(CultureInfo.GetCultureInfo("en-US"))))); } fSource.WriteLine(" ],\r\n ["); diff --git a/Core/Music.cs b/Core/Music.cs index f71f4c4..ff79b25 100644 --- a/Core/Music.cs +++ b/Core/Music.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.IO; using System.Text; using DWORD = System.UInt32; @@ -9,10 +10,10 @@ public static class Music { public static string[] Initialize() { - if (!File.Exists(Path.Combine(Common.InputPath, "music.txt"))) return new string[0]; + if (!File.Exists(Path.Combine(Common.InputPath, "music.txt"))) return Array.Empty(); var fId = new Win32FileReader(Path.Combine(Common.InputPath, "music.txt")); - int n = Convert.ToInt32(fId.ReadLine()); + int n = Convert.ToInt32(fId.ReadLine(), CultureInfo.GetCultureInfo("en-US")); var aMusic = new string[n]; for (int i = 0; i < n; i++) { diff --git a/Core/Operators/Operator.cs b/Core/Operators/Operator.cs index a5b8870..3a8ee4a 100644 --- a/Core/Operators/Operator.cs +++ b/Core/Operators/Operator.cs @@ -1,11 +1,10 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; -using System.Xml.Serialization; namespace Decomp.Core.Operators { +#pragma warning disable CA1720 // Identifier contains type name public enum Parameter { None, @@ -58,14 +57,17 @@ public enum Parameter EquipmentOverrideFlags, MissionTemplateIdentifier, SceneFlags, - SortMode + SortMode, + SkinIdentifier, } +#pragma warning restore CA1720 // Identifier contains type name +#pragma warning disable CA1716 // Identifiers should not match keywords public class Operator { - public string Value; - public int Code; - public Dictionary Parameters; + public string Value { get; set; } + public int Code { get; set; } + public IReadOnlyDictionary Parameters { get; set; } private void Initialize(string value, int code) { @@ -82,7 +84,10 @@ public Operator(string value, int code) public Operator(string value, int code, params Parameter[] @params) { Initialize(value, code); - for (int i = 0; i < @params.Length; i++) Parameters[i] = @params[i]; + + var p = new Dictionary(); + for (int i = 0; i < @params.Length; i++) p[i] = @params[i]; + Parameters = p; } public string GetParameter(int index, string s) @@ -95,185 +100,74 @@ public string GetParameter(int index, string s) if (!Parameters.ContainsKey(index)) return s; - switch (Parameters[index]) + return Parameters[index] switch { - case Parameter.None: - return s; - case Parameter.FaceKeyRegister: - return Common.GetFaceKey(t); - case Parameter.FloatRegister: - return "fp" + s; - case Parameter.GameKeyCode: - return Common.GetGameKey(t); - case Parameter.KeyCode: - return Common.GetKey(t); - case Parameter.Position: - return "pos" + s; - case Parameter.String: - return "s" + s; - case Parameter.InventorySlot: - return Common.GetInventorySlot(t); - case Parameter.Tooltip: - return Common.GetTooltip(t); - case Parameter.Color: - return Common.GetColor(t); - case Parameter.TextFlags: - return Common.DecompileTextFlags((uint)t); - case Parameter.Alpha: - return Common.GetAlpha(t); - case Parameter.MenuFlags: - return Menus.DecompileFlags(t); - case Parameter.TroopFlags: - return Troops.DecompileFlags((uint)t); - case Parameter.WeaponProficiency: - return Common.GetWeaponProficiency(t); - case Parameter.CharacterAttribute: - return Common.GetCharacterAttribute(t); - case Parameter.PartyFlags: - return Parties.DecompileFlags((uint)t); - case Parameter.AiBehavior: - return Parties.GetAiBehavior(t); - case Parameter.ItemProperty: - return Items.DecompileFlags(t); - case Parameter.ItemCapability: - return Items.DecompileCapabilities(t); - case Parameter.TroopIdentifier: - return Common.GetCommonIdentifier("trp", Common.Troops, t); - case Parameter.ItemIdentifier: - return Common.GetCommonIdentifier("itm", Common.Items, t); - case Parameter.PartyIdentifier: - return Common.GetCommonIdentifier("p", Common.Parties, t); - case Parameter.AnimationIdentifier: - return Common.GetCommonIdentifier("anim", Common.Animations, t); - case Parameter.ScenePropIdentifier: - return Common.GetCommonIdentifier("spr", Common.SceneProps, t); - case Parameter.SceneIdentifier: - return Common.GetCommonIdentifier("scn", Common.Scenes, t); - case Parameter.FactionIdentifier: - return Common.GetCommonIdentifier("fac", Common.Factions, t); - case Parameter.TableauMaterialIdentifier: - return Common.GetCommonIdentifier("tableau", Common.Tableaus, t); - case Parameter.QuestIdentifier: - return Common.GetCommonIdentifier("qst", Common.Factions, t); - case Parameter.PartyTemplateIdentifier: - return Common.GetCommonIdentifier("pt", Common.Factions, t); - case Parameter.InfoPageIdentifier: - return Common.GetCommonIdentifier("ip", Common.InfoPages, t); - case Parameter.SkillIdentifier: - return Common.GetCommonIdentifier("skl", Common.Skills, t); - case Parameter.MapIconIdentifier: - return Common.GetCommonIdentifier("icon", Common.MapIcons, t); - case Parameter.MeshIdentifier: - return Common.GetCommonIdentifier("mesh", Common.Meshes, t); - case Parameter.ItemType: - return Items.DecompileType(t); - case Parameter.SoundIdentifier: - return Common.GetCommonIdentifier("snd", Common.Sounds, t); - case Parameter.SoundFlags: - return Sounds.DecompileFlags((uint)t); - case Parameter.ScriptIdentifier: - return Common.GetCommonIdentifier("script", Common.Procedures, t); - case Parameter.ParticleSystemIdentifier: - return Common.GetCommonIdentifier("psys", Common.ParticleSystems, t); - case Parameter.AttributeIdentifier: - return Troops.DecompileCharacterAttribute((uint)t); - case Parameter.ItemModifier: - return Items.DecompileModifier((uint)t); - case Parameter.MenuIdentifier: - return Common.GetCommonIdentifier("mnu", Common.Menus, t); - case Parameter.PresentationIdentifier: - return Common.GetCommonIdentifier("prsnt", Common.Presentations, t); - case Parameter.TrackIdentifier: - return Common.GetCommonIdentifier("track", Common.Music, t); - case Parameter.MusicFlags: - return Music.DecompileFlags((uint)t); - case Parameter.EquipmentOverrideFlags: - return MissionTemplates.DecompileAlterFlags((uint)t); - case Parameter.MissionTemplateIdentifier: - return Common.GetCommonIdentifier("mt", Common.MissionTemplates, t); - case Parameter.SceneFlags: - return Scenes.DecompileFlags((uint)t); - case Parameter.SortMode: - return Common.DecompileSortMode(t); - default: - return s; - } + Parameter.None => s, + Parameter.FaceKeyRegister => Common.GetFaceKey(t), + Parameter.FloatRegister => "fp" + s, + Parameter.GameKeyCode => Common.GetGameKey(t), + Parameter.KeyCode => Common.GetKey(t), + Parameter.Position => "pos" + s, + Parameter.String => "s" + s, + Parameter.InventorySlot => Common.GetInventorySlot(t), + Parameter.Tooltip => Common.GetTooltip(t), + Parameter.Color => Common.GetColor(t), + Parameter.TextFlags => Common.DecompileTextFlags((uint)t), + Parameter.Alpha => Common.GetAlpha(t), + Parameter.MenuFlags => Menus.DecompileFlags(t), + Parameter.TroopFlags => Troops.DecompileFlags((uint)t), + Parameter.WeaponProficiency => Common.GetWeaponProficiency(t), + Parameter.CharacterAttribute => Common.GetCharacterAttribute(t), + Parameter.PartyFlags => Parties.DecompileFlags((uint)t), + Parameter.AiBehavior => Parties.GetAiBehavior(t), + Parameter.ItemProperty => Items.DecompileFlags(t), + Parameter.ItemCapability => Items.DecompileCapabilities(t), + Parameter.TroopIdentifier => Common.GetCommonIdentifier("trp", Common.Troops, t), + Parameter.ItemIdentifier => Common.GetCommonIdentifier("itm", Common.Items, t), + Parameter.PartyIdentifier => Common.GetCommonIdentifier("p", Common.Parties, t), + Parameter.AnimationIdentifier => Common.GetCommonIdentifier("anim", Common.Animations, t), + Parameter.ScenePropIdentifier => Common.GetCommonIdentifier("spr", Common.SceneProps, t), + Parameter.SceneIdentifier => Common.GetCommonIdentifier("scn", Common.Scenes, t), + Parameter.FactionIdentifier => Common.GetCommonIdentifier("fac", Common.Factions, t), + Parameter.TableauMaterialIdentifier => Common.GetCommonIdentifier("tableau", Common.Tableaus, t), + Parameter.QuestIdentifier => Common.GetCommonIdentifier("qst", Common.Factions, t), + Parameter.PartyTemplateIdentifier => Common.GetCommonIdentifier("pt", Common.Factions, t), + Parameter.InfoPageIdentifier => Common.GetCommonIdentifier("ip", Common.InfoPages, t), + Parameter.SkillIdentifier => Common.GetCommonIdentifier("skl", Common.Skills, t), + Parameter.MapIconIdentifier => Common.GetCommonIdentifier("icon", Common.MapIcons, t), + Parameter.MeshIdentifier => Common.GetCommonIdentifier("mesh", Common.Meshes, t), + Parameter.ItemType => Items.DecompileType(t), + Parameter.SoundIdentifier => Common.GetCommonIdentifier("snd", Common.Sounds, t), + Parameter.SoundFlags => Sounds.DecompileFlags((uint)t), + Parameter.ScriptIdentifier => Common.GetCommonIdentifier("script", Common.Procedures, t), + Parameter.ParticleSystemIdentifier => Common.GetCommonIdentifier("psys", Common.ParticleSystems, t), + Parameter.AttributeIdentifier => Troops.DecompileCharacterAttribute((uint)t), + Parameter.ItemModifier => Items.DecompileModifier((uint)t), + Parameter.MenuIdentifier => Common.GetCommonIdentifier("mnu", Common.Menus, t), + Parameter.PresentationIdentifier => Common.GetCommonIdentifier("prsnt", Common.Presentations, t), + Parameter.TrackIdentifier => Common.GetCommonIdentifier("track", Common.Music, t), + Parameter.MusicFlags => Music.DecompileFlags((uint)t), + Parameter.EquipmentOverrideFlags => MissionTemplates.DecompileAlterFlags((uint)t), + Parameter.MissionTemplateIdentifier => Common.GetCommonIdentifier("mt", Common.MissionTemplates, t), + Parameter.SceneFlags => Scenes.DecompileFlags((uint)t), + Parameter.SortMode => Common.DecompileSortMode(t), + Parameter.SkinIdentifier => Common.GetCommonIdentifier("tf_", Common.Skins, t), + _ => s, + }; } public static IEnumerable GetCollection(IEnumerable versions) => versions.SelectMany(x => x.GetOperators()); - public static IEnumerable GetCollection(Mode m) - { - switch (m) - { - case Mode.Caribbean: - return GetCollection(new List { new CaribbeanVersion() }); - case Mode.WarbandScriptEnhancer450: - return GetCollection(new List { new Warband1171Version(), new WarbandScriptEnhancer450Version() }); - case Mode.WarbandScriptEnhancer320: - return GetCollection(new List { new Warband1153Version(), new WarbandScriptEnhancer320Version() }); - case Mode.Vanilla: - return GetCollection(new List { new VanillaVersion() }); - default: - throw new ArgumentOutOfRangeException(nameof(m), m, null); - } - } - } - - [Serializable] - public class ParameterWithIndex - { - public int Index; - public Parameter Parameter; - - public ParameterWithIndex() - { - } - - public ParameterWithIndex(int index, Parameter parameter) - { - Index = index; - Parameter = parameter; - } - } - - [Serializable] - public class CustomOperator - { - public string Value; - public int Code; - public Mode TargetMode; - public List Parameters; - - public CustomOperator() - { - Parameters = new List(); - } - - public Operator ToOperator() + public static IEnumerable GetCollection(Mode m) => m switch { - var oper = new Operator(Value, Code); - foreach (var pair in Parameters) oper.Parameters[pair.Index] = pair.Parameter; - return oper; - } - - public static IEnumerable GetOperators(string fileName, Mode targetMode) - { - if (!File.Exists(fileName)) return new List(); - try - { - var serializer = new XmlSerializer(typeof(List)); - var reader = new StreamReader(fileName); - var customOperations = (List)serializer.Deserialize(reader); - reader.Close(); - return customOperations.Where(x => x.TargetMode == targetMode).Select(x => x.ToOperator()); - } - catch - { - return new List(); - } - } + Mode.Caribbean => GetCollection(new List { new CaribbeanVersion() }), + Mode.WarbandScriptEnhancer450 => GetCollection(new List { new Warband1171Version(), new WarbandScriptEnhancer450Version() }), + Mode.WarbandScriptEnhancer320 => GetCollection(new List { new Warband1153Version(), new WarbandScriptEnhancer320Version() }), + Mode.Vanilla => GetCollection(new List { new VanillaVersion() }), + _ => throw new ArgumentOutOfRangeException(nameof(m), m, null), + }; } +#pragma warning restore CA1716 // Identifiers should not match keywords public interface IGameVersion { diff --git a/Core/Operators/WarbandScriptEnhancer450.cs b/Core/Operators/WarbandScriptEnhancer450.cs index 7b0c681..9e91657 100644 --- a/Core/Operators/WarbandScriptEnhancer450.cs +++ b/Core/Operators/WarbandScriptEnhancer450.cs @@ -2,7 +2,7 @@ namespace Decomp.Core.Operators { - //real version: 4.7.3 + //real version: 4.7.7 public class WarbandScriptEnhancer450Version : IGameVersion { public IEnumerable GetOperators() @@ -121,6 +121,11 @@ public IEnumerable GetOperators() new Operator("agent_cancel_current_animation", 3322), new Operator("agent_get_ranged_damage_modifier", 3323), new Operator("agent_add_stun", 3324), + new Operator("agent_body_meta_mesh_deform_in_range", 3325), + new Operator("agent_body_meta_mesh_deform_in_cycle_loop", 3326), + new Operator("agent_body_meta_mesh_get_current_deform_progress", 3327), + new Operator("agent_body_meta_mesh_get_current_deform_frame", 3328), + new Operator("agent_set_footstep_sound", 3329, Parameter.None, Parameter.None, Parameter.SoundIdentifier), new Operator("multiplayer_send_chat_message_to_player", 3400), new Operator("multiplayer_send_composite_message_to_player", 3401), new Operator("multiplayer_send_composite_message_to_server", 3402), @@ -190,6 +195,7 @@ public IEnumerable GetOperators() new Operator("item_set_speed_rating", 3807, Parameter.ItemIdentifier), new Operator("item_set_missile_speed", 3808, Parameter.ItemIdentifier), new Operator("item_set_horse_blood_particles", 3809, Parameter.ItemIdentifier), + new Operator("item_set_horse_blood_color", 3810, Parameter.ItemIdentifier, Parameter.Color), new Operator("party_stack_get_experience", 3900, Parameter.None, Parameter.PartyIdentifier), new Operator("party_stack_get_num_upgradeable", 3901, Parameter.None, Parameter.PartyIdentifier), new Operator("party_has_flag", 3902, Parameter.PartyIdentifier, Parameter.PartyFlags), @@ -354,6 +360,7 @@ public IEnumerable GetOperators() new Operator("lua_get_type", 5111), new Operator("lua_call", 5112, Parameter.String), new Operator("lua_triggerCallback", 5113), + new Operator("skin_set_blood_color", 5200, Parameter.SkinIdentifier, Parameter.Color), }; } diff --git a/Core/ParticleSystems.cs b/Core/ParticleSystems.cs index c74d1df..4993824 100644 --- a/Core/ParticleSystems.cs +++ b/Core/ParticleSystems.cs @@ -10,11 +10,11 @@ public static class ParticleSystems { public static string[] Initialize() { - if (!File.Exists(Path.Combine(Common.InputPath, "particle_systems.txt"))) return new string[0]; + if (!File.Exists(Path.Combine(Common.InputPath, "particle_systems.txt"))) return Array.Empty(); var fId = new Text(Path.Combine(Common.InputPath, "particle_systems.txt")); fId.GetString(); - var n = Convert.ToInt32(fId.GetString()); + var n = Convert.ToInt32(fId.GetString(), CultureInfo.GetCultureInfo("en-US")); var aParticleSystems = new string[n]; for (int i = 0; i < n; i++) { diff --git a/Core/Parties.cs b/Core/Parties.cs index b620016..e9de629 100644 --- a/Core/Parties.cs +++ b/Core/Parties.cs @@ -18,7 +18,7 @@ public static string GetAiBehavior(ulong t) public static string[] Initialize() { - if (!File.Exists(Path.Combine(Common.InputPath, "parties.txt"))) return new string[0]; + if (!File.Exists(Path.Combine(Common.InputPath, "parties.txt"))) return Array.Empty(); var fId = new Text(Path.Combine(Common.InputPath, "parties.txt")); fId.GetString(); @@ -57,7 +57,7 @@ public static string DecompileFlags(DWORD dwFlag) DWORD dwIcon = dwFlag & 0xFF; if (dwIcon != 0) - sbFlag.Append(dwIcon < Common.MapIcons.Length ? "icon_" + Common.MapIcons[dwIcon] + "|" : Convert.ToString(dwIcon) + "|"); + sbFlag.Append(dwIcon < Common.MapIcons.Count ? "icon_" + Common.MapIcons[(int)dwIcon] + "|" : Convert.ToString(dwIcon, CultureInfo.GetCultureInfo("en-US")) + "|"); string[] strFlags = { "pf_town", "pf_castle", "pf_village", "pf_disabled", "pf_is_ship", "pf_is_static", "pf_label_medium", "pf_label_large", "pf_always_visible", "pf_default_behavior", "pf_auto_remove_in_town", "pf_quest_party", "pf_no_label", "pf_limit_members", @@ -102,7 +102,7 @@ public static void Decompile() fSource.Write(", {0}", iParty == 0 ? "pt_none" : "pt_" + Common.PTemps[iParty]); var iFaction = fParties.GetInt(); - fSource.Write(", {0}", iFaction < Common.Factions.Length ? "fac_" + Common.Factions[iFaction] : iFaction.ToString(CultureInfo.GetCultureInfo("en-US"))); + fSource.Write(", {0}", iFaction < Common.Factions.Count ? "fac_" + Common.Factions[iFaction] : iFaction.ToString(CultureInfo.GetCultureInfo("en-US"))); var iPersonality = fParties.GetInt(); fParties.GetInt(); fSource.Write(", {0}", iPersonality); @@ -126,7 +126,7 @@ public static void Decompile() var iTroop = fParties.GetInt(); var iNumTroops = fParties.GetInt(); fParties.GetInt(); var iFlag = fParties.GetInt(); - fSource.Write("(trp_{0}, {1}, {2}){3}", iTroop < Common.Troops.Length ? "trp_" + Common.Troops[iTroop] : iTroop.ToString(CultureInfo.GetCultureInfo("en-US")), iNumTroops, iFlag == 1 ? "pmf_is_prisoner" : "0", j == (iRecords - 1) ? "" : ","); + fSource.Write("(trp_{0}, {1}, {2}){3}", iTroop < Common.Troops.Count ? "trp_" + Common.Troops[iTroop] : iTroop.ToString(CultureInfo.GetCultureInfo("en-US")), iNumTroops, iFlag == 1 ? "pmf_is_prisoner" : "0", j == (iRecords - 1) ? "" : ","); } fSource.Write("]"); var dAngle = fParties.GetDouble(); diff --git a/Core/PartyTemplates.cs b/Core/PartyTemplates.cs index 8f00eb7..963b7f4 100644 --- a/Core/PartyTemplates.cs +++ b/Core/PartyTemplates.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.IO; using System.Text; using DWORD64 = System.UInt64; @@ -11,11 +12,11 @@ public static class PartyTemplates { public static string[] Initialize() { - if (!File.Exists(Path.Combine(Common.InputPath, "party_templates.txt"))) return new string[0]; + if (!File.Exists(Path.Combine(Common.InputPath, "party_templates.txt"))) return Array.Empty(); var fId = new Win32FileReader(Path.Combine(Common.InputPath, "party_templates.txt")); fId.ReadLine(); - var n = Convert.ToInt32(fId.ReadLine()); + var n = Convert.ToInt32(fId.ReadLine(), CultureInfo.GetCultureInfo("en-US")); var aPartyTemplates = new string[n]; for (int i = 0; i < n; i++) { @@ -35,7 +36,7 @@ public static string DecompileFlags(DWORD64 dwFlag) var wCarriesGoods = (WORD)((dwFlag & 0x00FF000000000000) >> 48); var wCarriesGold = (WORD)((dwFlag & 0xFF00000000000000) >> 56); - if (wIcon != 0) sbFlag.Append(wIcon < Common.MapIcons.Length ? "icon_" + Common.MapIcons[wIcon] + "|" : Convert.ToString(wIcon) + "|"); + if (wIcon != 0) sbFlag.Append(wIcon < Common.MapIcons.Count ? "icon_" + Common.MapIcons[wIcon] + "|" : Convert.ToString(wIcon, CultureInfo.GetCultureInfo("en-US")) + "|"); if (wCarriesGoods != 0) sbFlag.Append("carries_goods(" + wCarriesGoods + ")|"); if (wCarriesGold != 0) sbFlag.Append("carries_gold(" + wCarriesGold + ")|"); @@ -105,7 +106,7 @@ public static void Decompile() fSource.Write(", {0}, {1}", DecompileFlags(dwFlag), fTemplates.GetInt()); var iFaction = fTemplates.GetInt(); - if (iFaction >= 0 && iFaction < Common.Factions.Length) + if (iFaction >= 0 && iFaction < Common.Factions.Count) fSource.Write(", fac_{0}", Common.Factions[iFaction]); else fSource.Write(", {0}", iFaction); @@ -122,7 +123,7 @@ public static void Decompile() var iMinTroops = fTemplates.GetInt(); var iMaxTroops = fTemplates.GetInt(); var dwMemberFlag = fTemplates.GetDWord(); - sbTroopList.Append($"({(iTroop < Common.Troops.Length ? "trp_" + Common.Troops[iTroop] : iTroop.ToString())}, {iMinTroops}, {iMaxTroops}{(dwMemberFlag == 1 ? ", pmf_is_prisoner" : "")}),"); + sbTroopList.Append($"({(iTroop < Common.Troops.Count ? "trp_" + Common.Troops[iTroop] : iTroop.ToString(CultureInfo.GetCultureInfo("en-US")))}, {iMinTroops}, {iMaxTroops}{(dwMemberFlag == 1 ? ", pmf_is_prisoner" : "")}),"); } if (sbTroopList.Length != 0) sbTroopList.Length--; fSource.WriteLine("{0}]),", sbTroopList); diff --git a/Core/Presentations.cs b/Core/Presentations.cs index 2d0c5f0..d6bf4aa 100644 --- a/Core/Presentations.cs +++ b/Core/Presentations.cs @@ -1,4 +1,5 @@ -using System.Globalization; +using System; +using System.Globalization; using System.IO; namespace Decomp.Core @@ -7,7 +8,7 @@ public static class Presentations { public static string[] Initialize() { - if (!File.Exists(Path.Combine(Common.InputPath, "presentations.txt"))) return new string[0]; + if (!File.Exists(Path.Combine(Common.InputPath, "presentations.txt"))) return Array.Empty(); var fId = new Text(Path.Combine(Common.InputPath, "presentations.txt")); fId.GetString(); @@ -43,20 +44,13 @@ public static string[] Initialize() return aPresentations; } - public static string DecompileFlags(int iFlag) + public static string DecompileFlags(int iFlag) => iFlag switch { - switch (iFlag) - { - case 3: - return "prsntf_read_only|prsntf_manual_end_only"; - case 2: - return "prsntf_manual_end_only"; - case 1: - return "prsntf_read_only"; - default: - return iFlag.ToString(CultureInfo.GetCultureInfo("en-US")); - } - } + 3 => "prsntf_read_only|prsntf_manual_end_only", + 2 => "prsntf_manual_end_only", + 1 => "prsntf_read_only", + _ => iFlag.ToString(CultureInfo.GetCultureInfo("en-US")) + }; public static void Decompile() { @@ -74,7 +68,7 @@ public static void Decompile() fSource.Write(", {0}", DecompileFlags(iFlag)); int iMesh = fPresentations.GetInt(); - if (iMesh >= 0 && iMesh < Common.Meshes.Length) + if (iMesh >= 0 && iMesh < Common.Meshes.Count) fSource.Write(", mesh_{0}", Common.Meshes[iMesh]); else fSource.Write(", {0}", iMesh); diff --git a/Core/Quests.cs b/Core/Quests.cs index 940a6c6..d782c66 100644 --- a/Core/Quests.cs +++ b/Core/Quests.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.IO; namespace Decomp.Core @@ -7,11 +8,11 @@ public static class Quests { public static string[] Initialize() { - if (!File.Exists(Path.Combine(Common.InputPath, "quests.txt"))) return new string[0]; + if (!File.Exists(Path.Combine(Common.InputPath, "quests.txt"))) return Array.Empty(); var fId = new Win32FileReader(Path.Combine(Common.InputPath, "quests.txt")); fId.ReadLine(); - int n = Convert.ToInt32(fId.ReadLine()); + int n = Convert.ToInt32(fId.ReadLine(), CultureInfo.GetCultureInfo("en-US")); var aQuests = new string[n]; for (int i = 0; i < n; i++) { @@ -24,20 +25,13 @@ public static string[] Initialize() return aQuests; } - public static string DecompileFlags(int iFlag) + public static string DecompileFlags(int iFlag) => iFlag switch { - switch (iFlag) - { - case 0x00000001: - return "qf_show_progression"; - case 0x00000002: - return "qf_random_quest"; - case 0x00000003: - return "qf_show_progression|qf_random_quest"; - default: - return "0"; - } - } + 0x00000001 => "qf_show_progression", + 0x00000002 => "qf_random_quest", + 0x00000003 => "qf_show_progression|qf_random_quest", + _ => "0", + }; public static void Decompile() { diff --git a/Core/QuickStrings.cs b/Core/QuickStrings.cs index 5626328..ea377b7 100644 --- a/Core/QuickStrings.cs +++ b/Core/QuickStrings.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.IO; namespace Decomp.Core @@ -7,10 +8,10 @@ public static class QuickStrings { public static string[] Initialize() { - if (!File.Exists(Path.Combine(Common.InputPath, "quick_strings.txt"))) return new string[0]; + if (!File.Exists(Path.Combine(Common.InputPath, "quick_strings.txt"))) return Array.Empty(); var fId = new Win32FileReader(Path.Combine(Common.InputPath, "quick_strings.txt")); - int n = Convert.ToInt32(fId.ReadLine()); + int n = Convert.ToInt32(fId.ReadLine(), CultureInfo.GetCultureInfo("en-US")); var aQuickStrings = new string[n]; for (int i = 0; i < n; i++) { diff --git a/Core/SceneProps.cs b/Core/SceneProps.cs index bb3c61e..7f3de64 100644 --- a/Core/SceneProps.cs +++ b/Core/SceneProps.cs @@ -1,4 +1,5 @@ -using System.IO; +using System; +using System.IO; using System.Text; using DWORD = System.UInt32; @@ -8,7 +9,7 @@ public static class SceneProps { public static string[] Initialize() { - if (!File.Exists(Path.Combine(Common.InputPath, "scene_props.txt"))) return new string[0]; + if (!File.Exists(Path.Combine(Common.InputPath, "scene_props.txt"))) return Array.Empty(); var fId = new Text(Path.Combine(Common.InputPath, "scene_props.txt")); fId.GetString(); diff --git a/Core/Scenes.cs b/Core/Scenes.cs index 3ddc3af..0b080ff 100644 --- a/Core/Scenes.cs +++ b/Core/Scenes.cs @@ -1,4 +1,5 @@ -using System.Globalization; +using System; +using System.Globalization; using System.IO; using System.Text; using DWORD = System.UInt32; @@ -9,7 +10,7 @@ public static class Scenes { public static string[] Initialize() { - if (!File.Exists(Path.Combine(Common.InputPath, "scenes.txt"))) return new string[0]; + if (!File.Exists(Path.Combine(Common.InputPath, "scenes.txt"))) return Array.Empty(); var fId = new Text(Path.Combine(Common.InputPath, "scenes.txt")); fId.GetString(); @@ -88,7 +89,7 @@ public static void Decompile() //else if (iScene == 0) // fprintf(g_fOutput, "\"\""); else - fSource.Write("{0}", iScene < Common.Scenes.Length ? '"' + Common.Scenes[iScene] + '"' : iScene.ToString()); + fSource.Write("{0}", iScene < Common.Scenes.Count ? '"' + Common.Scenes[iScene] + '"' : iScene.ToString(CultureInfo.GetCultureInfo("en-US"))); if (i < iPassages - 1) fSource.Write(", "); } @@ -99,7 +100,7 @@ public static void Decompile() for (int i = 0; i < iChestTroops; i++) { int iTroop = fScenes.GetInt(); - if (iTroop < Common.Troops.Length) + if (iTroop < Common.Troops.Count) fSource.Write("\"{0}\"", Common.Troops[iTroop]); else fSource.Write("{0}", iTroop); diff --git a/Core/Scripts.cs b/Core/Scripts.cs index 5d58706..c992bd5 100644 --- a/Core/Scripts.cs +++ b/Core/Scripts.cs @@ -1,14 +1,15 @@ -using System.IO; +using System; +using System.IO; namespace Decomp.Core { public static class Scripts { - public static string[] InitializeVariables() => File.Exists(Path.Combine(Common.InputPath, "variables.txt")) ? Win32FileReader.ReadAllLines(Path.Combine(Common.InputPath, "variables.txt")) : new string[0]; + public static string[] InitializeVariables() => File.Exists(Path.Combine(Common.InputPath, "variables.txt")) ? Win32FileReader.ReadAllLines(Path.Combine(Common.InputPath, "variables.txt")) : Array.Empty(); public static string[] Initialize() { - if (!File.Exists(Path.Combine(Common.InputPath, "scripts.txt"))) return new string[0]; + if (!File.Exists(Path.Combine(Common.InputPath, "scripts.txt"))) return Array.Empty(); var fId = new Text(Path.Combine(Common.InputPath, "scripts.txt")); fId.GetString(); diff --git a/Core/Shaders/Shaders.cs b/Core/Shaders/Shaders.cs index fbf954e..0d5eff1 100644 --- a/Core/Shaders/Shaders.cs +++ b/Core/Shaders/Shaders.cs @@ -100,6 +100,7 @@ private struct D3DPRESENT_PARAMETERS public uint PresentationInterval; } +#pragma warning disable CA1707 // Identifiers should not contain underscores public const uint WS_OVERLAPPED = 0x00000000; public const uint WS_POPUP = 0x80000000; public const uint WS_CHILD = 0x40000000; @@ -131,10 +132,11 @@ private struct D3DPRESENT_PARAMETERS public const uint WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX; - public const uint WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU; + public const uint WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU; +#pragma warning restore CA1707 // Identifiers should not contain underscores [StructLayout(LayoutKind.Sequential, Pack = 4)] - public struct IDirect3D9 + private struct IDirect3D9 { public IntPtr* lpVtbl; /* @@ -170,19 +172,19 @@ private static int IDirect3D9_CreateDevice(IDirect3D9* p, uint Adapter, uint Dev } [StructLayout(LayoutKind.Sequential, Pack = 4)] - public struct IDirect3DDevice9 + private struct IDirect3DDevice9 { public IntPtr* lpVtbl; } [StructLayout(LayoutKind.Sequential, Pack = 4)] - public struct ID3DXEffect + private struct ID3DXEffect { public IntPtr* lpVtbl; } [StructLayout(LayoutKind.Sequential, Pack = 4)] - public struct ID3DXBuffer + private struct ID3DXBuffer { public IntPtr* lpVtbl; /* @@ -300,6 +302,7 @@ public static void Decompile(string sFileName) ID3DXEffect* pD3DEffect = null; ID3DXBuffer* pD3DError = null; ID3DXBuffer* pDisassembler = null; + D3DXCreateEffectFromFile(g_D3DDevice, sFileName, IntPtr.Zero, IntPtr.Zero, 0, IntPtr.Zero, &pD3DEffect, &pD3DError); D3DXDisassembleEffect(pD3DEffect, false, &pDisassembler); diff --git a/Core/Skills.cs b/Core/Skills.cs index c6425c5..2115965 100644 --- a/Core/Skills.cs +++ b/Core/Skills.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.IO; using System.Text; using DWORD = System.UInt32; @@ -9,10 +10,10 @@ public static class Skills { public static string[] Initialize() { - if (!File.Exists(Path.Combine(Common.InputPath, "skills.txt"))) return new string[0]; + if (!File.Exists(Path.Combine(Common.InputPath, "skills.txt"))) return Array.Empty(); var fId = new Win32FileReader(Path.Combine(Common.InputPath, "skills.txt")); - int n = Convert.ToInt32(fId.ReadLine()); + int n = Convert.ToInt32(fId.ReadLine(), CultureInfo.GetCultureInfo("en-US")); var aSkills = new string[n]; for (int i = 0; i < n; i++) { diff --git a/Core/Skins.cs b/Core/Skins.cs index e547422..345e149 100644 --- a/Core/Skins.cs +++ b/Core/Skins.cs @@ -1,6 +1,6 @@ -using System.Globalization; +using System; +using System.Globalization; using System.IO; -using DWORD = System.UInt32; namespace Decomp.Core { @@ -8,7 +8,7 @@ public static class Skins { public static string[] Initialize() { - if (!File.Exists(Path.Combine(Common.InputPath, "skins.txt"))) return new string[0]; + if (!File.Exists(Path.Combine(Common.InputPath, "skins.txt"))) return Array.Empty(); var fId = new Text(Path.Combine(Common.InputPath, "skins.txt")); fId.GetString(); @@ -172,8 +172,8 @@ public static void Decompile() int ixParticleSystem1 = fSkins.GetInt(), ixParticleSystem2 = fSkins.GetInt(); fSource.WriteLine(" {0}, {1},", - ixParticleSystem1 < Common.ParticleSystems.Length ? "psys_" + Common.ParticleSystems[ixParticleSystem1] : ixParticleSystem1.ToString(), - ixParticleSystem2 < Common.ParticleSystems.Length ? "psys_" + Common.ParticleSystems[ixParticleSystem2] : ixParticleSystem2.ToString()); + ixParticleSystem1 < Common.ParticleSystems.Count ? "psys_" + Common.ParticleSystems[ixParticleSystem1] : ixParticleSystem1.ToString(CultureInfo.GetCultureInfo("en-US")), + ixParticleSystem2 < Common.ParticleSystems.Count ? "psys_" + Common.ParticleSystems[ixParticleSystem2] : ixParticleSystem2.ToString(CultureInfo.GetCultureInfo("en-US"))); int iConstraints = fSkins.GetInt(); fSource.Write(" ["); diff --git a/Core/Sounds.cs b/Core/Sounds.cs index f83b490..f803ffd 100644 --- a/Core/Sounds.cs +++ b/Core/Sounds.cs @@ -1,4 +1,6 @@ -using System.IO; +using System; +using System.Globalization; +using System.IO; using System.Text; using DWORD = System.UInt32; @@ -8,7 +10,7 @@ public static class Sounds { public static string[] Initialize() { - if (!File.Exists(Path.Combine(Common.InputPath, "sounds.txt"))) return new string[0]; + if (!File.Exists(Path.Combine(Common.InputPath, "sounds.txt"))) return Array.Empty(); var fId = new Text(Path.Combine(Common.InputPath, "sounds.txt")); fId.GetString(); @@ -91,7 +93,7 @@ public static void Decompile() { int iSample = fSounds.GetInt(); fSounds.GetInt(); - fSource.Write("{0}{1}", iSample < aSamples.Length ? '"' + aSamples[iSample] + '"' : iSample.ToString(), l == iListCount - 1 ? "" : ", "); + fSource.Write("{0}{1}", iSample < aSamples.Length ? '"' + aSamples[iSample] + '"' : iSample.ToString(CultureInfo.GetCultureInfo("en-US")), l == iListCount - 1 ? "" : ", "); } fSource.WriteLine("]),"); } diff --git a/Core/Strings.cs b/Core/Strings.cs index 42ed8a4..061e7a6 100644 --- a/Core/Strings.cs +++ b/Core/Strings.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.IO; namespace Decomp.Core @@ -7,11 +8,11 @@ public static class Strings { public static string[] Initialize() { - if (!File.Exists(Path.Combine(Common.InputPath, "strings.txt"))) return new string[0]; + if (!File.Exists(Path.Combine(Common.InputPath, "strings.txt"))) return Array.Empty(); var fId = new Win32FileReader(Path.Combine(Common.InputPath, "strings.txt")); fId.ReadLine(); - int n = Convert.ToInt32(fId.ReadLine()); + int n = Convert.ToInt32(fId.ReadLine(), CultureInfo.GetCultureInfo("en-US")); var aStrings = new string[n]; for (int i = 0; i < n; i++) { @@ -31,7 +32,7 @@ public static void Decompile() fSource.WriteLine(Header.Standard); fSource.WriteLine(Header.Strings); fStrings.GetString(); - int iStrings = Convert.ToInt32(fStrings.GetString()); //fStrings.GetInt(); + int iStrings = Convert.ToInt32(fStrings.GetString(), CultureInfo.GetCultureInfo("en-US")); //fStrings.GetInt(); for (int s = 0; s < iStrings; s++) { diff --git a/Core/TableauMaterials.cs b/Core/TableauMaterials.cs index 1f2357e..4ae1539 100644 --- a/Core/TableauMaterials.cs +++ b/Core/TableauMaterials.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.IO; namespace Decomp.Core @@ -7,10 +8,10 @@ public static class TableauMaterials { public static string[] Initialize() { - if (!File.Exists(Path.Combine(Common.InputPath, "tableau_materials.txt"))) return new string[0]; + if (!File.Exists(Path.Combine(Common.InputPath, "tableau_materials.txt"))) return Array.Empty(); var fId = new Win32FileReader(Path.Combine(Common.InputPath, "tableau_materials.txt")); - int n = Convert.ToInt32(fId.ReadLine()); + int n = Convert.ToInt32(fId.ReadLine(), CultureInfo.GetCultureInfo("en-US")); var aTableauMateriales = new string[n]; for (int i = 0; i < n; i++) { diff --git a/Core/Trie.cs b/Core/Trie.cs index 9ae352f..093aea9 100644 --- a/Core/Trie.cs +++ b/Core/Trie.cs @@ -5,15 +5,17 @@ namespace Decomp.Core { public class SimpleTrieNode { - public SimpleTrieNode[] Next; - public bool Leaf; - public T Value; +#pragma warning disable CA1819 // Properties should not return arrays + public SimpleTrieNode[] Next { get; set; } +#pragma warning restore CA1819 // Properties should not return arrays + public bool Leaf { get; set; } + public T Value { get; set; } public SimpleTrieNode() { Next = new SimpleTrieNode[27]; Leaf = false; - Value = default(T); + Value = default; } } @@ -26,11 +28,13 @@ public class SimpleTrie public SimpleTrie(IEnumerable> enumerable) { _root = new SimpleTrieNode(); - foreach (var pair in enumerable) Add(pair); + + if (enumerable == null) return; + foreach (var pair in enumerable) Add(pair); } - public void Add(KeyValuePair pair) => Add(_root, pair.Key.ToLower(), pair.Value, 0); - public void Add(string key, T value) => Add(_root, key.ToLower(), value, 0); + public void Add(KeyValuePair pair) => Add(_root, pair.Key.ToUpperInvariant(), pair.Value, 0); + public void Add(string key, T value) => Add(_root, key?.ToUpperInvariant(), value, 0); private static void Add(SimpleTrieNode node, string s, T value, int index) { @@ -43,7 +47,7 @@ private static void Add(SimpleTrieNode node, string s, T value, int index) return; } - var nextIndex = Char.IsLetter(s, index) ? s[index] - 'a' : 26; + var nextIndex = Char.IsLetter(s, index) ? s[index] - 'A' : 26; var b = node.Next[nextIndex]; if (b != null) node = b; else @@ -58,12 +62,14 @@ private static void Add(SimpleTrieNode node, string s, T value, int index) public bool ContainsKey(string key) { + if (key == null) return false; + var b = _root; - var s = key.ToLower(); + var s = key.ToUpperInvariant(); for (int i = 0; i < s.Length; i++) { if (b == null) return false; - b = b.Next[Char.IsLetter(s, i) ? s[i] - 'a' : 26]; + b = b.Next[Char.IsLetter(s, i) ? s[i] - 'A' : 26]; } return b?.Leaf ?? false; @@ -71,30 +77,38 @@ public bool ContainsKey(string key) public T GetValue(string key) { + if (key == null) return default; + var b = _root; - var s = key.ToLower(); + var s = key.ToUpperInvariant(); for (int i = 0; i < s.Length; i++) { - if (b == null) return default(T); - b = b.Next[Char.IsLetter(s, i) ? s[i] - 'a' : 26]; + if (b == null) return default; + b = b.Next[Char.IsLetter(s, i) ? s[i] - 'A' : 26]; } - return b == null ? default(T) : (b.Leaf ? b.Value : default(T)); + return b == null ? default : b.Leaf ? b.Value : default; } public bool TryGetValue(string key, out T value) { + if (key == null) + { + value = default; + return false; + } + var b = _root; - var s = key.ToLower(); - value = default(T); + var s = key.ToUpperInvariant(); + value = default; for (int i = 0; i < s.Length; i++) { if (b == null) return false; - b = b.Next[Char.IsLetter(s, i) ? s[i] - 'a' : 26]; + b = b.Next[Char.IsLetter(s, i) ? s[i] - 'A' : 26]; } if (b == null) return false; - value = b.Leaf ? b.Value : default(T); + value = b.Leaf ? b.Value : default; return true; } @@ -108,12 +122,14 @@ public T this[string key] public bool Remove(string key) { + if (key == null) return false; + var b = _root; - var s = key.ToLower(); + var s = key.ToUpperInvariant(); for (int i = 0; i < s.Length; i++) { if (b == null) return false; - b = b.Next[Char.IsLetter(s, i) ? s[i] - 'a' : 26]; + b = b.Next[Char.IsLetter(s, i) ? s[i] - 'A' : 26]; } if (b == null) return false; diff --git a/Core/Troops.cs b/Core/Troops.cs index dc9ad93..a3c4ce3 100644 --- a/Core/Troops.cs +++ b/Core/Troops.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Text; @@ -20,7 +21,7 @@ public Upgrade(int from, int to) _upgradeTo = to; } - public override string ToString() => Math.Max(_upgradeFrom, _upgradeTo) >= Common.Troops.Length ? "" : $"upgrade(troops,\"{Common.Troops[_upgradeFrom]}\",\"{Common.Troops[_upgradeTo]}\")"; + public override string ToString() => Math.Max(_upgradeFrom, _upgradeTo) >= Common.Troops.Count ? "" : $"upgrade(troops,\"{Common.Troops[_upgradeFrom]}\",\"{Common.Troops[_upgradeTo]}\")"; } public class Upgrade2 @@ -36,12 +37,12 @@ public Upgrade2(int from, int to, int to2) _upgradeTo2 = to2; } - public override string ToString() => Math.Max(Math.Max(_upgradeFrom, _upgradeTo), _upgradeTo2) >= Common.Troops.Length ? "" : $"upgrade2(troops,\"{Common.Troops[_upgradeFrom]}\",\"{Common.Troops[_upgradeTo]}\",\"{Common.Troops[_upgradeTo2]}\")"; + public override string ToString() => Math.Max(Math.Max(_upgradeFrom, _upgradeTo), _upgradeTo2) >= Common.Troops.Count ? "" : $"upgrade2(troops,\"{Common.Troops[_upgradeFrom]}\",\"{Common.Troops[_upgradeTo]}\",\"{Common.Troops[_upgradeTo2]}\")"; } public static string[] Initialize() { - if (!File.Exists(Path.Combine(Common.InputPath, "troops.txt"))) return new string[0]; + if (!File.Exists(Path.Combine(Common.InputPath, "troops.txt"))) return Array.Empty(); var fId = new Text(Path.Combine(Common.InputPath, "troops.txt")); fId.GetString(); @@ -60,23 +61,20 @@ public static string[] Initialize() return aTroops; } - public static string DecompileCharacterAttribute(DWORD dwAttribute) + public static string DecompileCharacterAttribute(DWORD dwAttribute) => dwAttribute switch { - switch (dwAttribute) - { - case 0: return "ca_strength"; - case 1: return "ca_agility"; - case 2: return "ca_intelligence"; - case 3: return "ca_charisma"; - default: return dwAttribute.ToString(); - } - } + 0 => "ca_strength", + 1 => "ca_agility", + 2 => "ca_intelligence", + 3 => "ca_charisma", + _ => dwAttribute.ToString(CultureInfo.GetCultureInfo("en-US")), + }; public static string GetScene(DWORD dwScene) { DWORD dwEntry = (dwScene & 0xFFFF0000) >> 16; DWORD dwId = dwScene & 0xFFFF; - return dwId < Common.Scenes.Length ? $"scn_{Common.Scenes[dwId]}|entry({dwEntry})" : $"{dwId}|entry({dwEntry})"; + return dwId < Common.Scenes.Count ? $"scn_{Common.Scenes[(int)dwId]}|entry({dwEntry})" : $"{dwId}|entry({dwEntry})"; } public static string DecompileFlags(DWORD dwFlag) @@ -84,7 +82,7 @@ public static string DecompileFlags(DWORD dwFlag) var sbFlag = new StringBuilder(1024); DWORD dwSkin = dwFlag & 0xF; - if(dwSkin > 0) sbFlag.Append(dwSkin < Common.Skins.Length ? "tf_" + Common.Skins[dwSkin] + "|" : $"{dwSkin}|"); + if(dwSkin > 0) sbFlag.Append(dwSkin < Common.Skins.Count ? "tf_" + Common.Skins[(int)dwSkin] + "|" : $"{dwSkin}|"); if ((dwFlag & 0x7F00000) - 0x7F00000 == 0) { @@ -146,7 +144,7 @@ public static void Decompile() fSource.WriteLine(Header.Standard); fSource.WriteLine(Header.Troops); - for (int s = 0; s < Common.Skins.Length; s++) fSource.WriteLine("tf_" + Common.Skins[s] + " = " + s); + for (int s = 0; s < Common.Skins.Count; s++) fSource.WriteLine("tf_" + Common.Skins[s] + " = " + s); fSource.WriteLine("\r\ntroops = ["); @@ -170,7 +168,7 @@ public static void Decompile() fSource.Write(" {0},", fTroops.GetWord()); // reserved "0" var iFaction = fTroops.GetInt(); - if (iFaction > 0 && iFaction < Common.Factions.Length) + if (iFaction > 0 && iFaction < Common.Factions.Count) fSource.WriteLine(" fac_{0},", Common.Factions[iFaction]); else fSource.WriteLine(" {0},", iFaction); @@ -199,7 +197,7 @@ public static void Decompile() } fSource.WriteLine(" [{0}],", String.Join(",", itemList.Select(item => { - var u = item.Key < Common.Items.Length ? $"itm_{Common.Items[item.Key]}" : $"{item.Key}"; + var u = item.Key < Common.Items.Count ? $"itm_{Common.Items[item.Key]}" : $"{item.Key}"; return item.Value <= 0 || item.Value >= aImods.Count ? u : $"({u}, {aImods[item.Value]})"; }))); @@ -229,7 +227,7 @@ public static void Decompile() for (int q = 0; q < 8; q++) { DWORD dwKnow = 0xF & (dword >> (q << 2)); - if (dwKnow != 0 && (x << 3) + q < Common.Skills.Length) strKnow.Append($"knows_{Common.Skills[(x << 3) + q]}_{dwKnow}|"); + if (dwKnow != 0 && (x << 3) + q < Common.Skills.Count) strKnow.Append($"knows_{Common.Skills[(x << 3) + q]}_{dwKnow}|"); } } if (strKnow.Length == 0) strKnow.Append('0'); else strKnow.Length--; diff --git a/Core/Vanilla/Animations.cs b/Core/Vanilla/Animations.cs index 601e09f..0598289 100644 --- a/Core/Vanilla/Animations.cs +++ b/Core/Vanilla/Animations.cs @@ -10,7 +10,7 @@ public static class Animations public static string[] GetIdFromFile(string strFileName) { var fId = new StreamReader(strFileName); - int n = Convert.ToInt32(fId.ReadLine()); + int n = Convert.ToInt32(fId.ReadLine(), CultureInfo.GetCultureInfo("en-US")); var aAnimations = new string[n]; for (int i = 0; i < n; i++) { @@ -20,7 +20,7 @@ public static string[] GetIdFromFile(string strFileName) aAnimations[i] = animation.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[0]; - int j = Convert.ToInt32(animation.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[2]); + int j = Convert.ToInt32(animation.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[2], CultureInfo.GetCultureInfo("en-US")); while (j != 0) { fId.ReadLine(); diff --git a/Core/Vanilla/Dialogs.cs b/Core/Vanilla/Dialogs.cs index 58cd9b9..416b384 100644 --- a/Core/Vanilla/Dialogs.cs +++ b/Core/Vanilla/Dialogs.cs @@ -46,21 +46,21 @@ public static void Decompile() else if (dwPartner != 0) { if ((dwDialogPartner & PARTY_TPL) != 0) - sbDialogPartner.Append(dwPartner < Common.PTemps.Length ? "pt_" + Common.PTemps[dwPartner] + "|" : $"{dwPartner}|"); + sbDialogPartner.Append(dwPartner < Common.PTemps.Count ? "pt_" + Common.PTemps[(int)dwPartner] + "|" : $"{dwPartner}|"); else - sbDialogPartner.Append(dwPartner < Common.Troops.Length ? "trp_" + Common.Troops[dwPartner] + "|" : $"{dwPartner}|"); + sbDialogPartner.Append(dwPartner < Common.Troops.Count ? "trp_" + Common.Troops[(int)dwPartner] + "|" : $"{dwPartner}|"); } DWORD dwOther = (dwDialogPartner & 0xFFF00000) >> 20; if (dwOther != 0) - sbDialogPartner.Append(dwOther < Common.Troops.Length ? "other(trp_" + Common.Troops[dwOther] + ")|" : $"other({dwOther})|"); + sbDialogPartner.Append(dwOther < Common.Troops.Count ? "other(trp_" + Common.Troops[(int)dwOther] + ")|" : $"other({dwOther})|"); if (sbDialogPartner.Length == 0) sbDialogPartner.Append('0'); else sbDialogPartner.Length--; - if (iStartingDialogState < Common.DialogStates.Length) + if (iStartingDialogState < Common.DialogStates.Count) fSource.Write(" [{0}, \"{1}\",\r\n [", sbDialogPartner, Common.DialogStates[iStartingDialogState]); else fSource.Write(" [{0}, {1},\r\n [", sbDialogPartner, iStartingDialogState); @@ -80,7 +80,7 @@ public static void Decompile() int iEndingDialogState = fDialogs.GetInt(); - if (iEndingDialogState < Common.DialogStates.Length) + if (iEndingDialogState < Common.DialogStates.Count) fSource.Write(" \"{0}\",\r\n [", Common.DialogStates[iEndingDialogState]); else fSource.Write(" {0},\r\n [", iEndingDialogState); diff --git a/Core/Vanilla/Items.cs b/Core/Vanilla/Items.cs index 494cbb3..559f9ee 100644 --- a/Core/Vanilla/Items.cs +++ b/Core/Vanilla/Items.cs @@ -10,18 +10,20 @@ namespace Decomp.Core.Vanilla { public static class Items { + // ReSharper disable InconsistentNaming private const BYTE HORSE_TYPE = 0x1; private const BYTE GOODS_TYPE = 0xb; private const BYTE BOW_TYPE = 0x8; private const BYTE CROSSBOW_TYPE = 0x9; private const BYTE PISTOL_TYPE = 0x10; private const BYTE MUSKET_TYPE = 0x11; + // ReSharper restore InconsistentNaming public static string[] GetIdFromFile(string strFileName) { var fId = new Text(strFileName); fId.GetString(); - int n = Convert.ToInt32(fId.GetString()); + int n = Convert.ToInt32(fId.GetString(), CultureInfo.GetCultureInfo("en-US")); var aItems = new string[n]; for (int i = 0; i < n; i++) { @@ -144,7 +146,7 @@ public static void Decompile() { var strMeshName = fItems.GetWord(); var dwMeshBits = fItems.GetUInt64(); - strMeshes = strMeshes + $"(\"{strMeshName}\", {Core.Items.DecompileMeshesImodBits(dwMeshBits)}),"; + strMeshes += $"(\"{strMeshName}\", {Core.Items.DecompileMeshesImodBits(dwMeshBits)}),"; } if (strMeshes.Length > 0) strMeshes = strMeshes.Remove(strMeshes.Length - 1, 1); diff --git a/Core/Vanilla/Sounds.cs b/Core/Vanilla/Sounds.cs index 0194d88..54dee99 100644 --- a/Core/Vanilla/Sounds.cs +++ b/Core/Vanilla/Sounds.cs @@ -1,4 +1,5 @@ -using System.IO; +using System.Globalization; +using System.IO; namespace Decomp.Core.Vanilla { @@ -28,7 +29,7 @@ public static void Decompile() for (int l = 0; l < iListCount; l++) { var iSample = fSounds.GetInt(); - fSource.Write("{0}{1}", iSample < aSamples.Length ? '"' + aSamples[iSample] + '"' : iSample.ToString(), l == iListCount - 1 ? "" : ", "); + fSource.Write("{0}{1}", iSample < aSamples.Length ? '"' + aSamples[iSample] + '"' : iSample.ToString(CultureInfo.GetCultureInfo("en-US")), l == iListCount - 1 ? "" : ", "); } fSource.WriteLine("]),"); } diff --git a/Core/Vanilla/Troops.cs b/Core/Vanilla/Troops.cs index debfe72..7d16cf3 100644 --- a/Core/Vanilla/Troops.cs +++ b/Core/Vanilla/Troops.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Text; @@ -31,7 +32,7 @@ public static void Decompile() fSource.WriteLine(Header.Standard); fSource.WriteLine(Header.Troops); - for (int s = 0; s < Common.Skins.Length; s++) fSource.WriteLine("tf_" + Common.Skins[s] + " = " + s); + for (int s = 0; s < Common.Skins.Count; s++) fSource.WriteLine("tf_" + Common.Skins[s] + " = " + s); fSource.WriteLine("\r\ntroops = ["); fTroops.GetString(); @@ -52,7 +53,7 @@ public static void Decompile() fSource.Write(" {0},", fTroops.GetWord()); // reserved "0" var iFaction = fTroops.GetInt(); - if (iFaction > 0 && iFaction < Common.Factions.Length) + if (iFaction > 0 && iFaction < Common.Factions.Count) fSource.WriteLine(" fac_{0},", Common.Factions[iFaction]); else fSource.WriteLine(" {0},", iFaction); @@ -61,7 +62,7 @@ public static void Decompile() var iUp2 = fTroops.GetInt(); // ReSharper disable once InconsistentNaming - string fnGetTroopForUpgrade(int id) => id >= 0 && id < Common.Troops.Length ? '"' + Common.Troops[id] + '"' : id.ToString(); + string fnGetTroopForUpgrade(int id) => id >= 0 && id < Common.Troops.Count ? '"' + Common.Troops[id] + '"' : id.ToString(CultureInfo.GetCultureInfo("en-US")); if (iUp1 != 0 && iUp2 != 0) strUpList.Add( @@ -77,7 +78,7 @@ public static void Decompile() if (-1 == iItem) continue; itemList.Add(iItem); } - fSource.WriteLine(" [{0}],", String.Join(",", itemList.Select(item => item < Common.Items.Length ? $"itm_{Common.Items[item]}" : $"{item}"))); + fSource.WriteLine(" [{0}],", String.Join(",", itemList.Select(item => item < Common.Items.Count ? $"itm_{Common.Items[item]}" : $"{item}"))); int iStregth = fTroops.GetInt(), iAgility = fTroops.GetInt(), @@ -105,7 +106,7 @@ public static void Decompile() for (int q = 0; q < 8; q++) { var dwKnow = 0xF & (dword >> (q << 2)); - if (dwKnow != 0 && (x << 3) + q < Common.Skills.Length) sbKnow.Append($"knows_{Common.Skills[(x << 3) + q]}_{dwKnow}|"); + if (dwKnow != 0 && (x << 3) + q < Common.Skills.Count) sbKnow.Append($"knows_{Common.Skills[(x << 3) + q]}_{dwKnow}|"); } } diff --git a/Core/Win32FileWriter.cs b/Core/Win32FileWriter.cs index f329b87..1e63629 100644 --- a/Core/Win32FileWriter.cs +++ b/Core/Win32FileWriter.cs @@ -174,6 +174,8 @@ public void WriteLine(object value) public static unsafe void WriteAllText(string fileName, string data) { + if (data == null) data = ""; + var bufferSize = WideCharToMultiByte(CP_UTF8, 0, data, data.Length, null, 0, null, null); var buffer = new byte[bufferSize]; diff --git a/Decomp.csproj b/Decomp.csproj index bd96b4a..5eb983f 100644 --- a/Decomp.csproj +++ b/Decomp.csproj @@ -1,5 +1,10 @@  + + + + + Debug @@ -9,7 +14,7 @@ Properties Decomp Decomp - v4.5.2 + v4.7.2 512 {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 4 @@ -29,6 +34,9 @@ false false true + + + AnyCPU @@ -40,6 +48,7 @@ prompt 4 true + 8 AnyCPU @@ -51,6 +60,7 @@ 4 true false + 8 knight.ico @@ -65,6 +75,7 @@ prompt MinimumRecommendedRules.ruleset true + 8 bin\x86\Release\ @@ -76,15 +87,14 @@ prompt MinimumRecommendedRules.ruleset true + 8 - - 4.0 @@ -242,6 +252,8 @@ ResXFileCodeGenerator Resources.Designer.cs + + SettingsSingleFileGenerator Settings.Designer.cs @@ -281,8 +293,28 @@ - + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + +