diff --git a/DS_Map/DSPRE.csproj b/DS_Map/DSPRE.csproj
index d5cd73b..da19c95 100644
--- a/DS_Map/DSPRE.csproj
+++ b/DS_Map/DSPRE.csproj
@@ -280,14 +280,16 @@
+
+
-
-
-
+
+
+
-
+
@@ -303,7 +305,7 @@
BuildingEditor.cs
-
+
Form
@@ -312,7 +314,7 @@
ScriptTooltip.cs
-
+
Form
diff --git a/DS_Map/Editors/ScriptEditor.Designer.cs b/DS_Map/Editors/ScriptEditor.Designer.cs
index 1cd0f69..535d85d 100644
--- a/DS_Map/Editors/ScriptEditor.Designer.cs
+++ b/DS_Map/Editors/ScriptEditor.Designer.cs
@@ -31,12 +31,28 @@ namespace DSPRE.Editors
{
this.selectScriptFileComboBox = new System.Windows.Forms.ComboBox();
this.label5 = new System.Windows.Forms.Label();
+ this.scriptEditorTabControl = new System.Windows.Forms.TabControl();
+ this.scriptsTabPage = new System.Windows.Forms.TabPage();
this.PanelSearchScripts = new System.Windows.Forms.Panel();
this.BtnNextFindScript = new System.Windows.Forms.Button();
this.BtnPrevFindScript = new System.Windows.Forms.Button();
this.BtnCloseFindScript = new System.Windows.Forms.Button();
this.panelFindScriptTextBox = new System.Windows.Forms.TextBox();
this.scintillaScriptsPanel = new System.Windows.Forms.Panel();
+ this.functionsTabPage = new System.Windows.Forms.TabPage();
+ this.PanelSearchFunctions = new System.Windows.Forms.Panel();
+ this.BtnNextFindFunc = new System.Windows.Forms.Button();
+ this.BtnPrevFindFunc = new System.Windows.Forms.Button();
+ this.BtnCloseFindFunc = new System.Windows.Forms.Button();
+ this.panelFindFunctionTextBox = new System.Windows.Forms.TextBox();
+ this.scintillaFunctionsPanel = new System.Windows.Forms.Panel();
+ this.actionsTabPage = new System.Windows.Forms.TabPage();
+ this.PanelSearchActions = new System.Windows.Forms.Panel();
+ this.BtnNextFindActions = new System.Windows.Forms.Button();
+ this.BtnPrevFindActions = new System.Windows.Forms.Button();
+ this.BtnCloseFindActions = new System.Windows.Forms.Button();
+ this.panelFindActionTextBox = new System.Windows.Forms.TextBox();
+ this.scintillaActionsPanel = new System.Windows.Forms.Panel();
this.addScriptFileButton = new System.Windows.Forms.Button();
this.removeScriptFileButton = new System.Windows.Forms.Button();
this.saveScriptFileButton = new System.Windows.Forms.Button();
@@ -72,8 +88,13 @@ namespace DSPRE.Editors
this.scriptEditorNumberFormatHex = new System.Windows.Forms.RadioButton();
this.viewLevelScriptButton = new System.Windows.Forms.Button();
this.locateCurrentScriptFile = new System.Windows.Forms.Button();
+ this.scriptEditorTabControl.SuspendLayout();
+ this.scriptsTabPage.SuspendLayout();
this.PanelSearchScripts.SuspendLayout();
- this.scintillaScriptsPanel.SuspendLayout();
+ this.functionsTabPage.SuspendLayout();
+ this.PanelSearchFunctions.SuspendLayout();
+ this.actionsTabPage.SuspendLayout();
+ this.PanelSearchActions.SuspendLayout();
this.groupBox8.SuspendLayout();
this.groupBox24.SuspendLayout();
this.ScriptNavigatorTabControl.SuspendLayout();
@@ -102,6 +123,31 @@ namespace DSPRE.Editors
this.label5.TabIndex = 1;
this.label5.Text = "Script File";
//
+ // scriptEditorTabControl
+ //
+ this.scriptEditorTabControl.Controls.Add(this.scriptsTabPage);
+ this.scriptEditorTabControl.Controls.Add(this.functionsTabPage);
+ this.scriptEditorTabControl.Controls.Add(this.actionsTabPage);
+ this.scriptEditorTabControl.Location = new System.Drawing.Point(481, 22);
+ this.scriptEditorTabControl.Name = "scriptEditorTabControl";
+ this.scriptEditorTabControl.SelectedIndex = 0;
+ this.scriptEditorTabControl.Size = new System.Drawing.Size(692, 591);
+ this.scriptEditorTabControl.TabIndex = 18;
+ this.scriptEditorTabControl.SelectedIndexChanged += new System.EventHandler(this.scriptEditorTabControl_TabIndexChanged);
+ //
+ // scriptsTabPage
+ //
+ this.scriptsTabPage.Controls.Add(this.PanelSearchScripts);
+ this.scriptsTabPage.Controls.Add(this.scintillaScriptsPanel);
+ this.scriptsTabPage.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.scriptsTabPage.Location = new System.Drawing.Point(4, 22);
+ this.scriptsTabPage.Name = "scriptsTabPage";
+ this.scriptsTabPage.Padding = new System.Windows.Forms.Padding(3);
+ this.scriptsTabPage.Size = new System.Drawing.Size(684, 565);
+ this.scriptsTabPage.TabIndex = 0;
+ this.scriptsTabPage.Text = "Scripts";
+ this.scriptsTabPage.UseVisualStyleBackColor = true;
+ //
// PanelSearchScripts
//
this.PanelSearchScripts.BackColor = System.Drawing.Color.White;
@@ -110,7 +156,7 @@ namespace DSPRE.Editors
this.PanelSearchScripts.Controls.Add(this.BtnPrevFindScript);
this.PanelSearchScripts.Controls.Add(this.BtnCloseFindScript);
this.PanelSearchScripts.Controls.Add(this.panelFindScriptTextBox);
- this.PanelSearchScripts.Location = new System.Drawing.Point(383, 3);
+ this.PanelSearchScripts.Location = new System.Drawing.Point(386, 3);
this.PanelSearchScripts.Name = "PanelSearchScripts";
this.PanelSearchScripts.Size = new System.Drawing.Size(292, 40);
this.PanelSearchScripts.TabIndex = 14;
@@ -172,13 +218,193 @@ namespace DSPRE.Editors
//
// scintillaScriptsPanel
//
- this.scintillaScriptsPanel.Controls.Add(this.PanelSearchScripts);
- this.scintillaScriptsPanel.Location = new System.Drawing.Point(483, 50);
+ this.scintillaScriptsPanel.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.scintillaScriptsPanel.Location = new System.Drawing.Point(3, 3);
this.scintillaScriptsPanel.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
this.scintillaScriptsPanel.Name = "scintillaScriptsPanel";
this.scintillaScriptsPanel.Size = new System.Drawing.Size(678, 559);
this.scintillaScriptsPanel.TabIndex = 19;
//
+ // functionsTabPage
+ //
+ this.functionsTabPage.Controls.Add(this.PanelSearchFunctions);
+ this.functionsTabPage.Controls.Add(this.scintillaFunctionsPanel);
+ this.functionsTabPage.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.functionsTabPage.Location = new System.Drawing.Point(4, 22);
+ this.functionsTabPage.Name = "functionsTabPage";
+ this.functionsTabPage.Padding = new System.Windows.Forms.Padding(3);
+ this.functionsTabPage.Size = new System.Drawing.Size(684, 565);
+ this.functionsTabPage.TabIndex = 1;
+ this.functionsTabPage.Text = "Functions";
+ this.functionsTabPage.UseVisualStyleBackColor = true;
+ //
+ // PanelSearchFunctions
+ //
+ this.PanelSearchFunctions.BackColor = System.Drawing.Color.White;
+ this.PanelSearchFunctions.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.PanelSearchFunctions.Controls.Add(this.BtnNextFindFunc);
+ this.PanelSearchFunctions.Controls.Add(this.BtnPrevFindFunc);
+ this.PanelSearchFunctions.Controls.Add(this.BtnCloseFindFunc);
+ this.PanelSearchFunctions.Controls.Add(this.panelFindFunctionTextBox);
+ this.PanelSearchFunctions.Location = new System.Drawing.Point(386, 3);
+ this.PanelSearchFunctions.Name = "PanelSearchFunctions";
+ this.PanelSearchFunctions.Size = new System.Drawing.Size(292, 40);
+ this.PanelSearchFunctions.TabIndex = 16;
+ this.PanelSearchFunctions.Visible = false;
+ //
+ // BtnNextFindFunc
+ //
+ this.BtnNextFindFunc.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.BtnNextFindFunc.ForeColor = System.Drawing.Color.White;
+ this.BtnNextFindFunc.Image = global::DSPRE.Properties.Resources.arrowdown;
+ this.BtnNextFindFunc.Location = new System.Drawing.Point(233, 4);
+ this.BtnNextFindFunc.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
+ this.BtnNextFindFunc.Name = "BtnNextFindFunc";
+ this.BtnNextFindFunc.Size = new System.Drawing.Size(25, 30);
+ this.BtnNextFindFunc.TabIndex = 36;
+ this.BtnNextFindFunc.Tag = "Find next (Enter)";
+ this.BtnNextFindFunc.UseVisualStyleBackColor = true;
+ this.BtnNextFindFunc.Click += new System.EventHandler(this.BtnNextFindFunc_Click);
+ //
+ // BtnPrevFindFunc
+ //
+ this.BtnPrevFindFunc.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.BtnPrevFindFunc.ForeColor = System.Drawing.Color.White;
+ this.BtnPrevFindFunc.Image = global::DSPRE.Properties.Resources.arrowup;
+ this.BtnPrevFindFunc.Location = new System.Drawing.Point(205, 4);
+ this.BtnPrevFindFunc.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
+ this.BtnPrevFindFunc.Name = "BtnPrevFindFunc";
+ this.BtnPrevFindFunc.Size = new System.Drawing.Size(25, 30);
+ this.BtnPrevFindFunc.TabIndex = 35;
+ this.BtnPrevFindFunc.Tag = "Find previous (Shift+Enter)";
+ this.BtnPrevFindFunc.UseVisualStyleBackColor = true;
+ this.BtnPrevFindFunc.Click += new System.EventHandler(this.BtnPrevFindFunc_Click);
+ //
+ // BtnCloseFindFunc
+ //
+ this.BtnCloseFindFunc.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.BtnCloseFindFunc.ForeColor = System.Drawing.Color.White;
+ this.BtnCloseFindFunc.Image = global::DSPRE.Properties.Resources.Cross;
+ this.BtnCloseFindFunc.Location = new System.Drawing.Point(261, 4);
+ this.BtnCloseFindFunc.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
+ this.BtnCloseFindFunc.Name = "BtnCloseFindFunc";
+ this.BtnCloseFindFunc.Size = new System.Drawing.Size(25, 30);
+ this.BtnCloseFindFunc.TabIndex = 37;
+ this.BtnCloseFindFunc.Tag = "Close (Esc)";
+ this.BtnCloseFindFunc.UseVisualStyleBackColor = true;
+ this.BtnCloseFindFunc.Click += new System.EventHandler(this.BtnCloseFindFunc_Click);
+ //
+ // panelFindFunctionTextBox
+ //
+ this.panelFindFunctionTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None;
+ this.panelFindFunctionTextBox.Font = new System.Drawing.Font("Segoe UI", 13.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.panelFindFunctionTextBox.Location = new System.Drawing.Point(10, 6);
+ this.panelFindFunctionTextBox.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
+ this.panelFindFunctionTextBox.Name = "panelFindFunctionTextBox";
+ this.panelFindFunctionTextBox.Size = new System.Drawing.Size(189, 25);
+ this.panelFindFunctionTextBox.TabIndex = 34;
+ this.panelFindFunctionTextBox.TextChanged += new System.EventHandler(this.panelFindFunctionTextBox_TextChanged);
+ this.panelFindFunctionTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.functionTxtFind_KeyDown);
+ //
+ // scintillaFunctionsPanel
+ //
+ this.scintillaFunctionsPanel.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.scintillaFunctionsPanel.Location = new System.Drawing.Point(3, 3);
+ this.scintillaFunctionsPanel.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
+ this.scintillaFunctionsPanel.Name = "scintillaFunctionsPanel";
+ this.scintillaFunctionsPanel.Size = new System.Drawing.Size(678, 559);
+ this.scintillaFunctionsPanel.TabIndex = 20;
+ //
+ // actionsTabPage
+ //
+ this.actionsTabPage.Controls.Add(this.PanelSearchActions);
+ this.actionsTabPage.Controls.Add(this.scintillaActionsPanel);
+ this.actionsTabPage.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.actionsTabPage.Location = new System.Drawing.Point(4, 22);
+ this.actionsTabPage.Name = "actionsTabPage";
+ this.actionsTabPage.Padding = new System.Windows.Forms.Padding(3);
+ this.actionsTabPage.Size = new System.Drawing.Size(684, 565);
+ this.actionsTabPage.TabIndex = 2;
+ this.actionsTabPage.Text = "Actions";
+ this.actionsTabPage.UseVisualStyleBackColor = true;
+ //
+ // PanelSearchActions
+ //
+ this.PanelSearchActions.BackColor = System.Drawing.Color.White;
+ this.PanelSearchActions.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.PanelSearchActions.Controls.Add(this.BtnNextFindActions);
+ this.PanelSearchActions.Controls.Add(this.BtnPrevFindActions);
+ this.PanelSearchActions.Controls.Add(this.BtnCloseFindActions);
+ this.PanelSearchActions.Controls.Add(this.panelFindActionTextBox);
+ this.PanelSearchActions.Location = new System.Drawing.Point(386, 3);
+ this.PanelSearchActions.Name = "PanelSearchActions";
+ this.PanelSearchActions.Size = new System.Drawing.Size(292, 40);
+ this.PanelSearchActions.TabIndex = 16;
+ this.PanelSearchActions.Visible = false;
+ //
+ // BtnNextFindActions
+ //
+ this.BtnNextFindActions.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.BtnNextFindActions.ForeColor = System.Drawing.Color.White;
+ this.BtnNextFindActions.Image = global::DSPRE.Properties.Resources.arrowdown;
+ this.BtnNextFindActions.Location = new System.Drawing.Point(233, 4);
+ this.BtnNextFindActions.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
+ this.BtnNextFindActions.Name = "BtnNextFindActions";
+ this.BtnNextFindActions.Size = new System.Drawing.Size(25, 30);
+ this.BtnNextFindActions.TabIndex = 40;
+ this.BtnNextFindActions.Tag = "Find next (Enter)";
+ this.BtnNextFindActions.UseVisualStyleBackColor = true;
+ this.BtnNextFindActions.Click += new System.EventHandler(this.BtnNextFindActions_Click);
+ //
+ // BtnPrevFindActions
+ //
+ this.BtnPrevFindActions.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.BtnPrevFindActions.ForeColor = System.Drawing.Color.White;
+ this.BtnPrevFindActions.Image = global::DSPRE.Properties.Resources.arrowup;
+ this.BtnPrevFindActions.Location = new System.Drawing.Point(205, 4);
+ this.BtnPrevFindActions.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
+ this.BtnPrevFindActions.Name = "BtnPrevFindActions";
+ this.BtnPrevFindActions.Size = new System.Drawing.Size(25, 30);
+ this.BtnPrevFindActions.TabIndex = 39;
+ this.BtnPrevFindActions.Tag = "Find previous (Shift+Enter)";
+ this.BtnPrevFindActions.UseVisualStyleBackColor = true;
+ this.BtnPrevFindActions.Click += new System.EventHandler(this.BtnPrevFindActions_Click);
+ //
+ // BtnCloseFindActions
+ //
+ this.BtnCloseFindActions.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.BtnCloseFindActions.ForeColor = System.Drawing.Color.White;
+ this.BtnCloseFindActions.Image = global::DSPRE.Properties.Resources.Cross;
+ this.BtnCloseFindActions.Location = new System.Drawing.Point(261, 4);
+ this.BtnCloseFindActions.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
+ this.BtnCloseFindActions.Name = "BtnCloseFindActions";
+ this.BtnCloseFindActions.Size = new System.Drawing.Size(25, 30);
+ this.BtnCloseFindActions.TabIndex = 41;
+ this.BtnCloseFindActions.Tag = "Close (Esc)";
+ this.BtnCloseFindActions.UseVisualStyleBackColor = true;
+ this.BtnCloseFindActions.Click += new System.EventHandler(this.BtnCloseFindActions_Click);
+ //
+ // panelFindActionTextBox
+ //
+ this.panelFindActionTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None;
+ this.panelFindActionTextBox.Font = new System.Drawing.Font("Segoe UI", 13.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.panelFindActionTextBox.Location = new System.Drawing.Point(10, 6);
+ this.panelFindActionTextBox.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
+ this.panelFindActionTextBox.Name = "panelFindActionTextBox";
+ this.panelFindActionTextBox.Size = new System.Drawing.Size(189, 25);
+ this.panelFindActionTextBox.TabIndex = 38;
+ this.panelFindActionTextBox.TextChanged += new System.EventHandler(this.panelFindActionTextBox_TextChanged);
+ this.panelFindActionTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.actionTxtFind_KeyDown);
+ //
+ // scintillaActionsPanel
+ //
+ this.scintillaActionsPanel.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.scintillaActionsPanel.Location = new System.Drawing.Point(3, 3);
+ this.scintillaActionsPanel.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
+ this.scintillaActionsPanel.Name = "scintillaActionsPanel";
+ this.scintillaActionsPanel.Size = new System.Drawing.Size(678, 559);
+ this.scintillaActionsPanel.TabIndex = 21;
+ //
// addScriptFileButton
//
this.addScriptFileButton.Image = global::DSPRE.Properties.Resources.addIcon;
@@ -582,7 +808,6 @@ namespace DSPRE.Editors
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.Controls.Add(this.scintillaScriptsPanel);
this.Controls.Add(this.locateCurrentScriptFile);
this.Controls.Add(this.groupBox24);
this.Controls.Add(this.viewLevelScriptButton);
@@ -600,11 +825,19 @@ namespace DSPRE.Editors
this.Controls.Add(this.exportScriptFileButton);
this.Controls.Add(this.importScriptFileButton);
this.Controls.Add(this.groupBox8);
+ this.Controls.Add(this.scriptEditorTabControl);
this.Name = "ScriptEditor";
this.Size = new System.Drawing.Size(1177, 735);
+ this.scriptEditorTabControl.ResumeLayout(false);
+ this.scriptsTabPage.ResumeLayout(false);
this.PanelSearchScripts.ResumeLayout(false);
this.PanelSearchScripts.PerformLayout();
- this.scintillaScriptsPanel.ResumeLayout(false);
+ this.functionsTabPage.ResumeLayout(false);
+ this.PanelSearchFunctions.ResumeLayout(false);
+ this.PanelSearchFunctions.PerformLayout();
+ this.actionsTabPage.ResumeLayout(false);
+ this.PanelSearchActions.ResumeLayout(false);
+ this.PanelSearchActions.PerformLayout();
this.groupBox8.ResumeLayout(false);
this.groupBox8.PerformLayout();
this.groupBox24.ResumeLayout(false);
@@ -625,12 +858,28 @@ namespace DSPRE.Editors
public System.Windows.Forms.ComboBox selectScriptFileComboBox;
private System.Windows.Forms.Label label5;
+ public System.Windows.Forms.TabControl scriptEditorTabControl;
+ private System.Windows.Forms.TabPage scriptsTabPage;
private System.Windows.Forms.Panel PanelSearchScripts;
private System.Windows.Forms.Button BtnNextFindScript;
private System.Windows.Forms.Button BtnPrevFindScript;
private System.Windows.Forms.Button BtnCloseFindScript;
private System.Windows.Forms.TextBox panelFindScriptTextBox;
private System.Windows.Forms.Panel scintillaScriptsPanel;
+ private System.Windows.Forms.TabPage functionsTabPage;
+ private System.Windows.Forms.Panel PanelSearchFunctions;
+ private System.Windows.Forms.Button BtnNextFindFunc;
+ private System.Windows.Forms.Button BtnPrevFindFunc;
+ private System.Windows.Forms.Button BtnCloseFindFunc;
+ private System.Windows.Forms.TextBox panelFindFunctionTextBox;
+ private System.Windows.Forms.Panel scintillaFunctionsPanel;
+ private System.Windows.Forms.TabPage actionsTabPage;
+ private System.Windows.Forms.Panel PanelSearchActions;
+ private System.Windows.Forms.Button BtnNextFindActions;
+ private System.Windows.Forms.Button BtnPrevFindActions;
+ private System.Windows.Forms.Button BtnCloseFindActions;
+ private System.Windows.Forms.TextBox panelFindActionTextBox;
+ private System.Windows.Forms.Panel scintillaActionsPanel;
private System.Windows.Forms.Button addScriptFileButton;
private System.Windows.Forms.Button removeScriptFileButton;
private System.Windows.Forms.Button saveScriptFileButton;
diff --git a/DS_Map/Editors/ScriptEditor.cs b/DS_Map/Editors/ScriptEditor.cs
index 77e3326..4949642 100644
--- a/DS_Map/Editors/ScriptEditor.cs
+++ b/DS_Map/Editors/ScriptEditor.cs
@@ -9,12 +9,19 @@ using DSPRE.ROMFiles;
using ScintillaNET;
using ScintillaNET.Utils;
using System.Globalization;
-
-namespace DSPRE.Editors {
- public partial class ScriptEditor : UserControl {
+namespace DSPRE.Editors
+{
+ public partial class ScriptEditor : UserControl
+ {
public bool scriptEditorIsReady { get; set; } = false;
- private SearchManager scriptSearchManager;
private Scintilla ScriptTextArea;
+ private Scintilla FunctionTextArea;
+ private Scintilla ActionTextArea;
+ private SearchManager scriptSearchManager;
+ private SearchManager functionSearchManager;
+ private SearchManager actionSearchManager;
+ private Scintilla currentScintillaEditor;
+ private SearchManager currentSearchManager;
private bool scriptsDirty = false;
private bool functionsDirty = false;
private bool actionsDirty = false;
@@ -26,50 +33,40 @@ namespace DSPRE.Editors {
/// the background color of the text area
///
private readonly Color BACK_COLOR = Color.FromArgb(0x2A211C);
-
///
/// default text color of the text area
///
private readonly Color FORE_COLOR = Color.FromArgb(0xB7B7B7);
-
///
/// change this to whatever margin you want the line numbers to show in
///
private const int NUMBER_MARGIN = 1;
-
///
/// change this to whatever margin you want the bookmarks/breakpoints to show in
///
private const int BOOKMARK_MARGIN = 2;
-
private const int BOOKMARK_MARKER = 2;
-
///
/// change this to whatever margin you want the code folding tree (+/-) to show in
///
private const int FOLDING_MARGIN = 3;
-
///
/// set this true to show circular buttons for code folding (the [+] and [-] buttons on the margin)
///
private const bool CODE_FOLDING_CIRCULAR = true;
-
readonly Point initial_importScriptFileButton_location;
readonly Point initial_exportScriptFileButton_location;
readonly Point initial_addScriptFileButton_location;
readonly Point initial_removeScriptFileButton_location;
readonly Point initial_viewLevelScript_location;
-
readonly Point new_importScriptFileButton_location;
readonly Point new_exportScriptFileButton_location;
readonly Point new_addScriptFileButton_location;
readonly Point new_removeScriptFileButton_location;
readonly Point new_viewLevelScript_location;
-
- public ScriptEditor() {
+ public ScriptEditor()
+ {
InitializeComponent();
-
-
//initially, these buttons are off the canvas so they can be interacted with in the designer
//they are then moved as needed
initial_importScriptFileButton_location = importScriptFileButton.Location;
@@ -77,111 +74,132 @@ namespace DSPRE.Editors {
initial_addScriptFileButton_location = addScriptFileButton.Location;
initial_removeScriptFileButton_location = removeScriptFileButton.Location;
initial_viewLevelScript_location = viewLevelScriptButton.Location;
-
new_importScriptFileButton_location = new Point(164, 22);
new_exportScriptFileButton_location = new Point(239, 22);
new_addScriptFileButton_location = new Point(314, 22);
new_removeScriptFileButton_location = new Point(314, 49);
new_viewLevelScript_location = new Point(326, 37);
-
importScriptFileButton.Enabled = false;
exportScriptFileButton.Enabled = false;
addScriptFileButton.Enabled = false;
removeScriptFileButton.Enabled = false;
viewLevelScriptButton.Enabled = false;
}
-
- public void SetupScriptEditor(MainProgram parent, bool force = false) {
+ public void SetupScriptEditor(MainProgram parent, bool force = false)
+ {
if (scriptEditorIsReady && !force) { return; }
scriptEditorIsReady = true;
this._parent = parent;
SetupScriptEditorTextAreas();
-
/* Extract essential NARCs sub-archives*/
Helpers.statusLabelMessage("Setting up Script Editor...");
Update();
-
DSUtils.TryUnpackNarcs(new List { RomInfo.DirNames.scripts }); //12 = scripts Narc Dir
-
populate_selectScriptFileComboBox(0);
-
UpdateScriptNumberCheckBox((NumberStyles)Properties.Settings.Default.scriptEditorFormatPreference);
Helpers.statusLabelMessage();
}
-
- public void OpenScriptEditor(MainProgram parent, int scriptFileID) {
+ public void OpenScriptEditor(MainProgram parent, int scriptFileID)
+ {
SetupScriptEditor(parent);
+ scriptEditorTabControl.SelectedIndex = 0;
selectScriptFileComboBox.SelectedIndex = scriptFileID;
EditorPanels.mainTabControl.SelectedTab = EditorPanels.scriptEditorTabPage;
}
-
- private void SetupScriptEditorTextAreas() {
+ private void SetupScriptEditorTextAreas()
+ {
//PREPARE SCRIPT EDITOR KEYWORDS
cmdKeyWords = String.Join(" ", RomInfo.ScriptCommandNamesDict.Values) +
" " + String.Join(" ", ScriptDatabase.movementsDictIDName.Values);
cmdKeyWords += " " + cmdKeyWords.ToUpper() + " " + cmdKeyWords.ToLower();
-
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() +
" " + Event.EventType.Overworld +
" " + Overworld.MovementCodeKW;
secondaryKeyWords += " " + secondaryKeyWords.ToUpper() + " " + secondaryKeyWords.ToLower();
-
// CREATE CONTROLS
ScriptTextArea = new Scintilla();
scriptSearchManager = new SearchManager(EditorPanels.MainProgram, ScriptTextArea, panelFindScriptTextBox, PanelSearchScripts);
scintillaScriptsPanel.Controls.Clear();
scintillaScriptsPanel.Controls.Add(ScriptTextArea);
+ FunctionTextArea = new Scintilla();
+ functionSearchManager = new SearchManager(EditorPanels.MainProgram, FunctionTextArea, panelFindFunctionTextBox, PanelSearchFunctions);
+ scintillaFunctionsPanel.Controls.Clear();
+ scintillaFunctionsPanel.Controls.Add(FunctionTextArea);
+
+ ActionTextArea = new Scintilla();
+ actionSearchManager = new SearchManager(EditorPanels.MainProgram, ActionTextArea, panelFindActionTextBox, PanelSearchActions);
+ scintillaActionsPanel.Controls.Clear();
+ scintillaActionsPanel.Controls.Add(ActionTextArea);
+
+ currentScintillaEditor = ScriptTextArea;
+ currentSearchManager = scriptSearchManager;
+
// BASIC CONFIG
ScriptTextArea.TextChanged += (OnTextChangedScript);
+ FunctionTextArea.TextChanged += (OnTextChangedFunction);
+ ActionTextArea.TextChanged += (OnTextChangedAction);
// INITIAL VIEW CONFIG
InitialViewConfig(ScriptTextArea);
+ InitialViewConfig(FunctionTextArea);
+ InitialViewConfig(ActionTextArea);
InitSyntaxColoring(ScriptTextArea);
+ InitSyntaxColoring(FunctionTextArea);
+ InitSyntaxColoring(ActionTextArea);
// NUMBER MARGIN
InitNumberMargin(ScriptTextArea, ScriptTextArea_MarginClick);
+ InitNumberMargin(FunctionTextArea, FunctionTextArea_MarginClick);
+ InitNumberMargin(ActionTextArea, ActionTextArea_MarginClick);
// BOOKMARK MARGIN
InitBookmarkMargin(ScriptTextArea);
+ InitBookmarkMargin(FunctionTextArea);
+ InitBookmarkMargin(ActionTextArea);
// CODE FOLDING MARGIN
InitCodeFolding(ScriptTextArea);
+ InitCodeFolding(FunctionTextArea);
+ InitCodeFolding(ActionTextArea);
// INIT HOTKEYS
InitHotkeys(ScriptTextArea, scriptSearchManager);
+ InitHotkeys(FunctionTextArea, functionSearchManager);
+ InitHotkeys(ActionTextArea, actionSearchManager);
// INIT TOOLTIPS DWELLING
/*
ScriptTextArea.MouseDwellTime = 300;
ScriptTextArea.DwellEnd += TextArea_DwellEnd;
ScriptTextArea.DwellStart += TextArea_DwellStart;
-
FunctionTextArea.MouseDwellTime = 300;
FunctionTextArea.DwellEnd += TextArea_DwellEnd;
FunctionTextArea.DwellStart += TextArea_DwellStart;
*/
-
- // Style for prefixed words (label_*, script_*)
}
- private void populate_selectScriptFileComboBox(int selectedIndex = 0) {
+ private void populate_selectScriptFileComboBox(int selectedIndex = 0)
+ {
selectScriptFileComboBox.Items.Clear();
int scriptCount = Filesystem.GetScriptCount();
- for (int i = 0; i < scriptCount; i++) {
+ for (int i = 0; i < scriptCount; i++)
+ {
// ScriptFile currentScriptFile = new ScriptFile(i, true, true);
// selectScriptFileComboBox.Items.Add(currentScriptFile);
selectScriptFileComboBox.Items.Add($"Script File {i}");
}
-
selectScriptFileComboBox.SelectedIndex = selectedIndex;
}
-
- private void InitialViewConfig(Scintilla textArea) {
+ private void InitialViewConfig(Scintilla textArea)
+ {
textArea.Dock = DockStyle.Fill;
textArea.WrapMode = WrapMode.Word;
textArea.IndentationGuides = IndentView.LookBoth;
@@ -191,7 +209,9 @@ namespace DSPRE.Editors {
textArea.WrapIndentMode = WrapIndentMode.Same;
}
- private void InitSyntaxColoring(Scintilla textArea) {
+ private void InitSyntaxColoring(Scintilla textArea)
+ {
+ // Configure the default style
textArea.StyleResetDefault();
textArea.Styles[Style.Default].Font = "Consolas";
textArea.Styles[Style.Default].Size = 12;
@@ -199,127 +219,67 @@ namespace DSPRE.Editors {
textArea.Styles[Style.Default].ForeColor = Color.FromArgb(0xFFFFFF);
textArea.StyleClearAll();
- // Configure Assembly lexer styles
- textArea.Styles[Style.Asm.Identifier].ForeColor = Color.FromArgb(0xD0DAE2);
- textArea.Styles[Style.Asm.Number].ForeColor = Color.FromArgb(0xFFFF00);
- textArea.Styles[Style.Asm.String].ForeColor = Color.FromArgb(0xFF00FF);
- textArea.Styles[Style.Asm.Character].ForeColor = Color.FromArgb(0xE95454);
- textArea.Styles[Style.Asm.Operator].ForeColor = Color.FromArgb(0xFFFF00);
- textArea.Styles[Style.Asm.Comment].ForeColor = Color.FromArgb(0x40BF57);
+ // Configure the lexer styles
+ textArea.Styles[Style.Python.Identifier].ForeColor = Color.FromArgb(0xD0DAE2);
+ textArea.Styles[Style.Python.CommentLine].ForeColor = Color.FromArgb(0x40BF57);
+ textArea.Styles[Style.Python.Number].ForeColor = Color.FromArgb(0xFFFF00);
+ textArea.Styles[Style.Python.String].ForeColor = Color.FromArgb(0xFF00FF);
+ textArea.Styles[Style.Python.Character].ForeColor = Color.FromArgb(0xE95454);
+ textArea.Styles[Style.Python.Operator].ForeColor = Color.FromArgb(0xFFFF00);
+ textArea.Styles[Style.Python.Word].ForeColor = Color.FromArgb(0x48A8EE);
+ textArea.Styles[Style.Python.Word2].ForeColor = Color.FromArgb(0xF98906);
- // For command keywords - use CpuInstruction style
- textArea.Styles[Style.Asm.CpuInstruction].ForeColor = Color.FromArgb(0x48A8EE);
+ textArea.Lexer = Lexer.Python;
- // For secondary keywords - use Directive style
- textArea.Styles[Style.Asm.Directive].ForeColor = Color.FromArgb(0xF98906);
-
- // Configure indicators for prefix highlighting
- textArea.Indicators[0].Style = IndicatorStyle.TextFore;
- textArea.Indicators[0].ForeColor = Color.FromArgb(0x8A2BE2); // Purple for label_*
- textArea.Indicators[0].Under = false; // Draw over the lexer's styling
-
- textArea.Indicators[1].Style = IndicatorStyle.TextFore;
- textArea.Indicators[1].ForeColor = Color.FromArgb(0x00CED1); // Cyan for script_*
- textArea.Indicators[1].Under = false; // Draw over the lexer's styling
-
- // Set the lexer and keywords
- textArea.Lexer = Lexer.Asm;
- textArea.SetKeywords(0, cmdKeyWords); // CPU Instructions index
- textArea.SetKeywords(3, secondaryKeyWords); // Directives index
-
- // Apply the highlighting
- textArea.TextChanged += (sender, e) => HighlightPrefixedWords(textArea);
-
- // Initial highlighting
- HighlightPrefixedWords(textArea);
+ textArea.SetKeywords(0, cmdKeyWords);
+ textArea.SetKeywords(1, secondaryKeyWords);
}
- private void HighlightPrefixedWords(Scintilla textArea) {
- // Clear existing indicators
- textArea.IndicatorCurrent = 0;
- textArea.IndicatorClearRange(0, textArea.TextLength);
- textArea.IndicatorCurrent = 1;
- textArea.IndicatorClearRange(0, textArea.TextLength);
-
- // Process each line individually
- for (int i = 0; i < textArea.Lines.Count; i++) {
- string lineText = textArea.Lines[i].Text;
- int linePos = textArea.Lines[i].Position;
-
- // Trim for detection but use original text for positions
- string trimmedLine = lineText.Trim();
-
- // Handle script_ lines
- if (trimmedLine.Contains("script_") && trimmedLine.EndsWith(":")) {
- int startPos = linePos + lineText.IndexOf("script_");
- int endPos = linePos + lineText.IndexOf(":", lineText.IndexOf("script_")) + 1;
-
- textArea.IndicatorCurrent = 1;
- textArea.IndicatorFillRange(startPos, endPos - startPos);
- }
-
- // Handle label_ lines
- if (trimmedLine.Contains("label_") && trimmedLine.EndsWith(":")) {
- int startPos = linePos + lineText.IndexOf("label_");
- int endPos = linePos + lineText.IndexOf(":", lineText.IndexOf("label_")) + 1;
-
- textArea.IndicatorCurrent = 0;
- textArea.IndicatorFillRange(startPos, endPos - startPos);
- }
- }
- }
-
- private void InitNumberMargin(Scintilla textArea, EventHandler textArea_MarginClick) {
+ private void InitNumberMargin(Scintilla textArea, EventHandler textArea_MarginClick)
+ {
textArea.Styles[Style.LineNumber].BackColor = BACK_COLOR;
textArea.Styles[Style.LineNumber].ForeColor = FORE_COLOR;
textArea.Styles[Style.IndentGuide].ForeColor = FORE_COLOR;
textArea.Styles[Style.IndentGuide].BackColor = BACK_COLOR;
-
Margin nums = textArea.Margins[NUMBER_MARGIN];
nums.Type = MarginType.Number;
nums.Sensitive = true;
nums.Mask = 0;
-
textArea.MarginClick += textArea_MarginClick;
}
-
- private void InitBookmarkMargin(Scintilla textArea) {
+ private void InitBookmarkMargin(Scintilla textArea)
+ {
//TextArea.SetFoldMarginColor(true, IntToColor(BACK_COLOR));
-
Margin margin = textArea.Margins[BOOKMARK_MARGIN];
margin.Width = 20;
margin.Sensitive = true;
margin.Type = MarginType.Symbol;
margin.Mask = (1 << BOOKMARK_MARKER);
//margin.Cursor = MarginCursor.Arrow;
-
Marker marker = textArea.Markers[BOOKMARK_MARKER];
marker.Symbol = MarkerSymbol.Circle;
marker.SetBackColor(Color.FromArgb(0xFF003B));
marker.SetForeColor(Color.FromArgb(0x000000));
marker.SetAlpha(100);
}
-
- private void InitCodeFolding(Scintilla textArea) {
+ private void InitCodeFolding(Scintilla textArea)
+ {
textArea.SetFoldMarginColor(true, BACK_COLOR);
textArea.SetFoldMarginHighlightColor(true, BACK_COLOR);
-
// Enable code folding
textArea.SetProperty("fold", "1");
textArea.SetProperty("fold.compact", "1");
-
// Configure a margin to display folding symbols
textArea.Margins[FOLDING_MARGIN].Type = MarginType.Symbol;
textArea.Margins[FOLDING_MARGIN].Mask = Marker.MaskFolders;
textArea.Margins[FOLDING_MARGIN].Sensitive = true;
textArea.Margins[FOLDING_MARGIN].Width = 20;
-
// Set colors for all folding markers
- for (int i = 25; i <= 31; i++) {
+ for (int i = 25; i <= 31; i++)
+ {
textArea.Markers[i].SetForeColor(BACK_COLOR); // styles for [+] and [-]
textArea.Markers[i].SetBackColor(FORE_COLOR); // styles for [+] and [-]
}
-
// Configure folding markers with respective symbols
textArea.Markers[Marker.Folder].Symbol = CODE_FOLDING_CIRCULAR ? MarkerSymbol.CirclePlus : MarkerSymbol.BoxPlus;
textArea.Markers[Marker.FolderOpen].Symbol = CODE_FOLDING_CIRCULAR ? MarkerSymbol.CircleMinus : MarkerSymbol.BoxMinus;
@@ -328,12 +288,11 @@ namespace DSPRE.Editors {
textArea.Markers[Marker.FolderOpenMid].Symbol = CODE_FOLDING_CIRCULAR ? MarkerSymbol.CircleMinusConnected : MarkerSymbol.BoxMinusConnected;
textArea.Markers[Marker.FolderSub].Symbol = MarkerSymbol.VLine;
textArea.Markers[Marker.FolderTail].Symbol = MarkerSymbol.LCorner;
-
// Enable automatic folding
textArea.AutomaticFold = (AutomaticFold.Show | AutomaticFold.Click | AutomaticFold.Change);
}
-
- private void InitHotkeys(Scintilla scintillaTb, SearchManager sm) {
+ private void InitHotkeys(Scintilla scintillaTb, SearchManager sm)
+ {
// register the hotkeys with the form
HotKeyManager.AddHotKey(scintillaTb, sm.OpenSearch, Keys.F, true);
HotKeyManager.AddHotKey(scintillaTb, () => Uppercase(scintillaTb), Keys.U, true);
@@ -342,7 +301,6 @@ namespace DSPRE.Editors {
HotKeyManager.AddHotKey(scintillaTb, () => ZoomOut(scintillaTb), Keys.OemMinus, true);
HotKeyManager.AddHotKey(scintillaTb, () => ZoomDefault(scintillaTb), Keys.D0, true);
HotKeyManager.AddHotKey(scintillaTb, sm.CloseSearch, Keys.Escape);
-
// remove conflicting hotkeys from scintilla
scintillaTb.ClearCmdKey(Keys.Control | Keys.F);
scintillaTb.ClearCmdKey(Keys.Control | Keys.R);
@@ -350,86 +308,115 @@ namespace DSPRE.Editors {
scintillaTb.ClearCmdKey(Keys.Control | Keys.L);
scintillaTb.ClearCmdKey(Keys.Control | Keys.U);
}
-
- private void Uppercase(Scintilla textArea) {
+ private void Uppercase(Scintilla textArea)
+ {
// save the selection
int start = textArea.SelectionStart;
int end = textArea.SelectionEnd;
-
// modify the selected text
textArea.ReplaceSelection(textArea.GetTextRange(start, end - start).ToUpper());
-
// preserve the original selection
textArea.SetSelection(start, end);
}
-
- private void Lowercase(Scintilla textArea) {
+ private void Lowercase(Scintilla textArea)
+ {
// save the selection
int start = textArea.SelectionStart;
int end = textArea.SelectionEnd;
-
// modify the selected text
textArea.ReplaceSelection(textArea.GetTextRange(start, end - start).ToLower());
-
// preserve the original selection
textArea.SetSelection(start, end);
}
-
- private void ZoomIn(Scintilla textArea) {
+ private void ZoomIn(Scintilla textArea)
+ {
textArea.ZoomIn();
}
-
- private void ZoomOut(Scintilla textArea) {
+ private void ZoomOut(Scintilla textArea)
+ {
textArea.ZoomOut();
}
-
- private void ZoomDefault(Scintilla textArea) {
+ private void ZoomDefault(Scintilla textArea)
+ {
textArea.Zoom = 0;
}
-
- private void ScriptEditorSetClean() {
+ private void ScriptEditorSetClean()
+ {
Helpers.DisableHandlers();
- //scriptsTabPage.Text = ScriptFile.ContainerTypes.Script.ToString() + "s";
- scriptsDirty = false;
+ scriptsTabPage.Text = ScriptFile.ContainerTypes.Script.ToString() + "s";
+ functionsTabPage.Text = ScriptFile.ContainerTypes.Function.ToString() + "s";
+ actionsTabPage.Text = ScriptFile.ContainerTypes.Action.ToString() + "s";
+ scriptsDirty = functionsDirty = actionsDirty = false;
Helpers.EnableHandlers();
}
- private void OnTextChangedScript(object sender, EventArgs e) {
+ private void OnTextChangedScript(object sender, EventArgs e)
+ {
ScriptTextArea.Margins[NUMBER_MARGIN].Width = ScriptTextArea.Lines.Count.ToString().Length * 13;
scriptsDirty = true;
- //scriptsTabPage.Text = ScriptFile.ContainerTypes.Script.ToString() + "s" + "*";
+ scriptsTabPage.Text = ScriptFile.ContainerTypes.Script.ToString() + "s" + "*";
}
- private void ScriptTextArea_MarginClick(object sender, MarginClickEventArgs e) {
+ private void OnTextChangedFunction(object sender, EventArgs e)
+ {
+ FunctionTextArea.Margins[NUMBER_MARGIN].Width = FunctionTextArea.Lines.Count.ToString().Length * 13;
+ functionsDirty = true;
+ functionsTabPage.Text = ScriptFile.ContainerTypes.Function.ToString() + "s" + "*";
+ }
+
+ private void OnTextChangedAction(object sender, EventArgs e)
+ {
+ ActionTextArea.Margins[NUMBER_MARGIN].Width = ActionTextArea.Lines.Count.ToString().Length * 13;
+ actionsDirty = true;
+ actionsTabPage.Text = ScriptFile.ContainerTypes.Action.ToString() + "s" + "*";
+ }
+
+ private void ScriptTextArea_MarginClick(object sender, MarginClickEventArgs e)
+ {
MarginClick(ScriptTextArea, e);
}
- private void MarginClick(Scintilla textArea, MarginClickEventArgs e) {
- if (e.Margin == BOOKMARK_MARGIN) {
+ private void FunctionTextArea_MarginClick(object sender, MarginClickEventArgs e)
+ {
+ MarginClick(FunctionTextArea, e);
+ }
+
+ private void ActionTextArea_MarginClick(object sender, MarginClickEventArgs e)
+ {
+ MarginClick(ActionTextArea, e);
+ }
+
+ private void MarginClick(Scintilla textArea, MarginClickEventArgs e)
+ {
+ if (e.Margin == BOOKMARK_MARGIN)
+ {
// Do we have a marker for this line?
const uint mask = (1 << BOOKMARK_MARKER);
Line line = textArea.Lines[textArea.LineFromPosition(e.Position)];
- if ((line.MarkerGet() & mask) > 0) {
+ if ((line.MarkerGet() & mask) > 0)
+ {
// Remove existing bookmark
line.MarkerDelete(BOOKMARK_MARKER);
- } else {
+ }
+ else
+ {
// Add bookmark
line.MarkerAdd(BOOKMARK_MARKER);
}
}
}
-
- private void selectScriptFileComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+ private void selectScriptFileComboBox_SelectedIndexChanged(object sender, EventArgs e)
+ {
DisplayScript();
}
-
- public void UpdateScriptNumberCheckBox(NumberStyles toSet) {
+ public void UpdateScriptNumberCheckBox(NumberStyles toSet)
+ {
Helpers.DisableHandlers();
Properties.Settings.Default.scriptEditorFormatPreference = (int)toSet;
-
- switch ((NumberStyles)Properties.Settings.Default.scriptEditorFormatPreference) {
+ switch ((NumberStyles)Properties.Settings.Default.scriptEditorFormatPreference)
+ {
case NumberStyles.None:
scriptEditorNumberFormatNoPreference.Checked = true;
break;
@@ -440,341 +427,490 @@ namespace DSPRE.Editors {
scriptEditorNumberFormatDecimal.Checked = true;
break;
}
-
Console.WriteLine("changed style to " + Properties.Settings.Default.scriptEditorFormatPreference);
Helpers.EnableHandlers();
}
-
- private void UpdateScriptNumberFormat(NumberStyles numberStyle) {
- if (Helpers.HandlersEnabled) {
+ private void UpdateScriptNumberFormat(NumberStyles numberStyle)
+ {
+ if (Helpers.HandlersEnabled)
+ {
NumberStyles old = (NumberStyles)Properties.Settings.Default.scriptEditorFormatPreference; //Local Backup
Properties.Settings.Default.scriptEditorFormatPreference = (int)numberStyle;
-
- if (!DisplayScript()) {
+ if (!DisplayScript())
+ {
UpdateScriptNumberCheckBox(old); //Restore old checkbox status! Script couldn't be redrawn
}
}
}
-
- private void UpdateScriptNumberFormatNoPref(object sender, EventArgs e) {
+ private void UpdateScriptNumberFormatNoPref(object sender, EventArgs e)
+ {
UpdateScriptNumberFormat(NumberStyles.None);
}
-
- private void UpdateScriptNumberFormatDec(object sender, EventArgs e) {
+ private void UpdateScriptNumberFormatDec(object sender, EventArgs e)
+ {
UpdateScriptNumberFormat(NumberStyles.Integer);
}
-
- private void UpdateScriptNumberFormatHex(object sender, EventArgs e) {
+ private void UpdateScriptNumberFormatHex(object sender, EventArgs e)
+ {
UpdateScriptNumberFormat(NumberStyles.HexNumber);
}
-
- private bool DisplayScript() {
+ private bool DisplayScript()
+ {
Console.WriteLine("Script Reload has been requested");
-
/* clear controls */
- if (Helpers.HandlersDisabled || selectScriptFileComboBox.SelectedItem == null) {
+ if (Helpers.HandlersDisabled || selectScriptFileComboBox.SelectedItem == null)
+ {
return false;
}
- // Keep all the code that handles unsaved changes
- if (scriptsDirty || functionsDirty || actionsDirty) {
+ if (scriptsDirty || functionsDirty || actionsDirty)
+ {
DialogResult d = MessageBox.Show("There are unsaved changes in this Script File.\nDo you wish to discard them?", "Unsaved work", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
- if (!d.Equals(DialogResult.Yes)) {
+ if (!d.Equals(DialogResult.Yes))
+ {
Helpers.DisableHandlers();
+ // selectScriptFileComboBox.SelectedItem = currentScriptFile;
selectScriptFileComboBox.SelectedIndex = (int)currentScriptFile.fileID;
Helpers.EnableHandlers();
return false;
}
}
-
Helpers.DisableHandlers();
ScriptFile lastScriptFile = currentScriptFile;
- // Load the script file using our new label-based constructor
- currentScriptFile = new ScriptFile(selectScriptFileComboBox.SelectedIndex);
+ // currentScriptFile = (ScriptFile)selectScriptFileComboBox.SelectedItem;
+ currentScriptFile = new ScriptFile(selectScriptFileComboBox.SelectedIndex); // Load script file
- // Clear only the script text area and nav listbox
ScriptTextArea.ClearAll();
- scriptsNavListbox.Items.Clear();
+ FunctionTextArea.ClearAll();
+ ActionTextArea.ClearAll();
+ scriptsNavListbox.Items.Clear();
+ functionsNavListbox.Items.Clear();
+ actionsNavListbox.Items.Clear();
+
+ //prevent buttons from flickering when the combobox selection changes
bool typeChanged = true;
- if (lastScriptFile != null) {
+ if (lastScriptFile != null)
+ {
typeChanged = lastScriptFile.isLevelScript != currentScriptFile.isLevelScript;
}
-
- if (typeChanged) {
- if (currentScriptFile.isLevelScript) {
+ if (typeChanged)
+ {
+ if (currentScriptFile.isLevelScript)
+ {
importScriptFileButton.Location = initial_importScriptFileButton_location;
exportScriptFileButton.Location = initial_exportScriptFileButton_location;
addScriptFileButton.Location = initial_addScriptFileButton_location;
removeScriptFileButton.Location = initial_removeScriptFileButton_location;
-
viewLevelScriptButton.Location = new_viewLevelScript_location;
-
importScriptFileButton.Enabled = false;
exportScriptFileButton.Enabled = false;
addScriptFileButton.Enabled = false;
removeScriptFileButton.Enabled = false;
-
viewLevelScriptButton.Enabled = true;
- } else {
+ }
+ else
+ {
importScriptFileButton.Location = new_importScriptFileButton_location;
exportScriptFileButton.Location = new_exportScriptFileButton_location;
addScriptFileButton.Location = new_addScriptFileButton_location;
removeScriptFileButton.Location = new_removeScriptFileButton_location;
-
viewLevelScriptButton.Location = initial_viewLevelScript_location;
-
importScriptFileButton.Enabled = true;
exportScriptFileButton.Enabled = true;
addScriptFileButton.Enabled = true;
removeScriptFileButton.Enabled = true;
-
viewLevelScriptButton.Enabled = false;
}
}
- if (!currentScriptFile.isLevelScript) {
- displayScriptFile(scriptsNavListbox, ScriptTextArea);
+ if (!currentScriptFile.isLevelScript)
+ {
+ displayScriptFile(ScriptFile.ContainerTypes.Script, currentScriptFile.allScripts, scriptsNavListbox, ScriptTextArea);
+ displayScriptFile(ScriptFile.ContainerTypes.Function, currentScriptFile.allFunctions, functionsNavListbox, FunctionTextArea);
+ displayScriptFileActions(ScriptFile.ContainerTypes.Action, currentScriptFile.allActions, actionsNavListbox, ActionTextArea);
+ }
+
+ ScriptEditorSetClean();
+ Helpers.statusLabelMessage();
+ Helpers.EnableHandlers();
+ return true;
}
- ScriptEditorSetClean();
+ static void displayScriptFile(ScriptFile.ContainerTypes containerType, List commandList, ListBox navListBox, Scintilla textArea)
+ {
+ string buffer = "";
+ /* Add commands */
+ for (int i = 0; i < commandList.Count; i++)
+ {
+ ScriptCommandContainer scriptCommandContainer = commandList[i];
- Helpers.statusLabelMessage();
- Helpers.EnableHandlers();
+ /* Write header */
+ string header = containerType + " " + (i + 1);
+ buffer += header + ':' + Environment.NewLine;
+ navListBox.Items.Add(header);
- return true;
- }
+ /* If current command is identical to another, print UseScript instead of commands */
+ if (scriptCommandContainer.usedScriptID < 0)
+ {
+ for (int j = 0; j < scriptCommandContainer.commands.Count; j++)
+ {
+ ScriptCommand command = scriptCommandContainer.commands[j];
+ if (!ScriptDatabase.endCodes.Contains(command.id))
+ {
+ buffer += '\t';
+ }
- private void displayScriptFile(ListBox navListBox, Scintilla textArea) {
- if (currentScriptFile.CommandSequence == null || currentScriptFile.CommandSequence.Count == 0) {
- return;
- }
+ buffer += command.name + Environment.NewLine;
+ }
+ }
+ else
+ {
+ buffer += '\t' + "UseScript_#" + scriptCommandContainer.usedScriptID + Environment.NewLine;
+ }
- // First add all labels to the nav listbox
- HashSet addedLabels = new HashSet();
- foreach (var cmdPos in currentScriptFile.CommandSequence) {
- if (!string.IsNullOrEmpty(cmdPos.Label) && !addedLabels.Contains(cmdPos.Label)) {
- navListBox.Items.Add(cmdPos.Label);
- addedLabels.Add(cmdPos.Label);
+ textArea.AppendText(buffer + Environment.NewLine);
+ buffer = "";
}
}
- // Generate the script text
- string scriptText = currentScriptFile.ToText();
- textArea.Text = scriptText;
+ static void displayScriptFileActions(ScriptFile.ContainerTypes containerType, List commandList, ListBox navListBox, Scintilla textArea)
+ {
+ /* Add movements */
+ string buffer = "";
+ for (int i = 0; i < commandList.Count; i++)
+ {
+ ScriptActionContainer currentCommand = commandList[i];
+
+ string header = containerType + " " + (i + 1);
+ buffer += header + ':' + Environment.NewLine;
+ navListBox.Items.Add(header);
+
+ for (int j = 0; j < currentCommand.commands.Count; j++)
+ {
+ ScriptAction command = currentCommand.commands[j];
+ if (!ScriptDatabase.movementEndCodes.Contains(command.id))
+ {
+ buffer += '\t';
+ }
+
+ buffer += command.name + Environment.NewLine;
+ }
+
+ textArea.AppendText(buffer + Environment.NewLine);
+ buffer = "";
+ }
+ }
+
+ private void scriptEditorZoomInButton_Click(object sender, EventArgs e)
+ {
+ ZoomIn(currentScintillaEditor);
}
- private void scriptEditorZoomInButton_Click(object sender, EventArgs e) {
- ZoomIn(ScriptTextArea);
+ private void scriptEditorZoomOutButton_Click(object sender, EventArgs e)
+ {
+ ZoomOut(currentScintillaEditor);
}
- private void scriptEditorZoomOutButton_Click(object sender, EventArgs e) {
- ZoomOut(ScriptTextArea);
+ private void scriptEditorZoomResetButton_Click(object sender, EventArgs e)
+ {
+ ZoomDefault(currentScintillaEditor);
}
- private void scriptEditorZoomResetButton_Click(object sender, EventArgs e) {
- ZoomDefault(ScriptTextArea);
+ private void scriptEditorTabControl_TabIndexChanged(object sender, EventArgs e)
+ {
+ if (scriptEditorTabControl.SelectedTab == scriptsTabPage)
+ {
+ currentSearchManager = scriptSearchManager;
+ currentScintillaEditor = ScriptTextArea;
+ }
+ else if (scriptEditorTabControl.SelectedTab == functionsTabPage)
+ {
+ currentSearchManager = functionSearchManager;
+ currentScintillaEditor = FunctionTextArea;
+ }
+ else
+ {
+ //Actions
+ currentSearchManager = actionSearchManager;
+ currentScintillaEditor = ActionTextArea;
+ }
}
- private void removeScriptFileButton_Click(object sender, EventArgs e) {
+ private void removeScriptFileButton_Click(object sender, EventArgs e)
+ {
DialogResult d = MessageBox.Show("Are you sure you want to delete the last Script File?", "Confirm deletion", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
- if (d.Equals(DialogResult.Yes)) {
+ if (d.Equals(DialogResult.Yes))
+ {
/* Delete script file */
string path = Filesystem.GetScriptPath(selectScriptFileComboBox.Items.Count - 1);
File.Delete(path);
-
/* Check if currently selected file is the last one, and in that case select the one before it */
int lastIndex = selectScriptFileComboBox.Items.Count - 1;
- if (selectScriptFileComboBox.SelectedIndex == lastIndex) {
+ if (selectScriptFileComboBox.SelectedIndex == lastIndex)
+ {
selectScriptFileComboBox.SelectedIndex--;
}
-
/* Remove item from ComboBox */
selectScriptFileComboBox.Items.RemoveAt(lastIndex);
}
}
-
- private void addScriptFileButton_Click(object sender, EventArgs e) {
+ private void addScriptFileButton_Click(object sender, EventArgs e)
+ {
/* Add new event file to event folder */
int fileID = selectScriptFileComboBox.Items.Count;
- // Create a simple script with one labeled section
- List scriptLines = new List {
- "script_0:",
- "\tEnd"
- };
+ ScriptFile scriptFile = new ScriptFile(
+ scriptLines: new Scintilla { Text = "Script 1:\nEnd" }.Lines.ToStringsList(trim: true),
+ functionLines: null,
+ actionLines: null,
+ fileID
+ );
- // Use the new constructor that just takes script lines
- ScriptFile scriptFile = new ScriptFile(scriptLines, fileID);
-
- // Check if ScriptFile instance was created successfully
- if (scriptFile.SaveToFileDefaultDir(fileID, showSuccessMessage: false)) {
+ //check if ScriptFile instance was created successfully
+ if (scriptFile.SaveToFileDefaultDir(fileID, showSuccessMessage: false))
+ {
/* Update ComboBox and select new file */
- selectScriptFileComboBox.Items.Add($"Script File {fileID}");
- selectScriptFileComboBox.SelectedIndex = selectScriptFileComboBox.Items.Count - 1;
+ selectScriptFileComboBox.Items.Add(scriptFile);
+ selectScriptFileComboBox.SelectedItem = scriptFile;
}
}
- private void saveScriptFileButton_Click(object sender, EventArgs e) {
+ private void saveScriptFileButton_Click(object sender, EventArgs e)
+ {
/* Create new ScriptFile object using the values in the script editor */
int fileID = currentScriptFile.fileID;
- // We only need the script text area now, not function or action areas
ScriptFile userEdited = new ScriptFile(
- ScriptTextArea.Lines.ToStringsList(trim: true),
- fileID
+ scriptLines: ScriptTextArea.Lines.ToStringsList(trim: true),
+ functionLines: FunctionTextArea.Lines.ToStringsList(trim: true),
+ actionLines: ActionTextArea.Lines.ToStringsList(trim: true),
+ fileID
);
- // Check if ScriptFile instance was created successfully
- if (userEdited.SaveToFileDefaultDir(fileID)) {
+ if (userEdited.hasNoScripts)
+ {
+ MessageBox.Show("This " + nameof(ScriptFile) + " couldn't be saved. A minimum of one script is required.", "Can't save", MessageBoxButtons.OK, MessageBoxIcon.Warning);
+ return;
+ }
+
+ //check if ScriptFile instance was created successfully
+ if (userEdited.SaveToFileDefaultDir(fileID))
+ {
currentScriptFile = userEdited;
ScriptEditorSetClean();
}
}
-
- private void exportScriptFileButton_Click(object sender, EventArgs e) {
+ private void exportScriptFileButton_Click(object sender, EventArgs e)
+ {
currentScriptFile.SaveToFileExplorePath(currentScriptFile.ToString(), blindmode: true);
}
-
- private void importScriptFileButton_Click(object sender, EventArgs e) {
+ private void importScriptFileButton_Click(object sender, EventArgs e)
+ {
/* Prompt user to select .scr or .bin file */
- OpenFileDialog of = new OpenFileDialog {
+ OpenFileDialog of = new OpenFileDialog
+ {
Filter = "Script File (*.scr, *.bin)|*.scr;*.bin"
};
- if (of.ShowDialog(this) != DialogResult.OK) {
+ if (of.ShowDialog(this) != DialogResult.OK)
+ {
return;
}
-
/* Update scriptFile object in memory */
int i = selectScriptFileComboBox.SelectedIndex;
string path = Filesystem.GetScriptPath(i);
File.Copy(of.FileName, path, true);
-
populate_selectScriptFileComboBox(i);
-
/* Refresh controls */
selectScriptFileComboBox_SelectedIndexChanged(null, null);
-
/* Display success message */
MessageBox.Show("Scripts imported successfully!", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
-
- private void viewLevelScriptButton_Click(object sender, EventArgs e) {
+ private void viewLevelScriptButton_Click(object sender, EventArgs e)
+ {
EditorPanels.levelScriptEditor.OpenLevelScriptEditor(this._parent, selectScriptFileComboBox.SelectedIndex);
}
-
- private void locateCurrentScriptFile_Click(object sender, EventArgs e) {
+ private void locateCurrentScriptFile_Click(object sender, EventArgs e)
+ {
string path = Filesystem.GetScriptPath(selectScriptFileComboBox.SelectedIndex);
Helpers.ExplorerSelect(path);
}
-
- private void findNext(SearchManager searchManager) {
+ private void findNext(SearchManager searchManager)
+ {
searchManager.Find(true, false);
scrollResultToTop(searchManager);
}
-
- private void findPrev(SearchManager searchManager) {
+ private void findPrev(SearchManager searchManager)
+ {
searchManager.Find(false, false);
scrollResultToTop(searchManager);
}
-
- private void findCurrent(SearchManager searchManager) {
+ private void findCurrent(SearchManager searchManager)
+ {
searchManager.Find(true, true);
scrollResultToTop(searchManager);
}
-
- private void TxtFindKeyDown(SearchManager searchManager, KeyEventArgs e) {
- if (HotKeyManager.IsHotkey(e, Keys.Enter)) {
+ private void TxtFindKeyDown(SearchManager searchManager, KeyEventArgs e)
+ {
+ if (HotKeyManager.IsHotkey(e, Keys.Enter))
+ {
findNext(searchManager);
}
-
- if (HotKeyManager.IsHotkey(e, Keys.Enter, true) || HotKeyManager.IsHotkey(e, Keys.Enter, false, true)) {
+ if (HotKeyManager.IsHotkey(e, Keys.Enter, true) || HotKeyManager.IsHotkey(e, Keys.Enter, false, true))
+ {
findPrev(searchManager);
}
}
-
- private void BtnNextFindScript_Click(object sender, EventArgs e) {
+ private void BtnNextFindScript_Click(object sender, EventArgs e)
+ {
findNext(scriptSearchManager);
}
-
- private void BtnPrevFindScript_Click(object sender, EventArgs e) {
+ private void BtnPrevFindScript_Click(object sender, EventArgs e)
+ {
findPrev(scriptSearchManager);
}
-
- private void panelFindScriptTextBox_TextChanged(object sender, EventArgs e) {
+ private void panelFindScriptTextBox_TextChanged(object sender, EventArgs e)
+ {
findCurrent(scriptSearchManager);
}
-
- private void scriptTxtFind_KeyDown(object sender, KeyEventArgs e) {
+ private void scriptTxtFind_KeyDown(object sender, KeyEventArgs e)
+ {
TxtFindKeyDown(scriptSearchManager, e);
}
-
- private void BtnCloseFindScript_Click(object sender, EventArgs e) {
+ private void BtnCloseFindScript_Click(object sender, EventArgs e)
+ {
scriptSearchManager.CloseSearch();
}
+ private void BtnNextFindFunc_Click(object sender, EventArgs e)
+ {
+ findNext(functionSearchManager);
+ }
- void scrollResultToTop(SearchManager searchManager) {
+ private void BtnPrevFindFunc_Click(object sender, EventArgs e)
+ {
+ findNext(functionSearchManager);
+ }
+
+ private void panelFindFunctionTextBox_TextChanged(object sender, EventArgs e)
+ {
+ findNext(functionSearchManager);
+ }
+
+ private void functionTxtFind_KeyDown(object sender, KeyEventArgs e)
+ {
+ TxtFindKeyDown(functionSearchManager, e);
+ }
+
+ private void BtnCloseFindFunc_Click(object sender, EventArgs e)
+ {
+ functionSearchManager.CloseSearch();
+ }
+
+ private void BtnNextFindActions_Click(object sender, EventArgs e)
+ {
+ findNext(actionSearchManager);
+ }
+
+ private void BtnPrevFindActions_Click(object sender, EventArgs e)
+ {
+ findNext(actionSearchManager);
+ }
+
+ private void panelFindActionTextBox_TextChanged(object sender, EventArgs e)
+ {
+ findNext(actionSearchManager);
+ }
+
+ private void actionTxtFind_KeyDown(object sender, KeyEventArgs e)
+ {
+ TxtFindKeyDown(actionSearchManager, e);
+ }
+
+ private void BtnCloseFindActions_Click(object sender, EventArgs e)
+ {
+ actionSearchManager.CloseSearch();
+ }
+
+ void scrollResultToTop(SearchManager searchManager)
+ {
int resultStart = searchManager.textAreaScintilla.CurrentLine - ScriptEditorSearchResult.ResultsPadding;
searchManager.textAreaScintilla.FirstVisibleLine = resultStart;
}
- private void NavigatorGoTo(ListBox listBox, ScriptFile.ContainerTypes containerType) {
- if (listBox.SelectedIndex < 0) {
+ private void NavigatorGoTo(ListBox listBox, TabPage tabPage, SearchManager searchManager, ScriptFile.ContainerTypes containerType)
+ {
+ if (listBox.SelectedIndex < 0)
+ {
return;
}
+ scriptEditorTabControl.SelectedTab = tabPage;
int commandNumber = listBox.SelectedIndex + 1;
string CommandBlockOpen = $"{containerType} {commandNumber}:";
- scriptSearchManager.Find(true, false, CommandBlockOpen);
+ searchManager.Find(true, false, CommandBlockOpen);
- scrollResultToTop(scriptSearchManager);
+ scrollResultToTop(searchManager);
}
- private void scriptsNavListbox_SelectedIndexChanged(object sender, EventArgs e) {
- NavigatorGoTo((ListBox)sender, ScriptFile.ContainerTypes.Script);
+ private void scriptsNavListbox_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ NavigatorGoTo((ListBox)sender, scriptsTabPage, scriptSearchManager, ScriptFile.ContainerTypes.Script);
}
- private void functionsNavListbox_SelectedIndexChanged(object sender, EventArgs e) {
- //NavigatorGoTo((ListBox)sender, functionsTabPage, functionSearchManager, ScriptFile.ContainerTypes.Function);
+ private void functionsNavListbox_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ NavigatorGoTo((ListBox)sender, functionsTabPage, functionSearchManager, ScriptFile.ContainerTypes.Function);
}
- private void actionsNavListbox_SelectedIndexChanged(object sender, EventArgs e) {
- //NavigatorGoTo((ListBox)sender, actionsTabPage, actionSearchManager, ScriptFile.ContainerTypes.Action);
+ private void actionsNavListbox_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ NavigatorGoTo((ListBox)sender, actionsTabPage, actionSearchManager, ScriptFile.ContainerTypes.Action);
}
- private void openFindScriptEditorButton_Click(object sender, EventArgs e) {
- scriptSearchManager.OpenSearch();
+ private void openFindScriptEditorButton_Click(object sender, EventArgs e)
+ {
+ currentSearchManager.OpenSearch();
}
- private void ScriptEditorExpandButton_Click(object sender, EventArgs e) {
- ScriptTextArea.FoldAll(FoldAction.Expand);
+ private void ScriptEditorExpandButton_Click(object sender, EventArgs e)
+ {
+ currentScintillaEditor.FoldAll(FoldAction.Expand);
}
- private void ScriptEditorCollapseButton_Click(object sender, EventArgs e) {
- ScriptTextArea.FoldAll(FoldAction.Contract);
+ private void ScriptEditorCollapseButton_Click(object sender, EventArgs e)
+ {
+ currentScintillaEditor.FoldAll(FoldAction.Contract);
}
- private void scriptEditorWordWrapCheckbox_CheckedChanged(object sender, EventArgs e) {
+ private void scriptEditorWordWrapCheckbox_CheckedChanged(object sender, EventArgs e)
+ {
ScriptTextArea.WrapMode = scriptEditorWordWrapCheckbox.Checked ? WrapMode.Word : WrapMode.None;
+ FunctionTextArea.WrapMode = scriptEditorWordWrapCheckbox.Checked ? WrapMode.Word : WrapMode.None;
+ ActionTextArea.WrapMode = scriptEditorWordWrapCheckbox.Checked ? WrapMode.Word : WrapMode.None;
}
- private void viewWhiteSpacesButton_Click(object sender, EventArgs e) {
+ private void viewWhiteSpacesButton_Click(object sender, EventArgs e)
+ {
ScriptTextArea.ViewWhitespace = scriptEditorWhitespacesCheckbox.Checked ? WhitespaceMode.VisibleAlways : WhitespaceMode.Invisible;
+ FunctionTextArea.ViewWhitespace = scriptEditorWhitespacesCheckbox.Checked ? WhitespaceMode.VisibleAlways : WhitespaceMode.Invisible;
+ ActionTextArea.ViewWhitespace = scriptEditorWhitespacesCheckbox.Checked ? WhitespaceMode.VisibleAlways : WhitespaceMode.Invisible;
}
- private void searchInScriptsTextBox_KeyDown(object sender, KeyEventArgs e) {
- if (e.KeyCode == Keys.Enter) {
+ private void searchInScriptsTextBox_KeyDown(object sender, KeyEventArgs e)
+ {
+ if (e.KeyCode == Keys.Enter)
+ {
searchInScriptsButton_Click(null, null);
}
}
-
- public List getScriptsToSearch() {
+ public List getScriptsToSearch()
+ {
List scriptsToSearch = new List();
-
- if (searchOnlyCurrentScriptCheckBox.Checked) {
+ if (searchOnlyCurrentScriptCheckBox.Checked)
+ {
this.UIThread(() => {
searchProgressBar.Maximum = 1;
});
@@ -785,11 +921,14 @@ namespace DSPRE.Editors {
this.UIThread(() => {
searchProgressBar.IncrementNoAnimation();
});
- } else {
+ }
+ else
+ {
this.UIThread(() => {
searchProgressBar.Maximum = selectScriptFileComboBox.Items.Count;
});
- for (int i = 0; i < selectScriptFileComboBox.Items.Count; i++) {
+ for (int i = 0; i < selectScriptFileComboBox.Items.Count; i++)
+ {
ScriptFile scriptFile = new ScriptFile(i);
Console.WriteLine("Attempting to load script " + scriptFile.fileID);
scriptsToSearch.Add(scriptFile);
@@ -798,42 +937,37 @@ namespace DSPRE.Editors {
});
}
}
-
return scriptsToSearch;
}
-
- private void searchInScriptsButton_Click(object sender, EventArgs e) {
- if (searchInScriptsTextBox.Text == "") {
+ private void searchInScriptsButton_Click(object sender, EventArgs e)
+ {
+ if (searchInScriptsTextBox.Text == "")
+ {
return;
}
-
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += (_sender, args) => {
- this.UIThread(() => {
- searchInScriptsResultListBox.Items.Clear();
- searchProgressBar.Value = 0;
- });
+ this.UIThread(() => {
+ searchInScriptsResultListBox.Items.Clear();
+ searchProgressBar.Value = 0;
+ });
+ List scriptsToSearch = getScriptsToSearch();
- List scriptsToSearch = getScriptsToSearch();
-
- string searchString = searchInScriptsTextBox.Text;
- bool searchCriteriaCS(string s) => s.IndexOf(searchString, StringComparison.InvariantCulture) >= 0;
- bool searchCriteriaCI(string s) => s.IndexOf(searchString, StringComparison.InvariantCultureIgnoreCase) >= 0;
-
- Func searchCriteria;
- if (scriptSearchCaseSensitiveCheckBox.Checked) {
- searchCriteria = searchCriteriaCS;
- } else {
- searchCriteria = searchCriteriaCI;
- }
-
- List results = new List();
- foreach (ScriptFile scriptFile in scriptsToSearch) {
- List scriptResults = SearchInScripts(scriptFile, searchCriteria);
- results.AddRange(scriptResults);
- // results.AddRange(actionResults);
- }
+ string searchString = searchInScriptsTextBox.Text;
+ Func searchCriteriaCS = (string s) => s.IndexOf(searchString, StringComparison.InvariantCulture) >= 0;
+ Func searchCriteriaCI = (string s) => s.IndexOf(searchString, StringComparison.InvariantCultureIgnoreCase) >= 0;
+ Func searchCriteria = scriptSearchCaseSensitiveCheckBox.Checked ? searchCriteriaCS : searchCriteriaCI;
+ List results = new List();
+ foreach (ScriptFile scriptFile in scriptsToSearch)
+ {
+ List scriptResults = SearchInScripts(scriptFile, scriptFile.allScripts, searchCriteria);
+ List functionResults = SearchInScripts(scriptFile, scriptFile.allFunctions, searchCriteria);
+ // List actionResults = SearchInScripts(scriptFile, scriptFile.allActions, searchCriteria);
+ results.AddRange(scriptResults);
+ results.AddRange(functionResults);
+ // results.AddRange(actionResults);
+ }
this.UIThread(() => {
searchInScriptsResultListBox.Items.AddRange(results.ToArray());
searchProgressBar.Value = 0;
@@ -843,50 +977,84 @@ namespace DSPRE.Editors {
bw.RunWorkerAsync();
}
- private List SearchInScripts(ScriptFile scriptFile, Func criteria) {
+ private List SearchInScripts(ScriptFile scriptFile, List commandContainers, Func criteria)
+ {
List results = new List();
+ for (int j = 0; j < commandContainers.Count; j++)
+ {
+ if (commandContainers[j].commands is null)
+ {
+ continue;
+ }
+
+ ScriptCommandContainer scriptCommandContainer = commandContainers[j];
+ foreach (ScriptCommand scriptCommand in scriptCommandContainer.commands)
+ {
+ if (criteria(scriptCommand.name))
+ {
+ results.Add(new ScriptEditorSearchResult(scriptFile, scriptCommandContainer.containerType, j + 1, scriptCommand));
+ }
+ }
+ }
return results;
}
-
- private void searchInScriptsResultListBox_KeyDown(object sender, KeyEventArgs e) {
- if (e.KeyCode == Keys.Enter) {
+ private void searchInScriptsResultListBox_KeyDown(object sender, KeyEventArgs e)
+ {
+ if (e.KeyCode == Keys.Enter)
+ {
goToSearchResult();
}
}
-
- private void searchInScripts_GoToEntryResult(object sender, MouseEventArgs e) {
+ private void searchInScripts_GoToEntryResult(object sender, MouseEventArgs e)
+ {
goToSearchResult();
}
-
- private void goToSearchResult() {
+ private void goToSearchResult()
+ {
if (searchInScriptsResultListBox.SelectedItem == null) { return; }
-
ScriptEditorSearchResult searchResult = (ScriptEditorSearchResult)searchInScriptsResultListBox.SelectedItem;
ScriptFile scriptFile = searchResult.scriptFile;
ScriptFile.ContainerTypes containerType = searchResult.containerType;
-
selectScriptFileComboBox.SelectedIndex = scriptFile.fileID;
- if (containerType == ScriptFile.ContainerTypes.Script) {
- displaySearchResult(scriptSearchManager, searchResult);
+ if (containerType == ScriptFile.ContainerTypes.Script)
+ {
+ displaySearchResult(scriptsTabPage, scriptSearchManager, searchResult);
+ }
+ else if (containerType == ScriptFile.ContainerTypes.Function)
+ {
+ displaySearchResult(functionsTabPage, functionSearchManager, searchResult);
+ }
+ else if (containerType == ScriptFile.ContainerTypes.Action)
+ {
+ displaySearchResult(actionsTabPage, actionSearchManager, searchResult);
}
}
- private void displaySearchResult(SearchManager searchManager, ScriptEditorSearchResult searchResult) {
+ private void displaySearchResult(TabPage tabPage, SearchManager searchManager, ScriptEditorSearchResult searchResult)
+ {
+ if (scriptEditorTabControl.SelectedTab != tabPage)
+ {
+ scriptEditorTabControl.SelectedTab = tabPage;
+ }
+
searchManager.Find(true, false, searchResult.CommandBlockOpen);
int blockStart = searchManager.textAreaScintilla.CurrentLine - ScriptEditorSearchResult.ResultsPadding;
searchManager.Find(true, false, searchResult.scriptCommand.name);
int resultStart = searchManager.textAreaScintilla.CurrentLine - ScriptEditorSearchResult.ResultsPadding;
-
- if (scrollToBlockStartcheckBox.Checked) {
+ if (scrollToBlockStartcheckBox.Checked)
+ {
searchManager.textAreaScintilla.FirstVisibleLine = blockStart;
- } else {
+ }
+ else
+ {
searchManager.textAreaScintilla.FirstVisibleLine = resultStart;
}
}
+
}
public class ScriptEditorSearchResult {
diff --git a/DS_Map/Main Window.cs b/DS_Map/Main Window.cs
index 2c9fba5..636fa05 100644
--- a/DS_Map/Main Window.cs
+++ b/DS_Map/Main Window.cs
@@ -5494,12 +5494,14 @@ namespace DSPRE {
} else {
ScriptFile itemScript = new ScriptFile(RomInfo.itemScriptFileNumber);
owItemComboBox.Items.Clear();
- //foreach (ScriptCommandContainer cont in itemScript.allScripts) {
- // if (cont.commands.Count > 4) {
- // continue;
- // }
- // owItemComboBox.Items.Add(BitConverter.ToUInt16(cont.commands[1].Parameters[1].RawData, 0) + "x " + itemNames[BitConverter.ToUInt16(cont.commands[0].Parameters[1].RawData, 0)]);
- //}
+ foreach (ScriptCommandContainer cont in itemScript.allScripts)
+ {
+ if (cont.commands.Count > 4)
+ {
+ continue;
+ }
+ owItemComboBox.Items.Add(BitConverter.ToUInt16(cont.commands[1].cmdParams[1], 0) + "x " + itemNames[BitConverter.ToUInt16(cont.commands[0].cmdParams[1], 0)]);
+ }
}
/* Add ow movement list to box */
diff --git a/DS_Map/PatchToolboxDialog.cs b/DS_Map/PatchToolboxDialog.cs
index c96b456..bbbae98 100644
--- a/DS_Map/PatchToolboxDialog.cs
+++ b/DS_Map/PatchToolboxDialog.cs
@@ -258,18 +258,18 @@ namespace DSPRE
public static bool CheckScriptsStandardizedItemNumbers()
{
ScriptFile itemScript = new ScriptFile(RomInfo.itemScriptFileNumber);
- //if (itemScript.allScripts.Count - 1 < new TextArchive(RomInfo.itemNamesTextNumber).messages.Count)
- //{
- // return false;
- //}
+ if (itemScript.allScripts.Count - 1 < new TextArchive(RomInfo.itemNamesTextNumber).messages.Count)
+ {
+ return false;
+ }
- //for (ushort i = 0; i < itemScript.allScripts.Count - 1; i++)
- //{
- // if (BitConverter.ToUInt16(itemScript.allScripts[i].commands[0].Parameters[1].RawData, 0) != i || BitConverter.ToUInt16(itemScript.allScripts[i].commands[1].Parameters[1].RawData, 0) != 1)
- // {
- // return false;
- // }
- //}
+ for (ushort i = 0; i < itemScript.allScripts.Count - 1; i++)
+ {
+ if (BitConverter.ToUInt16(itemScript.allScripts[i].commands[0].cmdParams[1], 0) != i || BitConverter.ToUInt16(itemScript.allScripts[i].commands[1].cmdParams[1], 0) != 1)
+ {
+ return false;
+ }
+ }
return true;
}
@@ -590,12 +590,13 @@ namespace DSPRE
ScriptFile itemScriptFile = new ScriptFile(RomInfo.itemScriptFileNumber);
// Create map for: script no. -> vanilla item
- //int[] vanillaItemsArray = new int[itemScriptFile.allScripts.Count - 1];
- //
- //for (int i = 0; i < itemScriptFile.allScripts.Count - 1; i++)
- //{
- // vanillaItemsArray[i] = BitConverter.ToInt16(itemScriptFile.allScripts[i].commands[0].Parameters[1].RawData, 0);
- //};
+ int[] vanillaItemsArray = new int[itemScriptFile.allScripts.Count - 1];
+
+ for (int i = 0; i < itemScriptFile.allScripts.Count - 1; i++)
+ {
+ vanillaItemsArray[i] = BitConverter.ToInt16(itemScriptFile.allScripts[i].commands[0].cmdParams[1], 0);
+ }
+ ;
// Parse all event files and fix instances of ground items according to the new order
int cnt = Filesystem.GetEventFileCount();
@@ -617,7 +618,7 @@ namespace DSPRE
if (isItem)
{
int itemScriptID = eventFile.overworlds[j].scriptNumber - (itemScrMin - 1);
- //eventFile.overworlds[j].scriptNumber = (ushort)(itemScrMin + vanillaItemsArray[itemScriptID - 1]);
+ eventFile.overworlds[j].scriptNumber = (ushort)(itemScrMin + vanillaItemsArray[itemScriptID - 1]);
dirty = true;
}
}
@@ -644,29 +645,29 @@ namespace DSPRE
using (DSUtils.EasyWriter ewr = new DSUtils.EasyWriter(ow9path, ow9offs))
{
- //ewr.Write((ushort)(itemScrMin + vanillaItemsArray[itemScriptID - 1]));
+ ewr.Write((ushort)(itemScrMin + vanillaItemsArray[itemScriptID - 1]));
}
}
// Sort scripts in the Script File according to item indices
int itemCount = new TextArchive(RomInfo.itemNamesTextNumber).messages.Count;
- //ScriptCommandContainer executeGive = new ScriptCommandContainer((uint)itemCount + 1, itemScriptFile.allScripts[itemScriptFile.allScripts.Count - 1]);
+ ScriptCommandContainer executeGive = new ScriptCommandContainer((uint)itemCount + 1, itemScriptFile.allScripts[itemScriptFile.allScripts.Count - 1]);
- //itemScriptFile.allScripts.Clear();
+ itemScriptFile.allScripts.Clear();
- //for (ushort i = 0; i < itemCount; i++)
- //{
- // List cmdList = new List {
- // new ScriptCommand("SetVar 0x8008 " + i),
- // new ScriptCommand("SetVar 0x8009 0x1"),
- // new ScriptCommand("Jump Function_#1")
- // };
- //
- // itemScriptFile.allScripts.Add(new ScriptCommandContainer((ushort)(i + 1), ScriptFile.ContainerTypes.Script, commandList: cmdList));
- //}
- //
- //itemScriptFile.allScripts.Add(executeGive);
- //itemScriptFile.allFunctions[0].usedScriptID = itemCount + 1;
+ for (ushort i = 0; i < itemCount; i++)
+ {
+ List cmdList = new List {
+ new ScriptCommand("SetVar 0x8008 " + i),
+ new ScriptCommand("SetVar 0x8009 0x1"),
+ new ScriptCommand("Jump Function_#1")
+ };
+
+ itemScriptFile.allScripts.Add(new ScriptCommandContainer((ushort)(i + 1), ScriptFile.ContainerTypes.Script, commandList: cmdList));
+ }
+
+ itemScriptFile.allScripts.Add(executeGive);
+ itemScriptFile.allFunctions[0].usedScriptID = itemCount + 1;
itemScriptFile.SaveToFileDefaultDir(RomInfo.itemScriptFileNumber, showSuccessMessage: false);
MessageBox.Show("Operation successful.", "Process completed.", MessageBoxButtons.OK, MessageBoxIcon.Information);
diff --git a/DS_Map/Script/LevelScriptTrigger.cs b/DS_Map/ROMFiles/LevelScriptTrigger.cs
similarity index 100%
rename from DS_Map/Script/LevelScriptTrigger.cs
rename to DS_Map/ROMFiles/LevelScriptTrigger.cs
diff --git a/DS_Map/Script/MapScreenLoadTrigger.cs b/DS_Map/ROMFiles/MapScreenLoadTrigger.cs
similarity index 100%
rename from DS_Map/Script/MapScreenLoadTrigger.cs
rename to DS_Map/ROMFiles/MapScreenLoadTrigger.cs
diff --git a/DS_Map/Script/ScriptAction.cs b/DS_Map/ROMFiles/ScriptAction.cs
similarity index 100%
rename from DS_Map/Script/ScriptAction.cs
rename to DS_Map/ROMFiles/ScriptAction.cs
diff --git a/DS_Map/ROMFiles/ScriptActionContainer.cs b/DS_Map/ROMFiles/ScriptActionContainer.cs
new file mode 100644
index 0000000..ba3f414
--- /dev/null
+++ b/DS_Map/ROMFiles/ScriptActionContainer.cs
@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+
+namespace DSPRE.ROMFiles
+{
+ public class ScriptActionContainer
+ {
+ public List commands;
+ public uint manualUserID;
+
+ public ScriptActionContainer(uint actionNumber, List commands = null)
+ {
+ manualUserID = actionNumber;
+ this.commands = commands;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DS_Map/Script/ScriptCommand.cs b/DS_Map/ROMFiles/ScriptCommand.cs
similarity index 81%
rename from DS_Map/Script/ScriptCommand.cs
rename to DS_Map/ROMFiles/ScriptCommand.cs
index a21a23f..e176066 100644
--- a/DS_Map/Script/ScriptCommand.cs
+++ b/DS_Map/ROMFiles/ScriptCommand.cs
@@ -17,17 +17,18 @@ namespace DSPRE.ROMFiles {
OW_DIRECTION,
FUNCTION_ID,
ACTION_ID,
- CMD_NUMBER,
- LABEL_REF
+ CMD_NUMBER
};
public ushort? id;
- public List Parameters { get; set; } = new List();
+ public List cmdParams;
public string name;
// CHANGE: Update the constructor to use ScriptParameter
- public ScriptCommand(ushort id, List parameters) {
- if (parameters is null) {
+ public ScriptCommand(ushort id, List parametersList)
+ {
+ if (parametersList is null)
+ {
this.id = null;
return;
}
@@ -39,48 +40,48 @@ namespace DSPRE.ROMFiles {
switch (id) {
case 0x0016: // Jump
case 0x001A: // Call
- name += $" {FormatParameter(parameters[0], ParamTypeEnum.FUNCTION_ID)}";
+ name += $" {FormatNumber(parametersList[0], ParamTypeEnum.FUNCTION_ID)}";
break;
case 0x0017: // JumpIfObjID
case 0x0018: // JumpIfEventID
- name += $" {FormatParameter(parameters[0], ParamTypeEnum.OW_ID)} {FormatParameter(parameters[1])}";
+ name += $" {FormatNumber(parametersList[0], ParamTypeEnum.OW_ID)} {FormatNumber(parametersList[1])}";
break;
case 0x0019: // JumpIfPlayerDir
- name += $" {FormatParameter(parameters[0], ParamTypeEnum.OW_DIRECTION)} {FormatParameter(parameters[1], ParamTypeEnum.FUNCTION_ID)}";
+ name += $" {FormatNumber(parametersList[0], ParamTypeEnum.OW_DIRECTION)} {FormatNumber(parametersList[1], ParamTypeEnum.FUNCTION_ID)}";
break;
case 0x001C: // JumpIf
case 0x001D: // CallIf
{
- string number = FormatParameter(parameters[1], ParamTypeEnum.FUNCTION_ID);
+ string number = FormatNumber(parametersList[1], ParamTypeEnum.FUNCTION_ID);
// Access the byte value from the parameter's raw data
- if (RomInfo.ScriptComparisonOperatorsDict.TryGetValue(parameters[0].RawData[0], out string v)) {
+ if (RomInfo.ScriptComparisonOperatorsDict.TryGetValue(parametersList[0][0], out string v)) {
name += $" {v} {number}";
} else {
- name += $" {parameters[0].RawData[0]} {number}";
+ name += $" {parametersList[0][0]} {number}";
}
break;
}
case 0x005E: // Movement
- name += $" {FormatParameter(parameters[0], ParamTypeEnum.OW_ID)} {FormatParameter(parameters[1], ParamTypeEnum.ACTION_ID)}";
+ name += $" {FormatNumber(parametersList[0], ParamTypeEnum.OW_ID)} {FormatNumber(parametersList[1], ParamTypeEnum.ACTION_ID)}";
break;
case 0x006A: // GetOverworldPosition
- name += FormatCmd_Overworld_TwoParams(parameters);
+ name += FormatCmd_Overworld_TwoParams(parametersList);
break;
case 0x0062: // Lock
case 0x0063: // Release
case 0x0064: // AddOW
case 0x0065: // RemoveOW
- name += $" {FormatParameter(parameters[0], ParamTypeEnum.OW_ID)}";
+ name += $" {FormatNumber(parametersList[0], ParamTypeEnum.OW_ID)}";
break;
case 0x006D: // SetOverworldMovement
- name += FormatCmd_Overworld_Move(parameters);
+ name += FormatCmd_Overworld_Move(parametersList);
break;
case 0x00B0: // Warp [HGSS]
if (RomInfo.gameFamily.Equals(RomInfo.GameFamilies.HGSS)) {
- name += FormatCmd_Warp(parameters);
+ name += FormatCmd_Warp(parametersList);
} else {
goto default;
}
@@ -88,7 +89,7 @@ namespace DSPRE.ROMFiles {
break;
case 0x0152: // SetOverworldDefaultPosition [HGSS]
if (RomInfo.gameFamily.Equals(RomInfo.GameFamilies.HGSS)) {
- name += FormatCmd_Overworld_TwoParams(parameters);
+ name += FormatCmd_Overworld_TwoParams(parametersList);
} else {
goto default;
}
@@ -96,7 +97,7 @@ namespace DSPRE.ROMFiles {
break;
case 0x0153: // SetOverworldPosition [HGSS]
if (RomInfo.gameFamily.Equals(RomInfo.GameFamilies.HGSS)) {
- name += FormatCmd_Overworld_3Coords_Dir(parameters);
+ name += FormatCmd_Overworld_3Coords_Dir(parametersList);
} else {
goto default;
}
@@ -104,7 +105,7 @@ namespace DSPRE.ROMFiles {
break;
case 0x0154: // SetOverworldDefaultMovement [HGSS]
if (RomInfo.gameFamily.Equals(RomInfo.GameFamilies.HGSS)) {
- name += FormatCmd_Overworld_Move(parameters);
+ name += FormatCmd_Overworld_Move(parametersList);
} else {
goto default;
}
@@ -112,7 +113,7 @@ namespace DSPRE.ROMFiles {
break;
case 0x0155: // SetOverworldDefaultDirection [DPPt]
if (RomInfo.gameFamily.Equals(RomInfo.GameFamilies.HGSS)) {
- name += FormatCmd_Overworld_Dir(parameters);
+ name += FormatCmd_Overworld_Dir(parametersList);
} else {
goto default;
}
@@ -120,7 +121,7 @@ namespace DSPRE.ROMFiles {
break;
case 0x0158: // SetOverworldDirection [DPPt]
if (RomInfo.gameFamily.Equals(RomInfo.GameFamilies.HGSS)) {
- name += FormatCmd_Overworld_Dir(parameters);
+ name += FormatCmd_Overworld_Dir(parametersList);
} else {
goto default;
}
@@ -129,7 +130,7 @@ namespace DSPRE.ROMFiles {
case 0x00BE: // Warp [DPPt]
if (RomInfo.gameFamily.Equals(RomInfo.GameFamilies.DP) || RomInfo.gameFamily.Equals(RomInfo.GameFamilies.Plat)) {
- name += FormatCmd_Warp(parameters);
+ name += FormatCmd_Warp(parametersList);
} else {
goto default;
}
@@ -137,7 +138,7 @@ namespace DSPRE.ROMFiles {
break;
case 0x0186: // SetOverworldDefaultPosition [DPPt]
if (RomInfo.gameFamily.Equals(RomInfo.GameFamilies.DP) || RomInfo.gameFamily.Equals(RomInfo.GameFamilies.Plat)) {
- name += FormatCmd_Overworld_TwoParams(parameters);
+ name += FormatCmd_Overworld_TwoParams(parametersList);
} else {
goto default;
}
@@ -145,7 +146,7 @@ namespace DSPRE.ROMFiles {
break;
case 0x0187: // SetOverworldPosition [DPPt]
if (RomInfo.gameFamily.Equals(RomInfo.GameFamilies.DP) || RomInfo.gameFamily.Equals(RomInfo.GameFamilies.Plat)) {
- name += FormatCmd_Overworld_3Coords_Dir(parameters);
+ name += FormatCmd_Overworld_3Coords_Dir(parametersList);
} else {
goto default;
}
@@ -153,7 +154,7 @@ namespace DSPRE.ROMFiles {
break;
case 0x0188: // SetOverworldDefaultMovement [DPPt]
if (RomInfo.gameFamily.Equals(RomInfo.GameFamilies.DP) || RomInfo.gameFamily.Equals(RomInfo.GameFamilies.Plat)) {
- name += FormatCmd_Overworld_Move(parameters);
+ name += FormatCmd_Overworld_Move(parametersList);
} else {
goto default;
}
@@ -161,7 +162,7 @@ namespace DSPRE.ROMFiles {
break;
case 0x0189: // SetOverworldDefaultDirection [DPPt]
if (RomInfo.gameFamily.Equals(RomInfo.GameFamilies.DP) || RomInfo.gameFamily.Equals(RomInfo.GameFamilies.Plat)) {
- name += FormatCmd_Overworld_Dir(parameters);
+ name += FormatCmd_Overworld_Dir(parametersList);
} else {
goto default;
}
@@ -169,7 +170,7 @@ namespace DSPRE.ROMFiles {
break;
case 0x018C: // SetOverworldDirection [DPPt]
if (RomInfo.gameFamily.Equals(RomInfo.GameFamilies.DP) || RomInfo.gameFamily.Equals(RomInfo.GameFamilies.Plat)) {
- name += FormatCmd_Overworld_Dir(parameters);
+ name += FormatCmd_Overworld_Dir(parametersList);
} else {
goto default;
}
@@ -177,39 +178,39 @@ namespace DSPRE.ROMFiles {
break;
default:
- for (int i = 0; i < parameters.Count; i++) {
- name += $" {FormatParameter(parameters[i])}";
+ for (int i = 0; i < parametersList.Count; i++) {
+ name += $" {FormatNumber(parametersList[i])}";
}
break;
}
this.id = id;
- this.Parameters = parameters;
+ this.cmdParams = parametersList;
}
- private string FormatCmd_Warp(List parameters) {
- return $" {FormatParameter(parameters[0])} {FormatParameter(parameters[1])} {FormatParameter(parameters[2])} {FormatParameter(parameters[3])} {FormatParameter(parameters[4], ParamTypeEnum.OW_DIRECTION)}";
+ 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 parameters) {
- return $" {FormatParameter(parameters[0], ParamTypeEnum.OW_ID)} {FormatParameter(parameters[1])} {FormatParameter(parameters[2])}";
+ 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 parameters) {
- return $" {FormatParameter(parameters[0], ParamTypeEnum.OW_ID)} {FormatParameter(parameters[1], ParamTypeEnum.OW_MOVEMENT_TYPE)}";
+ 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 parameters) {
- return $" {FormatParameter(parameters[0], ParamTypeEnum.OW_ID)} {FormatParameter(parameters[1])} {FormatParameter(parameters[2])} {FormatParameter(parameters[3])} {FormatParameter(parameters[4], ParamTypeEnum.OW_DIRECTION)}";
+ 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 parameters) {
- return $" {FormatParameter(parameters[0], ParamTypeEnum.OW_ID)} {FormatParameter(parameters[1], 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;
- Parameters = new List();
+ cmdParams = new List();
string[] nameParts = wholeLine.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // Separate command code from parameters
/* Get command id, which is always first in the description */
@@ -244,7 +245,7 @@ namespace DSPRE.ROMFiles {
int firstParamValue = int.Parse(nameParts[1].PurgeSpecial(ScriptFile.specialChars), nameParts[1].GetNumberStyle());
byte firstParamSize = parametersSizeArr[1];
- Parameters.Add(new ScriptParameter(firstParamValue.ToByteArrayChooseSize(firstParamSize)));
+ cmdParams.Add(firstParamValue.ToByteArrayChooseSize(firstParamSize));
paramsProcessed++;
int i = 2;
@@ -306,8 +307,7 @@ namespace DSPRE.ROMFiles {
Console.WriteLine($"Parameter #{i}: {nameParts[i + 1]}");
if (RomInfo.ScriptComparisonOperatorsReverseDict.TryGetValue(nameParts[i + 1].ToLower(), out cmdID)) { //Check succeeds when command is like "asdfg LESS" or "asdfg DIFFERENT"
- // Create parameter with byte array
- Parameters.Add(new ScriptParameter(new byte[] { (byte)cmdID }));
+ cmdParams.Add(new byte[] { (byte)cmdID });
} else { //Not a comparison
/* Convert strings of parameters to the correct datatypes */
NumberStyles numStyle = nameParts[i + 1].GetNumberStyle();
@@ -316,16 +316,6 @@ namespace DSPRE.ROMFiles {
int result = 0;
try {
- // Check if this is a label reference
- if (nameParts[i + 1].StartsWith("label") || nameParts[i + 1].StartsWith("script")) {
- // This is a label reference
- ScriptParameter labelParam = new ScriptParameter(0, nameParts[i + 1]) {
- Type = ScriptParameter.ParameterType.RelativeJump
- };
- Parameters.Add(labelParam);
- continue;
- }
-
result = int.Parse(nameParts[i + 1], numStyle);
} catch {
if (string.IsNullOrWhiteSpace(nameParts[i + 1])) {
@@ -352,8 +342,7 @@ namespace DSPRE.ROMFiles {
}
try {
- byte[] paramData = result.ToByteArrayChooseSize(parametersSizeArr[i]);
- Parameters.Add(new ScriptParameter(paramData));
+ cmdParams.Add(result.ToByteArrayChooseSize(parametersSizeArr[i]));
} catch (OverflowException) {
MessageBox.Show($"Argument {nameParts[i + 1]} at line {lineNumber} is not in the range [0, {Math.Pow(2, 8 * parametersSizeArr[i]) - 1}].", "Argument error", MessageBoxButtons.OK, MessageBoxIcon.Error);
id = null;
@@ -369,10 +358,6 @@ namespace DSPRE.ROMFiles {
}
private string FormatNumber(byte[] par, ParamTypeEnum paramType = ParamTypeEnum.INTEGER) {
- if (paramType == ParamTypeEnum.LABEL_REF && par.Length > 0) {
- return FormatLabelReference(Encoding.ASCII.GetString(par));
- }
-
//number acquisition
uint num;
if (par.Length == 0) {
@@ -409,6 +394,9 @@ namespace DSPRE.ROMFiles {
case ParamTypeEnum.CMD_NUMBER:
return "CMD_" + prefix + num.ToString(formatOverride + '3');
+ case ParamTypeEnum.FUNCTION_ID:
+ return ScriptFile.ContainerTypes.Function.ToString() + "#" + num;
+
case ParamTypeEnum.ACTION_ID:
return ScriptFile.ContainerTypes.Action.ToString() + "#" + num;
diff --git a/DS_Map/ROMFiles/ScriptCommandContainer.cs b/DS_Map/ROMFiles/ScriptCommandContainer.cs
new file mode 100644
index 0000000..3b1793e
--- /dev/null
+++ b/DS_Map/ROMFiles/ScriptCommandContainer.cs
@@ -0,0 +1,29 @@
+using System.Collections.Generic;
+
+namespace DSPRE.ROMFiles
+{
+ public class ScriptCommandContainer
+ {
+ public List commands;
+ public uint manualUserID;
+ public int usedScriptID; //useScript ID referenced by this Script/Function
+ public ScriptFile.ContainerTypes containerType;
+ internal static readonly string functionStart;
+
+ public ScriptCommandContainer(uint scriptNumber, ScriptFile.ContainerTypes containerType, int usedScriptID = -1, List commandList = null)
+ {
+ manualUserID = scriptNumber;
+ this.usedScriptID = usedScriptID;
+ this.containerType = containerType;
+ commands = commandList;
+ }
+
+ public ScriptCommandContainer(uint newID, ScriptCommandContainer toCopy)
+ {
+ manualUserID = newID;
+ usedScriptID = toCopy.usedScriptID;
+ containerType = toCopy.containerType;
+ commands = new List(toCopy.commands); //command parameters need to be copied recursively
+ }
+ }
+}
\ No newline at end of file
diff --git a/DS_Map/ROMFiles/ScriptFile.cs b/DS_Map/ROMFiles/ScriptFile.cs
index 8f2d633..22a445c 100644
--- a/DS_Map/ROMFiles/ScriptFile.cs
+++ b/DS_Map/ROMFiles/ScriptFile.cs
@@ -1,3 +1,4 @@
+using DSPRE.Resources;
using System;
using System.Collections.Generic;
using System.IO;
@@ -13,13 +14,11 @@ namespace DSPRE.ROMFiles
///
public class ScriptFile : RomFile
{
- public List CommandSequence { get; set; } = new List();
- public Dictionary OffsetToLabelMap { get; set; } = new Dictionary();
public enum ContainerTypes
{
+ Function,
Action,
- Script,
- Label
+ Script
};
public struct ContainerReference
@@ -28,28 +27,29 @@ namespace DSPRE.ROMFiles
public uint offsetInFile;
}
+ public List allScripts = new List();
+ public List allFunctions = new List();
+ public List allActions = new List();
public int fileID = -1;
public bool isLevelScript = new bool();
- public bool HasNoScripts { get { return fileID == int.MaxValue; } }
+ public bool hasNoScripts { get { return fileID == int.MaxValue; } }
public static readonly char[] specialChars = { 'x', 'X', '#', '.', '_' };
- public ScriptFile(Stream fs)
+ public ScriptFile(Stream fs, bool readFunctions = true, bool readActions = true)
{
- // Initialize collections
- CommandSequence = new List();
- OffsetToLabelMap = new Dictionary();
+ List scriptOffsets = new List();
+ List functionOffsets = new List();
+ List movementOffsets = new List();
using (BinaryReader br = new BinaryReader(fs))
{
- // Read header to find entry points
- List entryPointOffsets = new List();
- isLevelScript = true; // Is Level Script until proved otherwise
+ /* Read script offsets from the header */
+ isLevelScript = true; // Is Level Script as long as magic number FD13 doesn't exist
try
{
- int entryPointIndex = 0;
while (true)
{
long headerPos = br.BaseStream.Position;
@@ -57,7 +57,7 @@ namespace DSPRE.ROMFiles
br.BaseStream.Position -= 0x2;
uint value = br.ReadUInt32();
- if (value == 0 && entryPointOffsets.Count == 0)
+ if (value == 0 && scriptOffsets.Count == 0)
{
isLevelScript = true;
break;
@@ -70,13 +70,8 @@ namespace DSPRE.ROMFiles
break;
}
- int offsetFromStart = (int)(value + headerPos + 4);
- entryPointOffsets.Add(offsetFromStart);
-
- // Create entry point label
- string entryLabel = $"script_{entryPointIndex}";
- OffsetToLabelMap[offsetFromStart] = entryLabel;
- entryPointIndex++;
+ int offsetFromStart = (int)(value + br.BaseStream.Position); // Don't change order of addition
+ scriptOffsets.Add(offsetFromStart);
}
}
catch (EndOfStreamException)
@@ -94,488 +89,673 @@ namespace DSPRE.ROMFiles
// Skip the 0xFD13 marker
br.ReadUInt16();
-
- // Process commands until end of file
- while (br.BaseStream.Position < br.BaseStream.Length)
+ /* Read scripts */
+ for (uint current = 0; current < scriptOffsets.Count; current++)
{
- int currentOffset = (int)br.BaseStream.Position;
+ int index = scriptOffsets.FindIndex(x => x == scriptOffsets[(int)current]); // Check for UseScript
- // Sometimes we might hit padding bytes - try to detect and skip
- if (br.BaseStream.Position + 2 <= br.BaseStream.Length)
+ if (index == current)
{
- byte[] peekBytes = br.ReadBytes(2);
- br.BaseStream.Position -= 2;
+ br.BaseStream.Position = scriptOffsets[(int)current];
- // Check if these look like padding
- if (peekBytes[0] == 0 && peekBytes[1] == 0)
+ List cmdList = new List();
+ bool endScript = new bool();
+ while (!endScript)
{
- // Skip padding byte
- br.ReadByte();
- continue;
+ ScriptCommand cmd = ReadCommand(br, ref functionOffsets, ref movementOffsets);
+ if (cmd.cmdParams is null)
+ {
+ return;
+ }
+
+ cmdList.Add(cmd);
+
+ if (ScriptDatabase.endCodes.Contains((ushort)cmd.id))
+ {
+ endScript = true;
+ }
+ }
+
+ allScripts.Add(new ScriptCommandContainer(current + 1, ContainerTypes.Script, commandList: cmdList));
+ }
+ else
+ {
+ allScripts.Add(new ScriptCommandContainer(current + 1, ContainerTypes.Script, usedScriptID: index + 1));
+ }
+ }
+
+ /* Read functions */
+ if (readFunctions)
+ {
+ for (uint current = 0; current < functionOffsets.Count; current++)
+ {
+ br.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(br, ref functionOffsets, ref movementOffsets);
+ if (command.cmdParams is null)
+ {
+ return;
+ }
+
+ cmdList.Add(command);
+ if (ScriptDatabase.endCodes.Contains((ushort)command.id))
+ {
+ endFunction = true;
+ }
+ }
+
+ allFunctions.Add(new ScriptCommandContainer(current + 1, ContainerTypes.Function, commandList: cmdList));
+ }
+ else
+ {
+ allFunctions.Add(new ScriptCommandContainer(current + 1, ContainerTypes.Function, usedScriptID: posInList + 1));
}
}
+ }
- ScriptCommand cmd = ReadCommand(br);
- if (cmd == null || cmd.id == null)
+ if (readActions)
+ {
+ /* Read movements */
+ for (uint current = 0; current < movementOffsets.Count; current++)
{
- break; // End of file or error
- }
+ br.BaseStream.Position = movementOffsets[(int)current];
- // Check if this is an entry point or jump target
- bool isEntryPoint = false;
- int entryPointIndex = -1;
- string label = null;
-
- if (OffsetToLabelMap.TryGetValue(currentOffset, out string existingLabel))
- {
- label = existingLabel;
- isEntryPoint = existingLabel.StartsWith("script_");
- if (isEntryPoint)
+ List cmdList = new List();
+ bool endMovement = new bool();
+ while (!endMovement)
{
- entryPointIndex = int.Parse(existingLabel.Substring("script_".Length));
+ ushort id = br.ReadUInt16();
+ if (id == 0xFE)
+ {
+ endMovement = true;
+ cmdList.Add(new ScriptAction(id, 0));
+ }
+ else
+ {
+ cmdList.Add(new ScriptAction(id, br.ReadUInt16()));
+ }
}
- }
- // Add to command sequence
- CommandSequence.Add(new ScriptCommandPosition(
- cmd, currentOffset, label, isEntryPoint, entryPointIndex));
+ allActions.Add(new ScriptActionContainer(current + 1, commands: cmdList));
+ }
}
}
}
- public ScriptFile(int fileID) : this(getFileStream(fileID))
+ public ScriptFile(int fileID, bool readFunctions = true, bool readActions = true) : this(getFileStream(fileID), readFunctions, readActions)
{
this.fileID = fileID;
}
- public static FileStream getFileStream(int fileID)
+ static FileStream getFileStream(int fileID)
{
string path = Filesystem.GetScriptPath(fileID);
return new FileStream(path, FileMode.OpenOrCreate);
}
-
public override string ToString()
{
string prefix = isLevelScript ? "Level " : "";
return $"{prefix}Script File " + this.fileID;
}
- public ScriptFile(IEnumerable lines, int fileID = -1)
+ public ScriptFile(List scripts, List functions, List movements, int fileID = -1)
{
- CommandSequence = new List();
- OffsetToLabelMap = new Dictionary();
- this.fileID = fileID;
+ allScripts = scripts;
+ allFunctions = functions;
+ allActions = movements;
+ isLevelScript = false;
+ }
- int currentOffset = 0;
- string currentLabel = null;
- int entryPointIndex = 0;
- bool isCurrentLabelEntryPoint = false; // Track this instead
-
- // Parse each line
- foreach (var line in lines)
+ public ScriptFile(IEnumerable scriptLines, IEnumerable functionLines, IEnumerable actionLines, int fileID = -1)
+ {
+ //TODO: give user the possibility to jump to/call a script
+ //once it's done, this Predicate below will be the only one needed, since there will be no distinction between
+ //a script and a function
+ bool functionEndCondition(List<(int linenum, string text)> source, int x, ushort? id)
{
- string trimmedLine = line.Trim();
+ return source[x].text.TrimEnd().IgnoreCaseEquals(RomInfo.ScriptCommandNamesDict[0x0002]) //End
+ || source[x].text.IndexOf(RomInfo.ScriptCommandNamesDict[0x0016] + ' ' + ContainerTypes.Function.ToString(), StringComparison.InvariantCultureIgnoreCase) >= 0 //Jump Function_#
+ || source[x].text.TrimEnd().IgnoreCaseEquals(RomInfo.ScriptCommandNamesDict[0x001B])
+ || ScriptDatabase.endCodes.Contains(id);
+ } //Return
- // Skip empty lines
- if (string.IsNullOrWhiteSpace(trimmedLine))
+ bool scriptEndCondition(List<(int linenum, string text)> source, int x, ushort? id)
+ {
+ return source[x].text.TrimEnd().IgnoreCaseEquals(RomInfo.ScriptCommandNamesDict[0x0002]) //End
+ || source[x].text.IndexOf(RomInfo.ScriptCommandNamesDict[0x0016] + ' ' + ContainerTypes.Function.ToString()) >= 0 //Jump Function_#
+ || ScriptDatabase.endCodes.Contains(id);
+ }
+
+ allScripts = ReadCommandsFromLines(scriptLines.ToList(), ContainerTypes.Script, scriptEndCondition); //Jump + whitespace
+ if (allScripts is null)
+ {
+ return;
+ }
+
+ if (allScripts.Count <= 0)
+ {
+ this.fileID = int.MaxValue;
+ return;
+ }
+
+ if (functionLines != null)
+ {
+ allFunctions = ReadCommandsFromLines(functionLines.ToList(), ContainerTypes.Function, functionEndCondition); //Jump + whitespace
+ if (allFunctions is null)
{
- continue;
+ return;
}
+ }
- // Check if this is a label
- if (trimmedLine.EndsWith(":"))
+ if (actionLines != null)
+ {
+ allActions = ReadActionsFromLines(actionLines.ToList());
+ if (allActions is null)
{
- currentLabel = trimmedLine.Substring(0, trimmedLine.Length - 1);
+ return;
+ }
+ }
- // Track if it's an entry point
- isCurrentLabelEntryPoint = currentLabel.StartsWith("script_");
- if (isCurrentLabelEntryPoint)
+ this.fileID = fileID;
+ }
+
+ private ScriptCommand ReadCommand(BinaryReader dataReader, ref List functionOffsets, ref List actionOffsets)
+ {
+ ushort id = dataReader.ReadUInt16();
+ List parameterList = new List();
+
+ /* How to read parameters for different commands for DPPt*/
+ switch (RomInfo.gameFamily)
+ {
+ case GameFamilies.DP:
+ case GameFamilies.Plat:
+ switch (id)
{
- if (int.TryParse(currentLabel.Substring("script_".Length), out int index))
- {
- entryPointIndex = index;
- }
+ case 0x16: //Jump
+ case 0x1A: //Call
+ ProcessRelativeJump(dataReader, ref parameterList, ref functionOffsets);
+ break;
+ case 0x17: //JumpIfObjID
+ case 0x18: //JumpIfBgID
+ case 0x19: //JumpIfPlayerDir
+ case 0x1C: //JumpIf
+ case 0x1D: //CallIf
+ //in the case of JumpIf and CallIf, the first param is a comparisonOperator
+ //for JumpIfPlayerDir it's a directionID
+ //for JumpIfObjID, it's an EventID
+ parameterList.Add(new byte[] { dataReader.ReadByte() });
+ ProcessRelativeJump(dataReader, ref parameterList, ref functionOffsets);
+ break;
+ case 0x5E: // Movement
+ parameterList.Add(BitConverter.GetBytes(dataReader.ReadUInt16()));
+ ProcessRelativeJump(dataReader, ref parameterList, ref actionOffsets);
+ break;
+ case 0x1CF:
+ case 0x1D0:
+ case 0x1D1:
+ {
+ byte parameter1 = dataReader.ReadByte();
+ parameterList.Add(new byte[] { parameter1 });
+ if (parameter1 == 0x2)
+ {
+ parameterList.Add(dataReader.ReadBytes(2)); //Read additional u16 if first param read is 2
+ }
+ }
+ break;
+ case 0x21D:
+ {
+ ushort parameter1 = dataReader.ReadUInt16();
+ parameterList.Add(BitConverter.GetBytes(parameter1));
+
+ switch (parameter1)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ parameterList.Add(dataReader.ReadBytes(2));
+ parameterList.Add(dataReader.ReadBytes(2));
+ break;
+ case 4:
+ case 5:
+ parameterList.Add(dataReader.ReadBytes(2));
+ break;
+ case 6:
+ break;
+ }
+ }
+ break;
+ case 0x235:
+ {
+ short parameter1 = dataReader.ReadInt16();
+ parameterList.Add(BitConverter.GetBytes(parameter1));
+
+ switch (parameter1)
+ {
+ case 0x1:
+ case 0x3:
+ parameterList.Add(dataReader.ReadBytes(2));
+ parameterList.Add(dataReader.ReadBytes(2));
+ parameterList.Add(dataReader.ReadBytes(2));
+ break;
+ case 0x4:
+ parameterList.Add(dataReader.ReadBytes(2));
+ parameterList.Add(dataReader.ReadBytes(2));
+ break;
+ case 0x0:
+ case 0x6:
+ parameterList.Add(dataReader.ReadBytes(2));
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case 0x23E:
+ {
+ short parameter1 = dataReader.ReadInt16();
+ parameterList.Add(BitConverter.GetBytes(parameter1));
+
+ switch (parameter1)
+ {
+ case 0x1:
+ case 0x3:
+ parameterList.Add(dataReader.ReadBytes(2));
+ break;
+ case 0x5:
+ case 0x6:
+ parameterList.Add(dataReader.ReadBytes(2));
+ parameterList.Add(dataReader.ReadBytes(2));
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case 0x2C4:
+ {
+ byte parameter1 = dataReader.ReadByte();
+ parameterList.Add(new byte[] { parameter1 });
+ if (parameter1 == 0 || parameter1 == 1)
+ {
+ parameterList.Add(dataReader.ReadBytes(2));
+ }
+ }
+ break;
+ case 0x2C5:
+ {
+ if (RomInfo.gameVersion == GameVersions.Platinum)
+ {
+ parameterList.Add(dataReader.ReadBytes(2));
+ parameterList.Add(dataReader.ReadBytes(2));
+ }
+ else
+ {
+ goto default;
+ }
+ }
+ break;
+ case 0x2C6:
+ case 0x2C9:
+ case 0x2CA:
+ case 0x2CD:
+ if (RomInfo.gameVersion == GameVersions.Platinum)
+ {
+ break;
+ }
+ else
+ {
+ goto default;
+ }
+ case 0x2CF:
+ if (RomInfo.gameVersion == GameVersions.Platinum)
+ {
+ parameterList.Add(dataReader.ReadBytes(2));
+ parameterList.Add(dataReader.ReadBytes(2));
+ }
+ else
+ {
+ goto default;
+ }
+
+ break;
+ default:
+ addParametersToList(ref parameterList, id, dataReader);
+ break;
}
- continue;
- }
+ break;
+ case GameFamilies.HGSS:
+ switch (id)
+ {
+ case 0x16: //Jump
+ case 0x1A: //Call
+ ProcessRelativeJump(dataReader, ref parameterList, ref functionOffsets);
+ break;
+ case 0x17: //JumpIfObjID
+ case 0x18: //JumpIfBgID
+ case 0x19: //JumpIfPlayerDir
+ case 0x1C: //JumpIf
+ case 0x1D: //CallIf
+ parameterList.Add(new byte[] { dataReader.ReadByte() }); //in the case of JumpIf and CallIf, the first param is a comparisonOperator
+ ProcessRelativeJump(dataReader, ref parameterList, ref functionOffsets);
+ break;
+ case 0x5E: // Movement
+ parameterList.Add(BitConverter.GetBytes(dataReader.ReadUInt16())); //in the case of Movement, the first param is an overworld ID
+ ProcessRelativeJump(dataReader, ref parameterList, ref actionOffsets);
+ break;
+ case 0x190:
+ case 0x191:
+ case 0x192:
+ {
+ byte parameter1 = dataReader.ReadByte();
+ parameterList.Add(new byte[] { parameter1 });
+ if (parameter1 == 0x2)
+ {
+ parameterList.Add(dataReader.ReadBytes(2));
+ }
+ }
+ break;
+ case 0x1D1: // Number of parameters differ depending on the first parameter value
+ {
+ short parameter1 = dataReader.ReadInt16();
+ parameterList.Add(BitConverter.GetBytes(parameter1));
+ switch (parameter1)
+ {
+ case 0x0:
+ case 0x1:
+ case 0x2:
+ case 0x3:
+ parameterList.Add(dataReader.ReadBytes(2));
+ parameterList.Add(dataReader.ReadBytes(2));
+ break;
+ case 0x4:
+ case 0x5:
+ parameterList.Add(dataReader.ReadBytes(2));
+ break;
+ case 0x6:
+ break;
+ case 0x7:
+ parameterList.Add(dataReader.ReadBytes(2));
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case 0x1E9: // Number of parameters differ depending on the first parameter value
+ {
+ short parameter1 = dataReader.ReadInt16();
+ parameterList.Add(BitConverter.GetBytes(parameter1));
+ switch (parameter1)
+ {
+ case 0x0:
+ break;
+ case 0x1:
+ case 0x2:
+ case 0x3:
+ parameterList.Add(dataReader.ReadBytes(2));
+ break;
+ case 0x4:
+ break;
+ case 0x5:
+ case 0x6:
+ parameterList.Add(dataReader.ReadBytes(2));
+ parameterList.Add(dataReader.ReadBytes(2));
+ break;
+ case 0x7:
+ case 0x8:
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ default:
+ addParametersToList(ref parameterList, id, dataReader);
+ break;
+ }
- // Parse the command
- ScriptCommand cmd = new ScriptCommand(trimmedLine);
- if (cmd.id == null)
+ break;
+ }
+
+ return new ScriptCommand(id, parameterList);
+ }
+
+ private void ProcessRelativeJump(BinaryReader dataReader, ref List parameterList, ref List offsetsList)
+ {
+ int relativeOffset = dataReader.ReadInt32();
+ int offsetFromScriptFileStart = (int)(relativeOffset + dataReader.BaseStream.Position);
+
+ if (!offsetsList.Contains(offsetFromScriptFileStart))
+ {
+ offsetsList.Add(offsetFromScriptFileStart);
+ }
+
+ int functionNumber = offsetsList.IndexOf(offsetFromScriptFileStart);
+ if (functionNumber < 0)
+ {
+ throw new InvalidOperationException();
+ }
+
+ parameterList.Add(BitConverter.GetBytes(functionNumber + 1));
+ }
+
+ private void addParametersToList(ref List parameterList, ushort id, BinaryReader dataReader)
+ {
+ Console.WriteLine("Loaded command id: " + id.ToString("X4"));
+ try
+ {
+ foreach (int bytesToRead in RomInfo.ScriptCommandParametersDict[id])
{
- continue; // Skip invalid commands
+ parameterList.Add(dataReader.ReadBytes(bytesToRead));
}
-
- // Calculate the size of this command for offset tracking
- int cmdSize = 2; // Command ID (2 bytes)
- foreach (var param in cmd.Parameters)
- {
- cmdSize += param.RawData.Length;
- }
-
- // Use the tracked entry point flag
- int epIndex = isCurrentLabelEntryPoint ? entryPointIndex : -1;
-
- CommandSequence.Add(new ScriptCommandPosition(
- cmd, currentOffset, currentLabel, isCurrentLabelEntryPoint, epIndex));
-
- // Map the offset to the label for jump targets
- if (currentLabel != null)
- {
- OffsetToLabelMap[currentOffset] = currentLabel;
- currentLabel = null; // Reset label
- isCurrentLabelEntryPoint = false; // Reset entry point flag
- }
-
- // Update offset for next command
- currentOffset += cmdSize;
+ }
+ catch (NullReferenceException)
+ {
+ MessageBox.Show("Script command " + id + "can't be handled for now." +
+ Environment.NewLine + "Reference offset 0x" + dataReader.BaseStream.Position.ToString("X"), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ parameterList = null;
+ return;
+ }
+ catch
+ {
+ MessageBox.Show("Error: ID Read - " + id +
+ Environment.NewLine + "Reference offset 0x" + dataReader.BaseStream.Position.ToString("X"), "Unrecognized script command", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ parameterList = null;
+ return;
}
}
- private ScriptCommand ReadCommand(BinaryReader br)
+ private void AddReference(ref List references, ushort commandID, List parameterList, int pos, ScriptCommandContainer cont)
{
- // Check if we've reached the end of the file
- if (br.BaseStream.Position >= br.BaseStream.Length)
+ if (ScriptDatabase.commandsWithRelativeJump.TryGetValue(commandID, out int parameterWithRelativeJump))
{
- return null;
+ uint invokedID = BitConverter.ToUInt32(parameterList[parameterWithRelativeJump], 0); // Jump, Call
+
+ if (commandID == 0x005E)
+ references.Add(new ScriptReference(cont.containerType, cont.manualUserID, ContainerTypes.Action, invokedID, pos - 4));
+ else
+ {
+ references.Add(new ScriptReference(cont.containerType, cont.manualUserID, ContainerTypes.Function, invokedID, pos - 4));
+ }
}
+ }
+
+ private List ReadCommandsFromLines(List linelist, ContainerTypes containerType, Func, int, ushort?, bool> endConditions)
+ {
+ List<(int linenum, string text)> lineSource = new List<(int linenum, string text)>();
+
+ for (int l = 0; l < linelist.Count; l++)
+ {
+ string cur = linelist[l];
+ if (!string.IsNullOrWhiteSpace(cur))
+ {
+ lineSource.Add((l, cur));
+ }
+ }
+
+ List ls = new List();
+ int i = 0;
try
{
- ushort id = br.ReadUInt16();
- List parameters = new List();
+ uint scriptNumber = 0;
- // Track the original position for jump calculations
- long commandStartPos = br.BaseStream.Position - 2;
-
- switch (gameFamily)
+ while (i < lineSource.Count)
{
- case GameFamilies.Plat:
- switch (id)
+ if (scriptNumber == 0)
+ {
+ int positionOfScriptNumber;
+ int positionOfScriptKeyword = lineSource[i].text.IndexOf(containerType.ToString(), StringComparison.InvariantCultureIgnoreCase);
+
+ if (positionOfScriptKeyword > 0)
{
- case 0x16: // Jump
- case 0x1A: // Call
- ProcessRelativeJumpLinear(br, parameters);
- break;
-
- case 0x17: // JumpIfObjID
- case 0x18: // JumpIfEventID
- case 0x19: // JumpIfPlayerDir
- case 0x1C: // JumpIf
- case 0x1D: // CallIf
- // First parameter (condition)
- parameters.Add(new ScriptParameter(new byte[] { br.ReadByte() }));
- // Then jump target
- ProcessRelativeJumpLinear(br, parameters);
- break;
-
- case 0x5E: // Movement
- parameters.Add(new ScriptParameter(BitConverter.GetBytes(br.ReadUInt16())));
- ProcessRelativeJumpLinear(br, parameters);
- break;
-
- case 0x1CF:
- case 0x1D0:
- case 0x1D1:
- {
- byte parameter1 = br.ReadByte();
- parameters.Add(new ScriptParameter(new byte[] { parameter1 }));
- if (parameter1 == 0x2)
- {
- parameters.Add(new ScriptParameter(br.ReadBytes(2))); //Read additional u16 if first param read is 2
- }
- }
- break;
- case 0x21D:
- {
- ushort parameter1 = br.ReadUInt16();
- parameters.Add(new ScriptParameter(BitConverter.GetBytes(parameter1)));
-
- switch (parameter1)
- {
- case 0:
- case 1:
- case 2:
- case 3:
- parameters.Add(new ScriptParameter(br.ReadBytes(2)));
- parameters.Add(new ScriptParameter(br.ReadBytes(2)));
- break;
- case 4:
- case 5:
- parameters.Add(new ScriptParameter(br.ReadBytes(2)));
- break;
- case 6:
- break;
- }
- }
- break;
- case 0x235:
- {
- short parameter1 = br.ReadInt16();
- parameters.Add(new ScriptParameter(BitConverter.GetBytes(parameter1)));
-
- switch (parameter1)
- {
- case 0x1:
- case 0x3:
- parameters.Add(new ScriptParameter(br.ReadBytes(2)));
- parameters.Add(new ScriptParameter(br.ReadBytes(2)));
- parameters.Add(new ScriptParameter(br.ReadBytes(2)));
- break;
- case 0x4:
- parameters.Add(new ScriptParameter(br.ReadBytes(2)));
- parameters.Add(new ScriptParameter(br.ReadBytes(2)));
- break;
- case 0x0:
- case 0x6:
- parameters.Add(new ScriptParameter(br.ReadBytes(2)));
- break;
- default:
- break;
- }
- }
- break;
- case 0x23E:
- {
- short parameter1 = br.ReadInt16();
- parameters.Add(new ScriptParameter(BitConverter.GetBytes(parameter1)));
-
- switch (parameter1)
- {
- case 0x1:
- case 0x3:
- parameters.Add(new ScriptParameter(br.ReadBytes(2)));
- break;
- case 0x5:
- case 0x6:
- parameters.Add(new ScriptParameter(br.ReadBytes(2)));
- parameters.Add(new ScriptParameter(br.ReadBytes(2)));
- break;
- default:
- break;
- }
- }
- break;
- case 0x2C4:
- {
- byte parameter1 = br.ReadByte();
- parameters.Add(new ScriptParameter(new byte[] { parameter1 }));
- if (parameter1 == 0 || parameter1 == 1)
- {
- parameters.Add(new ScriptParameter(br.ReadBytes(2)));
- }
- }
- break;
- case 0x2C5:
- {
- if (RomInfo.gameVersion == GameVersions.Platinum)
- {
- parameters.Add(new ScriptParameter(br.ReadBytes(2)));
- parameters.Add(new ScriptParameter(br.ReadBytes(2)));
- }
- else
- {
- goto default;
- }
- }
- break;
- case 0x2C6:
- case 0x2C9:
- case 0x2CA:
- case 0x2CD:
- if (RomInfo.gameVersion == GameVersions.Platinum)
- {
- break;
- }
- else
- {
- goto default;
- }
- case 0x2CF:
- if (RomInfo.gameVersion == GameVersions.Platinum)
- {
- parameters.Add(new ScriptParameter(br.ReadBytes(2)));
- parameters.Add(new ScriptParameter(br.ReadBytes(2)));
- }
- else
- {
- goto default;
- }
-
- break;
- default:
- // Standard command handling
- if (RomInfo.ScriptCommandParametersDict.TryGetValue(id, out byte[] paramSizes))
- {
- foreach (int size in paramSizes)
- {
- parameters.Add(new ScriptParameter(br.ReadBytes(size)));
- }
- }
- break;
+ MessageBox.Show("Unrecognized container keyword: \"" + lineSource[i] + '"', "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ return null;
}
- break;
-
- case GameFamilies.HGSS:
- switch (id)
+ else if (positionOfScriptKeyword < 0)
{
- case 0x16: //Jump
- case 0x1A: //Call
- ProcessRelativeJumpLinear(br, parameters);
- break;
-
- case 0x17: //JumpIfObjID
- case 0x18: //JumpIfBgID
- case 0x19: //JumpIfPlayerDir
- case 0x1C: //JumpIf
- case 0x1D: //CallIf
- parameters.Add(new ScriptParameter(new byte[] { br.ReadByte() })); //in the case of JumpIf and CallIf, the first param is a comparisonOperator
- ProcessRelativeJumpLinear(br, parameters);
- break;
-
- case 0x5E: // Movement
- parameters.Add(new ScriptParameter(BitConverter.GetBytes(br.ReadUInt16()))); //in the case of Movement, the first param is an overworld ID
- ProcessRelativeJumpLinear(br, parameters);
- break;
-
- case 0x190:
- case 0x191:
- case 0x192:
- {
- byte parameter1 = br.ReadByte();
- parameters.Add(new ScriptParameter(new byte[] { parameter1 }));
- if (parameter1 == 0x2)
- {
- parameters.Add(new ScriptParameter(br.ReadBytes(2)));
- }
- }
- break;
-
- case 0x1D1: // Number of parameters differ depending on the first parameter value
- {
- short parameter1 = br.ReadInt16();
- parameters.Add(new ScriptParameter(BitConverter.GetBytes(parameter1)));
- switch (parameter1)
- {
- case 0x0:
- case 0x1:
- case 0x2:
- case 0x3:
- parameters.Add(new ScriptParameter(br.ReadBytes(2)));
- parameters.Add(new ScriptParameter(br.ReadBytes(2)));
- break;
- case 0x4:
- case 0x5:
- parameters.Add(new ScriptParameter(br.ReadBytes(2)));
- break;
- case 0x6:
- break;
- case 0x7:
- parameters.Add(new ScriptParameter(br.ReadBytes(2)));
- break;
- default:
- break;
- }
- }
- break;
-
- case 0x1E9: // Number of parameters differ depending on the first parameter value
- {
- short parameter1 = br.ReadInt16();
- parameters.Add(new ScriptParameter(BitConverter.GetBytes(parameter1)));
- switch (parameter1)
- {
- case 0x0:
- break;
- case 0x1:
- case 0x2:
- case 0x3:
- parameters.Add(new ScriptParameter(br.ReadBytes(2)));
- break;
- case 0x4:
- break;
- case 0x5:
- case 0x6:
- parameters.Add(new ScriptParameter(br.ReadBytes(2)));
- parameters.Add(new ScriptParameter(br.ReadBytes(2)));
- break;
- case 0x7:
- case 0x8:
- break;
- default:
- break;
- }
- }
- break;
-
- default:
- // For standard commands, read parameters based on definition
- if (RomInfo.ScriptCommandParametersDict.TryGetValue(id, out byte[] paramSizes))
- {
- foreach (int size in paramSizes)
- {
- parameters.Add(new ScriptParameter(br.ReadBytes(size)));
- }
- }
- break;
+ i++;
+ continue;
+ }
+ else
+ {
+ if ((positionOfScriptNumber = lineSource[i].text.IndexOfFirstNumber()) < positionOfScriptKeyword)
+ {
+ MessageBox.Show("Unspecified Script/Function label.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ return null;
+ }
}
- break;
+ scriptNumber = uint.Parse(lineSource[i++].text.Substring(positionOfScriptNumber).Split()[0].Replace(":", ""));
+ }
+
+ if (lineSource[i].text.IndexOf("UseScript", StringComparison.InvariantCultureIgnoreCase) >= 0)
+ {
+ int useScriptNumber = short.Parse(lineSource[i].text.Substring(1 + lineSource[i].text.IndexOf('#')));
+ ls.Add(new ScriptCommandContainer(scriptNumber, containerType, useScriptNumber));
+ i++;
+ }
+ else
+ {
+ /* Read script commands */
+ List cmdList = new List();
+ ScriptCommand lastRead;
+
+ do
+ {
+ lastRead = new ScriptCommand(lineSource[i].text, lineSource[i].linenum + 1);
+ if (lastRead.id is null)
+ {
+ return null;
+ }
+
+ cmdList.Add(lastRead);
+ }
+ while (!endConditions(lineSource, i++, lastRead.id));
+
+ ls.Add(new ScriptCommandContainer(scriptNumber, containerType, commandList: cmdList));
+ }
+
+ scriptNumber = 0;
}
-
- return new ScriptCommand(id, parameters);
}
- catch (Exception ex)
+ catch (ArgumentOutOfRangeException)
{
- Console.WriteLine($"Error reading command at offset {br.BaseStream.Position}: {ex.Message}");
+ MessageBox.Show($"Unexpectedly reached end of lines.\n\n" +
+ $"Last line index: {lineSource[i].linenum}.\n" +
+ $"Managed to parse {ls.Count} Command Containers.", "Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
+
+ return ls;
}
- private void ProcessRelativeJumpLinear(BinaryReader br, List parameters)
+ private List ReadActionsFromLines(List linelist)
{
- // Read the relative offset
- int relativeOffset = br.ReadInt32();
+ List<(int linenum, string text)> lineSource = new List<(int linenum, string text)>();
- // Calculate absolute target
- int targetOffset = (int)(relativeOffset + br.BaseStream.Position);
-
- // Add to label map if not already there
- if (!OffsetToLabelMap.ContainsKey(targetOffset))
+ for (int l = 0; l < linelist.Count; l++)
{
- string labelName = $"label_0x{targetOffset:X}";
- OffsetToLabelMap[targetOffset] = labelName;
- }
-
- // Create jump parameter
- string targetLabel = OffsetToLabelMap[targetOffset];
- ScriptParameter jumpParam = new ScriptParameter(relativeOffset, targetLabel)
- {
- Type = ScriptParameter.ParameterType.RelativeJump
- };
- parameters.Add(jumpParam);
- }
-
- // Convert to text - outputs commands in the order they appear in the binary
- public string ToText()
- {
- StringBuilder sb = new StringBuilder();
-
- foreach (var cmdPos in CommandSequence)
- {
- // If this command needs a label, output it
- if (!string.IsNullOrEmpty(cmdPos.Label))
+ string cur = linelist[l];
+ if (!string.IsNullOrWhiteSpace(cur))
{
- sb.AppendLine($"\n{cmdPos.Label}:");
+ lineSource.Add((l, cur));
}
-
- // Output the command (indented if not an entry point)
- string indent = "\t";
- sb.AppendLine($"{indent}{cmdPos.Command.name}");
}
- return sb.ToString();
+ List ls = new List();
+ int i = 0;
+
+ try
+ {
+ uint actionNumber = 0;
+
+ while (i < lineSource.Count)
+ {
+ if (actionNumber == 0)
+ {
+ int positionOfActionNumber;
+ int positionOfActionKeyword = lineSource[i].text.IndexOf(ContainerTypes.Action.ToString(), StringComparison.InvariantCultureIgnoreCase);
+
+ if (positionOfActionKeyword > 0)
+ {
+ MessageBox.Show("Unrecognized container keyword: \"" + lineSource[i] + '"', "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ return null;
+ }
+ else if (positionOfActionKeyword < 0)
+ {
+ i++;
+ continue;
+ }
+ else
+ {
+ if ((positionOfActionNumber = lineSource[i].text.IndexOfFirstNumber()) < positionOfActionKeyword)
+ {
+ MessageBox.Show("Unspecified Action label.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ return null;
+ }
+ }
+
+ actionNumber = uint.Parse(lineSource[i].text.Substring(positionOfActionNumber).Split()[0].Replace(":", ""));
+ i++;
+ }
+
+ List cmdList = new List();
+ /* Read script actions */
+ do
+ {
+ ScriptAction toAdd = new ScriptAction(lineSource[i].text, lineSource[i].linenum + 1);
+ if (toAdd.id is null)
+ {
+ return null;
+ }
+
+ cmdList.Add(toAdd);
+ }
+ while (!lineSource[i++].text.IgnoreCaseEquals(RomInfo.ScriptActionNamesDict[0x00FE]));
+
+ ls.Add(new ScriptActionContainer(actionNumber, commands: cmdList));
+ actionNumber = 0;
+ }
+ }
+ catch (ArgumentOutOfRangeException)
+ {
+ MessageBox.Show($"Unexpectedly reached end of lines.\n\n" +
+ $"Last line index: {i}.\n" +
+ $"Managed to parse {ls.Count} Command Containers.", "Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ return null;
+ }
+
+ return ls;
}
public override byte[] ToByteArray()
@@ -583,83 +763,315 @@ namespace DSPRE.ROMFiles
MemoryStream newData = new MemoryStream();
using (BinaryWriter writer = new BinaryWriter(newData))
{
- // First, find all entry points and their positions in the command sequence
- var entryPoints = CommandSequence
- .Where(c => c.IsEntryPoint)
- .OrderBy(c => c.EntryPointIndex)
- .ToList();
+ List scriptOffsets = new List(); //uint OFFSET, int Function/Script/Action ID
+ List functionOffsets = new List();
+ List actionOffsets = new List();
- // Allocate space for header
- long headerStart = writer.BaseStream.Position;
- writer.BaseStream.Position += entryPoints.Count * 4;
- writer.Write((ushort)0xFD13); // End of header marker
+ List refList = new List();
- // Keep track of command offsets in the new file
- Dictionary oldOffsetToNewOffset = new Dictionary();
-
- // Write all commands sequentially
- foreach (var cmdPos in CommandSequence)
+ /* Allocate enough space for script pointers, which we do not know yet */
+ try
{
- // Record the position of this command
- oldOffsetToNewOffset[cmdPos.Offset] = writer.BaseStream.Position;
+ writer.BaseStream.Position += allScripts.Count * 0x4;
+ writer.Write((ushort)0xFD13); // Signal the end of header section
+ List useScriptCallers = new List();
- // Write the command
- writer.Write((ushort)cmdPos.Command.id);
-
- // Write parameters, handling jumps specially
- foreach (var param in cmdPos.Command.Parameters)
+ /* Write scripts */
+ foreach (ScriptCommandContainer currentScript in allScripts)
{
- if (param.Type == ScriptParameter.ParameterType.RelativeJump)
+ if (currentScript.usedScriptID == -1)
{
- // For jump targets, we need to recalculate the relative offset
- // based on the new positions of commands
-
- // Find the target offset in the original file
- int targetOffset = -1;
- foreach (var kvp in OffsetToLabelMap)
+ scriptOffsets.Add(new ContainerReference()
{
- if (kvp.Value == param.TargetLabel)
+ ID = currentScript.manualUserID,
+ offsetInFile = (uint)writer.BaseStream.Position
+ }
+ );
+
+ foreach (ScriptCommand currentCmd in currentScript.commands)
+ {
+ writer.Write((ushort)currentCmd.id);
+ //System.Diagnostics.Debug.Write(BitConverter.ToString(BitConverter.GetBytes(commandID)) + " ");
+
+ List parameterList = currentCmd.cmdParams;
+ foreach (byte[] b in parameterList)
{
- targetOffset = kvp.Key;
- break;
+ writer.Write(b);
+ //System.Diagnostics.Debug.WriteLine(BitConverter.ToString(parameterList[k]) + " ");
}
- }
- if (targetOffset != -1 && oldOffsetToNewOffset.TryGetValue(targetOffset, out long newTargetOffset))
- {
- // Calculate new relative offset
- int relativeOffset = (int)(newTargetOffset - (writer.BaseStream.Position + 4));
- writer.Write(relativeOffset);
- }
- else
- {
- // Fallback - write original offset
- writer.Write(param.TargetOffset);
+ /* If command calls a function/movement, store reference position */
+ AddReference(ref refList, (ushort)currentCmd.id, parameterList, (int)writer.BaseStream.Position, currentScript);
}
}
else
{
- // Regular parameter
- writer.Write(param.RawData);
+ useScriptCallers.Add(currentScript);
}
}
- }
- // Update header with entry point offsets
- writer.BaseStream.Position = headerStart;
- foreach (var entryPoint in entryPoints)
- {
- if (oldOffsetToNewOffset.TryGetValue(entryPoint.Offset, out long newOffset))
+ int scriptsCount = scriptOffsets.Count;
+ foreach (ScriptCommandContainer caller in useScriptCallers)
{
- uint relativeOffset = (uint)(newOffset - (headerStart + 4));
- writer.Write(relativeOffset);
+ for (int i = 0; i < scriptsCount; i++)
+ {
+ ContainerReference scriptReference = scriptOffsets[i];
+
+ if (scriptReference.ID == caller.usedScriptID)
+ {
+ scriptOffsets.Add(new ContainerReference()
+ {
+ ID = caller.manualUserID,
+ offsetInFile = scriptReference.offsetInFile
+ }); // If script has UseScript, copy offset
+ }
+ }
}
+
+ /* Write functions */
+ foreach (ScriptCommandContainer currentFunction in allFunctions)
+ {
+ if (currentFunction.usedScriptID == -1)
+ {
+ functionOffsets.Add(new ContainerReference()
+ {
+ ID = currentFunction.manualUserID,
+ offsetInFile = (uint)writer.BaseStream.Position
+ }
+ );
+
+ foreach (ScriptCommand currentCmd in currentFunction.commands)
+ {
+ writer.Write((ushort)currentCmd.id);
+ //System.Diagnostics.Debug.Write(BitConverter.ToString(BitConverter.GetBytes(commandID)) + " ");
+
+ List parameterList = currentCmd.cmdParams;
+ foreach (byte[] b in parameterList)
+ {
+ writer.Write(b);
+ //System.Diagnostics.Debug.Write(BitConverter.ToString(parameterList[k]) + " ");
+ }
+
+ /* If command calls a function/movement, store reference position */
+
+ AddReference(ref refList, (ushort)currentCmd.id, parameterList, (int)writer.BaseStream.Position, currentFunction);
+ }
+ }
+ else
+ {
+ int functionUsescript = currentFunction.usedScriptID - 1;
+ if (functionUsescript >= scriptOffsets.Count)
+ {
+ MessageBox.Show($"Function #{currentFunction.manualUserID} refers to Script {currentFunction.usedScriptID}, which does not exist.\n" +
+ $"This Script File can't be saved.", "Can't resolve UseScript reference", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ return null;
+ }
+
+ functionOffsets.Add(new ContainerReference()
+ {
+ ID = currentFunction.manualUserID,
+ offsetInFile = scriptOffsets.Find(x => x.ID == currentFunction.usedScriptID).offsetInFile
+ });
+ }
+ }
+
+ // Movements must be halfword-aligned
+ if (writer.BaseStream.Position % 2 == 1)
+ { //Check if the writer's head is on an odd byte
+ writer.Write((byte)0x00); //Add padding
+ }
+
+ /* Write movements */
+ foreach (ScriptActionContainer currentAction in allActions)
+ {
+ actionOffsets.Add(new ContainerReference()
+ {
+ ID = currentAction.manualUserID,
+ offsetInFile = (uint)writer.BaseStream.Position
+ });
+
+ foreach (ScriptAction currentCmd in currentAction.commands)
+ {
+ writer.Write((ushort)currentCmd.id);
+ writer.Write((ushort)currentCmd.repetitionCount);
+ }
+ }
+
+ /* Write script offsets to header */
+ writer.BaseStream.Position = 0x0;
+
+ scriptOffsets = scriptOffsets.OrderBy(x => x.ID).ToList(); //Write script offsets to header in the correct order
+ for (int i = 0; i < scriptOffsets.Count; i++)
+ {
+ writer.Write(scriptOffsets[i].offsetInFile - (uint)writer.BaseStream.Position - 0x4);
+ }
+
+ SortedSet undeclaredFuncs = new SortedSet();
+ SortedSet undeclaredActions = new SortedSet();
+
+ SortedSet uninvokedFuncs = new SortedSet(allFunctions.Select(x => x.manualUserID).ToArray());
+ SortedSet unreferencedActions = new SortedSet(allActions.Select(x => x.manualUserID).ToArray());
+
+ //refList = refList.OrderBy(x => x.invokedID).ToList(); //Sorting is not necessary, after all...
+
+ for (int i = 0; i < refList.Count; i++)
+ {
+ writer.BaseStream.Position = refList[i].invokedAt; //place seek head on parameter that is supposed to store the jump address
+ ContainerReference result;
+
+ if (refList[i].typeOfInvoked is ContainerTypes.Action)
+ { //isApplyMovement
+ result = actionOffsets.Find(entry => entry.ID == refList[i].invokedID);
+
+ if (result.Equals(default(ContainerReference)))
+ {
+ undeclaredActions.Add(refList[i].invokedID);
+ }
+ else
+ {
+ int relativeOffset = (int)(result.offsetInFile - refList[i].invokedAt - 4);
+ writer.Write(relativeOffset);
+ unreferencedActions.Remove(refList[i].invokedID);
+ }
+ }
+ else
+ {
+ result = functionOffsets.Find(entry => entry.ID == refList[i].invokedID);
+
+ if (result.Equals(default(ContainerReference)))
+ {
+ undeclaredFuncs.Add(refList[i].invokedID);
+ }
+ else
+ {
+ int relativeOffset = (int)(result.offsetInFile - refList[i].invokedAt - 4);
+ writer.Write(relativeOffset);
+
+ if (FunctionIsInvoked(refList, uninvokedFuncs, refList[i].invokedID, 0))
+ {
+ uninvokedFuncs.Remove(refList[i].invokedID);
+ }
+
+ //if (refList[i].callerType != containerTypes.Function ||
+ // (refList[i].callerType == refList[i].invokedType && refList[i].callerID == refList[i].invokedID) ||
+ // !uninvokedFuncs.Contains(refList[i].callerID)) { //remove reference if caller is a script, or if caller calls itself, or if caller is a function that's been invoked already
+ // uninvokedFuncs.Remove(refList[i].invokedID);
+ //}
+ }
+ }
+ }
+
+ //Error check
+ string errorMsg = "";
+ if (undeclaredFuncs.Count > 0)
+ {
+ string[] errorFunctionsUndeclared = undeclaredFuncs.ToArray().Select(x => x.ToString()).ToArray();
+ errorMsg += "These Functions have been invoked but not declared: " + Environment.NewLine + string.Join(separator: ",", errorFunctionsUndeclared);
+ errorMsg += Environment.NewLine;
+ }
+
+ if (undeclaredActions.Count > 0)
+ {
+ string[] errorActionsUndeclared = undeclaredActions.ToArray().Select(x => x.ToString()).ToArray();
+ errorMsg += "These Actions have been referenced but not declared: " + Environment.NewLine + string.Join(separator: ",", errorActionsUndeclared);
+ errorMsg += Environment.NewLine;
+ }
+
+ if (!string.IsNullOrEmpty(errorMsg))
+ {
+ MessageBox.Show(errorMsg + Environment.NewLine + "This Script File has not been overwritten since it can not be saved.", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ errorMsg = "";
+ return null;
+ }
+
+ if (uninvokedFuncs.Count > 0)
+ {
+ string[] orphanedFunctions = uninvokedFuncs.ToArray().Select(x => x.ToString()).ToArray();
+ errorMsg += "Unused Function IDs detected: " + Environment.NewLine + string.Join(", ", orphanedFunctions);
+ errorMsg += Environment.NewLine;
+ errorMsg += "\nIn order for a Function to be saved, it must be invoked by a Script or by another used Function.";
+ errorMsg += Environment.NewLine;
+ errorMsg += Environment.NewLine;
+ }
+
+ if (unreferencedActions.Count > 0)
+ {
+ string[] orphanedActions = unreferencedActions.ToArray().Select(x => x.ToString()).ToArray();
+ errorMsg += "Unused Action IDs detected: " + Environment.NewLine + string.Join(", ", orphanedActions);
+ errorMsg += Environment.NewLine;
+ errorMsg += "\nIn order for an Action to be saved, it must be called by a Script or by a used Function.";
+ errorMsg += Environment.NewLine;
+ errorMsg += Environment.NewLine;
+ }
+
+ if (!string.IsNullOrEmpty(errorMsg))
+ {
+ MessageBox.Show(errorMsg + Environment.NewLine + "Remember that every unused Function or Action is always lost upon reloading the Script File.", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Information);
+ errorMsg = "";
+ }
+ }
+ catch (NullReferenceException nre)
+ {
+ Console.WriteLine(nre);
+ return null;
}
}
return newData.ToArray();
}
+ private bool FunctionIsInvoked(List refList, SortedSet uninvokedFuncsSet, uint funcID, int callCount = 0, uint? excludedCaller = null)
+ {
+ if (callCount >= 30)
+ {
+ MessageBox.Show("Something went very wrong saving this Script File!" +
+ "\nIt is recommended that you backup its code somewhere, to avoid losing progress.",
+ "Fatal error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ return false;
+ }
+
+ Console.WriteLine("Checking calls of function " + funcID + (excludedCaller == null ? "" : " excluding Function " + excludedCaller + " as the caller."));
+
+ if (!uninvokedFuncsSet.Contains(funcID))
+ {
+ Console.WriteLine("Function " + funcID + " has already been invoked before. Nothing to check.");
+ return true; //Abort
+ }
+
+ if (refList is null || refList.Count <= 0)
+ {
+ return false;
+ }
+
+ //Find the first instance of funcID being called, excluding calls coming from an excludedCaller
+ //if excludedCaller is null, there's nothing to exclude: a normal search is performed.
+ ScriptReference sr = refList.Find(x => x.invokedID == funcID && (excludedCaller == null || x.callerID != excludedCaller));
+
+ if (sr is null)
+ {
+ Console.WriteLine("No reference found!!!");
+ return false;
+ }
+
+ if (sr.typeOfCaller is ContainerTypes.Script)
+ {
+ Console.WriteLine("Function " + funcID + " is directly called by Script " + sr.callerID);
+ return true;
+ }
+
+ if (sr.typeOfCaller is ContainerTypes.Function)
+ {
+ if (FunctionIsInvoked(refList, uninvokedFuncsSet, sr.callerID, ++callCount, excludedCaller: sr.invokedID))
+ { //check if caller function is invoked as well
+ Console.WriteLine("Function " + funcID + " is called by Function " + sr.callerID);
+ return true;
+ }
+ }
+
+ Console.WriteLine("Function " + funcID + " is unused");
+ return false;
+ }
+
public bool SaveToFileDefaultDir(int IDtoReplace, bool showSuccessMessage = true)
{
return SaveToFileDefaultDir(RomInfo.DirNames.scripts, IDtoReplace, showSuccessMessage);
diff --git a/DS_Map/Script/ScriptReference.cs b/DS_Map/ROMFiles/ScriptReference.cs
similarity index 100%
rename from DS_Map/Script/ScriptReference.cs
rename to DS_Map/ROMFiles/ScriptReference.cs
diff --git a/DS_Map/Script/VariableValueTrigger.cs b/DS_Map/ROMFiles/VariableValueTrigger.cs
similarity index 100%
rename from DS_Map/Script/VariableValueTrigger.cs
rename to DS_Map/ROMFiles/VariableValueTrigger.cs