mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-12-22 16:30:23 +00:00
Added ability to have completely custom levels that don't override anything
This commit is contained in:
parent
a40c3cf121
commit
946f16329c
28 changed files with 726 additions and 214 deletions
|
@ -42,6 +42,7 @@ in_files = [
|
|||
"src/pc/lua/utils/smlua_model_utils.h",
|
||||
"src/pc/lua/utils/smlua_text_utils.h",
|
||||
"src/pc/lua/utils/smlua_audio_utils.h",
|
||||
"src/pc/lua/utils/smlua_level_utils.h",
|
||||
"src/game/object_helpers.c",
|
||||
"src/game/obj_behaviors.c",
|
||||
"src/game/obj_behaviors_2.c",
|
||||
|
@ -87,7 +88,8 @@ override_disallowed_functions = {
|
|||
"src/game/camera.h": [ "update_camera", "init_camera", "stub_camera", "^reset_camera", "move_point_along_spline" ],
|
||||
"src/game/behavior_actions.h": [ "bhv_dust_smoke_loop", "bhv_init_room" ],
|
||||
"src/pc/lua/utils/smlua_audio_utils.h": [ "smlua_audio_utils_override", "audio_custom_shutdown"],
|
||||
"src/pc/djui/djui_hud_utils.h": [ "djui_hud_render_texture", "djui_hud_render_texture_raw" ],
|
||||
"src/pc/djui/djui_hud_utils.h": [ "djui_hud_render_texture", "djui_hud_render_texture_raw" ],
|
||||
"src/pc/lua/utils/smlua_level_utils.h": [ "smlua_level_util_reset" ],
|
||||
}
|
||||
|
||||
lua_function_params = {
|
||||
|
|
|
@ -18,6 +18,7 @@ in_files = [
|
|||
'src/pc/lua/utils/smlua_anim_utils.h',
|
||||
'src/pc/lua/utils/smlua_misc_utils.h',
|
||||
'src/pc/lua/utils/smlua_collision_utils.h',
|
||||
'src/pc/lua/utils/smlua_level_utils.h',
|
||||
'src/game/spawn_sound.h',
|
||||
'src/pc/network/network.h',
|
||||
'src/game/hardcoded.h',
|
||||
|
|
|
@ -7330,6 +7330,56 @@ function smlua_collision_util_get(name)
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param scriptEntryName string
|
||||
--- @param courseNum integer
|
||||
--- @param fullName string
|
||||
--- @param shortName string
|
||||
--- @param acousticReach integer
|
||||
--- @param echoLevel1 integer
|
||||
--- @param echoLevel2 integer
|
||||
--- @param echoLevel3 integer
|
||||
--- @return integer
|
||||
function level_register(scriptEntryName, courseNum, fullName, shortName, acousticReach, echoLevel1, echoLevel2, echoLevel3)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param levelNum integer
|
||||
--- @return CustomLevelInfo
|
||||
function smlua_level_util_get_info(levelNum)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param shortName string
|
||||
--- @return CustomLevelInfo
|
||||
function smlua_level_util_get_info_from_short_name(shortName)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param aDelay integer
|
||||
--- @return boolean
|
||||
function warp_exit_level(aDelay)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @return boolean
|
||||
function warp_restart_level()
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param aLevel integer
|
||||
--- @return boolean
|
||||
function warp_to_castle(aLevel)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param aLevel integer
|
||||
--- @param aArea integer
|
||||
--- @param aAct integer
|
||||
--- @return boolean
|
||||
function warp_to_level(aLevel, aArea, aAct)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param actFlags integer
|
||||
--- @return integer
|
||||
function allocate_mario_action(actFlags)
|
||||
|
@ -7593,31 +7643,6 @@ function set_override_near(near)
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param aDelay integer
|
||||
--- @return boolean
|
||||
function warp_exit_level(aDelay)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @return boolean
|
||||
function warp_restart_level()
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param aLevel integer
|
||||
--- @return boolean
|
||||
function warp_to_castle(aLevel)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param aLevel integer
|
||||
--- @param aArea integer
|
||||
--- @param aAct integer
|
||||
--- @return boolean
|
||||
function warp_to_level(aLevel, aArea, aAct)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param name string
|
||||
--- @return integer
|
||||
function smlua_model_util_get_id(name)
|
||||
|
|
|
@ -327,6 +327,19 @@
|
|||
--- @field public stickX number
|
||||
--- @field public stickY number
|
||||
|
||||
--- @class CustomLevelInfo
|
||||
--- @field public acousticReach integer
|
||||
--- @field public courseNum integer
|
||||
--- @field public echoLevel1 integer
|
||||
--- @field public echoLevel2 integer
|
||||
--- @field public echoLevel3 integer
|
||||
--- @field public fullName string
|
||||
--- @field public levelNum integer
|
||||
--- @field public next CustomLevelInfo
|
||||
--- @field public script Pointer_LevelScript
|
||||
--- @field public scriptEntryName string
|
||||
--- @field public shortName string
|
||||
|
||||
--- @class Cutscene
|
||||
--- @field public duration integer
|
||||
|
||||
|
@ -1777,6 +1790,7 @@
|
|||
|
||||
--- @class Pointer_integer
|
||||
--- @class Pointer_Trajectory
|
||||
--- @class Pointer_LevelScript
|
||||
--- @class Pointer_ObjectAnimPointer
|
||||
--- @class Pointer_Collision
|
||||
--- @class Pointer_BehaviorScript
|
||||
|
|
|
@ -17,6 +17,7 @@ s32 dynos_tex_import(void **output, void *ptr, s32 tile, void *grapi, void **h
|
|||
void dynos_gfx_swap_animations(void *ptr);
|
||||
|
||||
// -- warps -- //
|
||||
LevelScript* dynos_get_level_script(char* scriptEntryName);
|
||||
bool dynos_warp_to_level(s32 aLevel, s32 aArea, s32 aAct);
|
||||
bool dynos_warp_restart_level(void);
|
||||
bool dynos_warp_exit_level(s32 aDelay);
|
||||
|
|
|
@ -815,6 +815,7 @@ void DynOS_Tex_ModShutdown();
|
|||
//
|
||||
|
||||
Array<Pair<const char*, GfxData*>> &DynOS_Lvl_GetArray();
|
||||
LevelScript* DynOS_Lvl_GetScript(char* aScriptEntryName);
|
||||
void DynOS_Lvl_Activate(s32 modIndex, const SysPath &aFilePath, const char *aLevelName);
|
||||
GfxData* DynOS_Lvl_GetActiveGfx(void);
|
||||
const char* DynOS_Lvl_GetToken(u32 index);
|
||||
|
|
|
@ -30,6 +30,10 @@ void dynos_gfx_swap_animations(void *ptr) {
|
|||
|
||||
// -- warps -- //
|
||||
|
||||
LevelScript* dynos_get_level_script(char* scriptEntryName) {
|
||||
return DynOS_Lvl_GetScript(scriptEntryName);
|
||||
}
|
||||
|
||||
bool dynos_warp_to_level(s32 aLevel, s32 aArea, s32 aAct) {
|
||||
return DynOS_Warp_ToLevel(aLevel, aArea, aAct);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ extern "C" {
|
|||
#include "game/segment2.h"
|
||||
#include "game/save_file.h"
|
||||
#include "levels/scripts.h"
|
||||
#include "pc/lua/utils/smlua_level_utils.h"
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -198,7 +199,7 @@ static void DynOS_Level_Init() {
|
|||
for (s32 i = COURSE_MIN; i <= COURSE_MAX; ++i) {
|
||||
if (i == COURSE_CAKE_END) continue;
|
||||
for (s32 j = 1; j != LEVEL_COUNT; ++j) {
|
||||
if (gLevelToCourseNumTable[j - 1] == i) {
|
||||
if (get_level_course_num(j - 1) == i) {
|
||||
sDynosLevelList.Add(j);
|
||||
}
|
||||
}
|
||||
|
@ -249,6 +250,12 @@ void DynOS_Level_Unoverride() {
|
|||
}
|
||||
|
||||
const void *DynOS_Level_GetScript(s32 aLevel) {
|
||||
if (aLevel >= CUSTOM_LEVEL_NUM_START) {
|
||||
struct CustomLevelInfo* info = smlua_level_util_get_info(aLevel);
|
||||
if (!info || !info->script) { return NULL; }
|
||||
return info->script;
|
||||
}
|
||||
|
||||
DynOS_Level_Init();
|
||||
return sDynosLevelScripts[aLevel];
|
||||
}
|
||||
|
@ -844,6 +851,21 @@ static void DynOS_Level_ParseScript(const void *aScript, s32 (*aPreprocessFuncti
|
|||
//
|
||||
|
||||
s16 *DynOS_Level_GetWarp(s32 aLevel, s32 aArea, u8 aWarpId) {
|
||||
if (aLevel >= CUSTOM_LEVEL_NUM_START) {
|
||||
struct CustomLevelInfo* info = smlua_level_util_get_info(aLevel);
|
||||
if (!info || !info->script) { return NULL; }
|
||||
sDynosCurrentLevelNum = 1;
|
||||
DynOS_Level_ParseScript(info->script, DynOS_Level_PreprocessScript);
|
||||
for (const auto &_Warp : sDynosLevelWarps[1]) {
|
||||
if (_Warp.mArea == aArea) {
|
||||
if (_Warp.mId == aWarpId) {
|
||||
return (s16 *) &_Warp;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DynOS_Level_Init();
|
||||
for (const auto &_Warp : sDynosLevelWarps[aLevel]) {
|
||||
if (_Warp.mArea == aArea) {
|
||||
|
|
|
@ -21,6 +21,19 @@ Array<Pair<const char*, GfxData*>> &DynOS_Lvl_GetArray() {
|
|||
return sDynosCustomLevelScripts;
|
||||
}
|
||||
|
||||
LevelScript* DynOS_Lvl_GetScript(char* aScriptEntryName) {
|
||||
auto& _CustomLevelScripts = DynOS_Lvl_GetArray();
|
||||
for (s32 i = 0; i < _CustomLevelScripts.Count(); ++i) {
|
||||
auto& pair = _CustomLevelScripts[i];
|
||||
if (!strcmp(pair.first, aScriptEntryName)) {
|
||||
auto& newScripts = pair.second->mLevelScripts;
|
||||
auto& newScriptNode = newScripts[newScripts.Count() - 1];
|
||||
return newScriptNode->mData;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void DynOS_Lvl_ModShutdown() {
|
||||
DynOS_Level_Unoverride();
|
||||
|
||||
|
@ -66,6 +79,7 @@ void DynOS_Lvl_Activate(s32 modIndex, const SysPath &aFilename, const char *aLev
|
|||
|
||||
// Add to levels
|
||||
_CustomLevelScripts.Add({ levelName, _Node });
|
||||
DynOS_Tex_Valid(_Node);
|
||||
|
||||
// Override vanilla script
|
||||
auto& newScripts = _Node->mLevelScripts;
|
||||
|
@ -78,7 +92,6 @@ void DynOS_Lvl_Activate(s32 modIndex, const SysPath &aFilename, const char *aLev
|
|||
|
||||
DynOS_Level_Override((void*)originalScript, newScriptNode->mData);
|
||||
_OverrideLevelScripts.Add({ originalScript, newScriptNode->mData, _Node});
|
||||
DynOS_Tex_Valid(_Node);
|
||||
}
|
||||
|
||||
GfxData* DynOS_Lvl_GetActiveGfx(void) {
|
||||
|
@ -170,3 +183,4 @@ void *DynOS_Lvl_Override(void *aCmd) {
|
|||
}
|
||||
return aCmd;
|
||||
}
|
||||
|
||||
|
|
|
@ -6073,6 +6073,159 @@
|
|||
|
||||
<br />
|
||||
|
||||
---
|
||||
# functions from smlua_level_utils.h
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
## [level_register](#level_register)
|
||||
|
||||
### Lua Example
|
||||
`local integerValue = level_register(scriptEntryName, courseNum, fullName, shortName, acousticReach, echoLevel1, echoLevel2, echoLevel3)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| scriptEntryName | `string` |
|
||||
| courseNum | `integer` |
|
||||
| fullName | `string` |
|
||||
| shortName | `string` |
|
||||
| acousticReach | `integer` |
|
||||
| echoLevel1 | `integer` |
|
||||
| echoLevel2 | `integer` |
|
||||
| echoLevel3 | `integer` |
|
||||
|
||||
### Returns
|
||||
- `integer`
|
||||
|
||||
### C Prototype
|
||||
`s16 level_register(const char* scriptEntryName, s16 courseNum, const char* fullName, const char* shortName, u32 acousticReach, u32 echoLevel1, u32 echoLevel2, u32 echoLevel3);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [smlua_level_util_get_info](#smlua_level_util_get_info)
|
||||
|
||||
### Lua Example
|
||||
`local CustomLevelInfoValue = smlua_level_util_get_info(levelNum)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| levelNum | `integer` |
|
||||
|
||||
### Returns
|
||||
[CustomLevelInfo](structs.md#CustomLevelInfo)
|
||||
|
||||
### C Prototype
|
||||
`struct CustomLevelInfo* smlua_level_util_get_info(s16 levelNum);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [smlua_level_util_get_info_from_short_name](#smlua_level_util_get_info_from_short_name)
|
||||
|
||||
### Lua Example
|
||||
`local CustomLevelInfoValue = smlua_level_util_get_info_from_short_name(shortName)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| shortName | `string` |
|
||||
|
||||
### Returns
|
||||
[CustomLevelInfo](structs.md#CustomLevelInfo)
|
||||
|
||||
### C Prototype
|
||||
`struct CustomLevelInfo* smlua_level_util_get_info_from_short_name(char* shortName);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [warp_exit_level](#warp_exit_level)
|
||||
|
||||
### Lua Example
|
||||
`local booleanValue = warp_exit_level(aDelay)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| aDelay | `integer` |
|
||||
|
||||
### Returns
|
||||
- `boolean`
|
||||
|
||||
### C Prototype
|
||||
`bool warp_exit_level(s32 aDelay);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [warp_restart_level](#warp_restart_level)
|
||||
|
||||
### Lua Example
|
||||
`local booleanValue = warp_restart_level()`
|
||||
|
||||
### Parameters
|
||||
- None
|
||||
|
||||
### Returns
|
||||
- `boolean`
|
||||
|
||||
### C Prototype
|
||||
`bool warp_restart_level(void);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [warp_to_castle](#warp_to_castle)
|
||||
|
||||
### Lua Example
|
||||
`local booleanValue = warp_to_castle(aLevel)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| aLevel | `integer` |
|
||||
|
||||
### Returns
|
||||
- `boolean`
|
||||
|
||||
### C Prototype
|
||||
`bool warp_to_castle(s32 aLevel);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [warp_to_level](#warp_to_level)
|
||||
|
||||
### Lua Example
|
||||
`local booleanValue = warp_to_level(aLevel, aArea, aAct)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| aLevel | `integer` |
|
||||
| aArea | `integer` |
|
||||
| aAct | `integer` |
|
||||
|
||||
### Returns
|
||||
- `boolean`
|
||||
|
||||
### C Prototype
|
||||
`bool warp_to_level(s32 aLevel, s32 aArea, s32 aAct);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
---
|
||||
# functions from smlua_misc_utils.h
|
||||
|
||||
|
@ -6941,86 +7094,6 @@
|
|||
|
||||
<br />
|
||||
|
||||
## [warp_exit_level](#warp_exit_level)
|
||||
|
||||
### Lua Example
|
||||
`local booleanValue = warp_exit_level(aDelay)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| aDelay | `integer` |
|
||||
|
||||
### Returns
|
||||
- `boolean`
|
||||
|
||||
### C Prototype
|
||||
`bool warp_exit_level(s32 aDelay);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [warp_restart_level](#warp_restart_level)
|
||||
|
||||
### Lua Example
|
||||
`local booleanValue = warp_restart_level()`
|
||||
|
||||
### Parameters
|
||||
- None
|
||||
|
||||
### Returns
|
||||
- `boolean`
|
||||
|
||||
### C Prototype
|
||||
`bool warp_restart_level(void);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [warp_to_castle](#warp_to_castle)
|
||||
|
||||
### Lua Example
|
||||
`local booleanValue = warp_to_castle(aLevel)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| aLevel | `integer` |
|
||||
|
||||
### Returns
|
||||
- `boolean`
|
||||
|
||||
### C Prototype
|
||||
`bool warp_to_castle(s32 aLevel);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [warp_to_level](#warp_to_level)
|
||||
|
||||
### Lua Example
|
||||
`local booleanValue = warp_to_level(aLevel, aArea, aAct)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| aLevel | `integer` |
|
||||
| aArea | `integer` |
|
||||
| aAct | `integer` |
|
||||
|
||||
### Returns
|
||||
- `boolean`
|
||||
|
||||
### C Prototype
|
||||
`bool warp_to_level(s32 aLevel, s32 aArea, s32 aAct);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
---
|
||||
# functions from smlua_model_utils.h
|
||||
|
||||
|
|
|
@ -1368,6 +1368,17 @@
|
|||
|
||||
<br />
|
||||
|
||||
- smlua_level_utils.h
|
||||
- [level_register](functions-4.md#level_register)
|
||||
- [smlua_level_util_get_info](functions-4.md#smlua_level_util_get_info)
|
||||
- [smlua_level_util_get_info_from_short_name](functions-4.md#smlua_level_util_get_info_from_short_name)
|
||||
- [warp_exit_level](functions-4.md#warp_exit_level)
|
||||
- [warp_restart_level](functions-4.md#warp_restart_level)
|
||||
- [warp_to_castle](functions-4.md#warp_to_castle)
|
||||
- [warp_to_level](functions-4.md#warp_to_level)
|
||||
|
||||
<br />
|
||||
|
||||
- smlua_misc_utils.h
|
||||
- [allocate_mario_action](functions-4.md#allocate_mario_action)
|
||||
- [camera_config_enable_analog_cam](functions-4.md#camera_config_enable_analog_cam)
|
||||
|
@ -1413,10 +1424,6 @@
|
|||
- [set_override_far](functions-4.md#set_override_far)
|
||||
- [set_override_fov](functions-4.md#set_override_fov)
|
||||
- [set_override_near](functions-4.md#set_override_near)
|
||||
- [warp_exit_level](functions-4.md#warp_exit_level)
|
||||
- [warp_restart_level](functions-4.md#warp_restart_level)
|
||||
- [warp_to_castle](functions-4.md#warp_to_castle)
|
||||
- [warp_to_level](functions-4.md#warp_to_level)
|
||||
|
||||
<br />
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
- [ChainSegment](#ChainSegment)
|
||||
- [Character](#Character)
|
||||
- [Controller](#Controller)
|
||||
- [CustomLevelInfo](#CustomLevelInfo)
|
||||
- [Cutscene](#Cutscene)
|
||||
- [CutsceneSplinePoint](#CutsceneSplinePoint)
|
||||
- [CutsceneVariable](#CutsceneVariable)
|
||||
|
@ -506,6 +507,26 @@
|
|||
|
||||
<br />
|
||||
|
||||
## [CustomLevelInfo](#CustomLevelInfo)
|
||||
|
||||
| Field | Type | Access |
|
||||
| ----- | ---- | ------ |
|
||||
| acousticReach | `integer` | |
|
||||
| courseNum | `integer` | |
|
||||
| echoLevel1 | `integer` | |
|
||||
| echoLevel2 | `integer` | |
|
||||
| echoLevel3 | `integer` | |
|
||||
| fullName | `string` | read-only |
|
||||
| levelNum | `integer` | |
|
||||
| next | [CustomLevelInfo](structs.md#CustomLevelInfo) | |
|
||||
| script | `Pointer` <`LevelScript`> | read-only |
|
||||
| scriptEntryName | `string` | read-only |
|
||||
| shortName | `string` | read-only |
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [Cutscene](#Cutscene)
|
||||
|
||||
| Field | Type | Access |
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "seq_ids.h"
|
||||
#include "dialog_ids.h"
|
||||
#include "level_table.h"
|
||||
#include "pc/lua/utils/smlua_level_utils.h"
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
#define EU_FLOAT(x) x##f
|
||||
|
@ -511,6 +512,50 @@ void process_level_music_dynamics(void);
|
|||
static u8 begin_background_music_fade(u16 fadeDuration);
|
||||
void func_80320ED8(void);
|
||||
|
||||
static s16 get_level_dynamics(s16 levelNum, s16 index) {
|
||||
if (levelNum < 0 || levelNum >= LEVEL_COUNT) {
|
||||
return 0;
|
||||
}
|
||||
return sLevelDynamics[levelNum][index];
|
||||
}
|
||||
|
||||
static u8 get_level_area_reverb(s16 levelNum, s16 index) {
|
||||
if (levelNum >= CUSTOM_LEVEL_NUM_START) {
|
||||
struct CustomLevelInfo* info = smlua_level_util_get_info(levelNum);
|
||||
if (!info) { return 0x00; }
|
||||
switch (index) {
|
||||
case 0: return info->echoLevel1; break;
|
||||
case 1: return info->echoLevel2; break;
|
||||
case 2: return info->echoLevel3; break;
|
||||
}
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
if (levelNum < 0 || levelNum >= LEVEL_COUNT) {
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
if (index < 0 || index >= 3) {
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
return sLevelAreaReverbs[levelNum][index];
|
||||
|
||||
}
|
||||
|
||||
static u16 get_level_acoustic_reaches(s16 levelNum) {
|
||||
if (levelNum >= CUSTOM_LEVEL_NUM_START) {
|
||||
struct CustomLevelInfo* info = smlua_level_util_get_info(levelNum);
|
||||
return (info ? info->acousticReach : 20000);
|
||||
}
|
||||
|
||||
if (levelNum < 0 || levelNum >= LEVEL_COUNT) {
|
||||
return 20000;
|
||||
}
|
||||
|
||||
return sLevelAcousticReaches[levelNum];
|
||||
}
|
||||
|
||||
#ifndef VERSION_JP
|
||||
void unused_8031E4F0(void) {
|
||||
// This is a debug function which is almost entirely optimized away,
|
||||
|
@ -1215,7 +1260,7 @@ static f32 get_sound_volume(u8 bank, u8 soundIndex, f32 volumeRange) {
|
|||
if (!(sSoundBanks[bank][soundIndex].soundBits & SOUND_NO_VOLUME_LOSS)) {
|
||||
#ifdef VERSION_JP
|
||||
// Intensity linearly lowers from 1 at the camera to 0 at maxSoundDistance
|
||||
maxSoundDistance = sLevelAcousticReaches[gCurrLevelNum];
|
||||
maxSoundDistance = get_level_acoustic_reaches(gCurrLevelNum);
|
||||
if (maxSoundDistance < sSoundBanks[bank][soundIndex].distance) {
|
||||
intensity = 0.0f;
|
||||
} else {
|
||||
|
@ -1227,7 +1272,7 @@ static f32 get_sound_volume(u8 bank, u8 soundIndex, f32 volumeRange) {
|
|||
if (sSoundBanks[bank][soundIndex].distance > AUDIO_MAX_DISTANCE) {
|
||||
intensity = 0.0f;
|
||||
} else {
|
||||
maxSoundDistance = sLevelAcousticReaches[gCurrLevelNum] / div;
|
||||
maxSoundDistance = get_level_acoustic_reaches(gCurrLevelNum) / div;
|
||||
if (maxSoundDistance < sSoundBanks[bank][soundIndex].distance) {
|
||||
intensity = ((AUDIO_MAX_DISTANCE - sSoundBanks[bank][soundIndex].distance)
|
||||
/ (AUDIO_MAX_DISTANCE - maxSoundDistance))
|
||||
|
@ -1305,7 +1350,7 @@ static u8 get_sound_reverb(UNUSED u8 bank, UNUSED u8 soundIndex, u8 channelIndex
|
|||
// The volume-dependent value is 0 when volume is at maximum, and raises to
|
||||
// LOW_VOLUME_REVERB when the volume is 0
|
||||
reverb = (u8)((u8) gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->soundScriptIO[5]
|
||||
+ sLevelAreaReverbs[level][area]
|
||||
+ get_level_area_reverb(level, area)
|
||||
+ (US_FLOAT(1.0) - gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->volume)
|
||||
* LOW_VOLUME_REVERB);
|
||||
|
||||
|
@ -1867,12 +1912,12 @@ void process_level_music_dynamics(void) {
|
|||
sBackgroundMusicForDynamics = sCurrentBackgroundMusicSeqId;
|
||||
}
|
||||
|
||||
if (sBackgroundMusicForDynamics != sLevelDynamics[gCurrLevelNum][0]) {
|
||||
if (sBackgroundMusicForDynamics != get_level_dynamics(gCurrLevelNum, 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
conditionBits = sLevelDynamics[gCurrLevelNum][1] & 0xff00;
|
||||
musicDynIndex = (u8) sLevelDynamics[gCurrLevelNum][1] & 0xff;
|
||||
conditionBits = get_level_dynamics(gCurrLevelNum, 1) & 0xff00;
|
||||
musicDynIndex = (u8) get_level_dynamics(gCurrLevelNum, 1) & 0xff;
|
||||
i = 2;
|
||||
while (conditionBits & 0xff00) {
|
||||
j = 0;
|
||||
|
@ -1880,7 +1925,7 @@ void process_level_music_dynamics(void) {
|
|||
bit = 0x8000;
|
||||
while (j < 8) {
|
||||
if (conditionBits & bit) {
|
||||
conditionValues[condIndex] = sLevelDynamics[gCurrLevelNum][i++];
|
||||
conditionValues[condIndex] = get_level_dynamics(gCurrLevelNum, i++);
|
||||
conditionTypes[condIndex] = j;
|
||||
condIndex++;
|
||||
}
|
||||
|
@ -1946,8 +1991,8 @@ void process_level_music_dynamics(void) {
|
|||
// The area matches. Break out of the loop.
|
||||
tempBits = 0;
|
||||
} else {
|
||||
tempBits = sLevelDynamics[gCurrLevelNum][i] & 0xff00;
|
||||
musicDynIndex = sLevelDynamics[gCurrLevelNum][i] & 0xff;
|
||||
tempBits = get_level_dynamics(gCurrLevelNum, i) & 0xff00;
|
||||
musicDynIndex = get_level_dynamics(gCurrLevelNum, i) & 0xff;
|
||||
i++;
|
||||
}
|
||||
|
||||
|
@ -2809,7 +2854,7 @@ f32 sound_get_level_intensity(f32 distance) {
|
|||
}
|
||||
|
||||
f32 volumeRange = VOLUME_RANGE_UNK1;
|
||||
f32 maxSoundDistance = sLevelAcousticReaches[gCurrLevelNum] / 2.0f;
|
||||
f32 maxSoundDistance = get_level_acoustic_reaches(gCurrLevelNum) / 2.0f;
|
||||
if (maxSoundDistance < distance) {
|
||||
intensity = ((AUDIO_MAX_DISTANCE - distance) / (AUDIO_MAX_DISTANCE - maxSoundDistance)) * (1.0f - volumeRange);
|
||||
} else {
|
||||
|
|
|
@ -6610,6 +6610,14 @@ struct CutsceneSplinePoint sEndingLookAtSkyFocus[] = {
|
|||
{ -1, 0, { 636, 2027, -415 } }
|
||||
};
|
||||
|
||||
static struct CameraTrigger* get_camera_trigger(s16 levelNum) {
|
||||
if (levelNum < 0 || levelNum >= LEVEL_COUNT + 2) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sCameraTriggers[levelNum];
|
||||
}
|
||||
|
||||
/**
|
||||
* Activates any CameraTriggers that Mario is inside.
|
||||
* Then, applies area-specific processing to the camera, such as setting the default mode, or changing
|
||||
|
@ -6638,40 +6646,41 @@ s16 camera_course_processing(struct Camera *c) {
|
|||
level = LEVEL_COUNT + 1;
|
||||
}
|
||||
|
||||
if (sCameraTriggers[level] != NULL) {
|
||||
if (get_camera_trigger(level) != NULL) {
|
||||
b = 0;
|
||||
|
||||
// Process positional triggers.
|
||||
// All triggered events are called, not just the first one.
|
||||
while (sCameraTriggers[level][b].event != NULL) {
|
||||
struct CameraTrigger* camTrigger = get_camera_trigger(level);
|
||||
while (camTrigger[b].event != NULL) {
|
||||
|
||||
// Check only the current area's triggers
|
||||
if (sCameraTriggers[level][b].area == area) {
|
||||
if (camTrigger[b].area == area) {
|
||||
// Copy the bounding box into center and bounds
|
||||
vec3f_set(center, sCameraTriggers[level][b].centerX,
|
||||
sCameraTriggers[level][b].centerY,
|
||||
sCameraTriggers[level][b].centerZ);
|
||||
vec3f_set(bounds, sCameraTriggers[level][b].boundsX,
|
||||
sCameraTriggers[level][b].boundsY,
|
||||
sCameraTriggers[level][b].boundsZ);
|
||||
vec3f_set(center, camTrigger[b].centerX,
|
||||
camTrigger[b].centerY,
|
||||
camTrigger[b].centerZ);
|
||||
vec3f_set(bounds, camTrigger[b].boundsX,
|
||||
camTrigger[b].boundsY,
|
||||
camTrigger[b].boundsZ);
|
||||
|
||||
// Check if Mario is inside the bounds
|
||||
if (is_pos_in_bounds(sMarioCamState->pos, center, bounds,
|
||||
sCameraTriggers[level][b].boundsYaw) == TRUE) {
|
||||
camTrigger[b].boundsYaw) == TRUE) {
|
||||
//! This should be checked before calling is_pos_in_bounds. (It doesn't belong
|
||||
//! outside the while loop because some events disable area processing)
|
||||
if (!(sStatusFlags & CAM_FLAG_BLOCK_AREA_PROCESSING)) {
|
||||
sCameraTriggers[level][b].event(c);
|
||||
camTrigger[b].event(c);
|
||||
insideBounds = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((sCameraTriggers[level])[b].area == -1) {
|
||||
if ((camTrigger)[b].area == -1) {
|
||||
// Default triggers are only active if Mario is not already inside another trigger
|
||||
if (!insideBounds) {
|
||||
if (!(sStatusFlags & CAM_FLAG_BLOCK_AREA_PROCESSING)) {
|
||||
sCameraTriggers[level][b].event(c);
|
||||
camTrigger[b].event(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "level_info.h"
|
||||
#include "level_table.h"
|
||||
#include "types.h"
|
||||
#include "pc/lua/utils/smlua_level_utils.h"
|
||||
|
||||
#ifdef VERSION_EU
|
||||
extern u8 *course_name_table_eu_en[];
|
||||
|
@ -165,7 +166,17 @@ const char *get_level_name_ascii(s16 courseNum, s16 levelNum, s16 areaIndex, s16
|
|||
|
||||
// Valid course: BOB to RR, Bowser stages and Secret courses
|
||||
// There is no course name for Cake Ending, make it defaults to "Peach's Castle"
|
||||
if (courseNum >= COURSE_MIN && courseNum < COURSE_MAX) {
|
||||
|
||||
bool hasCustomName = false;
|
||||
if (levelNum >= CUSTOM_LEVEL_NUM_START) {
|
||||
struct CustomLevelInfo* info = smlua_level_util_get_info(levelNum);
|
||||
if (info) {
|
||||
hasCustomName = true;
|
||||
snprintf(output, 256, info->fullName);
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasCustomName && courseNum >= COURSE_MIN && courseNum < COURSE_MAX) {
|
||||
void **courseNameTbl = NULL;
|
||||
#ifdef VERSION_EU
|
||||
switch (gInGameLanguage) {
|
||||
|
@ -181,7 +192,7 @@ const char *get_level_name_ascii(s16 courseNum, s16 levelNum, s16 areaIndex, s16
|
|||
}
|
||||
|
||||
// Castle level
|
||||
else if (courseNum == COURSE_NONE) {
|
||||
else if (!hasCustomName && courseNum == COURSE_NONE) {
|
||||
switch (levelNum) {
|
||||
case LEVEL_CASTLE: {
|
||||
switch (areaIndex) {
|
||||
|
@ -198,7 +209,7 @@ const char *get_level_name_ascii(s16 courseNum, s16 levelNum, s16 areaIndex, s16
|
|||
}
|
||||
|
||||
// Default
|
||||
else {
|
||||
else if (!hasCustomName) {
|
||||
snprintf(output, 256, "Peach's Castle");
|
||||
}
|
||||
|
||||
|
|
|
@ -1525,7 +1525,7 @@ s32 lvl_set_current_level(UNUSED s16 arg0, s32 levelNum) {
|
|||
|
||||
sWarpCheckpointActive = FALSE;
|
||||
gCurrLevelNum = levelNum;
|
||||
gCurrCourseNum = gLevelToCourseNumTable[levelNum - 1];
|
||||
gCurrCourseNum = get_level_course_num(levelNum - 1);
|
||||
|
||||
if (gCurrDemoInput != NULL || gCurrCreditsEntry != NULL || gCurrCourseNum == COURSE_NONE) {
|
||||
return 0;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "macros.h"
|
||||
#include "pc/ini.h"
|
||||
#include "pc/network/network.h"
|
||||
#include "pc/lua/utils/smlua_level_utils.h"
|
||||
|
||||
#ifndef bcopy
|
||||
#define bcopy(b1,b2,len) (memmove((b2), (b1), (len)), (void) 0)
|
||||
|
@ -50,6 +51,19 @@ s8 gLevelToCourseNumTable[] = {
|
|||
STATIC_ASSERT(ARRAY_COUNT(gLevelToCourseNumTable) == LEVEL_COUNT - 1,
|
||||
"change this array if you are adding levels");
|
||||
|
||||
s8 get_level_course_num(s16 levelNum) {
|
||||
if (levelNum >= CUSTOM_LEVEL_NUM_START) {
|
||||
struct CustomLevelInfo* info = smlua_level_util_get_info(levelNum);
|
||||
return (info ? info->courseNum : COURSE_NONE);
|
||||
}
|
||||
|
||||
if (levelNum < 0 || levelNum >= LEVEL_COUNT) {
|
||||
return COURSE_NONE;
|
||||
}
|
||||
|
||||
return gLevelToCourseNumTable[levelNum];
|
||||
}
|
||||
|
||||
// This was probably used to set progress to 100% for debugging, but
|
||||
// it was removed from the release ROM.
|
||||
static void stub_save_file_1(void) {
|
||||
|
@ -745,7 +759,7 @@ void check_if_should_set_warp_checkpoint(struct WarpNode *warpNode) {
|
|||
*/
|
||||
s32 check_warp_checkpoint(struct WarpNode *warpNode) {
|
||||
s16 warpCheckpointActive = FALSE;
|
||||
s16 currCourseNum = gLevelToCourseNumTable[(warpNode->destLevel & 0x7F) - 1];
|
||||
s16 currCourseNum = get_level_course_num((warpNode->destLevel & 0x7F) - 1);
|
||||
|
||||
// gSavedCourseNum is only used in this function.
|
||||
if (gWarpCheckpoint.courseNum != COURSE_NONE && gSavedCourseNum == currCourseNum
|
||||
|
|
|
@ -128,6 +128,7 @@ extern struct WarpCheckpoint gWarpCheckpoint;
|
|||
extern s8 gMainMenuDataModified;
|
||||
extern s8 gSaveFileModified;
|
||||
|
||||
s8 get_level_course_num(s16 levelNum);
|
||||
void save_file_do_save(s32 fileIndex, s8 forceSave);
|
||||
void save_file_erase(s32 fileIndex);
|
||||
BAD_RETURN(s32) save_file_copy(s32 srcFileIndex, s32 destFileIndex);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "level_table.h"
|
||||
#include "seq_ids.h"
|
||||
#include "sm64.h"
|
||||
#include "pc/lua/utils/smlua_level_utils.h"
|
||||
|
||||
#define PRESS_START_DEMO_TIMER 800
|
||||
|
||||
|
@ -32,6 +33,19 @@ static s16 D_U_801A7C34 = 1;
|
|||
static s16 gameOverNotPlayed = 1;
|
||||
#endif
|
||||
|
||||
static char* get_level_stage_names(s16 levelNum) {
|
||||
if (levelNum >= CUSTOM_LEVEL_NUM_START) {
|
||||
struct CustomLevelInfo* info = smlua_level_util_get_info(levelNum);
|
||||
return (info ? info->fullName : "Unknown");
|
||||
}
|
||||
|
||||
if (levelNum < 0 || levelNum >= LEVEL_COUNT) {
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
return gLevelSelect_StageNamesText[levelNum];
|
||||
}
|
||||
|
||||
// run the demo timer on the PRESS START screen.
|
||||
// this function will return a non-0 timer once
|
||||
// the demo starts, signaling to the subsystem that
|
||||
|
@ -140,7 +154,7 @@ s16 level_select_input_loop(void) {
|
|||
print_text_centered(160, 80, "SELECT STAGE");
|
||||
print_text_centered(160, 30, "PRESS START BUTTON");
|
||||
print_text_fmt_int(40, 60, "%2d", gCurrLevelNum);
|
||||
print_text(80, 60, gLevelSelect_StageNamesText[gCurrLevelNum - 1]); // print stage name
|
||||
print_text(80, 60, get_level_stage_names(gCurrLevelNum - 1)); // print stage name
|
||||
|
||||
#define QUIT_LEVEL_SELECT_COMBO (Z_TRIG | START_BUTTON | L_CBUTTONS | R_CBUTTONS)
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "pc/network/ban_list.h"
|
||||
#include "pc/network/moderator_list.h"
|
||||
#include "pc/debuglog.h"
|
||||
#include "pc/lua/utils/smlua_level_utils.h"
|
||||
#include "level_table.h"
|
||||
|
||||
|
||||
|
@ -265,6 +266,12 @@ bool exec_chat_command(char* command) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (level == -1) {
|
||||
struct CustomLevelInfo* info = smlua_level_util_get_info_from_short_name(paramLevel);
|
||||
if (info != NULL) {
|
||||
level = info->levelNum;
|
||||
}
|
||||
}
|
||||
if (level == -1) {
|
||||
char message[256];
|
||||
snprintf(message, 256, "Invalid [LEVEL] parameter: %s", paramLevel);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "pc/lua/utils/smlua_text_utils.h"
|
||||
#include "pc/lua/utils/smlua_audio_utils.h"
|
||||
#include "pc/lua/utils/smlua_model_utils.h"
|
||||
#include "pc/lua/utils/smlua_level_utils.h"
|
||||
#include "pc/djui/djui.h"
|
||||
|
||||
lua_State* gLuaState = NULL;
|
||||
|
@ -188,6 +189,7 @@ void smlua_shutdown(void) {
|
|||
smlua_cpointer_allowlist_shutdown();
|
||||
smlua_clear_hooks();
|
||||
smlua_model_util_reset();
|
||||
smlua_level_util_reset();
|
||||
lua_State* L = gLuaState;
|
||||
if (L != NULL) {
|
||||
lua_close(L);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "src/pc/lua/utils/smlua_anim_utils.h"
|
||||
#include "src/pc/lua/utils/smlua_misc_utils.h"
|
||||
#include "src/pc/lua/utils/smlua_collision_utils.h"
|
||||
#include "src/pc/lua/utils/smlua_level_utils.h"
|
||||
#include "src/game/spawn_sound.h"
|
||||
#include "src/pc/network/network.h"
|
||||
#include "src/game/hardcoded.h"
|
||||
|
@ -392,6 +393,21 @@ static struct LuaObjectField sControllerFields[LUA_CONTROLLER_FIELD_COUNT] = {
|
|||
{ "stickY", LVT_F32, offsetof(struct Controller, stickY), false, LOT_NONE },
|
||||
};
|
||||
|
||||
#define LUA_CUSTOM_LEVEL_INFO_FIELD_COUNT 11
|
||||
static struct LuaObjectField sCustomLevelInfoFields[LUA_CUSTOM_LEVEL_INFO_FIELD_COUNT] = {
|
||||
{ "acousticReach", LVT_U32, offsetof(struct CustomLevelInfo, acousticReach), false, LOT_NONE },
|
||||
{ "courseNum", LVT_S16, offsetof(struct CustomLevelInfo, courseNum), false, LOT_NONE },
|
||||
{ "echoLevel1", LVT_U32, offsetof(struct CustomLevelInfo, echoLevel1), false, LOT_NONE },
|
||||
{ "echoLevel2", LVT_U32, offsetof(struct CustomLevelInfo, echoLevel2), false, LOT_NONE },
|
||||
{ "echoLevel3", LVT_U32, offsetof(struct CustomLevelInfo, echoLevel3), false, LOT_NONE },
|
||||
{ "fullName", LVT_STRING_P, offsetof(struct CustomLevelInfo, fullName), true, LOT_NONE },
|
||||
{ "levelNum", LVT_S16, offsetof(struct CustomLevelInfo, levelNum), false, LOT_NONE },
|
||||
{ "next", LVT_COBJECT_P, offsetof(struct CustomLevelInfo, next), false, LOT_CUSTOMLEVELINFO },
|
||||
{ "script", LVT_LEVELSCRIPT_P, offsetof(struct CustomLevelInfo, script), true, LOT_POINTER },
|
||||
{ "scriptEntryName", LVT_STRING_P, offsetof(struct CustomLevelInfo, scriptEntryName), true, LOT_NONE },
|
||||
{ "shortName", LVT_STRING_P, offsetof(struct CustomLevelInfo, shortName), true, LOT_NONE },
|
||||
};
|
||||
|
||||
#define LUA_CUTSCENE_FIELD_COUNT 1
|
||||
static struct LuaObjectField sCutsceneFields[LUA_CUTSCENE_FIELD_COUNT] = {
|
||||
{ "duration", LVT_S16, offsetof(struct Cutscene, duration), false, LOT_NONE },
|
||||
|
@ -1979,6 +1995,7 @@ struct LuaObjectTable sLuaObjectAutogenTable[LOT_AUTOGEN_MAX - LOT_AUTOGEN_MIN]
|
|||
{ LOT_CHAINSEGMENT, sChainSegmentFields, LUA_CHAIN_SEGMENT_FIELD_COUNT },
|
||||
{ LOT_CHARACTER, sCharacterFields, LUA_CHARACTER_FIELD_COUNT },
|
||||
{ LOT_CONTROLLER, sControllerFields, LUA_CONTROLLER_FIELD_COUNT },
|
||||
{ LOT_CUSTOMLEVELINFO, sCustomLevelInfoFields, LUA_CUSTOM_LEVEL_INFO_FIELD_COUNT },
|
||||
{ LOT_CUTSCENE, sCutsceneFields, LUA_CUTSCENE_FIELD_COUNT },
|
||||
{ LOT_CUTSCENESPLINEPOINT, sCutsceneSplinePointFields, LUA_CUTSCENE_SPLINE_POINT_FIELD_COUNT },
|
||||
{ LOT_CUTSCENEVARIABLE, sCutsceneVariableFields, LUA_CUTSCENE_VARIABLE_FIELD_COUNT },
|
||||
|
|
|
@ -20,6 +20,7 @@ enum LuaObjectAutogenType {
|
|||
LOT_CHAINSEGMENT,
|
||||
LOT_CHARACTER,
|
||||
LOT_CONTROLLER,
|
||||
LOT_CUSTOMLEVELINFO,
|
||||
LOT_CUTSCENE,
|
||||
LOT_CUTSCENESPLINEPOINT,
|
||||
LOT_CUTSCENEVARIABLE,
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "src/pc/lua/utils/smlua_model_utils.h"
|
||||
#include "src/pc/lua/utils/smlua_text_utils.h"
|
||||
#include "src/pc/lua/utils/smlua_audio_utils.h"
|
||||
#include "src/pc/lua/utils/smlua_level_utils.h"
|
||||
#include "src/engine/surface_load.h"
|
||||
#include "src/game/object_list_processor.h"
|
||||
#include "src/game/behavior_actions.h"
|
||||
|
@ -15108,6 +15109,103 @@ int smlua_func_smlua_collision_util_get(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// smlua_level_utils.h //
|
||||
/////////////////////////
|
||||
|
||||
int smlua_func_level_register(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 8)) { return 0; }
|
||||
|
||||
const char* scriptEntryName = smlua_to_string(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
||||
s16 courseNum = smlua_to_integer(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2"); return 0; }
|
||||
const char* fullName = smlua_to_string(L, 3);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 3"); return 0; }
|
||||
const char* shortName = smlua_to_string(L, 4);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 4"); return 0; }
|
||||
u32 acousticReach = smlua_to_integer(L, 5);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 5"); return 0; }
|
||||
u32 echoLevel1 = smlua_to_integer(L, 6);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 6"); return 0; }
|
||||
u32 echoLevel2 = smlua_to_integer(L, 7);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 7"); return 0; }
|
||||
u32 echoLevel3 = smlua_to_integer(L, 8);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 8"); return 0; }
|
||||
|
||||
lua_pushinteger(L, level_register(scriptEntryName, courseNum, fullName, shortName, acousticReach, echoLevel1, echoLevel2, echoLevel3));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_smlua_level_util_get_info(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||
|
||||
s16 levelNum = smlua_to_integer(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
||||
|
||||
smlua_push_object(L, LOT_CUSTOMLEVELINFO, smlua_level_util_get_info(levelNum));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_smlua_level_util_get_info_from_short_name(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||
|
||||
char* shortName = (char*)smlua_to_cobject(L, 1, LOT_NONE);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
||||
|
||||
smlua_push_object(L, LOT_CUSTOMLEVELINFO, smlua_level_util_get_info_from_short_name(shortName));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_warp_exit_level(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||
|
||||
s32 aDelay = smlua_to_integer(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
||||
|
||||
lua_pushboolean(L, warp_exit_level(aDelay));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_warp_restart_level(UNUSED lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 0)) { return 0; }
|
||||
|
||||
|
||||
lua_pushboolean(L, warp_restart_level());
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_warp_to_castle(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||
|
||||
s32 aLevel = smlua_to_integer(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
||||
|
||||
lua_pushboolean(L, warp_to_castle(aLevel));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_warp_to_level(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 3)) { return 0; }
|
||||
|
||||
s32 aLevel = smlua_to_integer(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
||||
s32 aArea = smlua_to_integer(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2"); return 0; }
|
||||
s32 aAct = smlua_to_integer(L, 3);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 3"); return 0; }
|
||||
|
||||
lua_pushboolean(L, warp_to_level(aLevel, aArea, aAct));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////
|
||||
// smlua_misc_utils.h //
|
||||
////////////////////////
|
||||
|
@ -15594,52 +15692,6 @@ int smlua_func_set_override_near(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_warp_exit_level(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||
|
||||
s32 aDelay = smlua_to_integer(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
||||
|
||||
lua_pushboolean(L, warp_exit_level(aDelay));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_warp_restart_level(UNUSED lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 0)) { return 0; }
|
||||
|
||||
|
||||
lua_pushboolean(L, warp_restart_level());
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_warp_to_castle(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||
|
||||
s32 aLevel = smlua_to_integer(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
||||
|
||||
lua_pushboolean(L, warp_to_castle(aLevel));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_warp_to_level(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 3)) { return 0; }
|
||||
|
||||
s32 aLevel = smlua_to_integer(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
||||
s32 aArea = smlua_to_integer(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2"); return 0; }
|
||||
s32 aAct = smlua_to_integer(L, 3);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 3"); return 0; }
|
||||
|
||||
lua_pushboolean(L, warp_to_level(aLevel, aArea, aAct));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// smlua_model_utils.h //
|
||||
/////////////////////////
|
||||
|
@ -17847,6 +17899,15 @@ void smlua_bind_functions_autogen(void) {
|
|||
smlua_bind_function(L, "get_water_surface_pseudo_floor", smlua_func_get_water_surface_pseudo_floor);
|
||||
smlua_bind_function(L, "smlua_collision_util_get", smlua_func_smlua_collision_util_get);
|
||||
|
||||
// smlua_level_utils.h
|
||||
smlua_bind_function(L, "level_register", smlua_func_level_register);
|
||||
smlua_bind_function(L, "smlua_level_util_get_info", smlua_func_smlua_level_util_get_info);
|
||||
smlua_bind_function(L, "smlua_level_util_get_info_from_short_name", smlua_func_smlua_level_util_get_info_from_short_name);
|
||||
smlua_bind_function(L, "warp_exit_level", smlua_func_warp_exit_level);
|
||||
smlua_bind_function(L, "warp_restart_level", smlua_func_warp_restart_level);
|
||||
smlua_bind_function(L, "warp_to_castle", smlua_func_warp_to_castle);
|
||||
smlua_bind_function(L, "warp_to_level", smlua_func_warp_to_level);
|
||||
|
||||
// smlua_misc_utils.h
|
||||
smlua_bind_function(L, "allocate_mario_action", smlua_func_allocate_mario_action);
|
||||
smlua_bind_function(L, "camera_config_enable_analog_cam", smlua_func_camera_config_enable_analog_cam);
|
||||
|
@ -17892,10 +17953,6 @@ void smlua_bind_functions_autogen(void) {
|
|||
smlua_bind_function(L, "set_override_far", smlua_func_set_override_far);
|
||||
smlua_bind_function(L, "set_override_fov", smlua_func_set_override_fov);
|
||||
smlua_bind_function(L, "set_override_near", smlua_func_set_override_near);
|
||||
smlua_bind_function(L, "warp_exit_level", smlua_func_warp_exit_level);
|
||||
smlua_bind_function(L, "warp_restart_level", smlua_func_warp_restart_level);
|
||||
smlua_bind_function(L, "warp_to_castle", smlua_func_warp_to_castle);
|
||||
smlua_bind_function(L, "warp_to_level", smlua_func_warp_to_level);
|
||||
|
||||
// smlua_model_utils.h
|
||||
smlua_bind_function(L, "smlua_model_util_get_id", smlua_func_smlua_model_util_get_id);
|
||||
|
|
143
src/pc/lua/utils/smlua_level_utils.c
Normal file
143
src/pc/lua/utils/smlua_level_utils.c
Normal file
|
@ -0,0 +1,143 @@
|
|||
#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(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;
|
||||
|
||||
// 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 warp_to_level(s32 aLevel, s32 aArea, s32 aAct) {
|
||||
return dynos_warp_to_level(aLevel, aArea, aAct);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
29
src/pc/lua/utils/smlua_level_utils.h
Normal file
29
src/pc/lua/utils/smlua_level_utils.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef SMLUA_LEVEL_UTILS_H
|
||||
#define SMLUA_LEVEL_UTILS_H
|
||||
|
||||
struct CustomLevelInfo {
|
||||
LevelScript* script;
|
||||
char* scriptEntryName;
|
||||
s16 courseNum;
|
||||
s16 levelNum;
|
||||
char* fullName;
|
||||
char* shortName;
|
||||
u32 acousticReach;
|
||||
u32 echoLevel1;
|
||||
u32 echoLevel2;
|
||||
u32 echoLevel3;
|
||||
struct CustomLevelInfo* next;
|
||||
};
|
||||
|
||||
#define CUSTOM_LEVEL_NUM_START 50
|
||||
|
||||
void smlua_level_util_reset(void);
|
||||
struct CustomLevelInfo* smlua_level_util_get_info(s16 levelNum);
|
||||
struct CustomLevelInfo* smlua_level_util_get_info_from_short_name(char* shortName);
|
||||
s16 level_register(const char* scriptEntryName, s16 courseNum, const char* fullName, const char* shortName, u32 acousticReach, u32 echoLevel1, u32 echoLevel2, u32 echoLevel3);
|
||||
bool warp_to_level(s32 aLevel, s32 aArea, s32 aAct);
|
||||
bool warp_restart_level(void);
|
||||
bool warp_exit_level(s32 aDelay);
|
||||
bool warp_to_castle(s32 aLevel);
|
||||
|
||||
#endif
|
|
@ -272,24 +272,6 @@ bool is_game_paused(void) {
|
|||
|
||||
///
|
||||
|
||||
bool warp_to_level(s32 aLevel, s32 aArea, s32 aAct) {
|
||||
return dynos_warp_to_level(aLevel, aArea, aAct);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
u32 allocate_mario_action(u32 actFlags) {
|
||||
actFlags = actFlags & (~((u32)0xFF));
|
||||
return actFlags | ACT_FLAG_CUSTOM_ACTION | gLuaMarioActionIndex++;
|
||||
|
|
|
@ -63,11 +63,6 @@ void camera_config_set_deceleration(u32 value);
|
|||
|
||||
bool is_game_paused(void);
|
||||
|
||||
bool warp_to_level(s32 aLevel, s32 aArea, s32 aAct);
|
||||
bool warp_restart_level(void);
|
||||
bool warp_exit_level(s32 aDelay);
|
||||
bool warp_to_castle(s32 aLevel);
|
||||
|
||||
u32 allocate_mario_action(u32 actFlags);
|
||||
|
||||
f32 get_hand_foot_pos_x(struct MarioState* m, u8 index);
|
||||
|
|
Loading…
Reference in a new issue