DS-Pokemon-Rom-Editor/DS_Map/ScriptCommand.cs
AdAstra-LD e52712bfab Finished conversion of script editor + bugfixing
+ Minor refactor
+ Export MAP BIN button
+ Fixed type painters resetting after changing map
+ Added more type painter colors
+ Fixed type painters font size
+ Fixed type painter value [updown] limit
+ Moved ScriptCommand and Script to a separate file

+ Fixed Encounter Editor unpacking HG encounters for SS roms
2021-02-04 17:45:59 +01:00

199 lines
9.8 KiB
C#
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
namespace DSPRE {
public class Script {
public List<ScriptCommand> commands;
public int useScript;
#region Constructors (2)
public Script(int useScript = -1, List<ScriptCommand> commandList = null) {
commands = commandList;
this.useScript = useScript;
}
#endregion
}
public class ScriptCommand {
#region Fields (4)
public ushort id;
public List<byte[]> parameterList;
public string cmdName;
public bool isMovement;
#endregion
#region Constructors (2)
public ScriptCommand(ushort id, List<byte[]> parameterList, bool isMovement = false) {
this.id = id;
this.isMovement = isMovement;
this.parameterList = parameterList;
Dictionary<ushort, string> commandNamesDatabase;
if (isMovement) {
commandNamesDatabase = PokeDatabase.ScriptEditor.movementsDictIDName;
} else {
commandNamesDatabase = RomInfo.scriptCommandNamesDict;
}
try {
cmdName = commandNamesDatabase[id];
} catch (KeyNotFoundException) {
cmdName = id.ToString("X4");
}
if (isMovement) {
for (int i = 0; i < parameterList.Count; i++) {
if (parameterList[i].Length == 1)
this.cmdName += " " + "0x" + (parameterList[i][0]).ToString("X1");
else if (parameterList[i].Length == 2)
this.cmdName += " " + "0x" + (BitConverter.ToInt16(parameterList[i], 0)).ToString("X1");
else if (parameterList[i].Length == 4)
this.cmdName += " " + "0x" + (BitConverter.ToInt32(parameterList[i], 0)).ToString("X1");
}
} else {
switch (id) {
case 0x16: // Jump
case 0x1A: // Call
this.cmdName += " " + "Function_#" + (1 + BitConverter.ToInt32(parameterList[0], 0)).ToString("D");
break;
case 0x17: // JumpIfObjID
case 0x18: // JumpIfBgID
case 0x19: // JumpIfPlayerDir
this.cmdName += " " + (BitConverter.ToInt32(parameterList[0], 0)).ToString("D") + " " + "Function_#" + (1 + (BitConverter.ToInt32(parameterList[1], 0))).ToString("D");
break;
case 0x1C: // CompareLastResultJump
case 0x1D: // CompareLastResultCall
byte opcode = parameterList[0][0];
this.cmdName += " " + PokeDatabase.ScriptEditor.comparisonOperators[opcode] + " " + "Function_#" + (1 + (BitConverter.ToInt32(parameterList[1], 0))).ToString("D");
break;
case 0x5E: // ApplyMovement
ushort flexID = BitConverter.ToUInt16(parameterList[0], 0);
this.cmdName += OverworldFlexDecode(flexID);
this.cmdName += " " + "Movement_#" + (1 + (BitConverter.ToInt32(parameterList[1], 0))).ToString("D");
break;
case 0x62: // Lock
case 0x63: // Release
case 0x64: // AddPeople
case 0x65: // RemoveOW
flexID = BitConverter.ToUInt16(parameterList[0], 0);
cmdName += OverworldFlexDecode(flexID);
break;
default:
for (int i = 0; i < parameterList.Count; i++) {
if (parameterList[i].Length == 1)
this.cmdName += " " + "0x" + (parameterList[i][0]).ToString("X1");
else if (parameterList[i].Length == 2)
this.cmdName += " " + "0x" + (BitConverter.ToInt16(parameterList[i], 0)).ToString("X1");
else if (parameterList[i].Length == 4)
this.cmdName += " " + "0x" + (BitConverter.ToInt32(parameterList[i], 0)).ToString("X1");
}
break;
}
}
}
public ScriptCommand(string wholeLine, bool isMovement = false) {
this.cmdName = wholeLine;
this.isMovement = isMovement;
this.parameterList = new List<byte[]>();
string[] nameParts = wholeLine.Split(' '); // Separate command code from parameters
/* Get command id, which is always first in the description */
try {
if (isMovement) {
id = PokeDatabase.ScriptEditor.movementsDictIDName.First(x => x.Value == nameParts[0]).Key;
} else {
id = RomInfo.scriptCommandNamesDict.First(x => x.Value == nameParts[0]).Key;
}
} catch (InvalidOperationException) {
UInt16.TryParse(nameParts[0], NumberStyles.HexNumber, CultureInfo.InvariantCulture, out this.id);
}
/* Read parameters from remainder of the description */
Console.WriteLine("ID = " + id.ToString("X4"));
if (nameParts.Length > 1) {
if (isMovement) {
if (nameParts[1].Length > 4) { // Cases where movement is followed by an Overworld parameter
int positionOfOverworldID = nameParts[1].IndexOf('#'); // Find position of #
parameterList.Add(BitConverter.GetBytes(Int32.Parse(nameParts[1].Substring(positionOfOverworldID + 1), NumberStyles.Integer))); // Add Overworld_#
parameterList[0] = BitConverter.GetBytes(BitConverter.ToInt32(parameterList[0], 0) - 1); // Add Overworld number
// TODO: Check if other cases may apply to movement parameters
} else {
parameterList.Add(BitConverter.GetBytes(Int16.Parse(nameParts[1].Substring(2), NumberStyles.HexNumber)));
}
} else {
byte[] parametersArr = RomInfo.scriptParametersDict[id];
for (int i = 0; i < parametersArr.Length; i++) {
Console.WriteLine("Parameter #" + i.ToString() + ": " + nameParts[i + 1]);
try {
ushort comparisonOperator = PokeDatabase.ScriptEditor.comparisonOperators.First(x => x.Value == nameParts[i + 1]).Key;
parameterList.Add(new byte[] { (byte)comparisonOperator });
} catch { //Not a comparison
int indexOfSpecialCharacter = nameParts[i + 1].IndexOfAny(new char[] { 'x', '#' });
/* If number is preceded by 0x parse it as hex, otherwise as decimal */
NumberStyles style;
if (nameParts[i + 1].Contains("0x"))
style = NumberStyles.HexNumber;
else
style = NumberStyles.Integer;
/* Convert strings of parameters to the correct datatypes */
switch (parametersArr[i]) {
case 1:
parameterList.Add(new byte[] { Byte.Parse(nameParts[i + 1].Substring(indexOfSpecialCharacter + 1), style) });
break;
case 2:
switch (nameParts[i + 1]) {
case "Player":
parameterList.Add(BitConverter.GetBytes((ushort)255));
break;
case "Following":
parameterList.Add(BitConverter.GetBytes((ushort)253));
break;
case "Cam":
parameterList.Add(BitConverter.GetBytes((ushort)241));
break;
default:
parameterList.Add(BitConverter.GetBytes(Int16.Parse(nameParts[i + 1].Substring(indexOfSpecialCharacter + 1), style)));
break;
}
break;
case 4:
parameterList.Add(BitConverter.GetBytes(Int32.Parse(nameParts[i + 1].Substring(indexOfSpecialCharacter + 1), style)));
break;
}
}
}
}
}
}
#endregion
#region Utilities
private string OverworldFlexDecode(ushort flexID) {
if (flexID > 255) {
return " " + "0x" + flexID.ToString("X4");
} else {
switch (flexID) {
case 255:
return " " + "Player";
case 253:
return " " + "Following";
case 241:
return " " + "Cam";
default:
return " " + "Overworld_#" + flexID.ToString("D");
}
}
}
public override string ToString() {
return cmdName + " (" + id.ToString("X") + ")";
}
#endregion
}
}