mirror of
https://github.com/AdAstra-LD/DS-Pokemon-Rom-Editor.git
synced 2026-10-22 09:07:29 -05:00
merge
This commit is contained in:
31
DS_Map/Script/LevelScriptTrigger.cs
Normal file
31
DS_Map/Script/LevelScriptTrigger.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
|
||||
namespace DSPRE.ROMFiles {
|
||||
public class LevelScriptTrigger {
|
||||
public const int VARIABLEVALUE = 1;
|
||||
public const int MAPCHANGE = 2;
|
||||
public const int SCREENRESET = 3;
|
||||
public const int LOADGAME = 4;
|
||||
|
||||
private static int[] _triggerTypes;
|
||||
public int triggerType { get; set; }
|
||||
public int scriptTriggered { get; set; }
|
||||
|
||||
public LevelScriptTrigger(int triggerType, int scriptTriggered) {
|
||||
this.triggerType = triggerType;
|
||||
this.scriptTriggered = scriptTriggered;
|
||||
}
|
||||
|
||||
public static bool IsValidTriggerType(byte triggerType) {
|
||||
if (_triggerTypes == null) {
|
||||
_triggerTypes = new[] { VARIABLEVALUE, MAPCHANGE, SCREENRESET, LOADGAME };
|
||||
}
|
||||
|
||||
return Array.IndexOf(_triggerTypes, triggerType) != -1;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return "Starts Script " + scriptTriggered;
|
||||
}
|
||||
}
|
||||
}
|
||||
35
DS_Map/Script/MapScreenLoadTrigger.cs
Normal file
35
DS_Map/Script/MapScreenLoadTrigger.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
namespace DSPRE.ROMFiles {
|
||||
public class MapScreenLoadTrigger : LevelScriptTrigger {
|
||||
public MapScreenLoadTrigger(int type, int scriptTriggered) : base(type, scriptTriggered) { }
|
||||
|
||||
public override string ToString() {
|
||||
switch (triggerType) {
|
||||
case LevelScriptTrigger.MAPCHANGE:
|
||||
return base.ToString() + " upon entering the LS map.";
|
||||
case LevelScriptTrigger.SCREENRESET:
|
||||
return base.ToString() + " when a fadescreen happens in the LS map.";
|
||||
case LevelScriptTrigger.LOADGAME:
|
||||
return base.ToString() + " when the game resumes in the LS map.";
|
||||
default:
|
||||
return base.ToString() + " under unknown circumstances.";
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Equals(object obj) {
|
||||
// If the passed object is null
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (obj is MapScreenLoadTrigger) {
|
||||
return this.ToString() == ((MapScreenLoadTrigger)obj).ToString();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode() {
|
||||
return this.triggerType.GetHashCode() ^ scriptTriggered.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
87
DS_Map/Script/ScriptAction.cs
Normal file
87
DS_Map/Script/ScriptAction.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using DSPRE.Resources;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace DSPRE.ROMFiles {
|
||||
public class ActionContainer {
|
||||
public List<ScriptAction> actionCommandsList;
|
||||
public uint manualUserID;
|
||||
|
||||
#region Constructors (2)
|
||||
public ActionContainer(uint actionNumber, List<ScriptAction> actionCommandsList = null) {
|
||||
manualUserID = actionNumber;
|
||||
this.actionCommandsList = actionCommandsList;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
public class ScriptAction {
|
||||
|
||||
#region Fields (4)
|
||||
public ushort? id;
|
||||
public ushort? repetitionCount;
|
||||
public string name;
|
||||
#endregion
|
||||
|
||||
public ScriptAction(ushort id, ushort? repetitionCount = null) {
|
||||
this.id = id;
|
||||
this.repetitionCount = repetitionCount;
|
||||
|
||||
if (!RomInfo.ScriptActionNamesDict.TryGetValue(id, out name)) {
|
||||
name = id.ToString("X4");
|
||||
}
|
||||
|
||||
if (repetitionCount != null && id != 0x00FE) {
|
||||
name += " " + "0x" + ((ushort)repetitionCount).ToString("X");
|
||||
}
|
||||
}
|
||||
public ScriptAction(string wholeLine, int lineNumber) {
|
||||
name = wholeLine;
|
||||
|
||||
string[] nameParts = wholeLine.Replace("\t", "").Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // Separate command code from parameters
|
||||
/* Get command id, which is always first in the description */
|
||||
|
||||
if (RomInfo.ScriptActionNamesReverseDict.TryGetValue(nameParts[0].ToLower(), out ushort cmdID)) {
|
||||
this.id = cmdID;
|
||||
} else {
|
||||
if (ushort.TryParse(nameParts[0], NumberStyles.HexNumber, CultureInfo.InvariantCulture, out ushort buf)) {
|
||||
id = buf;
|
||||
} else {
|
||||
string details;
|
||||
if (wholeLine.Contains(':') && wholeLine.ContainsNumber()) {
|
||||
details = "This probably means you forgot to \"End\" the Action above it.";
|
||||
} else {
|
||||
details = "Are you sure it's a proper Action Command?";
|
||||
}
|
||||
MessageBox.Show("This Script file could not be saved." +
|
||||
Environment.NewLine + "Parser failed to interpret line " + lineNumber + ": \"" + wholeLine + "\"." +
|
||||
Environment.NewLine + "\n" + details, "Parser error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
id = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (id == 0x00FE && nameParts.Length != 1 || id != 0x00FE && nameParts.Length != 2) { //E.g.: End 0x2 0x40 OR LookUp
|
||||
MessageBox.Show("Wrong number of parameters for action " + nameParts[0] + " at line " + lineNumber + "." + Environment.NewLine +
|
||||
"Received: " + (nameParts.Length - 1) + Environment.NewLine + "Expected: 1"
|
||||
+ Environment.NewLine + "\nThis Script File can not be saved.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
id = null;
|
||||
} else {
|
||||
if (id == 0x00FE) {
|
||||
repetitionCount = 0;
|
||||
} else {
|
||||
NumberStyles style;
|
||||
if (nameParts[1].StartsWith("0x", StringComparison.InvariantCultureIgnoreCase)) {
|
||||
style = NumberStyles.HexNumber;
|
||||
nameParts[1] = nameParts[1].Substring(2);
|
||||
} else {
|
||||
style = NumberStyles.Integer;
|
||||
}
|
||||
repetitionCount = ushort.Parse(nameParts[1], style);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
476
DS_Map/Script/ScriptCommand.cs
Normal file
476
DS_Map/Script/ScriptCommand.cs
Normal file
@@ -0,0 +1,476 @@
|
||||
using DSPRE.Resources;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace DSPRE.ROMFiles {
|
||||
public class ScriptCommand {
|
||||
enum ParamTypeEnum {
|
||||
INTEGER,
|
||||
VARIABLE,
|
||||
FLEX,
|
||||
OW_ID,
|
||||
OW_MOVEMENT_TYPE,
|
||||
OW_DIRECTION,
|
||||
FUNCTION_ID,
|
||||
ACTION_ID,
|
||||
CMD_NUMBER,
|
||||
LABEL_REF
|
||||
};
|
||||
|
||||
public ushort? id;
|
||||
public List<ScriptParameter> Parameters { get; set; } = new List<ScriptParameter>();
|
||||
public string name;
|
||||
|
||||
// CHANGE: Update the constructor to use ScriptParameter
|
||||
public ScriptCommand(ushort id, List<ScriptParameter> parameters) {
|
||||
if (parameters is null) {
|
||||
this.id = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!RomInfo.ScriptCommandNamesDict.TryGetValue(id, out name)) {
|
||||
name = FormatNumber(id, ParamTypeEnum.CMD_NUMBER);
|
||||
}
|
||||
|
||||
switch (id) {
|
||||
case 0x0016: // Jump
|
||||
case 0x001A: // Call
|
||||
name += $" {FormatParameter(parameters[0], ParamTypeEnum.FUNCTION_ID)}";
|
||||
break;
|
||||
case 0x0017: // JumpIfObjID
|
||||
case 0x0018: // JumpIfEventID
|
||||
name += $" {FormatParameter(parameters[0], ParamTypeEnum.OW_ID)} {FormatParameter(parameters[1])}";
|
||||
break;
|
||||
case 0x0019: // JumpIfPlayerDir
|
||||
name += $" {FormatParameter(parameters[0], ParamTypeEnum.OW_DIRECTION)} {FormatParameter(parameters[1], ParamTypeEnum.FUNCTION_ID)}";
|
||||
break;
|
||||
case 0x001C: // JumpIf
|
||||
case 0x001D: // CallIf
|
||||
{
|
||||
string number = FormatParameter(parameters[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)) {
|
||||
name += $" {v} {number}";
|
||||
} else {
|
||||
name += $" {parameters[0].RawData[0]} {number}";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x005E: // Movement
|
||||
name += $" {FormatParameter(parameters[0], ParamTypeEnum.OW_ID)} {FormatParameter(parameters[1], ParamTypeEnum.ACTION_ID)}";
|
||||
break;
|
||||
case 0x006A: // GetOverworldPosition
|
||||
name += FormatCmd_Overworld_TwoParams(parameters);
|
||||
break;
|
||||
case 0x0062: // Lock
|
||||
case 0x0063: // Release
|
||||
case 0x0064: // AddOW
|
||||
case 0x0065: // RemoveOW
|
||||
name += $" {FormatParameter(parameters[0], ParamTypeEnum.OW_ID)}";
|
||||
break;
|
||||
case 0x006D: // SetOverworldMovement
|
||||
name += FormatCmd_Overworld_Move(parameters);
|
||||
break;
|
||||
|
||||
case 0x00B0: // Warp [HGSS]
|
||||
if (RomInfo.gameFamily.Equals(RomInfo.GameFamilies.HGSS)) {
|
||||
name += FormatCmd_Warp(parameters);
|
||||
} else {
|
||||
goto default;
|
||||
}
|
||||
|
||||
break;
|
||||
case 0x0152: // SetOverworldDefaultPosition [HGSS]
|
||||
if (RomInfo.gameFamily.Equals(RomInfo.GameFamilies.HGSS)) {
|
||||
name += FormatCmd_Overworld_TwoParams(parameters);
|
||||
} else {
|
||||
goto default;
|
||||
}
|
||||
|
||||
break;
|
||||
case 0x0153: // SetOverworldPosition [HGSS]
|
||||
if (RomInfo.gameFamily.Equals(RomInfo.GameFamilies.HGSS)) {
|
||||
name += FormatCmd_Overworld_3Coords_Dir(parameters);
|
||||
} else {
|
||||
goto default;
|
||||
}
|
||||
|
||||
break;
|
||||
case 0x0154: // SetOverworldDefaultMovement [HGSS]
|
||||
if (RomInfo.gameFamily.Equals(RomInfo.GameFamilies.HGSS)) {
|
||||
name += FormatCmd_Overworld_Move(parameters);
|
||||
} else {
|
||||
goto default;
|
||||
}
|
||||
|
||||
break;
|
||||
case 0x0155: // SetOverworldDefaultDirection [DPPt]
|
||||
if (RomInfo.gameFamily.Equals(RomInfo.GameFamilies.HGSS)) {
|
||||
name += FormatCmd_Overworld_Dir(parameters);
|
||||
} else {
|
||||
goto default;
|
||||
}
|
||||
|
||||
break;
|
||||
case 0x0158: // SetOverworldDirection [DPPt]
|
||||
if (RomInfo.gameFamily.Equals(RomInfo.GameFamilies.HGSS)) {
|
||||
name += FormatCmd_Overworld_Dir(parameters);
|
||||
} else {
|
||||
goto default;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 0x00BE: // Warp [DPPt]
|
||||
if (RomInfo.gameFamily.Equals(RomInfo.GameFamilies.DP) || RomInfo.gameFamily.Equals(RomInfo.GameFamilies.Plat)) {
|
||||
name += FormatCmd_Warp(parameters);
|
||||
} else {
|
||||
goto default;
|
||||
}
|
||||
|
||||
break;
|
||||
case 0x0186: // SetOverworldDefaultPosition [DPPt]
|
||||
if (RomInfo.gameFamily.Equals(RomInfo.GameFamilies.DP) || RomInfo.gameFamily.Equals(RomInfo.GameFamilies.Plat)) {
|
||||
name += FormatCmd_Overworld_TwoParams(parameters);
|
||||
} else {
|
||||
goto default;
|
||||
}
|
||||
|
||||
break;
|
||||
case 0x0187: // SetOverworldPosition [DPPt]
|
||||
if (RomInfo.gameFamily.Equals(RomInfo.GameFamilies.DP) || RomInfo.gameFamily.Equals(RomInfo.GameFamilies.Plat)) {
|
||||
name += FormatCmd_Overworld_3Coords_Dir(parameters);
|
||||
} else {
|
||||
goto default;
|
||||
}
|
||||
|
||||
break;
|
||||
case 0x0188: // SetOverworldDefaultMovement [DPPt]
|
||||
if (RomInfo.gameFamily.Equals(RomInfo.GameFamilies.DP) || RomInfo.gameFamily.Equals(RomInfo.GameFamilies.Plat)) {
|
||||
name += FormatCmd_Overworld_Move(parameters);
|
||||
} else {
|
||||
goto default;
|
||||
}
|
||||
|
||||
break;
|
||||
case 0x0189: // SetOverworldDefaultDirection [DPPt]
|
||||
if (RomInfo.gameFamily.Equals(RomInfo.GameFamilies.DP) || RomInfo.gameFamily.Equals(RomInfo.GameFamilies.Plat)) {
|
||||
name += FormatCmd_Overworld_Dir(parameters);
|
||||
} else {
|
||||
goto default;
|
||||
}
|
||||
|
||||
break;
|
||||
case 0x018C: // SetOverworldDirection [DPPt]
|
||||
if (RomInfo.gameFamily.Equals(RomInfo.GameFamilies.DP) || RomInfo.gameFamily.Equals(RomInfo.GameFamilies.Plat)) {
|
||||
name += FormatCmd_Overworld_Dir(parameters);
|
||||
} else {
|
||||
goto default;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
for (int i = 0; i < parameters.Count; i++) {
|
||||
name += $" {FormatParameter(parameters[i])}";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
this.id = id;
|
||||
this.Parameters = parameters;
|
||||
}
|
||||
|
||||
private string FormatCmd_Warp(List<ScriptParameter> parameters) {
|
||||
return $" {FormatParameter(parameters[0])} {FormatParameter(parameters[1])} {FormatParameter(parameters[2])} {FormatParameter(parameters[3])} {FormatParameter(parameters[4], ParamTypeEnum.OW_DIRECTION)}";
|
||||
}
|
||||
|
||||
private string FormatCmd_Overworld_TwoParams(List<ScriptParameter> parameters) {
|
||||
return $" {FormatParameter(parameters[0], ParamTypeEnum.OW_ID)} {FormatParameter(parameters[1])} {FormatParameter(parameters[2])}";
|
||||
}
|
||||
|
||||
private string FormatCmd_Overworld_Move(List<ScriptParameter> parameters) {
|
||||
return $" {FormatParameter(parameters[0], ParamTypeEnum.OW_ID)} {FormatParameter(parameters[1], ParamTypeEnum.OW_MOVEMENT_TYPE)}";
|
||||
}
|
||||
|
||||
private string FormatCmd_Overworld_3Coords_Dir(List<ScriptParameter> 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_Dir(List<ScriptParameter> parameters) {
|
||||
return $" {FormatParameter(parameters[0], ParamTypeEnum.OW_ID)} {FormatParameter(parameters[1], ParamTypeEnum.OW_DIRECTION)}";
|
||||
}
|
||||
public ScriptCommand(string wholeLine, int lineNumber = 0) {
|
||||
name = wholeLine;
|
||||
Parameters = new List<ScriptParameter>();
|
||||
|
||||
string[] nameParts = wholeLine.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // Separate command code from parameters
|
||||
/* Get command id, which is always first in the description */
|
||||
|
||||
if (RomInfo.ScriptCommandNamesReverseDict.TryGetValue(nameParts[0].ToLower(), out ushort cmdID)) {
|
||||
id = cmdID;
|
||||
} else {
|
||||
try {
|
||||
id = ushort.Parse(nameParts[0].PurgeSpecial(ScriptFile.specialChars), nameParts[0].GetNumberStyle());
|
||||
} catch {
|
||||
string details;
|
||||
if (wholeLine.Contains(':') && wholeLine.ContainsNumber()) {
|
||||
details = "This probably means you forgot to \"End\" the Script or Function above it.";
|
||||
details += Environment.NewLine + "Please, also note that only Functions can be terminated\nwith \"Return\".";
|
||||
} else {
|
||||
details = "Are you sure it's a proper Script Command?";
|
||||
}
|
||||
|
||||
MessageBox.Show("This Script file could not be saved." +
|
||||
$"\nParser failed to interpret line {lineNumber}: \"{wholeLine}\".\n\n{details}", "Parser error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read parameters from remainder of the description */
|
||||
byte[] parametersSizeArr = RomInfo.ScriptCommandParametersDict[(ushort)id];
|
||||
|
||||
int paramLength = 0;
|
||||
int paramsProcessed = 0;
|
||||
|
||||
if (parametersSizeArr.First() == 0xFF) {
|
||||
int firstParamValue = int.Parse(nameParts[1].PurgeSpecial(ScriptFile.specialChars), nameParts[1].GetNumberStyle());
|
||||
byte firstParamSize = parametersSizeArr[1];
|
||||
|
||||
Parameters.Add(new ScriptParameter(firstParamValue.ToByteArrayChooseSize(firstParamSize)));
|
||||
paramsProcessed++;
|
||||
|
||||
int i = 2;
|
||||
int optionsCount = 0;
|
||||
|
||||
bool found = false;
|
||||
while (i < parametersSizeArr.Length) {
|
||||
paramLength = parametersSizeArr[i + 1];
|
||||
|
||||
if (parametersSizeArr[i] == firstParamValue) {
|
||||
//Firstly, build subarray of parameter sizes, starting from the chosen option [firstParamValue]
|
||||
//FOR EXAMPLE: CMD 0x235 and firstParamValue = 5
|
||||
|
||||
// { 0xFF, 2,
|
||||
// 0, 1, 2,
|
||||
// 1, 3, 2, 2, 2,
|
||||
// 2, 0,
|
||||
// 3, 3, 2, 2, 2,
|
||||
// 4, 2, 2, 2,
|
||||
// 5, 3, (2, 2, 2) => this will be the parameters subarray
|
||||
// 6, 1, 2
|
||||
// },
|
||||
byte[] subParametersSize = parametersSizeArr.SubArray(i + 2, paramLength++);
|
||||
|
||||
//Create a slightly bigger temp array
|
||||
byte[] temp = new byte[1 + subParametersSize.Length];
|
||||
|
||||
//Store the size of the firstParamValue there
|
||||
temp[0] = firstParamSize;
|
||||
|
||||
//Then copy the whole subarray of parameter sizes
|
||||
Array.Copy(subParametersSize, 0, temp, 1, temp.Length - 1);
|
||||
|
||||
//Replace the original parametersSizeArr with the new array
|
||||
parametersSizeArr = temp;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
i += 2 + paramLength;
|
||||
optionsCount++;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
MessageBox.Show($"Command {nameParts[0]} is a special Script Command.\n" +
|
||||
$"The value of the first parameter must be a number in the range [0 - {optionsCount}].\n\n" +
|
||||
$"Line {lineNumber}: {wholeLine}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
id = null;
|
||||
return;
|
||||
}
|
||||
} else if (parametersSizeArr.Length == 1 && parametersSizeArr.First() == 0) {
|
||||
paramLength = 0;
|
||||
} else {
|
||||
paramLength = parametersSizeArr.Length;
|
||||
}
|
||||
|
||||
if (nameParts.Length - 1 == paramLength) {
|
||||
for (int i = paramsProcessed; i < paramLength; i++) {
|
||||
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 }));
|
||||
} else { //Not a comparison
|
||||
/* Convert strings of parameters to the correct datatypes */
|
||||
NumberStyles numStyle = nameParts[i + 1].GetNumberStyle();
|
||||
nameParts[i + 1] = nameParts[i + 1].PurgeSpecial(ScriptFile.specialChars);
|
||||
|
||||
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])) {
|
||||
MessageBox.Show($"You must specify an Overworld ID, Script, Function or Action number.\n\n" +
|
||||
$"Line {lineNumber}: {wholeLine}", "Unspecified identifier", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
id = null;
|
||||
} else {
|
||||
var first = ScriptDatabase.specialOverworlds.FirstOrDefault(x => x.Value.IgnoreCaseEquals(nameParts[i + 1]));
|
||||
|
||||
if (string.IsNullOrWhiteSpace(first.Value)) {
|
||||
var res = ScriptDatabase.overworldDirections.FirstOrDefault(x => x.Value.IgnoreCaseEquals(nameParts[i + 1]));
|
||||
|
||||
if (string.IsNullOrWhiteSpace(res.Value)) {
|
||||
MessageBox.Show($"Argument {nameParts[i + 1]} couldn't be parsed as a valid Condition, Overworld ID, Direction ID, Script, Function or Action number.\n\n" +
|
||||
$"Line {lineNumber}: {wholeLine}", "Invalid identifier", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
id = null;
|
||||
} else {
|
||||
result = res.Key;
|
||||
}
|
||||
} else {
|
||||
result = first.Key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
byte[] paramData = result.ToByteArrayChooseSize(parametersSizeArr[i]);
|
||||
Parameters.Add(new ScriptParameter(paramData));
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
MessageBox.Show($"Wrong number of parameters for command {nameParts[0]} at line {lineNumber}.\n" +
|
||||
$"Received: {nameParts.Length - 1}\n" +
|
||||
$"Expected: {paramLength}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
id = null;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
return "";
|
||||
} else if (par.Length == 1) {
|
||||
num = par[0];
|
||||
} else if (par.Length == 2) {
|
||||
num = BitConverter.ToUInt16(par, 0);
|
||||
} else if (par.Length == 4) {
|
||||
num = BitConverter.ToUInt32(par, 0);
|
||||
} else {
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
return FormatNumber(num, paramType);
|
||||
}
|
||||
|
||||
private string FormatNumber(uint num, ParamTypeEnum paramType = ParamTypeEnum.INTEGER) {
|
||||
//differentiate depending on param type
|
||||
string formatOverride;
|
||||
string prefix;
|
||||
|
||||
if (Properties.Settings.Default.scriptEditorFormatPreference == (int)NumberStyles.HexNumber) {
|
||||
formatOverride = "X";
|
||||
prefix = "0x";
|
||||
} else { //(Properties.Settings.Default.scriptEditorFormatPreference == NumberStyles.Integer)
|
||||
formatOverride = "D";
|
||||
prefix = "";
|
||||
}
|
||||
|
||||
string outp = "";
|
||||
|
||||
switch (paramType) {
|
||||
case ParamTypeEnum.CMD_NUMBER:
|
||||
return "CMD_" + prefix + num.ToString(formatOverride + '3');
|
||||
|
||||
case ParamTypeEnum.ACTION_ID:
|
||||
return ScriptFile.ContainerTypes.Action.ToString() + "#" + num;
|
||||
|
||||
case ParamTypeEnum.OW_MOVEMENT_TYPE:
|
||||
if (num < 4000) {
|
||||
outp += "Move.";
|
||||
}
|
||||
|
||||
goto default;
|
||||
|
||||
case ParamTypeEnum.OW_ID: {
|
||||
if (ScriptDatabase.specialOverworlds.TryGetValue((ushort)num, out string output)) {
|
||||
return output;
|
||||
} else {
|
||||
if (num < 4000) {
|
||||
outp += $"{Event.EventType.Overworld}.";
|
||||
}
|
||||
|
||||
goto default;
|
||||
}
|
||||
}
|
||||
case ParamTypeEnum.OW_DIRECTION: {
|
||||
if (ScriptDatabase.overworldDirections.TryGetValue((byte)num, out string output)) {
|
||||
return output;
|
||||
} else {
|
||||
if (num < 4000) {
|
||||
outp += $"Direction.";
|
||||
}
|
||||
|
||||
goto default;
|
||||
}
|
||||
}
|
||||
default:
|
||||
if (Properties.Settings.Default.scriptEditorFormatPreference == (int)NumberStyles.None) {
|
||||
if (num >= 4000) {
|
||||
formatOverride = "X";
|
||||
prefix = "0x";
|
||||
}
|
||||
}
|
||||
|
||||
outp += prefix + num.ToString(formatOverride);
|
||||
break;
|
||||
}
|
||||
|
||||
return outp;
|
||||
}
|
||||
|
||||
private string FormatParameter(ScriptParameter param, ParamTypeEnum paramType = ParamTypeEnum.INTEGER) {
|
||||
// For jump-to-label parameters, return the label name
|
||||
if (param.Type == ScriptParameter.ParameterType.RelativeJump && !string.IsNullOrEmpty(param.TargetLabel)) {
|
||||
return param.TargetLabel;
|
||||
}
|
||||
|
||||
// Otherwise handle the numeric value
|
||||
return FormatNumber(param.RawData, paramType);
|
||||
}
|
||||
public override string ToString() {
|
||||
return name + " (" + ((ushort)id).ToString("X") + ")";
|
||||
}
|
||||
|
||||
private string FormatLabelReference(string labelName) {
|
||||
return labelName;
|
||||
}
|
||||
}
|
||||
}
|
||||
20
DS_Map/Script/ScriptCommandPosition.cs
Normal file
20
DS_Map/Script/ScriptCommandPosition.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
// ScriptCommandPosition.cs
|
||||
using System;
|
||||
|
||||
namespace DSPRE.ROMFiles {
|
||||
public class ScriptCommandPosition {
|
||||
public ScriptCommand Command { get; set; }
|
||||
public int Offset { get; set; }
|
||||
public string Label { get; set; } // null if no label needed
|
||||
public bool IsEntryPoint { get; set; }
|
||||
public int EntryPointIndex { get; set; } // -1 if not an entry point
|
||||
|
||||
public ScriptCommandPosition(ScriptCommand cmd, int offset, string label = null, bool isEntryPoint = false, int entryPointIndex = -1) {
|
||||
Command = cmd;
|
||||
Offset = offset;
|
||||
Label = label;
|
||||
IsEntryPoint = isEntryPoint;
|
||||
EntryPointIndex = entryPointIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
21
DS_Map/Script/ScriptLabeledSection.cs
Normal file
21
DS_Map/Script/ScriptLabeledSection.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
// Create this as a new file: ScriptLabeledSection.cs
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DSPRE.ROMFiles {
|
||||
public class ScriptLabeledSection {
|
||||
public string LabelName { get; set; }
|
||||
public List<ScriptCommand> Commands { get; set; }
|
||||
public uint OffsetInFile { get; set; }
|
||||
public bool IsReferenced { get; set; } = false;
|
||||
|
||||
public ScriptLabeledSection(string labelName, List<ScriptCommand> commands = null) {
|
||||
LabelName = labelName;
|
||||
Commands = commands ?? new List<ScriptCommand>();
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return LabelName;
|
||||
}
|
||||
}
|
||||
}
|
||||
45
DS_Map/Script/ScriptParameter.cs
Normal file
45
DS_Map/Script/ScriptParameter.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
|
||||
public class ScriptParameter {
|
||||
public enum ParameterType {
|
||||
Integer,
|
||||
RelativeJump,
|
||||
Byte,
|
||||
Variable
|
||||
}
|
||||
|
||||
public ParameterType Type { get; set; } = ParameterType.Integer;
|
||||
public byte[] RawData { get; set; }
|
||||
public string TargetLabel { get; set; } // For RelativeJump type
|
||||
public int TargetOffset { get; set; } // For RelativeJump type
|
||||
|
||||
// Constructor for regular parameters
|
||||
public ScriptParameter(byte[] data) {
|
||||
Type = ParameterType.Integer;
|
||||
RawData = data;
|
||||
}
|
||||
|
||||
// Constructor for relative jumps
|
||||
public ScriptParameter(int targetOffset, string targetLabel) {
|
||||
Type = ParameterType.RelativeJump;
|
||||
TargetOffset = targetOffset;
|
||||
TargetLabel = targetLabel;
|
||||
// Store raw bytes only for display purposes
|
||||
RawData = BitConverter.GetBytes(targetOffset);
|
||||
}
|
||||
|
||||
// Get display representation
|
||||
public string GetFormattedValue() {
|
||||
if (Type == ParameterType.RelativeJump && !string.IsNullOrEmpty(TargetLabel)) {
|
||||
return TargetLabel;
|
||||
}
|
||||
|
||||
// Default formatting for other types
|
||||
if (RawData.Length == 0) return "";
|
||||
if (RawData.Length == 1) return RawData[0].ToString("X2");
|
||||
if (RawData.Length == 2) return BitConverter.ToUInt16(RawData, 0).ToString("X4");
|
||||
if (RawData.Length == 4) return BitConverter.ToUInt32(RawData, 0).ToString("X8");
|
||||
|
||||
return BitConverter.ToString(RawData);
|
||||
}
|
||||
}
|
||||
22
DS_Map/Script/ScriptReference.cs
Normal file
22
DS_Map/Script/ScriptReference.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
namespace DSPRE.ROMFiles {
|
||||
internal class ScriptReference {
|
||||
public ScriptFile.ContainerTypes typeOfCaller { get; private set; }
|
||||
public uint callerID { get; private set; }
|
||||
public ScriptFile.ContainerTypes typeOfInvoked { get; private set; }
|
||||
public uint invokedID { get; private set; }
|
||||
public int invokedAt { get; private set; }
|
||||
|
||||
public ScriptReference(ScriptFile.ContainerTypes typeOfCaller, uint callerID, ScriptFile.ContainerTypes invokedType, uint invokedID, int invokedAt) {
|
||||
this.typeOfCaller = typeOfCaller;
|
||||
this.callerID = callerID;
|
||||
this.typeOfInvoked = invokedType;
|
||||
this.invokedID = invokedID;
|
||||
|
||||
this.invokedAt = invokedAt;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return typeOfCaller + " " + callerID + " invokes " + typeOfInvoked + " " + invokedID + " at " + invokedAt;
|
||||
}
|
||||
}
|
||||
}
|
||||
32
DS_Map/Script/VariableValueTrigger.cs
Normal file
32
DS_Map/Script/VariableValueTrigger.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
namespace DSPRE.ROMFiles {
|
||||
public class VariableValueTrigger : LevelScriptTrigger {
|
||||
public int variableToWatch { get; set; }
|
||||
public int expectedValue { get; set; }
|
||||
|
||||
public VariableValueTrigger(int scriptIDtoTrigger, int variableToWatch, int expectedValue) : base(VARIABLEVALUE, scriptIDtoTrigger) {
|
||||
this.variableToWatch = variableToWatch;
|
||||
this.expectedValue = expectedValue;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return base.ToString() + " when Var " + variableToWatch + " == " + expectedValue;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj) {
|
||||
// If the passed object is null
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(obj is VariableValueTrigger)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.ToString() == ((VariableValueTrigger)obj).ToString();
|
||||
}
|
||||
|
||||
public override int GetHashCode() {
|
||||
return this.triggerType.GetHashCode() ^ variableToWatch.GetHashCode() ^ expectedValue.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user