From 984cb73bfc618153b6bb8e6a22bbaa39b4b4167e Mon Sep 17 00:00:00 2001 From: VladiStep Date: Fri, 5 Jan 2024 23:08:39 +0300 Subject: [PATCH] Add a support for multidimensional arrays in function args. --- .../UndertaleResourceReferenceMethodsMap.cs | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/UndertaleModTool/Windows/FindReferencesTypesDialog/UndertaleResourceReferenceMethodsMap.cs b/UndertaleModTool/Windows/FindReferencesTypesDialog/UndertaleResourceReferenceMethodsMap.cs index 2f0419d04..4556ea8e2 100644 --- a/UndertaleModTool/Windows/FindReferencesTypesDialog/UndertaleResourceReferenceMethodsMap.cs +++ b/UndertaleModTool/Windows/FindReferencesTypesDialog/UndertaleResourceReferenceMethodsMap.cs @@ -51,7 +51,7 @@ public static class UndertaleResourceReferenceMethodsMap private static Dictionary> gameObjReferences; #region Call instructions processing - private static bool isGM2023_8; + private static bool isGMS2_3, isGM2023_8; private static int dummyInt; private static bool ConsumeCallArgument(bool isLastArg, ref int i, UndertaleCode code, ref int val, bool dontParse = false) { @@ -59,6 +59,9 @@ private static bool ConsumeCallArgument(bool isLastArg, ref int i, UndertaleCode { // If it's an asset argument and we don't need to consume // all instructions, then we only check one (GM 2023.8+) or two instructions. + // Also, it's possible that it will be `conv` + `pushi` in GM 2023.8+, but + // it would mean that the reference is not recognized, so + // we should also skip that. var instr = code.Instructions[i]; if (isGM2023_8 && instr.Kind == Opcode.Break @@ -103,23 +106,29 @@ private static bool ConsumeCallArgument(bool isLastArg, ref int i, UndertaleCode break; - // It's possible that it will be `conv` and `pushi` in GM 2023.8+, but - // it would mean that the reference is not recognized, so - // we should also skip that. - case Opcode.PushI when !isGM2023_8: - case Opcode.Break: - case Opcode.PushBltn or Opcode.PushGlb or Opcode.PushEnv - or Opcode.PushLoc: + case Opcode.PushI: + case Opcode.PushBltn or Opcode.PushGlb or Opcode.PushEnv or Opcode.PushLoc: break; case Opcode.Push: if (instr.Value is Reference varRef) { - if (varRef.Type == VariableType.Array) + if (varRef.Type == VariableType.Array + || varRef.Type == VariableType.ArrayPushAF) + { instrRemaining += 2; + } else if (varRef.Type == VariableType.StackTop) + { instrRemaining++; - // TODO: check other `VariableType` values + } + } + break; + case Opcode.Break when isGMS2_3: + if (instr.Value is short v) + { + if (v == -2 || v == -4) // `pushaf`, `pushac` + instrRemaining += 2; } break; @@ -1787,6 +1796,7 @@ public static Dictionary> GetReferencesOfObject(object obj, gameObjFunctions = new(kvpList); } + isGMS2_3 = data.IsVersionAtLeast(2, 3); isGM2023_8 = data.IsVersionAtLeast(2023, 8); getAssetIndexCurr = isGM2023_8 ? getAssetIndexGM2023_8 : getAssetIndex; } @@ -1841,6 +1851,7 @@ public static async Task>> GetUnreferencedObject gameObjFunctions = new(kvpList); } + isGMS2_3 = data.IsVersionAtLeast(2, 3); isGM2023_8 = data.IsVersionAtLeast(2023, 8); getAssetIndexCurr = isGM2023_8 ? getAssetIndexGM2023_8 : getAssetIndex;