Added viewing and modifying local vars for critters to the debug editor.

This commit is contained in:
NovaRain
2019-06-15 09:57:14 +08:00
parent ddda559898
commit 04d06a8167
11 changed files with 169 additions and 9 deletions
+1
View File
@@ -164,6 +164,7 @@
this.bCrittersLvar.TabIndex = 7; this.bCrittersLvar.TabIndex = 7;
this.bCrittersLvar.Text = "Local variables"; this.bCrittersLvar.Text = "Local variables";
this.bCrittersLvar.UseVisualStyleBackColor = true; this.bCrittersLvar.UseVisualStyleBackColor = true;
this.bCrittersLvar.Click += new System.EventHandler(this.bCrittersLvar_Click);
// //
// DebugEditor // DebugEditor
// //
+42 -1
View File
@@ -38,7 +38,7 @@ namespace FalloutClient {
private static ByteConverter converter = new ByteConverter(); private static ByteConverter converter = new ByteConverter();
private enum Mode { Globals, MapVars, SGlobals, Arrays, Critters } private enum Mode { Globals, MapVars, SGlobals, Arrays, Critters, LocalVars }
private readonly EditorConnection connection; private readonly EditorConnection connection;
private Mode mode; private Mode mode;
@@ -47,6 +47,7 @@ namespace FalloutClient {
private readonly Dictionary<uint, string> CritNames = new Dictionary<uint, string>(); private readonly Dictionary<uint, string> CritNames = new Dictionary<uint, string>();
private void Redraw() { private void Redraw() {
bCrittersLvar.Enabled = false;
bEdit.Enabled = false; bEdit.Enabled = false;
Column2.ReadOnly = false; Column2.ReadOnly = false;
Column3.ReadOnly = false; Column3.ReadOnly = false;
@@ -96,6 +97,7 @@ namespace FalloutClient {
Column2.HeaderText = "PID"; Column2.HeaderText = "PID";
Column3.HeaderText = "Pointer"; Column3.HeaderText = "Pointer";
bEdit.Enabled = true; bEdit.Enabled = true;
bCrittersLvar.Enabled = true;
for (int i = 0; i < connection.Critters.Length / 2; i++) { for (int i = 0; i < connection.Critters.Length / 2; i++) {
uint modcrit = (connection.Critters[i, 0] & 0xfffff); uint modcrit = (connection.Critters[i, 0] & 0xfffff);
string name = CritNames.ContainsKey(modcrit) ? CritNames[modcrit] : ""; string name = CritNames.ContainsKey(modcrit) ? CritNames[modcrit] : "";
@@ -333,6 +335,45 @@ namespace FalloutClient {
} }
} }
private void bCrittersLvar_Click(object sender, EventArgs e) {
if (dataGridView1.SelectedRows.Count == 0) return;
int i = (int)dataGridView1.SelectedRows[0].Tag;
connection.WriteDataType(DataTypeSend.RetrieveCritter);
connection.WriteInt(i);
BinaryReader br = new BinaryReader(new System.IO.MemoryStream(connection.ReadBytes(33 * 4)));
br.BaseStream.Position = 30 * 4;
int sid = br.ReadInt32();
br.Close();
if (sid != -1) {
connection.WriteDataType(DataTypeSend.GetLocal);
connection.WriteInt(sid);
int totalVar = connection.ReadInt();
string[] values = new string[totalVar];
if (totalVar > 0) {
br = new BinaryReader(new System.IO.MemoryStream(connection.ReadBytes(totalVar * 4)));
for (int j = 0; j < totalVar; j++) {
values[j] = br.ReadInt32().ToString();
}
br.Close();
}
values = EditorWindow.ShowEditor(this, values);
if (values != null) {
int countVar = values.Length;
MemoryStream ms = new MemoryStream(countVar * 4);
BinaryWriter bw = new BinaryWriter(ms);
for (int j = 0; j < countVar; j++) bw.Write(int.Parse(values[j]));
connection.WriteDataType(DataTypeSend.SetLocal);
connection.WriteInt(sid);
connection.WriteInt(countVar);
connection.WriteBytes(ms.GetBuffer(), 0, countVar * 4);
bw.Close();
}
} else {
MessageBox.Show("This critter has no script attached.");
}
}
private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e) { private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e) {
bEdit.PerformClick(); bEdit.PerformClick();
} }
+16
View File
@@ -29,6 +29,7 @@
this.Column1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.Column1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column2 = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.Column2 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column3 = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.Column3 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.checkBox = new System.Windows.Forms.CheckBox();
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
this.SuspendLayout(); this.SuspendLayout();
// //
@@ -100,11 +101,24 @@
this.Column3.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; this.Column3.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
this.Column3.Width = 150; this.Column3.Width = 150;
// //
// checkBox
//
this.checkBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.checkBox.AutoSize = true;
this.checkBox.Location = new System.Drawing.Point(103, 341);
this.checkBox.Name = "checkBox";
this.checkBox.Size = new System.Drawing.Size(91, 17);
this.checkBox.TabIndex = 3;
this.checkBox.Text = "Values in Hex";
this.checkBox.UseVisualStyleBackColor = true;
this.checkBox.Click += new System.EventHandler(this.checkBox_Click);
//
// EditorWindow // EditorWindow
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(458, 371); this.ClientSize = new System.Drawing.Size(458, 371);
this.Controls.Add(this.checkBox);
this.Controls.Add(this.dataGridView1); this.Controls.Add(this.dataGridView1);
this.Controls.Add(this.bCancel); this.Controls.Add(this.bCancel);
this.Controls.Add(this.bSave); this.Controls.Add(this.bSave);
@@ -115,6 +129,7 @@
this.Text = "Edit Values"; this.Text = "Edit Values";
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
this.ResumeLayout(false); this.ResumeLayout(false);
this.PerformLayout();
} }
@@ -126,5 +141,6 @@
private System.Windows.Forms.DataGridViewTextBoxColumn Column1; private System.Windows.Forms.DataGridViewTextBoxColumn Column1;
private System.Windows.Forms.DataGridViewTextBoxColumn Column2; private System.Windows.Forms.DataGridViewTextBoxColumn Column2;
private System.Windows.Forms.DataGridViewTextBoxColumn Column3; private System.Windows.Forms.DataGridViewTextBoxColumn Column3;
private System.Windows.Forms.CheckBox checkBox;
} }
} }
+64 -6
View File
@@ -8,15 +8,34 @@ namespace FalloutClient {
public partial class EditorWindow : Form public partial class EditorWindow : Form
{ {
private readonly DataType[] types; private readonly DataType[] types = null;
private readonly string[] values; private string[] values;
private bool save; private bool save;
private static bool valueInHex = false;
private void ConvertValues(bool toHex) {
for (int i = 0; i < values.Length; i++) {
if (toHex) {
if (types == null || types[i] == DataType.Int) {
int val = int.Parse(values[i]);
values[i] = "0x" + val.ToString("x").ToUpper();
}
} else {
if (types == null || types[i] == DataType.Int) {
values[i] = Convert.ToInt32(values[i], 16).ToString();
}
}
}
}
private EditorWindow(string[] names, DataType[] types, string[] values, bool isMap) { private EditorWindow(string[] names, DataType[] types, string[] values, bool isMap) {
this.types = types; this.types = types;
this.values = values; this.values = values;
InitializeComponent(); InitializeComponent();
checkBox.Checked = EditorWindow.valueInHex;
dataGridView1.SuspendLayout(); dataGridView1.SuspendLayout();
if (valueInHex) ConvertValues(true);
if (names == null) if (names == null)
for (int i = 0; i < types.Length; i++) { for (int i = 0; i < types.Length; i++) {
string element = i.ToString(); string element = i.ToString();
@@ -31,15 +50,46 @@ namespace FalloutClient {
public static string[] ShowEditor(DebugEditor form, string[] names, DataType[] types, string[] values, bool isMap = false) { public static string[] ShowEditor(DebugEditor form, string[] names, DataType[] types, string[] values, bool isMap = false) {
EditorWindow editor = new EditorWindow(names, types, values, isMap); EditorWindow editor = new EditorWindow(names, types, values, isMap);
editor.ShowDialog(); editor.ShowDialog();
if (editor.save) if (editor.save) {
if (valueInHex) editor.ConvertValues(false);
return editor.values; return editor.values;
else }
return null; return null;
}
private EditorWindow(string[] values) {
this.values = values;
InitializeComponent();
checkBox.Checked = EditorWindow.valueInHex;
dataGridView1.SuspendLayout();
if (valueInHex) ConvertValues(true);
for (int i = 0; i < values.Length; i++) {
dataGridView1.Rows.Add(i.ToString(), "Int", values[i]);
}
dataGridView1.ResumeLayout();
}
public static string[] ShowEditor(DebugEditor form, string[] lvalues) {
EditorWindow editor = new EditorWindow(lvalues);
editor.ShowDialog();
if (editor.save) {
if (valueInHex) editor.ConvertValues(false);
return editor.values;
}
return null;
} }
private bool CheckInput(DataType type, string str) { private bool CheckInput(DataType type, string str) {
switch (type) { switch (type) {
case DataType.Int: case DataType.Int:
if (valueInHex) {
try {
Convert.ToInt32(str, 16);
return true;
} catch (Exception) {
return false;
}
}
int i; int i;
return int.TryParse(str, out i); return int.TryParse(str, out i);
case DataType.Float: case DataType.Float:
@@ -51,7 +101,7 @@ namespace FalloutClient {
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e) { private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e) {
string str = (string)dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value; string str = (string)dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
if (str != null && CheckInput(types[e.RowIndex], str)) if (str != null && CheckInput(((types != null) ? types[e.RowIndex] : DataType.Int), str))
values[e.RowIndex] = str; values[e.RowIndex] = str;
else else
dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = values[e.RowIndex]; dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = values[e.RowIndex];
@@ -65,5 +115,13 @@ namespace FalloutClient {
save = true; save = true;
Close(); Close();
} }
private void checkBox_Click(object sender, EventArgs e) {
valueInHex = checkBox.Checked;
ConvertValues(valueInHex);
for (int i = 0; i < values.Length; i++) {
dataGridView1.Rows[i].Cells[2].Value = values[i];
}
}
} }
} }
+2
View File
@@ -29,6 +29,8 @@ namespace FalloutClient {
SetSGlobal = 4, SetSGlobal = 4,
GetArray = 9, GetArray = 9,
SetArray = 10, SetArray = 10,
GetLocal = 11,
SetLocal = 12,
Exit = 254 Exit = 254
} }
} }
+2 -2
View File
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
// Build Number // Build Number
// Revision // Revision
// //
[assembly: AssemblyVersion("4.1.7.0")] [assembly: AssemblyVersion("4.1.9.0")]
[assembly: AssemblyFileVersion("4.1.7.0")] [assembly: AssemblyFileVersion("4.1.9.0")]
+1
View File
@@ -266,6 +266,7 @@
#define get_ini_section(file, sect) sfall_func2("get_ini_section", file, sect) #define get_ini_section(file, sect) sfall_func2("get_ini_section", file, sect)
#define get_ini_sections(file) sfall_func1("get_ini_sections", file) #define get_ini_sections(file) sfall_func1("get_ini_sections", file)
#define get_map_enter_position sfall_func0("get_map_enter_position") #define get_map_enter_position sfall_func0("get_map_enter_position")
#define get_metarule_table sfall_func0("get_metarule_table")
#define get_object_ai_data(obj, aiParam) sfall_func2("get_object_ai_data", obj, aiParam) #define get_object_ai_data(obj, aiParam) sfall_func2("get_object_ai_data", obj, aiParam)
#define get_object_data(obj, offset) sfall_func2("get_object_data", obj, offset) #define get_object_data(obj, offset) sfall_func2("get_object_data", obj, offset)
#define get_outline(obj) sfall_func1("get_outline", obj) #define get_outline(obj) sfall_func1("get_outline", obj)
+7
View File
@@ -174,6 +174,13 @@ bool IsPartyMember(fo::GameObject* critter) {
return (IsPartyMemberByPid(critter->protoId) > 0); return (IsPartyMemberByPid(critter->protoId) > 0);
} }
// Returns the number of local variables of the object script
long GetScriptLocalVars(long sid) {
fo::ScriptInstance* script = nullptr;
fo::func::scr_ptr(sid, &script);
return (script) ? script->numLocalVars : 0;
}
//--------------------------------------------------------- //---------------------------------------------------------
//print text to surface //print text to surface
void PrintText(char *DisplayText, BYTE ColourIndex, DWORD Xpos, DWORD Ypos, DWORD TxtWidth, DWORD ToWidth, BYTE *ToSurface) { void PrintText(char *DisplayText, BYTE ColourIndex, DWORD Xpos, DWORD Ypos, DWORD TxtWidth, DWORD ToWidth, BYTE *ToSurface) {
+3
View File
@@ -73,6 +73,9 @@ long IsPartyMemberByPid(long pid);
bool IsPartyMember(fo::GameObject* critter); bool IsPartyMember(fo::GameObject* critter);
// Returns the number of local variables of the object script
long GetScriptLocalVars(long sid);
// Print text to surface // Print text to surface
void PrintText(char *displayText, BYTE colorIndex, DWORD x, DWORD y, DWORD textWidth, DWORD destWidth, BYTE *surface); void PrintText(char *displayText, BYTE colorIndex, DWORD x, DWORD y, DWORD textWidth, DWORD destWidth, BYTE *surface);
// gets the height of the currently selected font // gets the height of the currently selected font
+2
View File
@@ -23,6 +23,8 @@ WRAP_WATCOM_FFUNC4(void, display_target_inventory, long, inventoryOffset, long,
WRAP_WATCOM_FFUNC3(FrmFrameData*, frame_ptr, FrmHeaderData*, frm, long, frame, long, direction) WRAP_WATCOM_FFUNC3(FrmFrameData*, frame_ptr, FrmHeaderData*, frm, long, frame, long, direction)
WRAP_WATCOM_FFUNC7(void, make_straight_path_func, fo::GameObject*, objFrom, DWORD, tileFrom, DWORD, tileTo, void*, rotationPtr, DWORD*, result, long, flags, void*, func) WRAP_WATCOM_FFUNC7(void, make_straight_path_func, fo::GameObject*, objFrom, DWORD, tileFrom, DWORD, tileTo, void*, rotationPtr, DWORD*, result, long, flags, void*, func)
WRAP_WATCOM_FFUNC3(long, object_under_mouse, long, crSwitch, long, inclDude, long, elevation) WRAP_WATCOM_FFUNC3(long, object_under_mouse, long, crSwitch, long, inclDude, long, elevation)
WRAP_WATCOM_FFUNC3(long, scr_get_local_var, long, sid, long, varId, long*, value)
WRAP_WATCOM_FFUNC3(long, scr_set_local_var, long, sid, long, varId, long, value)
// stdcall // stdcall
WRAP_WATCOM_FUNC1(AIcap*, ai_cap, GameObject*, critter) WRAP_WATCOM_FUNC1(AIcap*, ai_cap, GameObject*, critter)
+29
View File
@@ -42,6 +42,8 @@ enum DECode {
CODE_SET_PLAYER = 8, CODE_SET_PLAYER = 8,
CODE_GET_ARRAY = 9, CODE_GET_ARRAY = 9,
CODE_SET_ARRAY = 10, CODE_SET_ARRAY = 10,
CODE_GET_LOCVARS = 11,
CODE_SET_LOCVARS = 12,
CODE_EXIT = 254 CODE_EXIT = 254
}; };
@@ -194,6 +196,33 @@ static void RunEditorInternal(SOCKET &s) {
delete[] data; delete[] data;
} }
break; break;
case CODE_GET_LOCVARS:
{
InternalRecv(s, &id, 4); // sid
val = fo::GetScriptLocalVars(id);
InternalSend(s, &val, 4);
if (val) {
std::vector<int> values(val);
long varVal;
for (int i = 0; i < val; i++) {
fo::func::scr_get_local_var(id, i, &varVal);
values[i] = varVal;
}
InternalSend(s, values.data(), val * 4);
}
}
break;
case CODE_SET_LOCVARS:
{
InternalRecv(s, &id, 4); // sid
InternalRecv(s, &val, 4); // len data
std::vector<int> values(val);
InternalRecv(s, values.data(), val * 4);
for (int i = 0; i < val; i++) {
fo::func::scr_set_local_var(id, i, values[i]);
}
}
break;
} }
DEGameWinRedraw(); DEGameWinRedraw();
} }