mirror of
https://github.com/haven1433/HexManiacAdvance.git
synced 2026-05-31 20:42:43 -05:00
Update move expansion: add level-up list length expansion
This commit is contained in:
parent
a1ae7fb83f
commit
a43101cc8e
|
|
@ -25,14 +25,14 @@ BPEE0.scripts.shiny.odds-1 067C56,06E76C,06E7E2,06EBE4,172F46
|
|||
# -1: GetHoennPokedexCount,GetPokedexRatingText
|
||||
# -2: GetPokedexRatingText
|
||||
# -3: HasAllHoennMons,GetPokedexRatingText
|
||||
AXPV0.scripts.pokedex.regional.length 0406FA,08D6BA,08D6E2,10D5E8
|
||||
AXPV0.scripts.pokedex.regional.length-1 090FB4,10D5A8
|
||||
AXPV0.scripts.pokedex.regional.length-2 10D570
|
||||
AXPV0.scripts.pokedex.regional.length-3 090FE6,10D56C
|
||||
AXPV1.scripts.pokedex.regional.length 04071A,08D6DA,08D702,10D608
|
||||
AXPV1.scripts.pokedex.regional.length-1 090FD4,10D5C8
|
||||
AXPV1.scripts.pokedex.regional.length-2 10D590
|
||||
AXPV1.scripts.pokedex.regional.length-3 091006,10D58C
|
||||
AXVE0.scripts.pokedex.regional.length 0406FA,08D6BA,08D6E2,10D5E8
|
||||
AXVE0.scripts.pokedex.regional.length-1 090FB4,10D5A8
|
||||
AXVE0.scripts.pokedex.regional.length-2 10D570
|
||||
AXVE0.scripts.pokedex.regional.length-3 090FE6,10D56C
|
||||
AXVE1.scripts.pokedex.regional.length 04071A,08D6DA,08D702,10D608
|
||||
AXVE1.scripts.pokedex.regional.length-1 090FD4,10D5C8
|
||||
AXVE1.scripts.pokedex.regional.length-2 10D590
|
||||
AXVE1.scripts.pokedex.regional.length-3 091006,10D58C
|
||||
AXPE0.scripts.pokedex.regional.length 0406FA,08D6BA,08D6E2,10D5E8
|
||||
AXPE0.scripts.pokedex.regional.length-1 090FB4,10D5A8
|
||||
AXPE0.scripts.pokedex.regional.length-2 10D570
|
||||
|
|
@ -213,3 +213,4 @@ AXVE1.data.pokemon.type.length*8 0A0214,0A0310
|
|||
AXPE1.data.pokemon.type.length+5 3C1235
|
||||
AXPE1.data.pokemon.type.length*8 0A0214,0A0310
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -23,28 +23,88 @@ namespace HavenSoft.HexManiac.Core.ViewModels.QuickEditItems {
|
|||
return viewPort is IEditableViewPort;
|
||||
}
|
||||
|
||||
public static IReadOnlyDictionary<string, int> GetNumberOfRelearnableMoves = new Dictionary<string, int> {
|
||||
{ "AXVE0", 0x040574 },
|
||||
{ "AXPE0", 0x040574 },
|
||||
{ "AXVE1", 0x040594 },
|
||||
{ "AXPE1", 0x040594 },
|
||||
{ "BPRE0", 0x043E2C },
|
||||
{ "BPGE0", 0x043E2C },
|
||||
{ "BPRE1", 0x043E40 },
|
||||
{ "BPGE1", 0x043E40 },
|
||||
{ "BPEE0", 0x06e25c },
|
||||
};
|
||||
public static IReadOnlyDictionary<string, int[]> MaxLevelUpMoveCountLocations = new Dictionary<string, int[]> { // each of these stores the max number of level-up moves, minus 1
|
||||
{ "AXVE0", new[] { 0x0404E8, 0x040556, 0x0406A4 } },
|
||||
{ "AXPE0", new[] { 0x0404E8, 0x040556, 0x0406A4 } },
|
||||
{ "AXVE1", new[] { 0x040508, 0x040576, 0x0406C4 } },
|
||||
{ "AXPE1", new[] { 0x040508, 0x040576, 0x0406C4 } },
|
||||
{ "BPRE0", new[] { 0x043DA0, 0x043E0E, 0x043F5C } },
|
||||
{ "BPGE0", new[] { 0x043DA0, 0x043E0E, 0x043F5C } },
|
||||
{ "BPRE1", new[] { 0x043DB4, 0x043E22, 0x043F70 } },
|
||||
{ "BPGE1", new[] { 0x043DB4, 0x043E22, 0x043F70 } },
|
||||
{ "BPEE0", new[] { 0x06E1D0, 0x06E23E, 0x06E38C } },
|
||||
};
|
||||
|
||||
public ErrorInfo Run(IViewPort viewPortInterface) {
|
||||
var viewPort = (IEditableViewPort)viewPortInterface;
|
||||
var model = viewPort.Model;
|
||||
var token = viewPort.ChangeHistory.CurrentChange;
|
||||
var parser = viewPort.Tools.CodeTool.Parser;
|
||||
|
||||
// fix limit for move effects
|
||||
var error = RefactorMoveByteFieldInTable(parser, viewPort.Model, token, MoveDataTable, "power", 9);
|
||||
if (error.HasError) return error;
|
||||
error = RefactorByteToHalfWordInTable(parser, viewPort.Model, token, MoveDataTable, "effect");
|
||||
var error = ExpandMoveEffects(parser, model, token);
|
||||
if (error.HasError) return error;
|
||||
|
||||
// update limiters
|
||||
ReplaceAll(parser, viewPort.Model, token,
|
||||
// update limiters for move names
|
||||
error = ReplaceAll(parser, viewPort.Model, token,
|
||||
new[] { "mov r0, #177", "lsl r0, r0, #1", "cmp r1, r0" },
|
||||
new[] { "mov r0, #177", "lsl r0, r0, #9", "cmp r1, r0" });
|
||||
if (error.HasError) return error;
|
||||
|
||||
// update max level-up moves from 20 to 40
|
||||
var code = model.GetGameCode();
|
||||
error = AddStackSpace(parser, viewPort.Model, token, GetNumberOfRelearnableMoves[code], 48, 40);
|
||||
if (error.HasError) return error;
|
||||
foreach (var address in MaxLevelUpMoveCountLocations[code]) token.ChangeData(viewPort.Model, address, 40 - 1);
|
||||
|
||||
// TODO update levelup moves
|
||||
var table = model.GetTable(LevelMovesTableName) as ArrayRun;
|
||||
|
||||
viewPort.Refresh();
|
||||
return ErrorInfo.NoError;
|
||||
}
|
||||
|
||||
public static ErrorInfo ExpandMoveEffects(ThumbParser parser, IDataModel model, ModelDelta token) {
|
||||
// make move effects 2 bytes instead of 1 byte
|
||||
var table = model.GetTable(MoveDataTable);
|
||||
var fieldNames = table.ElementContent.Select(seg => seg.Name).ToArray();
|
||||
Func<ErrorInfo> shiftField(int i) => () => RefactorMoveByteFieldInTable(parser, model, token, MoveDataTable, fieldNames[i], i + 1);
|
||||
var error = ChainErrors(
|
||||
shiftField(8), shiftField(7), shiftField(6), shiftField(5),
|
||||
shiftField(4), shiftField(3), shiftField(2), shiftField(1),
|
||||
() => RefactorByteToHalfWordInTable(parser, model, token, MoveDataTable, fieldNames[0]));
|
||||
if (error.HasError) return error;
|
||||
|
||||
// update offset pointers (because the PP field moved)
|
||||
foreach (OffsetPointerRun pointerRun in table.PointerSources
|
||||
.Select(address => model.GetNextRun(address))
|
||||
.Where(pointer => pointer is OffsetPointerRun)
|
||||
) {
|
||||
model.WritePointer(token, pointerRun.Start, table.Start + 5);
|
||||
model.ObserveRunWritten(token, new OffsetPointerRun(pointerRun.Start, 5));
|
||||
}
|
||||
|
||||
return ErrorInfo.NoError;
|
||||
}
|
||||
|
||||
public static ErrorInfo ChainErrors(params Func<ErrorInfo>[] actions) {
|
||||
foreach (var action in actions) {
|
||||
var result = action();
|
||||
if (result.HasError) return result;
|
||||
}
|
||||
return ErrorInfo.NoError;
|
||||
}
|
||||
|
||||
public static ErrorInfo RefactorMoveByteFieldInTable(ThumbParser parser, IDataModel model, ModelDelta token, string tableName, string fieldName, int newOffset) {
|
||||
// setup
|
||||
var table = model.GetTable(tableName) as ArrayRun;
|
||||
|
|
@ -135,6 +195,31 @@ namespace HavenSoft.HexManiac.Core.ViewModels.QuickEditItems {
|
|||
return ErrorInfo.NoError;
|
||||
}
|
||||
|
||||
public static ErrorInfo AddStackSpace(ThumbParser parser, IDataModel model, ModelDelta token, int funcStart, int stackAddOffset, int stackAddCount) {
|
||||
for (int i = funcStart; true; i += 2) {
|
||||
var commandLine = parser.Parse(model, i, 2).Trim().SplitLines().Last().Trim();
|
||||
if (commandLine.Contains("[sp, ")) {
|
||||
if (commandLine.StartsWith("str ") || commandLine.StartsWith("ldr ")) {
|
||||
var currentValue = model[i] * 4;
|
||||
if (currentValue >= stackAddOffset) {
|
||||
var newValue = (currentValue + stackAddCount) / 4;
|
||||
if (newValue > 255) return new ErrorInfo($"{i:X6}: Could not add {stackAddCount}, the result would be larger than 1020.");
|
||||
token.ChangeData(model, i, (byte)newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (commandLine.Contains(" sp, ")) {
|
||||
var writer = new TupleSegment(default, 7);
|
||||
var value = writer.Read(model, i, 0) * 4;
|
||||
value += stackAddCount;
|
||||
writer.Write(model, token, i, 0, value / 4);
|
||||
}
|
||||
if (commandLine.StartsWith("bx ")) break;
|
||||
}
|
||||
|
||||
return ErrorInfo.NoError;
|
||||
}
|
||||
|
||||
public static ErrorInfo ReplaceAll(ThumbParser parser, IDataModel model, ModelDelta token, string[] inputCode, string[] outputCode) {
|
||||
var search = parser.Compile(model, 0, inputCode);
|
||||
var replace = parser.Compile(model, 0, outputCode);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user