Add networking for custom behaviors

This commit is contained in:
MysterD 2022-03-04 20:03:00 -08:00
parent 9c7036afe3
commit a87116a632
11 changed files with 307 additions and 5 deletions

View file

@ -39,6 +39,7 @@ in_files = [
"src/game/object_helpers.c",
"src/game/obj_behaviors.c",
"src/game/obj_behaviors_2.c",
"src/game/spawn_sound.c",
]
override_allowed_functions = {
@ -69,6 +70,7 @@ override_disallowed_functions = {
"src/game/object_helpers.c": [ "spawn_obj", "^bhv_", "abs[fi]", "^bit_shift", "_debug$", "^stub_" ],
"src/game/obj_behaviors.c": [ "debug_" ],
"src/game/obj_behaviors_2.c": [ "wiggler_jumped_on_attack_handler", "huge_goomba_weakly_attacked" ],
"src/game/spawn_sound.c": [ "spawner" ],
}
lua_function_params = {

View file

@ -16,6 +16,7 @@ in_files = [
'src/game/object_helpers.h',
'src/game/mario_step.h',
'src/pc/lua/smlua_anim_utils.h',
'src/game/spawn_sound.h',
]
smlua_cobject_autogen = 'src/pc/lua/smlua_cobject_autogen'

View file

@ -644,6 +644,15 @@
<br />
- spawn_sound.c
- [calc_dist_to_volume_range_1](#calc_dist_to_volume_range_1)
- [calc_dist_to_volume_range_2](#calc_dist_to_volume_range_2)
- [cur_obj_play_sound_1](#cur_obj_play_sound_1)
- [cur_obj_play_sound_2](#cur_obj_play_sound_2)
- [exec_anim_sound_state](#exec_anim_sound_state)
<br />
- surface_collision.h
- [find_ceil_height](#find_ceil_height)
- [find_floor_height](#find_floor_height)
@ -11843,6 +11852,112 @@
<br />
---
# functions from spawn_sound.c
<br />
## [calc_dist_to_volume_range_1](#calc_dist_to_volume_range_1)
### Lua Example
`local integerValue = calc_dist_to_volume_range_1(distance)`
### Parameters
| Field | Type |
| ----- | ---- |
| distance | number |
### Returns
- integer
### C Prototype
`s32 calc_dist_to_volume_range_1(f32 distance);`
[:arrow_up_small:](#)
<br />
## [calc_dist_to_volume_range_2](#calc_dist_to_volume_range_2)
### Lua Example
`local integerValue = calc_dist_to_volume_range_2(distance)`
### Parameters
| Field | Type |
| ----- | ---- |
| distance | number |
### Returns
- integer
### C Prototype
`s32 calc_dist_to_volume_range_2(f32 distance);`
[:arrow_up_small:](#)
<br />
## [cur_obj_play_sound_1](#cur_obj_play_sound_1)
### Lua Example
`cur_obj_play_sound_1(soundMagic)`
### Parameters
| Field | Type |
| ----- | ---- |
| soundMagic | integer |
### Returns
- None
### C Prototype
`void cur_obj_play_sound_1(s32 soundMagic);`
[:arrow_up_small:](#)
<br />
## [cur_obj_play_sound_2](#cur_obj_play_sound_2)
### Lua Example
`cur_obj_play_sound_2(soundMagic)`
### Parameters
| Field | Type |
| ----- | ---- |
| soundMagic | integer |
### Returns
- None
### C Prototype
`void cur_obj_play_sound_2(s32 soundMagic);`
[:arrow_up_small:](#)
<br />
## [exec_anim_sound_state](#exec_anim_sound_state)
### Lua Example
`exec_anim_sound_state(soundStates)`
### Parameters
| Field | Type |
| ----- | ---- |
| soundStates | [SoundState](structs.md#SoundState) |
### Returns
- None
### C Prototype
`void exec_anim_sound_state(struct SoundState *soundStates);`
[:arrow_up_small:](#)
<br />
---
# functions from surface_collision.h

View file

@ -40,6 +40,7 @@
- [PlayerCameraState](#PlayerCameraState)
- [PlayerGeometry](#PlayerGeometry)
- [SPTask](#SPTask)
- [SoundState](#SoundState)
- [SpawnInfo](#SpawnInfo)
- [SpawnParticlesInfo](#SpawnParticlesInfo)
- [Struct802A272C](#Struct802A272C)
@ -1603,6 +1604,19 @@
<br />
## [SoundState](#SoundState)
| Field | Type | Access |
| ----- | ---- | ------ |
| animFrame1 | integer | |
| animFrame2 | integer | |
| playSound | integer | |
| soundMagic | integer | |
[:arrow_up_small:](#)
<br />
## [SpawnInfo](#SpawnInfo)
| Field | Type | Access |

View file

@ -30,7 +30,7 @@ struct LuaObjectTable sLuaObjectTable[LOT_MAX] = {
{ LOT_VEC3F, sVec3fFields, LUA_VEC3F_FIELD_COUNT },
};
static struct LuaObjectField* smlua_get_object_field(u16 lot, const char* key) {
struct LuaObjectField* smlua_get_object_field(u16 lot, const char* key) {
if (lot > LOT_AUTOGEN_MIN) {
return smlua_get_object_field_autogen(lot, key);
}
@ -174,7 +174,7 @@ static int smlua_func_define_custom_obj_fields(lua_State* L) {
return 1;
}
static struct LuaObjectField* smlua_get_custom_field(lua_State* L, u32 lot, int keyIndex) {
struct LuaObjectField* smlua_get_custom_field(lua_State* L, u32 lot, int keyIndex) {
LUA_STACK_CHECK_BEGIN();
static struct LuaObjectField lof = { 0 };
if (lot != LOT_OBJECT) { return NULL; }

View file

@ -54,6 +54,8 @@ struct LuaObjectTable {
bool smlua_valid_lot(u16 lot);
bool smlua_valid_lvt(u16 lvt);
struct LuaObjectField* smlua_get_object_field(u16 lot, const char* key);
struct LuaObjectField* smlua_get_custom_field(lua_State* L, u32 lot, int keyIndex);
void smlua_cobject_init_globals(void);
void smlua_cobject_init_per_file_globals(char* path);
void smlua_bind_cobject(void);

View file

@ -11,6 +11,7 @@
#include "src/game/object_helpers.h"
#include "src/game/mario_step.h"
#include "src/pc/lua/smlua_anim_utils.h"
#include "src/game/spawn_sound.h"
#include "include/object_fields.h"
@ -1403,6 +1404,14 @@ static struct LuaObjectField sPlayerGeometryFields[LUA_PLAYER_GEOMETRY_FIELD_COU
{ "waterHeight", LVT_F32, offsetof(struct PlayerGeometry, waterHeight), false, LOT_NONE },
};
#define LUA_SOUND_STATE_FIELD_COUNT 4
static struct LuaObjectField sSoundStateFields[LUA_SOUND_STATE_FIELD_COUNT] = {
{ "animFrame1", LVT_S8, offsetof(struct SoundState, animFrame1), false, LOT_NONE },
{ "animFrame2", LVT_S8, offsetof(struct SoundState, animFrame2), false, LOT_NONE },
{ "playSound", LVT_S16, offsetof(struct SoundState, playSound), false, LOT_NONE },
{ "soundMagic", LVT_S32, offsetof(struct SoundState, soundMagic), false, LOT_NONE },
};
#define LUA_SPAWN_INFO_FIELD_COUNT 7
static struct LuaObjectField sSpawnInfoFields[LUA_SPAWN_INFO_FIELD_COUNT] = {
{ "activeAreaIndex", LVT_S8, offsetof(struct SpawnInfo, activeAreaIndex), false, LOT_NONE },
@ -1590,6 +1599,7 @@ struct LuaObjectTable sLuaObjectAutogenTable[LOT_AUTOGEN_MAX - LOT_AUTOGEN_MIN]
{ LOT_PARALLELTRACKINGPOINT, sParallelTrackingPointFields, LUA_PARALLEL_TRACKING_POINT_FIELD_COUNT },
{ LOT_PLAYERCAMERASTATE, sPlayerCameraStateFields, LUA_PLAYER_CAMERA_STATE_FIELD_COUNT },
{ LOT_PLAYERGEOMETRY, sPlayerGeometryFields, LUA_PLAYER_GEOMETRY_FIELD_COUNT },
{ LOT_SOUNDSTATE, sSoundStateFields, LUA_SOUND_STATE_FIELD_COUNT },
{ LOT_SPAWNINFO, sSpawnInfoFields, LUA_SPAWN_INFO_FIELD_COUNT },
{ LOT_SPAWNPARTICLESINFO, sSpawnParticlesInfoFields, LUA_SPAWN_PARTICLES_INFO_FIELD_COUNT },
{ LOT_STRUCT802A272C, sStruct802A272CFields, LUA_STRUCT802_A272_C_FIELD_COUNT },

View file

@ -42,6 +42,7 @@ enum LuaObjectAutogenType {
LOT_PARALLELTRACKINGPOINT,
LOT_PLAYERCAMERASTATE,
LOT_PLAYERGEOMETRY,
LOT_SOUNDSTATE,
LOT_SPAWNINFO,
LOT_SPAWNPARTICLESINFO,
LOT_STRUCT802A272C,

View file

@ -1,4 +1,5 @@
#include "smlua.h"
#include "smlua_cobject.h"
#include "game/level_update.h"
#include "game/area.h"
@ -79,6 +80,83 @@ int smlua_func_init_mario_after_warp(lua_State* L) {
return 1;
}
int smlua_func_network_init_object(lua_State* L) {
if (!smlua_functions_valid_param_count(L, 3)) { return 0; }
struct Object* obj = smlua_to_cobject(L, 1, LOT_OBJECT);
if (!gSmLuaConvertSuccess || obj == NULL) { return 0; }
bool standardSync = smlua_to_boolean(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
if (lua_type(L, 3) != LUA_TNIL && lua_type(L, 3) != LUA_TTABLE) {
LOG_LUA("network_init_object() called with an invalid type for param 3: %u", lua_type(L, 3));
return 0;
}
struct SyncObject* so = network_init_object(obj, standardSync ? 4000.0f : SYNC_DISTANCE_ONLY_EVENTS);
if (so == NULL) {
LOG_LUA("Failed to allocate sync object.");
return 0;
}
if (lua_type(L, 3) == LUA_TTABLE) {
lua_pushnil(L); // first key
while (lua_next(L, 3) != 0) {
// uses 'key' (at index -2) and 'value' (at index -1)
if (lua_type(L, -1) != LUA_TSTRING) {
LOG_LUA("Invalid type passed to network_init_object(): %u", lua_type(L, -1));
lua_pop(L, 1); // pop value
continue;
}
const char* fieldIdentifier = smlua_to_string(L, -1);
if (!gSmLuaConvertSuccess || fieldIdentifier[0] != 'o') {
LOG_LUA("Invalid field passed to network_init_object()");
lua_pop(L, 1); // pop value
continue;
}
struct LuaObjectField* data = smlua_get_object_field(LOT_OBJECT, fieldIdentifier);
if (data == NULL) {
data = smlua_get_custom_field(L, LOT_OBJECT, lua_gettop(L));
}
if (data == NULL) {
LOG_LUA("Invalid field passed to network_init_object(): %s", fieldIdentifier);
lua_pop(L, 1); // pop value
continue;
}
u8* field = ((u8*)(intptr_t)obj) + data->valueOffset;
network_init_object_field(obj, field);
lua_pop(L, 1); // pop value
}
lua_pop(L, 1); // pop key
}
return 1;
}
int smlua_func_network_send_object(lua_State* L) {
if (!smlua_functions_valid_param_count(L, 2)) { return 0; }
struct Object* obj = smlua_to_cobject(L, 1, LOT_OBJECT);
if (!gSmLuaConvertSuccess || obj == NULL) { return 0; }
bool reliable = smlua_to_boolean(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
if (obj->oSyncID == 0 || gSyncObjects[obj->oSyncID].o != obj) {
LOG_LUA("Failed to retrieve sync object.");
return 0;
}
network_send_object_reliability(obj, reliable);
return 1;
}
//////////
// bind //
//////////
@ -91,4 +169,6 @@ void smlua_bind_functions(void) {
smlua_bind_function(L, "coss", smlua_func_coss);
smlua_bind_function(L, "atan2s", smlua_func_atan2s);
smlua_bind_function(L, "init_mario_after_warp", smlua_func_init_mario_after_warp);
smlua_bind_function(L, "network_init_object", smlua_func_network_init_object);
smlua_bind_function(L, "network_send_object", smlua_func_network_send_object);
}

View file

@ -7582,6 +7582,70 @@ int smlua_func_stop_shell_music(UNUSED lua_State* L) {
return 1;
}
///////////////////
// spawn_sound.c //
///////////////////
int smlua_func_calc_dist_to_volume_range_1(lua_State* L) {
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
f32 distance = smlua_to_number(L, 1);
if (!gSmLuaConvertSuccess) { return 0; }
extern s32 calc_dist_to_volume_range_1(f32 distance);
lua_pushinteger(L, calc_dist_to_volume_range_1(distance));
return 1;
}
int smlua_func_calc_dist_to_volume_range_2(lua_State* L) {
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
f32 distance = smlua_to_number(L, 1);
if (!gSmLuaConvertSuccess) { return 0; }
extern s32 calc_dist_to_volume_range_2(f32 distance);
lua_pushinteger(L, calc_dist_to_volume_range_2(distance));
return 1;
}
int smlua_func_cur_obj_play_sound_1(lua_State* L) {
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
s32 soundMagic = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { return 0; }
extern void cur_obj_play_sound_1(s32 soundMagic);
cur_obj_play_sound_1(soundMagic);
return 1;
}
int smlua_func_cur_obj_play_sound_2(lua_State* L) {
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
s32 soundMagic = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { return 0; }
extern void cur_obj_play_sound_2(s32 soundMagic);
cur_obj_play_sound_2(soundMagic);
return 1;
}
int smlua_func_exec_anim_sound_state(lua_State* L) {
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
struct SoundState* soundStates = (struct SoundState*)smlua_to_cobject(L, 1, LOT_SOUNDSTATE);
if (!gSmLuaConvertSuccess) { return 0; }
extern void exec_anim_sound_state(struct SoundState *soundStates);
exec_anim_sound_state(soundStates);
return 1;
}
/////////////////////////
// surface_collision.h //
/////////////////////////
@ -8422,6 +8486,13 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "stop_cap_music", smlua_func_stop_cap_music);
smlua_bind_function(L, "stop_shell_music", smlua_func_stop_shell_music);
// spawn_sound.c
smlua_bind_function(L, "calc_dist_to_volume_range_1", smlua_func_calc_dist_to_volume_range_1);
smlua_bind_function(L, "calc_dist_to_volume_range_2", smlua_func_calc_dist_to_volume_range_2);
smlua_bind_function(L, "cur_obj_play_sound_1", smlua_func_cur_obj_play_sound_1);
smlua_bind_function(L, "cur_obj_play_sound_2", smlua_func_cur_obj_play_sound_2);
smlua_bind_function(L, "exec_anim_sound_state", smlua_func_exec_anim_sound_state);
// surface_collision.h
//smlua_bind_function(L, "find_ceil", smlua_func_find_ceil); <--- UNIMPLEMENTED
smlua_bind_function(L, "find_ceil_height", smlua_func_find_ceil_height);

View file

@ -305,6 +305,7 @@ u32 smlua_get_action_interaction_type(struct MarioState* m) {
struct LuaHookedBehavior {
u32 behaviorId;
u32 overrideId;
BehaviorScript behavior[2];
int initReference;
int loopReference;
@ -331,7 +332,7 @@ const BehaviorScript* get_lua_behavior_from_id(enum BehaviorId id) {
if (L == NULL) { return false; }
for (int i = 0; i < sHookedBehaviorsCount; i++) {
struct LuaHookedBehavior* hooked = &sHookedBehaviors[i];
if (hooked->behaviorId != id) { continue; }
if (hooked->behaviorId != id && hooked->overrideId != id) { continue; }
return hooked->behavior;
}
return NULL;
@ -396,7 +397,8 @@ int smlua_hook_behavior(lua_State* L) {
struct LuaHookedBehavior* hooked = &sHookedBehaviors[sHookedBehaviorsCount];
u16 customBehaviorId = (sHookedBehaviorsCount & 0xFFFF) | LUA_BEHAVIOR_FLAG;
hooked->behaviorId = overrideBehaviorId != 0 ? overrideBehaviorId : customBehaviorId;
hooked->behaviorId = customBehaviorId;
hooked->overrideId = (overrideBehaviorId == 0) ? customBehaviorId : overrideBehaviorId;
hooked->behavior[0] = (((unsigned int) (((unsigned int)(0x00) & ((0x01 << (8)) - 1)) << (24))) | ((unsigned int) (((unsigned int)(objectList) & ((0x01 << (8)) - 1)) << (16)))); // gross. this is BEGIN(objectList)
hooked->behavior[1] = (((unsigned int) (((unsigned int)(0x39) & ((0x01 << (8)) - 1)) << (24))) | ((unsigned int) (((unsigned int)(customBehaviorId) & ((0x01 << (16)) - 1)) << (0)))); // gross. this is ID(customBehaviorId)
hooked->initReference = initReference;
@ -643,11 +645,13 @@ static void smlua_clear_hooks(void) {
sHookedEvents[i].reference[j] = 0;
}
sHookedEvents[i].count = 0;
sHookedEvents[i].entry = NULL;
}
for (int i = 0; i < sHookedMarioActionsCount; i++) {
sHookedMarioActions[i].action = 0;
sHookedMarioActions[i].reference = 0;
sHookedMarioActions[i].entry = NULL;
}
sHookedMarioActionsCount = 0;
@ -659,6 +663,7 @@ static void smlua_clear_hooks(void) {
sHookedChatCommands[i].description = NULL;
sHookedChatCommands[i].reference = 0;
sHookedChatCommands[i].entry = NULL;
}
sHookedChatCommandsCount = 0;
@ -669,6 +674,7 @@ static void smlua_clear_hooks(void) {
hooked->behavior[1] = 0;
hooked->initReference = 0;
hooked->loopReference = 0;
hooked->entry = NULL;
}
sHookedBehaviorsCount = 0;
}