better level_script_parse

implemented all fields of the currently supported level commands:
- object model, position and angles
- macro model
This commit is contained in:
Isaac0-dev 2025-03-05 00:02:26 +10:00
parent 2fca847499
commit 0876d161e0
2 changed files with 76 additions and 44 deletions

View file

@ -353,8 +353,8 @@ end
--- @param func fun(areaIndex:number, bhvData:bhvData, macroBhvIds:BehaviorId[], macroBhvArgs:integer[]) --- @param func fun(areaIndex:number, bhvData:bhvData, macroBhvIds:BehaviorId[], macroBhvArgs:integer[])
--- When `func` is called, arguments are filled depending on the level command: --- When `func` is called, arguments are filled depending on the level command:
--- - `AREA` command: only `areaIndex` is filled. It's a number. --- - `AREA` command: only `areaIndex` is filled. It's a number.
--- - `OBJECT` command: only `bhvData` is filled. `bhvData` is a table with two fields: `behavior` and `behaviorArg`. --- - `OBJECT` command: only `bhvData` is filled. `bhvData` is a table with nine fields: 'behavior', 'behaviorArg', 'model', 'posX', 'posY', 'posZ', 'pitch', 'yaw' and 'roll'.
--- - `MACRO` command: only `macroBhvIds` and `macroBhvArgs` are filled. `macrobhvIds` is a list of behavior ids. `macroBhvArgs` is a list of behavior params. Both lists have the same size and start at index 0. --- - `MACRO` command: only `macroBhvIds`, `macroBhvArgs` and 'macroBhvModels' are filled. `macroBhvIds` is a list of behavior ids. `macroBhvArgs` is a list of behavior params. 'macroBhvModels' is a list of model ids. All lists have the same size and start at index 0.
function level_script_parse(levelNum, func) function level_script_parse(levelNum, func)
-- ... -- ...
end end

View file

