mirror of
https://github.com/haven1433/HexManiacAdvance.git
synced 2026-10-01 04:36:35 -05:00
don't auto-format script pointers in edge cases
* points to itself? Don't add the format * points into existing data? Don't add the format
This commit is contained in:
@@ -28,6 +28,10 @@ namespace HavenSoft.HexManiac.Core {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static bool InRange<T>(this T value, T min, T max) where T : IComparable<T> {
|
||||
return min.CompareTo(value) <= 0 && value.CompareTo(max) < 0;
|
||||
}
|
||||
|
||||
public static bool TryParseInt(this string str, out int result) {
|
||||
if (str.StartsWith("0x") && int.TryParse(str.Substring(2), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out result)) return true;
|
||||
if (int.TryParse(str, out result)) return true;
|
||||
|
||||
@@ -229,24 +229,31 @@ namespace HavenSoft.HexManiac.Core.Models.Code {
|
||||
}
|
||||
} else {
|
||||
var destination = model.ReadPointer(address + length);
|
||||
if (destination >= 0 && destination < model.Count) {
|
||||
if (model.GetNextRun(address + length) is PointerRun pointerRun && pointerRun.Start == address + length) {
|
||||
// no need to clear/update
|
||||
if (destination.InRange(0, model.Count) && !destination.InRange(address + length, address + length + 4)) {
|
||||
var destinationRun = model.GetNextRun(destination);
|
||||
if (destinationRun.Start < destination) {
|
||||
// we're trying to point into already formatted data
|
||||
// don't add the pointer source or destination
|
||||
} else {
|
||||
model.ClearFormat(token, address + length, 4);
|
||||
model.ObserveRunWritten(token, new PointerRun(address + length));
|
||||
}
|
||||
if (arg.PointerType == ExpectedPointerType.Script) toProcess.Add(destination);
|
||||
if (arg.PointerType == ExpectedPointerType.Text) {
|
||||
WriteTextStream(model, token, destination, address + length);
|
||||
} else if (arg.PointerType == ExpectedPointerType.Movement) {
|
||||
WriteMovementStream(model, token, destination, address + length);
|
||||
} else if (arg.PointerType == ExpectedPointerType.Mart) {
|
||||
WriteMartStream(model, token, destination, address + length);
|
||||
} else if (arg.PointerType == ExpectedPointerType.Decor) {
|
||||
WriteDecorStream(model, token, destination, address + length);
|
||||
} else if (arg.PointerType == ExpectedPointerType.SpriteTemplate) {
|
||||
WriteSpriteTemplateStream(model, token, destination, address + length);
|
||||
var pointerSource = model.GetNextRun(address + length);
|
||||
if (pointerSource is PointerRun pointerRun && pointerRun.Start == address + length) {
|
||||
// no need to clear/update
|
||||
} else {
|
||||
model.ClearFormat(token, address + length, 4);
|
||||
model.ObserveRunWritten(token, new PointerRun(address + length));
|
||||
}
|
||||
if (arg.PointerType == ExpectedPointerType.Script) toProcess.Add(destination);
|
||||
if (arg.PointerType == ExpectedPointerType.Text) {
|
||||
WriteTextStream(model, token, destination, address + length);
|
||||
} else if (arg.PointerType == ExpectedPointerType.Movement) {
|
||||
WriteMovementStream(model, token, destination, address + length);
|
||||
} else if (arg.PointerType == ExpectedPointerType.Mart) {
|
||||
WriteMartStream(model, token, destination, address + length);
|
||||
} else if (arg.PointerType == ExpectedPointerType.Decor) {
|
||||
WriteDecorStream(model, token, destination, address + length);
|
||||
} else if (arg.PointerType == ExpectedPointerType.SpriteTemplate) {
|
||||
WriteSpriteTemplateStream(model, token, destination, address + length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -706,7 +706,48 @@ label2:;goto <000050>;end";
|
||||
Assert.Single(Messages);
|
||||
}
|
||||
|
||||
// TODO trainer ai script change -> no auto repoint?
|
||||
[Theory]
|
||||
[InlineData("02")]
|
||||
[InlineData("03")]
|
||||
[InlineData("04")]
|
||||
[InlineData("05")]
|
||||
public void ScriptWithPointerToPointer_Format_NoPointerFormat(string destination) {
|
||||
SetFullModel(0xFF);
|
||||
$"06 00 {destination} 00 00 08 02".ToByteArray().WriteInto(Model.RawData, 0);
|
||||
ViewPort.Edit("^script`xse`");
|
||||
|
||||
EventScript += " "; // force formatting
|
||||
|
||||
var run = Model.GetNextRun(1);
|
||||
Assert.Equal(int.MaxValue, run.Start);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("09")]
|
||||
[InlineData("0A")]
|
||||
[InlineData("0B")]
|
||||
public void ScriptWithPointerToFuturePointer_Format_OnlySecondPointerKept(string destination) {
|
||||
SetFullModel(0xFF);
|
||||
$"06 00 {destination} 00 00 08 06 00 00 01 00 08 02".ToByteArray().WriteInto(Model.RawData, 0);
|
||||
ViewPort.Edit("^script`xse`");
|
||||
|
||||
EventScript += " "; // force formatting
|
||||
|
||||
var run = Model.GetNextRun(1);
|
||||
Assert.Equal(8, run.Start);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ScriptWithPointerIntoExistingData_Format_DoNotFormatPointer() {
|
||||
SetFullModel(0xFF);
|
||||
CreateTextTable("names", 0x100, "Adam", "Brad", "Carl", "Dave", "Eric", "Fred");
|
||||
"06 00 02 01 00 08 02".ToByteArray().WriteInto(Model.RawData, 0);
|
||||
ViewPort.Edit("@000 ^script`xse`");
|
||||
|
||||
EventScript += " "; // force formatting
|
||||
|
||||
Model.ResolveConflicts(); // no conflicts = pass
|
||||
}
|
||||
|
||||
// TODO test that we get an error (not an exception) if we do auto on an unformatted pointer
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user