sm64coopdx/src/pc/lua/utils/smlua_level_utils.c
2023-08-18 18:31:59 +02:00

176 lines
4.7 KiB
C

#include "sm64.h"
#include "types.h"
#include "smlua_level_utils.h"
#include "pc/lua/smlua.h"
struct CustomLevelInfo* sCustomLevelHead = NULL;
static s16 sCustomLevelNumNext = CUSTOM_LEVEL_NUM_START;
void smlua_level_util_reset(void) {
struct CustomLevelInfo* node = sCustomLevelHead;
while (node != NULL) {
struct CustomLevelInfo* next = node->next;
if (node->scriptEntryName) {
free(node->scriptEntryName);
node->scriptEntryName = NULL;
}
if (node->fullName) {
free(node->fullName);
node->fullName = NULL;
}
if (node->shortName) {
free(node->shortName);
node->shortName = NULL;
}
free(node);
node = next;
}
sCustomLevelHead = NULL;
sCustomLevelNumNext = CUSTOM_LEVEL_NUM_START;
}
struct CustomLevelInfo* smlua_level_util_get_info(s16 levelNum) {
struct CustomLevelInfo* node = sCustomLevelHead;
while (node != NULL) {
if (node->levelNum == levelNum) {
return node;
}
node = node->next;
}
return NULL;
}
struct CustomLevelInfo* smlua_level_util_get_info_from_short_name(const char* shortName) {
struct CustomLevelInfo* node = sCustomLevelHead;
while (node != NULL) {
if (!strcmp(node->shortName, shortName)) {
return node;
}
node = node->next;
}
return NULL;
}
static struct CustomLevelInfo* smlua_level_util_get_info_from_script(char* scriptEntryName) {
struct CustomLevelInfo* node = sCustomLevelHead;
while (node != NULL) {
if (!strcmp(node->scriptEntryName, scriptEntryName)) {
return node;
}
node = node->next;
}
return NULL;
}
s16 level_register(const char* scriptEntryName, s16 courseNum, const char* fullName, const char* shortName, u32 acousticReach, u32 echoLevel1, u32 echoLevel2, u32 echoLevel3) {
// validate params
if (scriptEntryName == NULL) {
LOG_LUA("Provided nil scriptEntryName");
return 0;
}
if (fullName == NULL) {
LOG_LUA("Provided nil fullName");
return 0;
}
if (shortName == NULL) {
LOG_LUA("Provided nil shortName");
return 0;
}
// find duplicate
struct CustomLevelInfo* info = smlua_level_util_get_info_from_script((char*)scriptEntryName);
if (info != NULL) {
return info->levelNum;
}
// find script
LevelScript* script = dynos_get_level_script((char*)scriptEntryName);
if (script == NULL) {
LOG_LUA("Failed to find script: %s", scriptEntryName);
return 0;
}
// allocate and fill
info = calloc(1, sizeof(struct CustomLevelInfo));
info->script = script;
info->scriptEntryName = strdup(scriptEntryName);
info->courseNum = courseNum;
info->levelNum = sCustomLevelNumNext++;
info->fullName = strdup(fullName);
info->shortName = strdup(shortName);
info->acousticReach = acousticReach;
info->echoLevel1 = echoLevel1;
info->echoLevel2 = echoLevel2;
info->echoLevel3 = echoLevel3;
if (gLuaLoadingMod) {
info->modIndex = gLuaLoadingMod->index;
} else if (gLuaActiveMod) {
info->modIndex = gLuaActiveMod->index;
} else {
if (info->scriptEntryName) {
free(info->scriptEntryName);
info->scriptEntryName = NULL;
}
if (info->fullName) {
free(info->fullName);
info->fullName = NULL;
}
if (info->shortName) {
free(info->shortName);
info->shortName = NULL;
}
free(info);
LOG_LUA("Failed to find mod index for level: %s", scriptEntryName);
return 0;
}
// add to list
if (!sCustomLevelHead) {
sCustomLevelHead = info;
return info->levelNum;
}
struct CustomLevelInfo* node = sCustomLevelHead;
while (node) {
if (!node->next) {
node->next = info;
return info->levelNum;
}
node = node->next;
}
// just in case, should never trigger
return 0;
}
bool level_is_vanilla_level(s16 levelNum) {
return dynos_level_is_vanilla_level(levelNum);
}
bool warp_to_warpnode(s32 aLevel, s32 aArea, s32 aAct, s32 aWarpId) {
return dynos_warp_to_warpnode(aLevel, aArea, aAct, aWarpId);
}
bool warp_to_level(s32 aLevel, s32 aArea, s32 aAct) {
return dynos_warp_to_level(aLevel, aArea, aAct);
}
bool warp_to_start_level(void) {
return dynos_warp_to_start_level();
}
bool warp_restart_level(void) {
return dynos_warp_restart_level();
}
bool warp_exit_level(s32 aDelay) {
return dynos_warp_exit_level(aDelay);
}
bool warp_to_castle(s32 aLevel) {
return dynos_warp_to_castle(aLevel);
}