diff --git a/DS_Map/Extensions.cs b/DS_Map/Extensions.cs index ada4a8b..e624c99 100644 --- a/DS_Map/Extensions.cs +++ b/DS_Map/Extensions.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -55,8 +56,37 @@ namespace DSPRE { return BitConverter.GetBytes(checked((ushort)num)); case 4: return BitConverter.GetBytes(num); + default: + MessageBox.Show("Invalid size for number conversion!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error); + throw new InvalidOperationException(); + } + } + public static string PurgeSpecial(this string str, char[] special) { + foreach (char c in special) { + int pos = str.IndexOf(c); + if (pos >= 0) { + return str.Substring(pos + 1); + } + } + return str; + } + public static NumberStyles GetNumberStyle(this string s) { + int posOfPrefix = s.IndexOf("0x", StringComparison.InvariantCultureIgnoreCase); + if (posOfPrefix >= 0) { + foreach (char c in s.Substring(posOfPrefix + 2)) { + if (!char.IsDigit(c) && char.ToUpper(c) > 'F') { + return NumberStyles.None; + } + } + return NumberStyles.HexNumber; + } else { + foreach (char c in s) { + if (!char.IsDigit(c)) { + return NumberStyles.None; + } + } + return NumberStyles.Integer; } - throw new InvalidOperationException(); } public static bool IgnoreCaseEquals(this string str, string other) { return str.Equals(other, StringComparison.InvariantCultureIgnoreCase); diff --git a/DS_Map/Main Window.cs b/DS_Map/Main Window.cs index 72e17a9..ee6584d 100644 --- a/DS_Map/Main Window.cs +++ b/DS_Map/Main Window.cs @@ -21,6 +21,7 @@ using Microsoft.WindowsAPICodePack.Dialogs; using ScintillaNET; using ScintillaNET.Utils; using System.Globalization; +using static DSPRE.ROMFiles.Event; namespace DSPRE { public partial class MainProgram : Form { @@ -4522,9 +4523,11 @@ namespace DSPRE { using (Graphics g = Graphics.FromImage(eventPictureBox.Image)) { Bitmap icon; + /* Draw spawnables */ if (showSpawnablesCheckBox.Checked) { icon = (Bitmap)Properties.Resources.ResourceManager.GetObject("sign"); + for (int i = 0; i < currentEvFile.spawnables.Count; i++) { Spawnable spawnable = currentEvFile.spawnables[i]; @@ -4562,6 +4565,7 @@ namespace DSPRE { for (int y = 0; y < MapFile.mapSize; y++) { for (int x = 0; x < MapFile.mapSize; x++) { byte moveperm = eventMapFile.types[x, y]; + if (PokeDatabase.System.MapCollisionTypePainters.TryGetValue(moveperm, out string val)) { if (val.IndexOf("Warp", StringComparison.InvariantCultureIgnoreCase) >= 0) { //Console.WriteLine("Found warp at " + i + ", " + j); @@ -4702,13 +4706,13 @@ namespace DSPRE { private void FillSpawnablesBox() { spawnablesListBox.Items.Clear(); for (int i = 0; i < currentEvFile.spawnables.Count; i++) { - spawnablesListBox.Items.Add("Spawnable " + i); + spawnablesListBox.Items.Add($"{Event.EventType.Spawnable} {i}"); } } private void FillOverworldsBox() { overworldsListBox.Items.Clear(); for (int i = 0; i < currentEvFile.overworlds.Count; i++) { - overworldsListBox.Items.Add("Overworld " + i); + overworldsListBox.Items.Add($"{Event.EventType.Overworld} {i}"); } } private void FillWarpsBox() { @@ -4722,7 +4726,7 @@ namespace DSPRE { private void FillTriggersBox() { triggersListBox.Items.Clear(); for (int i = 0; i < currentEvFile.triggers.Count; i++) { - triggersListBox.Items.Add("Trigger " + i); + triggersListBox.Items.Add($"{Event.EventType.Trigger} {i}"); } } private Bitmap GetOverworldImage(ushort eventEntryID, ushort orientation) { @@ -5221,7 +5225,7 @@ namespace DSPRE { if (mea.Button == MouseButtons.Left) { if (selectedEvent != null) { switch (selectedEvent.evType) { - case Event.EventType.SPAWNABLE: + case Event.EventType.Spawnable: if (!showSpawnablesCheckBox.Checked) { return; } @@ -5231,7 +5235,7 @@ namespace DSPRE { spawnableYMatrixUpDown.Value = (short)eventMatrixYUpDown.Value; break; - case Event.EventType.OVERWORLD: + case Event.EventType.Overworld: if (!showOwsCheckBox.Checked) { return; } @@ -5241,7 +5245,7 @@ namespace DSPRE { owYMatrixUpDown.Value = (short)eventMatrixYUpDown.Value; break; - case Event.EventType.WARP: + case Event.EventType.Warp: if (!showWarpsCheckBox.Checked) { return; } @@ -5251,7 +5255,7 @@ namespace DSPRE { warpYMatrixUpDown.Value = (short)eventMatrixYUpDown.Value; break; - case Event.EventType.TRIGGER: + case Event.EventType.Trigger: if (!showTriggersCheckBox.Checked) { return; } @@ -6181,9 +6185,14 @@ namespace DSPRE { " " + String.Join(" ", ScriptDatabase.movementsDictIDName.Values); cmdKeyWords += " " + cmdKeyWords.ToUpper() + " " + cmdKeyWords.ToLower(); - secondaryKeyWords = String.Join(" ", RomInfo.ScriptComparisonOperatorsDict.Values) + - " " + String.Join(" ", ScriptDatabase.specialOverworlds.Values) + - " " + ScriptFile.containerTypes.Script.ToString() + " " + ScriptFile.containerTypes.Function.ToString() + " " + ScriptFile.containerTypes.Action.ToString() + " " + "Overworld"; + secondaryKeyWords = String.Join(" ", RomInfo.ScriptComparisonOperatorsDict.Values) + + " " + String.Join(" ", ScriptDatabase.specialOverworlds.Values) + + " " + String.Join(" ", ScriptDatabase.overworldDirections.Values) + + " " + ScriptFile.containerTypes.Script.ToString() + + " " + ScriptFile.containerTypes.Function.ToString() + + " " + ScriptFile.containerTypes.Action.ToString() + + " " + EventType.Overworld + + " " + Overworld.MovementCodeKW; secondaryKeyWords += " " + secondaryKeyWords.ToUpper() + " " + secondaryKeyWords.ToLower(); @@ -6793,8 +6802,9 @@ namespace DSPRE { } } private void searchInScriptsButton_Click(object sender, EventArgs e) { - if (searchInScriptsTextBox.Text == "") + if (searchInScriptsTextBox.Text == "") { return; + } int firstArchive; int lastArchive; @@ -6812,21 +6822,26 @@ namespace DSPRE { searchProgressBar.Maximum = selectScriptFileComboBox.Items.Count; List results = new List(); + + string scriptKw = ScriptFile.containerTypes.Script.ToString(); + string functionKw = ScriptFile.containerTypes.Function.ToString(); + for (int i = firstArchive; i < lastArchive; i++) { try { Console.WriteLine("Attempting to load script " + i); - ScriptFile file = new ScriptFile(i); + ScriptFile file = new ScriptFile(i, readActions: false); if (scriptSearchCaseSensitiveCheckBox.Checked) { - results.AddRange(SearchInScripts(i, file.allScripts, ScriptFile.containerTypes.Script.ToString(), (string s) => s.Contains(searchString))); - results.AddRange(SearchInScripts(i, file.allFunctions, ScriptFile.containerTypes.Function.ToString(), (string s) => s.Contains(searchString))); + results.AddRange(SearchInScripts(i, file.allScripts, scriptKw, (string s) => s.Contains(searchString))); + results.AddRange(SearchInScripts(i, file.allFunctions, functionKw, (string s) => s.Contains(searchString))); } else { - results.AddRange(SearchInScripts(i, file.allScripts, ScriptFile.containerTypes.Script.ToString(), (string s) => s.IndexOf(searchString, StringComparison.InvariantCultureIgnoreCase) >= 0)); - results.AddRange(SearchInScripts(i, file.allFunctions, ScriptFile.containerTypes.Function.ToString(), (string s) => s.IndexOf(searchString, StringComparison.InvariantCultureIgnoreCase) >= 0)); + results.AddRange(SearchInScripts(i, file.allScripts, scriptKw, (string s) => s.IndexOf(searchString, StringComparison.InvariantCultureIgnoreCase) >= 0)); + results.AddRange(SearchInScripts(i, file.allFunctions, functionKw, (string s) => s.IndexOf(searchString, StringComparison.InvariantCultureIgnoreCase) >= 0)); } } catch { } searchProgressBar.Value = i; } + searchProgressBar.Value = 0; searchInScriptsResultListBox.Items.AddRange(results.ToArray()); } @@ -6839,7 +6854,7 @@ namespace DSPRE { } foreach (ScriptCommand cur in cmdList[j].commands) { if (criteria(cur.name)) { - results.Add("File " + fileID + " - " + entryType + " " + (j + 1) + ": " + cur.name + Environment.NewLine); + results.Add($"File {fileID} - {entryType} {j + 1}: {cur.name}{Environment.NewLine}"); } } } @@ -8945,7 +8960,7 @@ namespace DSPRE { private void HOWpbEffectsTableButton_Click(object sender, EventArgs e) { MessageBox.Show("An entry of this table is a combination of VS. Graphics + Battle Theme.\n\n" + - (RomInfo.gameVersion.Equals(gFamEnum.HGSS) ? "Each entry can be \"inherited\" by one or more Pokémon or Trainer classes." : ""), + (RomInfo.gameFamily.Equals(gFamEnum.HGSS) ? "Each entry can be \"inherited\" by one or more Pokémon or Trainer classes." : ""), "How this table works", MessageBoxButtons.OK, MessageBoxIcon.Information); } diff --git a/DS_Map/ROMFiles/EventFile.cs b/DS_Map/ROMFiles/EventFile.cs index 97aa073..8e63cd4 100644 --- a/DS_Map/ROMFiles/EventFile.cs +++ b/DS_Map/ROMFiles/EventFile.cs @@ -56,23 +56,27 @@ namespace DSPRE.ROMFiles { using (BinaryWriter writer = new BinaryWriter(newData)) { /* Write spawnables */ writer.Write((uint)spawnables.Count); - for (int i = 0; i < spawnables.Count; i++) + for (int i = 0; i < spawnables.Count; i++) { writer.Write(spawnables[i].ToByteArray()); + } /* Write overworlds */ writer.Write((uint)overworlds.Count); - for (int i = 0; i < overworlds.Count; i++) + for (int i = 0; i < overworlds.Count; i++) { writer.Write(overworlds[i].ToByteArray()); + } /* Write warps */ writer.Write((uint)warps.Count); - for (int i = 0; i < warps.Count; i++) + for (int i = 0; i < warps.Count; i++) { writer.Write(warps[i].ToByteArray()); + } /* Write triggers */ writer.Write((uint)triggers.Count); - for (int i = 0; i < triggers.Count; i++) + for (int i = 0; i < triggers.Count; i++) { writer.Write(triggers[i].ToByteArray()); + } } return newData.ToArray(); } @@ -88,10 +92,10 @@ namespace DSPRE.ROMFiles { public abstract class Event { public enum EventType : byte { - SPAWNABLE, - OVERWORLD, - WARP, - TRIGGER + Spawnable, + Overworld, + Warp, + Trigger } #region Fields (6) public EventType evType; @@ -125,7 +129,7 @@ namespace DSPRE.ROMFiles { #region Constructors (2) public Spawnable(Stream data) { - evType = EventType.SPAWNABLE; + evType = EventType.Spawnable; using (BinaryReader reader = new BinaryReader(data)) { scriptNumber = reader.ReadUInt16(); type = reader.ReadUInt16(); @@ -150,7 +154,7 @@ namespace DSPRE.ROMFiles { } } public Spawnable(int xMatrixPosition, int yMatrixPosition) { - evType = EventType.SPAWNABLE; + evType = EventType.Spawnable; scriptNumber = 0; type = 0; @@ -167,7 +171,7 @@ namespace DSPRE.ROMFiles { this.yMatrixPosition = (ushort)yMatrixPosition; } public Spawnable(Spawnable toCopy) { - evType = EventType.SPAWNABLE; + evType = EventType.Spawnable; scriptNumber = toCopy.scriptNumber; type = toCopy.type; @@ -209,6 +213,7 @@ namespace DSPRE.ROMFiles { public class Overworld : Event { #region Fields (14) + public static string MovementCodeKW = "Move"; public enum OwType : ushort { NORMAL = 0, TRAINER = 1, ITEM = 3 }; public ushort owID; @@ -229,7 +234,7 @@ namespace DSPRE.ROMFiles { #region Constructors (2) public Overworld(Stream data) { - evType = EventType.OVERWORLD; + evType = EventType.Overworld; using (BinaryReader reader = new BinaryReader(data)) { owID = reader.ReadUInt16(); overlayTableEntry = reader.ReadUInt16(); @@ -257,7 +262,7 @@ namespace DSPRE.ROMFiles { } } public Overworld(int owID, int xMatrixPosition, int yMatrixPosition) { - evType = EventType.OVERWORLD; + evType = EventType.Overworld; this.owID = (ushort)owID; overlayTableEntry = 1; @@ -280,7 +285,7 @@ namespace DSPRE.ROMFiles { this.yMatrixPosition = (ushort)yMatrixPosition; } public Overworld(Overworld toCopy) { - evType = EventType.OVERWORLD; + evType = EventType.Overworld; this.owID = toCopy.owID; overlayTableEntry = toCopy.overlayTableEntry; @@ -345,7 +350,7 @@ namespace DSPRE.ROMFiles { #region Constructors (2) public Warp(Stream data) { - evType = EventType.WARP; + evType = EventType.Warp; using (BinaryReader reader = new BinaryReader(data)) { /* Decompose x-y coordinates in matrix and map positions */ int xPosition = reader.ReadInt16(); @@ -361,7 +366,7 @@ namespace DSPRE.ROMFiles { } } public Warp(int xMatrixPosition, int yMatrixPosition) { - evType = EventType.WARP; + evType = EventType.Warp; header = 0; anchor = 0; @@ -372,7 +377,7 @@ namespace DSPRE.ROMFiles { this.yMatrixPosition = (ushort)yMatrixPosition; } public Warp(Warp toCopy) { - evType = EventType.WARP; + evType = EventType.Warp; header = toCopy.header; anchor = toCopy.anchor; @@ -419,7 +424,7 @@ namespace DSPRE.ROMFiles { #region Constructors (2) public Trigger(Stream data) { - evType = EventType.TRIGGER; + evType = EventType.Trigger; using (BinaryReader reader = new BinaryReader(data)) { scriptNumber = reader.ReadUInt16(); @@ -440,7 +445,7 @@ namespace DSPRE.ROMFiles { } } public Trigger(int xMatrixPosition, int yMatrixPosition) { - evType = EventType.TRIGGER; + evType = EventType.Trigger; scriptNumber = 0; variableWatched = 0; @@ -454,7 +459,7 @@ namespace DSPRE.ROMFiles { this.yMatrixPosition = (ushort)yMatrixPosition; } public Trigger(Trigger toCopy) { - evType = EventType.TRIGGER; + evType = EventType.Trigger; scriptNumber = toCopy.scriptNumber; variableWatched = toCopy.variableWatched; diff --git a/DS_Map/ROMFiles/ScriptCommand.cs b/DS_Map/ROMFiles/ScriptCommand.cs index 7e44c94..0ee1a10 100644 --- a/DS_Map/ROMFiles/ScriptCommand.cs +++ b/DS_Map/ROMFiles/ScriptCommand.cs @@ -4,10 +4,11 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Windows.Forms; +using static DSPRE.ROMFiles.Event; using static DSPRE.ROMFiles.ScriptFile; namespace DSPRE.ROMFiles { - public enum ParamTypeEnum { INTEGER, VARIABLE, FLEX, OW_ID, FUNCTION_ID, ACTION_ID, CMD_NUMBER }; + public enum ParamTypeEnum { INTEGER, VARIABLE, FLEX, OW_ID, OW_MOVEMENT_TYPE, OW_DIRECTION, FUNCTION_ID, ACTION_ID, CMD_NUMBER }; public class CommandContainer { public List commands; public uint manualUserID; @@ -46,7 +47,7 @@ namespace DSPRE.ROMFiles { if (!RomInfo.ScriptCommandNamesDict.TryGetValue(id, out name)) { name = FormatNumber(id, ParamTypeEnum.CMD_NUMBER); - } + } switch (id) { case 0x0016: // Jump @@ -58,7 +59,7 @@ namespace DSPRE.ROMFiles { name += $" {FormatNumber(parametersList[0], ParamTypeEnum.OW_ID)} {FormatNumber(parametersList[1])}"; break; case 0x0019: // JumpIfPlayerDir - name += $" {FormatNumber(parametersList[0])} {FormatNumber(parametersList[1], ParamTypeEnum.ACTION_ID)}"; + name += $" {FormatNumber(parametersList[0], ParamTypeEnum.OW_DIRECTION)} {FormatNumber(parametersList[1], ParamTypeEnum.ACTION_ID)}"; break; case 0x001C: // JumpIf case 0x001D: // CallIf @@ -76,7 +77,7 @@ namespace DSPRE.ROMFiles { name += $" {FormatNumber(parametersList[0], ParamTypeEnum.OW_ID)} {FormatNumber(parametersList[1], ParamTypeEnum.ACTION_ID)}"; break; case 0x006A: // CheckOverworldPosition - name += $" {FormatNumber(parametersList[0], ParamTypeEnum.OW_ID)} {FormatNumber(parametersList[1])} {FormatNumber(parametersList[2])}"; + name += FormatCmd_Overworld_TwoParams(parametersList); break; case 0x0062: // Lock case 0x0063: // Release @@ -84,9 +85,98 @@ namespace DSPRE.ROMFiles { case 0x0065: // RemoveOW name += $" {FormatNumber(parametersList[0], ParamTypeEnum.OW_ID)}"; break; + case 0x006D: // SetOverworldMovement + name += FormatCmd_Overworld_Move(parametersList); + break; + + case 0x00B0: // Warp [HGSS] + if (RomInfo.gameFamily.Equals(RomInfo.gFamEnum.HGSS)) { + name += FormatCmd_Warp(parametersList); + } else { + goto default; + } + break; + case 0x0152: // SetOverworldDefaultPosition [HGSS] + if (RomInfo.gameFamily.Equals(RomInfo.gFamEnum.HGSS)) { + name += FormatCmd_Overworld_TwoParams(parametersList); + } else { + goto default; + } + break; + case 0x0153: // SetOverworldPosition [HGSS] + if (RomInfo.gameFamily.Equals(RomInfo.gFamEnum.HGSS)) { + name += FormatCmd_Overworld_3Coords_Dir(parametersList); + } else { + goto default; + } + break; + case 0x0154: // SetOverworldDefaultMovement [HGSS] + if (RomInfo.gameFamily.Equals(RomInfo.gFamEnum.HGSS)) { + name += FormatCmd_Overworld_Move(parametersList); + } else { + goto default; + } + break; + case 0x0155: // SetOverworldDefaultDirection [DPPt] + if (RomInfo.gameFamily.Equals(RomInfo.gFamEnum.HGSS)) { + name += FormatCmd_Overworld_Dir(parametersList); + } else { + goto default; + } + break; + case 0x0158: // SetOverworldDirection [DPPt] + if (RomInfo.gameFamily.Equals(RomInfo.gFamEnum.HGSS)) { + name += FormatCmd_Overworld_Dir(parametersList); + } else { + goto default; + } + break; + + case 0x00BE: // Warp [DPPt] + if (RomInfo.gameFamily.Equals(RomInfo.gFamEnum.DP) || RomInfo.gameFamily.Equals(RomInfo.gFamEnum.Plat)) { + name += FormatCmd_Warp(parametersList); + } else { + goto default; + } + break; + case 0x0186: // SetOverworldDefaultPosition [DPPt] + if (RomInfo.gameFamily.Equals(RomInfo.gFamEnum.DP) || RomInfo.gameFamily.Equals(RomInfo.gFamEnum.Plat)) { + name += FormatCmd_Overworld_TwoParams(parametersList); + } else { + goto default; + } + break; + case 0x0187: // SetOverworldPosition [DPPt] + if (RomInfo.gameFamily.Equals(RomInfo.gFamEnum.DP) || RomInfo.gameFamily.Equals(RomInfo.gFamEnum.Plat)) { + name += FormatCmd_Overworld_3Coords_Dir(parametersList); + } else { + goto default; + } + break; + case 0x0188: // SetOverworldDefaultMovement [DPPt] + if (RomInfo.gameFamily.Equals(RomInfo.gFamEnum.DP) || RomInfo.gameFamily.Equals(RomInfo.gFamEnum.Plat)) { + name += FormatCmd_Overworld_Move(parametersList); + } else { + goto default; + } + break; + case 0x0189: // SetOverworldDefaultDirection [DPPt] + if (RomInfo.gameFamily.Equals(RomInfo.gFamEnum.DP) || RomInfo.gameFamily.Equals(RomInfo.gFamEnum.Plat)) { + name += FormatCmd_Overworld_Dir(parametersList); + } else { + goto default; + } + break; + case 0x018C: // SetOverworldDirection [DPPt] + if (RomInfo.gameFamily.Equals(RomInfo.gFamEnum.DP) || RomInfo.gameFamily.Equals(RomInfo.gFamEnum.Plat)) { + name += FormatCmd_Overworld_Dir(parametersList); + } else { + goto default; + } + break; default: for (int i = 0; i < parametersList.Count; i++) { - this.name += $" {FormatNumber(parametersList[i])}"; + name += $" {FormatNumber(parametersList[i])}"; } break; @@ -94,6 +184,21 @@ namespace DSPRE.ROMFiles { this.id = id; this.cmdParams = parametersList; } + private string FormatCmd_Warp(List parametersList) { + return $" {FormatNumber(parametersList[0])} {FormatNumber(parametersList[1])} {FormatNumber(parametersList[2])} {FormatNumber(parametersList[3])} {FormatNumber(parametersList[4], ParamTypeEnum.OW_DIRECTION)}"; + } + private string FormatCmd_Overworld_TwoParams(List parametersList) { + return $" {FormatNumber(parametersList[0], ParamTypeEnum.OW_ID)} {FormatNumber(parametersList[1])} {FormatNumber(parametersList[2])}"; + } + private string FormatCmd_Overworld_Move(List parametersList) { + return $" {FormatNumber(parametersList[0], ParamTypeEnum.OW_ID)} {FormatNumber(parametersList[1], ParamTypeEnum.OW_MOVEMENT_TYPE)}"; + } + private string FormatCmd_Overworld_3Coords_Dir(List parametersList) { + return $" {FormatNumber(parametersList[0], ParamTypeEnum.OW_ID)} {FormatNumber(parametersList[1])} {FormatNumber(parametersList[2])} {FormatNumber(parametersList[3])} {FormatNumber(parametersList[4], ParamTypeEnum.OW_DIRECTION)}"; + } + private string FormatCmd_Overworld_Dir(List parametersList) { + return $" {FormatNumber(parametersList[0], ParamTypeEnum.OW_ID)} {FormatNumber(parametersList[1], ParamTypeEnum.OW_DIRECTION)}"; + } public ScriptCommand(string wholeLine, int lineNumber = 0) { name = wholeLine; @@ -106,7 +211,7 @@ namespace DSPRE.ROMFiles { id = cmdID; } else { try { - id = ushort.Parse(GetStringWithoutSpecialCharacters(nameParts[0]), GetNumberStyleFromString(nameParts[0])); + id = ushort.Parse(nameParts[0].PurgeSpecial(ScriptFile.specialChars), nameParts[0].GetNumberStyle()); //id = ushort.Parse(nameParts[0].Substring(nameParts[0].("_")+1), Properties.Settings.Default.scriptEditorFormatPreference, CultureInfo.InvariantCulture); } catch { string details; @@ -116,9 +221,9 @@ namespace DSPRE.ROMFiles { } else { details = "Are you sure it's a proper Script Command?"; } + MessageBox.Show("This Script file could not be saved." + - Environment.NewLine + "Parser failed to interpret line " + lineNumber + ": \"" + wholeLine + "\"." + - Environment.NewLine + "\n" + details, "Parser error", MessageBoxButtons.OK, MessageBoxIcon.Error); + $"\nParser failed to interpret line {lineNumber}: \"{wholeLine}\".\n\n{details}", "Parser error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } @@ -131,7 +236,7 @@ namespace DSPRE.ROMFiles { int paramsProcessed = 0; if (parametersSizeArr.First() == 0xFF) { - int firstParamValue = int.Parse(GetStringWithoutSpecialCharacters(nameParts[1]), GetNumberStyleFromString(nameParts[1])); + int firstParamValue = int.Parse(nameParts[1].PurgeSpecial(ScriptFile.specialChars), nameParts[1].GetNumberStyle()); byte firstParamSize = parametersSizeArr[1]; cmdParams.Add(firstParamValue.ToByteArrayChooseSize(firstParamSize)); @@ -191,34 +296,40 @@ namespace DSPRE.ROMFiles { if (nameParts.Length - 1 == paramLength) { for (int i = paramsProcessed; i < paramLength; i++) { - Console.WriteLine("Parameter #" + i.ToString() + ": " + nameParts[i + 1]); + Console.WriteLine($"Parameter #{i.ToString()}: {nameParts[i + 1]}"); - if (RomInfo.ScriptComparisonOperatorsReverseDict.TryGetValue(nameParts[i + 1].ToLower(), out cmdID)) { + if (RomInfo.ScriptComparisonOperatorsReverseDict.TryGetValue(nameParts[i + 1].ToLower(), out cmdID)) { //Check succeeds when command is like "asdfg LESS" or "asdfg DIFFERENT" cmdParams.Add(new byte[] { (byte)cmdID }); } else { //Not a comparison /* Convert strings of parameters to the correct datatypes */ - NumberStyles numStyle = GetNumberStyleFromString(nameParts[i + 1]); - nameParts[i + 1] = GetStringWithoutSpecialCharacters(nameParts[i + 1]); + NumberStyles numStyle = nameParts[i + 1].GetNumberStyle(); + nameParts[i + 1] = nameParts[i + 1].PurgeSpecial(ScriptFile.specialChars); int result = 0; + try { result = int.Parse(nameParts[i + 1], numStyle); } catch { - try { - result = ScriptDatabase.specialOverworlds.First(x => x.Value.Equals(nameParts[i + 1])).Key; - } catch (InvalidOperationException) { - if (string.IsNullOrWhiteSpace(nameParts[i + 1])){ - MessageBox.Show($"You must specify an Overworld ID, Script, Function or Action number.\n\n" + - $"Line {lineNumber}: {wholeLine}", "Unspecified identifier", MessageBoxButtons.OK, MessageBoxIcon.Error); - } else { - MessageBox.Show($"Argument {nameParts[i+1]} couldn't be parsed as a valid Overworld ID, Script, Function or Action number.\n\n" + + if (string.IsNullOrWhiteSpace(nameParts[i + 1])) { + MessageBox.Show($"You must specify an Overworld ID, Script, Function or Action number.\n\n" + + $"Line {lineNumber}: {wholeLine}", "Unspecified identifier", MessageBoxButtons.OK, MessageBoxIcon.Error); + id = null; + } else { + var first = ScriptDatabase.specialOverworlds.FirstOrDefault(x => x.Value.IgnoreCaseEquals(nameParts[i + 1])); + + if (string.IsNullOrWhiteSpace(first.Value)) { + var res = ScriptDatabase.overworldDirections.FirstOrDefault(x => x.Value.IgnoreCaseEquals(nameParts[i + 1])); + + if (string.IsNullOrWhiteSpace(res.Value)) { + MessageBox.Show($"Argument {nameParts[i + 1]} couldn't be parsed as a valid Condition, Overworld ID, Direction ID, Script, Function or Action number.\n\n" + $"Line {lineNumber}: {wholeLine}", "Invalid identifier", MessageBoxButtons.OK, MessageBoxIcon.Error); + id = null; + } else { + result = res.Key; + } + } else { + result = first.Key; } - id = null; - } catch (FormatException) { - MessageBox.Show($"Argument {nameParts[i + 1]} is not a valid {numStyle}.\n\n" + - $"Line {lineNumber}: {wholeLine}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - id = null; } } @@ -269,58 +380,63 @@ namespace DSPRE.ROMFiles { prefix = ""; } + string outp = ""; + switch (paramType) { case ParamTypeEnum.CMD_NUMBER: return "CMD_" + prefix + num.ToString(formatOverride + '3'); - case ParamTypeEnum.OW_ID: - if (ScriptDatabase.specialOverworlds.TryGetValue((ushort)num, out string output)) { - return output; - } else { - return "Overworld." + prefix + num.ToString(formatOverride); - } + case ParamTypeEnum.FUNCTION_ID: return containerTypes.Function.ToString() + "#" + num; + case ParamTypeEnum.ACTION_ID: return containerTypes.Action.ToString() + "#" + num; + + case ParamTypeEnum.OW_MOVEMENT_TYPE: + if (num < 4000) { + outp += "Move."; + } + goto default; + + case ParamTypeEnum.OW_ID: + { + if (ScriptDatabase.specialOverworlds.TryGetValue((ushort)num, out string output)) { + return output; + } else { + if (num < 4000) { + outp += $"{EventType.Overworld}."; + } + goto default; + } + + break; + } + case ParamTypeEnum.OW_DIRECTION: + { + if (ScriptDatabase.overworldDirections.TryGetValue((byte)num, out string output)) { + return output; + } else { + if (num < 4000) { + outp += $"Direction."; + } + goto default; + } + + break; + } default: if (Properties.Settings.Default.scriptEditorFormatPreference == (int)NumberStyles.None) { if (num >= 4000) { - return "0x" + num.ToString("X"); + formatOverride = "X"; + prefix = "0x"; } } - return prefix + num.ToString(formatOverride); + outp += prefix + num.ToString(formatOverride); + break; } + + return outp; } - - private string GetStringWithoutSpecialCharacters(string s) { - foreach (char c in ScriptFile.specialChars) { - int pos = s.IndexOf(c); - if (pos >= 0) { - return s.Substring(pos + 1); - } - } - return s; - } - - public NumberStyles GetNumberStyleFromString(string s) { - int posOfPrefix = s.IndexOf("0x", StringComparison.InvariantCultureIgnoreCase); - if (posOfPrefix >= 0) { - foreach (char c in s.Substring(posOfPrefix+2)) { - if (!Char.IsDigit(c) && Char.ToUpper(c) > 'F') { - return NumberStyles.None; - } - } - return NumberStyles.HexNumber; - } else { - foreach (char c in s) { - if (!Char.IsDigit(c)) { - return NumberStyles.None; - } - } - return NumberStyles.Integer; - } - } - public override string ToString() { return name + " (" + ((ushort)id).ToString("X") + ")"; } diff --git a/DS_Map/ROMFiles/ScriptFile.cs b/DS_Map/ROMFiles/ScriptFile.cs index ec592bb..dcd526d 100644 --- a/DS_Map/ROMFiles/ScriptFile.cs +++ b/DS_Map/ROMFiles/ScriptFile.cs @@ -32,7 +32,7 @@ namespace DSPRE.ROMFiles { #region Constructors (1) - public ScriptFile(Stream fs) { + public ScriptFile(Stream fs, bool readFunctions = true, bool readActions = true) { List scriptOffsets = new List(); List functionOffsets = new List(); List movementOffsets = new List(); @@ -96,51 +96,56 @@ namespace DSPRE.ROMFiles { } /* Read functions */ - for (uint current = 0; current < functionOffsets.Count; current++) { - scrReader.BaseStream.Position = functionOffsets[(int)current]; - int posInList = scriptOffsets.IndexOf(functionOffsets[(int)current]); // Check for UseScript + if (readFunctions) { + for (uint current = 0; current < functionOffsets.Count; current++) { + scrReader.BaseStream.Position = functionOffsets[(int)current]; + int posInList = scriptOffsets.IndexOf(functionOffsets[(int)current]); // Check for UseScript - if (posInList == -1) { - List cmdList = new List(); - bool endFunction = new bool(); - while (!endFunction) { - ScriptCommand command = ReadCommand(scrReader, ref functionOffsets, ref movementOffsets); - if (command.cmdParams is null) { - return; - } + if (posInList == -1) { + List cmdList = new List(); + bool endFunction = new bool(); + while (!endFunction) { + ScriptCommand command = ReadCommand(scrReader, ref functionOffsets, ref movementOffsets); + if (command.cmdParams is null) { + return; + } - cmdList.Add(command); - if (ScriptDatabase.endCodes.Contains((ushort)command.id)) { - endFunction = true; + cmdList.Add(command); + if (ScriptDatabase.endCodes.Contains((ushort)command.id)) { + endFunction = true; + } } + allFunctions.Add(new CommandContainer(current + 1, containerTypes.Function, commandList: cmdList)); + } else { + allFunctions.Add(new CommandContainer(current + 1, containerTypes.Function, useScript: posInList + 1)); } - allFunctions.Add(new CommandContainer(current+1, containerTypes.Function, commandList: cmdList)); - } else { - allFunctions.Add(new CommandContainer(current+1, containerTypes.Function, useScript: posInList +1)); } } - /* Read movements */ - for (uint current = 0; current < movementOffsets.Count; current++) { - scrReader.BaseStream.Position = movementOffsets[(int)current]; + if (readActions) { + /* Read movements */ + for (uint current = 0; current < movementOffsets.Count; current++) { + scrReader.BaseStream.Position = movementOffsets[(int)current]; - List cmdList = new List(); - bool endMovement = new bool(); - while (!endMovement) { - ushort id = scrReader.ReadUInt16(); - if (id == 0xFE) { - endMovement = true; - cmdList.Add(new ScriptAction(id, 0)); - } else { - cmdList.Add(new ScriptAction(id, scrReader.ReadUInt16())); + List cmdList = new List(); + bool endMovement = new bool(); + while (!endMovement) { + ushort id = scrReader.ReadUInt16(); + if (id == 0xFE) { + endMovement = true; + cmdList.Add(new ScriptAction(id, 0)); + } else { + cmdList.Add(new ScriptAction(id, scrReader.ReadUInt16())); + } } + allActions.Add(new ActionContainer(current + 1, actionCommandsList: cmdList)); } - allActions.Add(new ActionContainer(current+1, actionCommandsList: cmdList)); } } } - public ScriptFile(int fileID) : this(new FileStream(RomInfo.gameDirs[DirNames.scripts].unpackedDir + - "\\" + fileID.ToString("D4"), FileMode.Open)) { + public ScriptFile(int fileID, bool readFunctions = true, bool readActions = true) : + this(new FileStream(RomInfo.gameDirs[DirNames.scripts].unpackedDir + "\\" + fileID.ToString("D4"), FileMode.Open), readFunctions, readActions) { + this.fileID = fileID; } public ScriptFile(List scripts, List functions, List movements, int fileID = -1) { @@ -175,14 +180,18 @@ namespace DSPRE.ROMFiles { return; } - allFunctions = ReadCommandsFromLines(functionLines.ToList(), containerTypes.Function, functionEndCondition); //Jump + whitespace - if (allFunctions is null) { - return; + if (functionLines != null) { + allFunctions = ReadCommandsFromLines(functionLines.ToList(), containerTypes.Function, functionEndCondition); //Jump + whitespace + if (allFunctions is null) { + return; + } } - allActions = ReadActionsFromLines(actionLines.ToList()); - if (allActions is null) { - return; + if (actionLines != null) { + allActions = ReadActionsFromLines(actionLines.ToList()); + if (allActions is null) { + return; + } } this.fileID = fileID; diff --git a/DS_Map/Resources/ScriptDatabase.cs b/DS_Map/Resources/ScriptDatabase.cs index 62afef4..4140424 100644 --- a/DS_Map/Resources/ScriptDatabase.cs +++ b/DS_Map/Resources/ScriptDatabase.cs @@ -27,6 +27,12 @@ namespace DSPRE.Resources { [253] = "Following", [255] = "Player" }; + public static Dictionary overworldDirections = new Dictionary() { + [0] = "Up", + [1] = "Down", + [2] = "Left", + [3] = "Right" + }; public static Dictionary commandsWithRelativeJump = new Dictionary() { //commandID, ID of parameter With Jump Address @@ -277,7 +283,7 @@ namespace DSPRE.Resources { [0x006A] = "CheckOverworldPosition", [0x006C] = "KeepOverworld", - [0x006D] = "SetObjectDefaultMovement", + [0x006D] = "SetOverworldMovement", [0x006E] = "SetFollowingOverworld", [0x006F] = "GiveMoney", [0x0070] = "TakeMoney", @@ -429,7 +435,7 @@ namespace DSPRE.Resources { [0x0128] = "CheckHoneyTree", [0x0129] = "HoneyTreeBattle", [0x012A] = "StopHoneyTreeAnimation", - + [0x012B] = "SignatureScreen", [0x012C] = "CheckSaveGame", [0x012D] = "SaveGame", [0x012E] = "CheckPortrait", @@ -499,12 +505,13 @@ namespace DSPRE.Resources { [0x0183] = "SetBerrySpecies", [0x0184] = "WateringAnimation", [0x0185] = "TakeBerries", - [0x0186] = "SetOverworldPosition", - [0x0187] = "SetOverworldFullPosition", - [0x0188] = "SetOverworldMovement", - [0x0189] = "SetOverworldDirection", + [0x0186] = "SetOverworldDefaultPosition", + [0x0187] = "SetOverworldPosition", + [0x0188] = "SetOverworldDefaultMovement", + [0x0189] = "SetOverworldDefaultDirection", [0x018A] = "SetWarpPosition", [0x018B] = "SetSpawnablePosition", + [0x018C] = "SetOverworldDirection", [0x0190] = "WaitTimeOrAB", [0x0191] = "PokemonSelectionScreen", @@ -653,6 +660,7 @@ namespace DSPRE.Resources { [0x029F] = "ShakeCamera", [0x02AC] = "ActivateMysteryGift", + [0x02AD] = "GetOverworldMovement", [0x02A5] = "PartyPokemonTradeScreen", @@ -1729,7 +1737,7 @@ namespace DSPRE.Resources { [0x006A] = "CheckOverworldPosition", [0x006C] = "KeepOverworld", - [0x006D] = "SetObjectDefaultMovement", + [0x006D] = "SetOverworldMovement", [0x006E] = "GiveMoney", [0x006F] = "TakeMoney", [0x0070] = "CompareMoney", @@ -1882,12 +1890,13 @@ namespace DSPRE.Resources { [0x014C] = "GetPartyCount", - [0x0152] = "SetOverworldPosition", - [0x0153] = "SetOverworldFullPosition", - [0x0154] = "SetOverworldMovement", - [0x0155] = "SetOverworldDirection", + [0x0152] = "SetOverworldDefaultPosition", + [0x0153] = "SetOverworldPosition", + [0x0154] = "SetOverworldDefaultMovement", + [0x0155] = "SetOverworldDefaultDirection", [0x0156] = "SetWarpPosition", [0x0157] = "SetSpawnablePosition", + [0x0158] = "SetOverworldDirection", [0x015C] = "WaitTimeOrAB",