@ -623,65 +623,88 @@ struct LuaLevelScriptParse {
struct LuaLevelScriptParse sLevelScriptParse = { 0 }; struct LuaLevelScriptParse sLevelScriptParse = { 0 };
s32 smlua_func_level_script_parse_callback(u8 type, void *cmd) { s32 smlua_func_level_script_parse_callback(u8 type, void *cmd) {
u32 areaIndex, bhvId, bhvArgs; u32 areaIndex, bhvId, bhvArgs, bhvModelId;
u32 *pAreaIndex = NULL, *pBhvId = NULL, *pBhvArgs = NULL; s16 bhvPosX, bhvPosY, bhvPosZ;
MacroObject *pMacroData = NULL; s32 bhvPitch, bhvYaw, bhvRoll;
bool area = false, bhv = false;
MacroObject *macroData = NULL;
// Gather arguments // Gather arguments
switch (type) { switch (type) {
// AREA // AREA
case 0x1F: { case 0x1F: {
areaIndex = (u8) dynos_level_cmd_get(cmd, 2); areaIndex = dynos_level_cmd_get(cmd, 2);
pAreaIndex = &areaIndex; area = true;
} break; } break;
// OBJECT_WITH_ACTS // OBJECT, OBJECT_WITH_ACTS
case 0x24: { case 0x24: {
const BehaviorScript *bhv = (const BehaviorScript *) dynos_level_cmd_get(cmd, 20); const BehaviorScript *bhvPtr = (const BehaviorScript *) dynos_level_cmd_get(cmd, 20);
if (bhv) { if (bhvPtr) {
bhvId = (u32) get_id_from_behavior(bhv); bhvId = get_id_from_behavior(bhvPtr);
bhvArgs = (u32) dynos_level_cmd_get(cmd, 16); if (bhvId == id_bhv1Up) {
pBhvId = &bhvId; bhvId = get_id_from_vanilla_behavior(bhvPtr); // for behaviors with no id in the script (e.g. bhvInstantActiveWarp)
pBhvArgs = &bhvArgs; }
bhvArgs = dynos_level_cmd_get(cmd, 16);
bhvModelId = dynos_level_cmd_get(cmd, 3);
bhvPosX = dynos_level_cmd_get(cmd, 4);
bhvPosY = dynos_level_cmd_get(cmd, 6);
bhvPosZ = dynos_level_cmd_get(cmd, 8);
bhvPitch = (dynos_level_cmd_get(cmd, 10) * 0x8000) / 180;
bhvYaw = (dynos_level_cmd_get(cmd, 12) * 0x8000) / 180;
bhvRoll = (dynos_level_cmd_get(cmd, 14) * 0x8000) / 180;
bhv = true;
} }
} break; } break;
// OBJECT_WITH_ACTS_EXT // OBJECT_EXT, OBJECT_WITH_ACTS_EXT
case 0x3F: { case 0x3F: {
if (gLevelScriptModIndex != -1) { if (gLevelScriptModIndex != -1) {
const char *bhvStr = dynos_level_get_token(dynos_level_cmd_get(cmd, 20)); const char *bhvStr = dynos_level_get_token(dynos_level_cmd_get(cmd, 20));
if (bhvStr) { if (bhvStr) {
gSmLuaConvertSuccess = true; gSmLuaConvertSuccess = true;
bhvId = (u32) smlua_get_integer_mod_variable(gLevelScriptModIndex, bhvStr); bhvId = smlua_get_integer_mod_variable(gLevelScriptModIndex, bhvStr);
if (!gSmLuaConvertSuccess) { if (!gSmLuaConvertSuccess) {
gSmLuaConvertSuccess = true; gSmLuaConvertSuccess = true;
bhvId = (u32) smlua_get_any_integer_mod_variable(bhvStr); bhvId = smlua_get_any_integer_mod_variable(bhvStr);
} }
if (gSmLuaConvertSuccess) { if (gSmLuaConvertSuccess) {
bhvArgs = (u32) dynos_level_cmd_get(cmd, 16); bhvArgs = dynos_level_cmd_get(cmd, 16);
pBhvId = &bhvId; bhvModelId = dynos_level_cmd_get(cmd, 3);
pBhvArgs = &bhvArgs; bhvPosX = dynos_level_cmd_get(cmd, 4);
bhvPosY = dynos_level_cmd_get(cmd, 6);
bhvPosZ = dynos_level_cmd_get(cmd, 8);
bhvPitch = (dynos_level_cmd_get(cmd, 10) * 0x8000) / 180;
bhvYaw = (dynos_level_cmd_get(cmd, 12) * 0x8000) / 180;
bhvRoll = (dynos_level_cmd_get(cmd, 14) * 0x8000) / 180;
bhv = true;
} }
} }
} }
} break; } break;
// OBJECT_WITH_ACTS_EXT2 // OBJECT_EXT2, OBJECT_WITH_ACTS_EXT2
case 0x40: { case 0x40: {
if (gLevelScriptModIndex != -1) { if (gLevelScriptModIndex != -1) {
const char *bhvStr = dynos_level_get_token(dynos_level_cmd_get(cmd, 24)); const char *bhvStr = dynos_level_get_token(dynos_level_cmd_get(cmd, 24));
if (bhvStr) { if (bhvStr) {
gSmLuaConvertSuccess = true; gSmLuaConvertSuccess = true;
bhvId = (u32) smlua_get_integer_mod_variable(gLevelScriptModIndex, bhvStr); bhvId = smlua_get_integer_mod_variable(gLevelScriptModIndex, bhvStr);
if (!gSmLuaConvertSuccess) { if (!gSmLuaConvertSuccess) {
gSmLuaConvertSuccess = true; gSmLuaConvertSuccess = true;
bhvId = (u32) smlua_get_any_integer_mod_variable(bhvStr); bhvId = smlua_get_any_integer_mod_variable(bhvStr);
} }
if (gSmLuaConvertSuccess) { if (gSmLuaConvertSuccess) {
bhvArgs = (u32) dynos_level_cmd_get(cmd, 16); bhvArgs = dynos_level_cmd_get(cmd, 16);
pBhvId = &bhvId; bhvModelId = dynos_level_cmd_get(cmd, 3);
pBhvArgs = &bhvArgs; bhvPosX = dynos_level_cmd_get(cmd, 4);
bhvPosY = dynos_level_cmd_get(cmd, 6);
bhvPosZ = dynos_level_cmd_get(cmd, 8);
bhvPitch = (dynos_level_cmd_get(cmd, 10) * 0x8000) / 180;
bhvYaw = (dynos_level_cmd_get(cmd, 12) * 0x8000) / 180;
bhvRoll = (dynos_level_cmd_get(cmd, 14) * 0x8000) / 180;
bhv = true;
} }
} }
} }
@ -689,7 +712,7 @@ s32 smlua_func_level_script_parse_callback(u8 type, void *cmd) {
// MACRO_OBJECTS // MACRO_OBJECTS
case 0x39: { case 0x39: {
pMacroData = (MacroObject *) dynos_level_cmd_get(cmd, 4); macroData = (MacroObject *) dynos_level_cmd_get(cmd, 4);
} break; } break;
// None of the above // None of the above
@ -703,35 +726,40 @@ s32 smlua_func_level_script_parse_callback(u8 type, void *cmd) {
lua_rawgeti(L, LUA_REGISTRYINDEX, preprocess->reference); lua_rawgeti(L, LUA_REGISTRYINDEX, preprocess->reference);
// Push 'areaIndex' // Push 'areaIndex'
if (pAreaIndex) { if (area) {
lua_pushinteger(L, *pAreaIndex); lua_pushinteger(L, areaIndex);
} else { } else {
lua_pushnil(L); lua_pushnil(L);
} }
// Push 'bhvData' // Push 'bhvData'
if (pBhvId && pBhvArgs) { if (bhv) {
lua_newtable(L); lua_newtable(L);
lua_pushstring(L, "behavior"); smlua_push_integer_field(-2, "behavior", bhvId);
lua_pushinteger(L, *pBhvId); smlua_push_integer_field(-2, "behaviorArg", bhvArgs);
lua_settable(L, -3); smlua_push_integer_field(-2, "model", bhvModelId);
lua_pushstring(L, "behaviorArg"); smlua_push_integer_field(-2, "posX", bhvPosX);
lua_pushinteger(L, *pBhvArgs); smlua_push_integer_field(-2, "posY", bhvPosY);
lua_settable(L, -3); smlua_push_integer_field(-2, "posZ", bhvPosZ);
smlua_push_integer_field(-2, "pitch", bhvPitch);
smlua_push_integer_field(-2, "yaw", bhvYaw);
smlua_push_integer_field(-2, "roll", bhvRoll);
} else { } else {
lua_pushnil(L); lua_pushnil(L);
} }
// Push 'macroBhvIds' and 'macroBhvArgs' // Push 'macroBhvIds' and 'macroBhvArgs' and 'macroBhvModels'
if (pMacroData) { if (macroData) {
lua_newtable(L); lua_newtable(L);
s32 macroBhvIdsIdx = lua_gettop(gLuaState); s32 macroBhvIdsIdx = lua_gettop(L);
lua_newtable(L); lua_newtable(L);
s32 macroBhvArgsIdx = lua_gettop(gLuaState); s32 macroBhvArgsIdx = lua_gettop(L);
for (s32 i = 0; *pMacroData != MACRO_OBJECT_END(); pMacroData += 5, i++) { lua_newtable(L);
s32 presetId = (s32) ((pMacroData[0] & 0x1FF) - 0x1F); s32 macroBhvModelsIdx = lua_gettop(L);
for (s32 i = 0; *macroData != MACRO_OBJECT_END(); macroData += 5, i++) {
s32 presetId = (s32) ((macroData[0] & 0x1FF) - 0x1F);
s32 presetParams = MacroObjectPresets[presetId].param; s32 presetParams = MacroObjectPresets[presetId].param;
s32 objParams = (pMacroData[4] & 0xFF00) | (presetParams & 0x00FF); s32 objParams = (macroData[4] & 0xFF00) | (presetParams & 0x00FF);
s32 bhvParams = ((objParams & 0x00FF) << 16) | (objParams & 0xFF00); s32 bhvParams = ((objParams & 0x00FF) << 16) | (objParams & 0xFF00);
lua_pushinteger(L, i); lua_pushinteger(L, i);
lua_pushinteger(L, get_id_from_behavior(MacroObjectPresets[presetId].behavior)); lua_pushinteger(L, get_id_from_behavior(MacroObjectPresets[presetId].behavior));
@ -739,14 +767,18 @@ s32 smlua_func_level_script_parse_callback(u8 type, void *cmd) {
lua_pushinteger(L, i); lua_pushinteger(L, i);
lua_pushinteger(L, bhvParams); lua_pushinteger(L, bhvParams);
lua_settable(L, macroBhvArgsIdx); lua_settable(L, macroBhvArgsIdx);
lua_pushinteger(L, i);
lua_pushinteger(L, MacroObjectPresets[presetId].model);
lua_settable(L, macroBhvModelsIdx);
} }
} else { } else {
lua_pushnil(L); lua_pushnil(L);
lua_pushnil(L); lua_pushnil(L);
lua_pushnil(L);
} }
// call the callback // call the callback
if (0 != smlua_call_hook(L, 4, 0, 0, preprocess->mod)) { if (0 != smlua_call_hook(L, 5, 0, 0, preprocess->mod)) {
LOG_LUA("Failed to call the callback behaviors: %u", type); LOG_LUA("Failed to call the callback behaviors: %u", type);
return 0; return 0;
} }