Create `hook_exclamation_box` in place of `set_exclamation_box_contents` (#524)
* Revert set_exclamation_box_contents() In favor of the hook * Create `hook_exclamation_box`
This commit is contained in:
parent
a0e0493e45
commit
80f1d06ed8
|
@ -339,7 +339,7 @@ def def_constant(processed_constant):
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def build_to_def(processed_files):
|
def build_to_def(processed_files):
|
||||||
s = '-- AUTOGENERATED FOR CODE EDITORS -- \n--- @meta\n--- @diagnostic disable\n\n'
|
s = '-- AUTOGENERATED FOR CODE EDITORS --\n\n'
|
||||||
with open(get_path(in_filename), 'r', newline='\n') as f:
|
with open(get_path(in_filename), 'r', newline='\n') as f:
|
||||||
s += f.read()
|
s += f.read()
|
||||||
s += '\n'
|
s += '\n'
|
||||||
|
|
|
@ -105,7 +105,7 @@ override_disallowed_functions = {
|
||||||
"src/game/obj_behaviors_2.c": [ "wiggler_jumped_on_attack_handler", "huge_goomba_weakly_attacked" ],
|
"src/game/obj_behaviors_2.c": [ "wiggler_jumped_on_attack_handler", "huge_goomba_weakly_attacked" ],
|
||||||
"src/game/spawn_sound.c": [ "spawner" ],
|
"src/game/spawn_sound.c": [ "spawner" ],
|
||||||
"src/game/level_info.h": [ "_name_table" ],
|
"src/game/level_info.h": [ "_name_table" ],
|
||||||
"src/pc/lua/utils/smlua_obj_utils.h": [ "spawn_object_remember_field", "set_exclamation_box_new_contents", "get_exclamation_box_new_contents_pointer", "get_exclamation_box_new_contents_size" ],
|
"src/pc/lua/utils/smlua_obj_utils.h": [ "spawn_object_remember_field" ],
|
||||||
"src/game/camera.h": [ "update_camera", "init_camera", "stub_camera", "^reset_camera", "move_point_along_spline" ],
|
"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/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/lua/utils/smlua_audio_utils.h": [ "smlua_audio_utils_override", "audio_custom_shutdown"],
|
||||||
|
@ -1071,7 +1071,7 @@ def def_function(function):
|
||||||
|
|
||||||
|
|
||||||
def def_files(processed_files):
|
def def_files(processed_files):
|
||||||
s = '-- AUTOGENERATED FOR CODE EDITORS -- \n--- @meta\n--- @diagnostic disable\n\n'
|
s = '-- AUTOGENERATED FOR CODE EDITORS --\n\n'
|
||||||
for processed_file in processed_files:
|
for processed_file in processed_files:
|
||||||
for function in processed_file['functions']:
|
for function in processed_file['functions']:
|
||||||
s += def_function(function)
|
s += def_function(function)
|
||||||
|
|
|
@ -127,8 +127,7 @@ sLuaManuallyDefinedStructs = [{
|
||||||
'structs': [
|
'structs': [
|
||||||
'struct Vec3f { float x; float y; float z; }',
|
'struct Vec3f { float x; float y; float z; }',
|
||||||
'struct Vec3s { s16 x; s16 y; s16 z; }',
|
'struct Vec3s { s16 x; s16 y; s16 z; }',
|
||||||
'struct Color { u8 r; u8 g; u8 b; }',
|
'struct Color { u8 r; u8 g; u8 b; }'
|
||||||
'struct ExclamationBoxContents { u8 index; u8 unused; u8 firstByte; enum ModelExtendedId emodel; enum BehaviorId behaviorId; }'
|
|
||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
|
|
||||||
|
@ -629,7 +628,7 @@ def def_struct(struct):
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def def_structs(structs):
|
def def_structs(structs):
|
||||||
s = '-- AUTOGENERATED FOR CODE EDITORS -- \n--- @meta\n--- @diagnostic disable\n\n'
|
s = '-- AUTOGENERATED FOR CODE EDITORS --\n'
|
||||||
|
|
||||||
for struct in structs:
|
for struct in structs:
|
||||||
if struct['identifier'] in exclude_structs:
|
if struct['identifier'] in exclude_structs:
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
-- AUTOGENERATED FOR CODE EDITORS --
|
-- AUTOGENERATED FOR CODE EDITORS --
|
||||||
--- @meta
|
|
||||||
--- @diagnostic disable
|
|
||||||
|
|
||||||
math.randomseed(get_time())
|
math.randomseed(get_time())
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
-- AUTOGENERATED FOR CODE EDITORS --
|
-- AUTOGENERATED FOR CODE EDITORS --
|
||||||
--- @meta
|
|
||||||
--- @diagnostic disable
|
|
||||||
|
|
||||||
--- @param id integer
|
--- @param id integer
|
||||||
--- @return ObjectWarpNode
|
--- @return ObjectWarpNode
|
||||||
|
@ -9129,11 +9127,6 @@ function obj_set_vel(o, vx, vy, vz)
|
||||||
-- ...
|
-- ...
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @return nil
|
|
||||||
function restore_exclamation_box_original_contents()
|
|
||||||
-- ...
|
|
||||||
end
|
|
||||||
|
|
||||||
--- @param x number
|
--- @param x number
|
||||||
--- @param y number
|
--- @param y number
|
||||||
--- @param z number
|
--- @param z number
|
||||||
|
|
|
@ -279,14 +279,8 @@ function level_script_parse(levelNum, func)
|
||||||
-- ...
|
-- ...
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param contents ExclamationBoxContents[]
|
--- @param readFunc (fun(obj:Object):nil)? Called after the exclamation box spawns an object. Use this function to read the contents of the object that spawned.
|
||||||
--- @return nil
|
--- @param writeFunc (fun(box:Object):Object)? Called when the exclamation box is about to spawn an object. Use this function to spawn a different object, and return the object for the read function to use.
|
||||||
--- The parameter should be a table containing several subtables with the following keys
|
function hook_exclamation_box(readFunc, writeFunc)
|
||||||
--- - index: The index of the content (used by oBehParam2ndByte)
|
|
||||||
--- - unused: Unused
|
|
||||||
--- - firstByte: The spawned object's oBehParam's 1st byte
|
|
||||||
--- - emodel: The spawned object's model
|
|
||||||
--- - behaviorId: The spawned object's behavior ID
|
|
||||||
function set_exclamation_box_new_contents(contents)
|
|
||||||
-- ...
|
|
||||||
end
|
end
|
|
@ -1,7 +1,4 @@
|
||||||
-- AUTOGENERATED FOR CODE EDITORS --
|
-- AUTOGENERATED FOR CODE EDITORS --
|
||||||
--- @meta
|
|
||||||
--- @diagnostic disable
|
|
||||||
|
|
||||||
|
|
||||||
--- @class AnimInfo
|
--- @class AnimInfo
|
||||||
--- @field public animAccel integer
|
--- @field public animAccel integer
|
||||||
|
@ -2148,13 +2145,6 @@
|
||||||
--- @field public g integer
|
--- @field public g integer
|
||||||
--- @field public r integer
|
--- @field public r integer
|
||||||
|
|
||||||
--- @class ExclamationBoxContents
|
|
||||||
--- @field public behaviorId BehaviorId
|
|
||||||
--- @field public emodel ModelExtendedId
|
|
||||||
--- @field public firstByte integer
|
|
||||||
--- @field public index integer
|
|
||||||
--- @field public unused integer
|
|
||||||
|
|
||||||
--- @class Pointer_integer
|
--- @class Pointer_integer
|
||||||
--- @class Pointer_Trajectory
|
--- @class Pointer_Trajectory
|
||||||
--- @class Pointer_LevelScript
|
--- @class Pointer_LevelScript
|
||||||
|
|
|
@ -2325,24 +2325,6 @@
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
## [restore_exclamation_box_original_contents](#restore_exclamation_box_original_contents)
|
|
||||||
|
|
||||||
### Lua Example
|
|
||||||
`restore_exclamation_box_original_contents()`
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
- None
|
|
||||||
|
|
||||||
### Returns
|
|
||||||
- None
|
|
||||||
|
|
||||||
### C Prototype
|
|
||||||
`void restore_exclamation_box_original_contents(void);`
|
|
||||||
|
|
||||||
[:arrow_up_small:](#)
|
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
## [set_whirlpools](#set_whirlpools)
|
## [set_whirlpools](#set_whirlpools)
|
||||||
|
|
||||||
### Lua Example
|
### Lua Example
|
||||||
|
|
|
@ -1695,7 +1695,6 @@
|
||||||
- [obj_move_xyz](functions-5.md#obj_move_xyz)
|
- [obj_move_xyz](functions-5.md#obj_move_xyz)
|
||||||
- [obj_set_model_extended](functions-5.md#obj_set_model_extended)
|
- [obj_set_model_extended](functions-5.md#obj_set_model_extended)
|
||||||
- [obj_set_vel](functions-5.md#obj_set_vel)
|
- [obj_set_vel](functions-5.md#obj_set_vel)
|
||||||
- [restore_exclamation_box_original_contents](functions-5.md#restore_exclamation_box_original_contents)
|
|
||||||
- [set_whirlpools](functions-5.md#set_whirlpools)
|
- [set_whirlpools](functions-5.md#set_whirlpools)
|
||||||
- [spawn_non_sync_object](functions-5.md#spawn_non_sync_object)
|
- [spawn_non_sync_object](functions-5.md#spawn_non_sync_object)
|
||||||
- [spawn_sync_object](functions-5.md#spawn_sync_object)
|
- [spawn_sync_object](functions-5.md#spawn_sync_object)
|
||||||
|
|
|
@ -145,6 +145,52 @@ hook_event(HOOK_MARIO_UPDATE, mario_update)
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
## [hook_exclamation_box](#hook_exclamation_box)
|
||||||
|
|
||||||
|
Activated when an exclamation box breaks, allowing mods to take control over exclamation boxes.
|
||||||
|
- `readFunction` is called after the exclamation box breaks, allowing mods to read the object that spawned.
|
||||||
|
- No return value is necessary.
|
||||||
|
- `writeFunction` is called when the exclamation box breaks, allowing mods to override the spawned object.
|
||||||
|
- Returning the spawned object is highly recommended as it prevents spawning both the vanilla and new object at the same time. It also allows `readFunction` to function properly.
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
|
||||||
|
| Field | Type |
|
||||||
|
| ----- | ---- |
|
||||||
|
| readFunction | `Lua Function` ([Object](structs.md#Object)) |
|
||||||
|
| writeFunction | `Lua Function` ([Object](structs.md#Object)): [Object](structs.md#Object) |
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local objects_to_spawn = {
|
||||||
|
[0] = {id_bhvGoomba, E_MODEL_GOOMBA},
|
||||||
|
[1] = {id_bhvKoopa, E_MODEL_KOOPA_WITH_SHELL},
|
||||||
|
[2] = {id_bhvTenCoinsSpawn, E_MODEL_NONE},
|
||||||
|
[3] = {id_bhvChainChomp, E_MODEL_CHAIN_CHOMP},
|
||||||
|
[4] = {id_bhvHeaveHo, E_MODEL_HEAVE_HO},
|
||||||
|
[5] = {id_bhvWingCap, E_MODEL_MARIOS_WING_CAP},
|
||||||
|
[6] = {id_bhvKoopaShell, E_MODEL_KOOPA_SHELL},
|
||||||
|
[7] = {id_bhvBoo, E_MODEL_BOO},
|
||||||
|
}
|
||||||
|
|
||||||
|
local function readFunction(obj)
|
||||||
|
if obj_has_behavior_id(obj, id_bhvFlame) ~= 0 then
|
||||||
|
print("FIREEEEEEEEE")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param box Object
|
||||||
|
local function writeFunction(box)
|
||||||
|
local spawn_object = objects_to_spawn[box.oBehParams2ndByte]
|
||||||
|
return spawn_sync_object(spawn_object[1], spawn_object[2], box.oPosX, box.oPosY, box.oPosZ, nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
hook_exclamation_box(readFunction, writeFunction)
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
## [hook_mario_action](#hook_mario_action)
|
## [hook_mario_action](#hook_mario_action)
|
||||||
`hook_mario_action()` allows Lua mods to create new actions or override existing ones.
|
`hook_mario_action()` allows Lua mods to create new actions or override existing ones.
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
- [Cutscene](#Cutscene)
|
- [Cutscene](#Cutscene)
|
||||||
- [CutsceneSplinePoint](#CutsceneSplinePoint)
|
- [CutsceneSplinePoint](#CutsceneSplinePoint)
|
||||||
- [CutsceneVariable](#CutsceneVariable)
|
- [CutsceneVariable](#CutsceneVariable)
|
||||||
- [ExclamationBoxContents](#ExclamationBoxContents)
|
|
||||||
- [FloorGeometry](#FloorGeometry)
|
- [FloorGeometry](#FloorGeometry)
|
||||||
- [GlobalObjectAnimations](#GlobalObjectAnimations)
|
- [GlobalObjectAnimations](#GlobalObjectAnimations)
|
||||||
- [GlobalObjectCollisionData](#GlobalObjectCollisionData)
|
- [GlobalObjectCollisionData](#GlobalObjectCollisionData)
|
||||||
|
@ -810,20 +809,6 @@
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
## [ExclamationBoxContents](#ExclamationBoxContents)
|
|
||||||
|
|
||||||
| Field | Type | Access |
|
|
||||||
| ----- | ---- | ------ |
|
|
||||||
| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) | |
|
|
||||||
| emodel | [enum ModelExtendedId](constants.md#enum-ModelExtendedId) | |
|
|
||||||
| firstByte | `integer` | |
|
|
||||||
| index | `integer` | |
|
|
||||||
| unused | `integer` | |
|
|
||||||
|
|
||||||
[:arrow_up_small:](#)
|
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
## [FloorGeometry](#FloorGeometry)
|
## [FloorGeometry](#FloorGeometry)
|
||||||
|
|
||||||
| Field | Type | Access |
|
| Field | Type | Access |
|
||||||
|
|
|
@ -49,10 +49,6 @@
|
||||||
#include "pc/lua/utils/smlua_model_utils.h"
|
#include "pc/lua/utils/smlua_model_utils.h"
|
||||||
#include "pc/lua/smlua_hooks.h"
|
#include "pc/lua/smlua_hooks.h"
|
||||||
|
|
||||||
#include "pc/lua/smlua.h"
|
|
||||||
#include "pc/lua/smlua_utils.h"
|
|
||||||
#include "pc/lua/utils/smlua_obj_utils.h"
|
|
||||||
|
|
||||||
#define o gCurrentObject
|
#define o gCurrentObject
|
||||||
|
|
||||||
struct WFRotatingPlatformData {
|
struct WFRotatingPlatformData {
|
||||||
|
@ -78,7 +74,6 @@ struct Struct8032F698 {
|
||||||
s16 unk4;
|
s16 unk4;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Moved to smlua_obj_utils.h
|
|
||||||
struct Struct802C0DF0 {
|
struct Struct802C0DF0 {
|
||||||
u8 unk0;
|
u8 unk0;
|
||||||
u8 unk1;
|
u8 unk1;
|
||||||
|
@ -86,7 +81,6 @@ struct Struct802C0DF0 {
|
||||||
u8 model;
|
u8 model;
|
||||||
const BehaviorScript *behavior;
|
const BehaviorScript *behavior;
|
||||||
};
|
};
|
||||||
*/
|
|
||||||
|
|
||||||
struct Struct8032F754 {
|
struct Struct8032F754 {
|
||||||
s32 unk0;
|
s32 unk0;
|
||||||
|
|
|
@ -28,7 +28,7 @@ struct Struct802C0DF0 sExclamationBoxContents[] = { { 0, 0, 0, MODEL_MARIOS_WING
|
||||||
{ 12, 0, 3, MODEL_STAR, bhvSpawnedStar },
|
{ 12, 0, 3, MODEL_STAR, bhvSpawnedStar },
|
||||||
{ 13, 0, 4, MODEL_STAR, bhvSpawnedStar },
|
{ 13, 0, 4, MODEL_STAR, bhvSpawnedStar },
|
||||||
{ 14, 0, 5, MODEL_STAR, bhvSpawnedStar },
|
{ 14, 0, 5, MODEL_STAR, bhvSpawnedStar },
|
||||||
{ 255, 0, 0, 0, NULL } };
|
{ 99, 0, 0, 0, NULL } };
|
||||||
|
|
||||||
void bhv_rotating_exclamation_box_loop(void) {
|
void bhv_rotating_exclamation_box_loop(void) {
|
||||||
if (!o->parentObj || o->parentObj->oAction != 1)
|
if (!o->parentObj || o->parentObj->oAction != 1)
|
||||||
|
@ -122,26 +122,33 @@ static s32 exclamation_replace_model(struct MarioState* m, s32 model) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void exclamation_box_spawn_contents(struct Struct802C0DF0 *a0, u8 a1, u8 size) {
|
void exclamation_box_spawn_contents(struct Struct802C0DF0 *a0, u8 a1) {
|
||||||
struct MarioState* marioState = nearest_mario_state_to_object(o);
|
struct MarioState* marioState = nearest_mario_state_to_object(o);
|
||||||
struct Object* player = marioState ? marioState->marioObj : NULL;
|
struct Object* player = marioState ? marioState->marioObj : NULL;
|
||||||
struct Object *sp1C = NULL;
|
struct Object *spawnedObject = NULL;
|
||||||
|
|
||||||
if (o->oExclamationBoxForce) {
|
if (o->oExclamationBoxForce) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u8 i = 0; i < size; i++) {
|
struct Object* luaSpawnedObject = NULL;
|
||||||
|
if ((luaSpawnedObject = smlua_call_exclamation_box_hook(o, true)) != NULL) {
|
||||||
|
(void *)smlua_call_exclamation_box_hook(luaSpawnedObject, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (a0->unk0 != 99) {
|
||||||
if (a1 == a0->unk0) {
|
if (a1 == a0->unk0) {
|
||||||
s32 model = exclamation_replace_model(marioState, a0->model);
|
s32 model = exclamation_replace_model(marioState, a0->model);
|
||||||
|
|
||||||
sp1C = spawn_object(o, model, a0->behavior);
|
spawnedObject = spawn_object(o, model, a0->behavior);
|
||||||
if (sp1C != NULL) {
|
(void *)smlua_call_exclamation_box_hook(spawnedObject, false);
|
||||||
sp1C->oVelY = 20.0f;
|
if (spawnedObject != NULL) {
|
||||||
sp1C->oForwardVel = 3.0f;
|
spawnedObject->oVelY = 20.0f;
|
||||||
|
spawnedObject->oForwardVel = 3.0f;
|
||||||
if (player) {
|
if (player) {
|
||||||
sp1C->oMoveAngleYaw = player->oMoveAngleYaw;
|
spawnedObject->oMoveAngleYaw = player->oMoveAngleYaw;
|
||||||
sp1C->globalPlayerIndex = player->globalPlayerIndex;
|
spawnedObject->globalPlayerIndex = player->globalPlayerIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
o->oBehParams |= a0->unk2 << 24;
|
o->oBehParams |= a0->unk2 << 24;
|
||||||
|
@ -150,13 +157,12 @@ void exclamation_box_spawn_contents(struct Struct802C0DF0 *a0, u8 a1, u8 size) {
|
||||||
|
|
||||||
// send non-star spawn events
|
// send non-star spawn events
|
||||||
// stars cant be sent here to due jankiness in oBehParams
|
// stars cant be sent here to due jankiness in oBehParams
|
||||||
if (a0->behavior != smlua_override_behavior(bhvSpawnedStar) && sp1C != NULL) {
|
if (a0->behavior != smlua_override_behavior(bhvSpawnedStar) && spawnedObject != NULL) {
|
||||||
// hack: if any other sync objects get spawned here we have to check for them
|
// hack: if any other sync objects get spawned here we have to check for them
|
||||||
// problem: going to need to sync every object
|
|
||||||
if (a0->behavior == smlua_override_behavior(bhvKoopaShell)) {
|
if (a0->behavior == smlua_override_behavior(bhvKoopaShell)) {
|
||||||
sync_object_set_id(sp1C);
|
sync_object_set_id(spawnedObject);
|
||||||
}
|
}
|
||||||
struct Object* spawn_objects[] = { sp1C };
|
struct Object* spawn_objects[] = { spawnedObject };
|
||||||
u32 models[] = { model };
|
u32 models[] = { model };
|
||||||
network_send_spawn_objects(spawn_objects, models, 1);
|
network_send_spawn_objects(spawn_objects, models, 1);
|
||||||
}
|
}
|
||||||
|
@ -167,9 +173,7 @@ void exclamation_box_spawn_contents(struct Struct802C0DF0 *a0, u8 a1, u8 size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void exclamation_box_act_4(void) {
|
void exclamation_box_act_4(void) {
|
||||||
struct Struct802C0DF0 *newContents = get_exclamation_box_new_contents_pointer();
|
exclamation_box_spawn_contents(sExclamationBoxContents, o->oBehParams2ndByte);
|
||||||
u8 newContentsSize = get_exclamation_box_new_contents_size();
|
|
||||||
exclamation_box_spawn_contents(newContents ? newContents : sExclamationBoxContents, o->oBehParams2ndByte, newContentsSize);
|
|
||||||
spawn_mist_particles_variable(0, 0, 46.0f);
|
spawn_mist_particles_variable(0, 0, 46.0f);
|
||||||
spawn_triangle_break_particles(20, 139, 0.3f, o->oAnimState);
|
spawn_triangle_break_particles(20, 139, 0.3f, o->oAnimState);
|
||||||
create_sound_spawner(SOUND_GENERAL_BREAK_BOX);
|
create_sound_spawner(SOUND_GENERAL_BREAK_BOX);
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#include "pc/lua/utils/smlua_model_utils.h"
|
#include "pc/lua/utils/smlua_model_utils.h"
|
||||||
#include "pc/lua/utils/smlua_level_utils.h"
|
#include "pc/lua/utils/smlua_level_utils.h"
|
||||||
#include "pc/lua/utils/smlua_anim_utils.h"
|
#include "pc/lua/utils/smlua_anim_utils.h"
|
||||||
#include "pc/lua/utils/smlua_obj_utils.h"
|
|
||||||
#include "pc/djui/djui.h"
|
#include "pc/djui/djui.h"
|
||||||
|
|
||||||
lua_State* gLuaState = NULL;
|
lua_State* gLuaState = NULL;
|
||||||
|
@ -322,8 +321,6 @@ void smlua_shutdown(void) {
|
||||||
smlua_model_util_clear();
|
smlua_model_util_clear();
|
||||||
smlua_level_util_reset();
|
smlua_level_util_reset();
|
||||||
smlua_anim_util_reset();
|
smlua_anim_util_reset();
|
||||||
restore_exclamation_box_original_contents();
|
|
||||||
|
|
||||||
lua_State* L = gLuaState;
|
lua_State* L = gLuaState;
|
||||||
if (L != NULL) {
|
if (L != NULL) {
|
||||||
lua_close(L);
|
lua_close(L);
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include "include/level_misc_macros.h"
|
#include "include/level_misc_macros.h"
|
||||||
#include "include/macro_presets.h"
|
#include "include/macro_presets.h"
|
||||||
#include "utils/smlua_anim_utils.h"
|
#include "utils/smlua_anim_utils.h"
|
||||||
#include "utils/smlua_obj_utils.h"
|
|
||||||
|
|
||||||
bool smlua_functions_valid_param_count(lua_State* L, int expected) {
|
bool smlua_functions_valid_param_count(lua_State* L, int expected) {
|
||||||
int top = lua_gettop(L);
|
int top = lua_gettop(L);
|
||||||
|
@ -211,98 +210,6 @@ int smlua_func_network_send_to(lua_State* L) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int smlua_func_set_exclamation_box_new_contents(lua_State* L) {
|
|
||||||
if (L == NULL) { return 0; }
|
|
||||||
if (!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
|
||||||
|
|
||||||
static struct Struct802C0DF0 sExclamationBoxContentsArray[255];
|
|
||||||
|
|
||||||
u8 subtable_counter = 0;
|
|
||||||
if (lua_type(L, 1) != LUA_TTABLE) {
|
|
||||||
LOG_LUA("Failed to convert parameter 1 to table");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
lua_pushnil(L); // Set so lua_next() pops this off upon starting
|
|
||||||
// Enter main table
|
|
||||||
while (lua_next(L, 1) != 0) {
|
|
||||||
// key is index -2, value is index -1
|
|
||||||
if (lua_type(L, -1) != LUA_TTABLE) {
|
|
||||||
LOG_LUA("Failed to find subtable\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create an empty struct to put values in
|
|
||||||
struct Struct802C0DF0 sContents = { 0 };
|
|
||||||
|
|
||||||
int initialTop = lua_gettop(L); // Hopefully 3
|
|
||||||
lua_pushnil(L); // Set so lua_next() pops this off upon starting
|
|
||||||
u8 elements_counter = 0;
|
|
||||||
// Special care is taken here, so any invalid subtables will error
|
|
||||||
while (lua_next(L, initialTop) != 0) {
|
|
||||||
int keyIndex = lua_gettop(L) - 1;
|
|
||||||
int valueIndex = lua_gettop(L) - 0;
|
|
||||||
|
|
||||||
const char* key = smlua_to_string(L, keyIndex);
|
|
||||||
if (!gSmLuaConvertSuccess) {
|
|
||||||
LOG_LUA("Failed to convert key to string in subtable %u", subtable_counter);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int value = smlua_to_integer(L, valueIndex);
|
|
||||||
if (!gSmLuaConvertSuccess) {
|
|
||||||
LOG_LUA("The key \"%s\" within subtable %u has a value that is not a number (Type: %u)", key, subtable_counter, lua_type(L, valueIndex));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bad
|
|
||||||
if (!strcmp(key, "index")) {
|
|
||||||
sContents.unk0 = value;
|
|
||||||
elements_counter++;
|
|
||||||
lua_pop(L, 1); // pop value
|
|
||||||
} else if (!strcmp(key, "unused")) {
|
|
||||||
sContents.unk1 = value;
|
|
||||||
elements_counter++;
|
|
||||||
lua_pop(L, 1); // pop value
|
|
||||||
} else if (!strcmp(key, "firstByte")) {
|
|
||||||
sContents.unk2 = value;
|
|
||||||
elements_counter++;
|
|
||||||
lua_pop(L, 1); // pop value
|
|
||||||
} else if (!strcmp(key, "emodel")) {
|
|
||||||
u16 loadedModelId = smlua_model_util_load(value);
|
|
||||||
sContents.model = loadedModelId;
|
|
||||||
elements_counter++;
|
|
||||||
lua_pop(L, 1); // pop value
|
|
||||||
} else if (!strcmp(key, "behaviorId")) {
|
|
||||||
sContents.behavior = get_behavior_from_id(value);
|
|
||||||
elements_counter++;
|
|
||||||
lua_pop(L, 1); // pop value
|
|
||||||
} else {
|
|
||||||
LOG_LUA("The key \"%s\" in subtable %u is invalid", key, subtable_counter);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (elements_counter != 5) {
|
|
||||||
LOG_LUA("Invalid elements count in subtable %u (There should be 5)", subtable_counter);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Element 254 will not be set
|
|
||||||
if (subtable_counter < 254) {
|
|
||||||
sExclamationBoxContentsArray[subtable_counter] = sContents;
|
|
||||||
subtable_counter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
lua_pop(L, 1); // pop key
|
|
||||||
}
|
|
||||||
lua_pop(L, 1); // pop key
|
|
||||||
|
|
||||||
set_exclamation_box_new_contents(sExclamationBoxContentsArray, subtable_counter);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////
|
//////////////
|
||||||
// Textures //
|
// Textures //
|
||||||
//////////////
|
//////////////
|
||||||
|
@ -840,5 +747,4 @@ void smlua_bind_functions(void) {
|
||||||
smlua_bind_function(L, "djui_hud_render_texture_tile_interpolated", smlua_func_djui_hud_render_texture_tile_interpolated);
|
smlua_bind_function(L, "djui_hud_render_texture_tile_interpolated", smlua_func_djui_hud_render_texture_tile_interpolated);
|
||||||
smlua_bind_function(L, "level_script_parse", smlua_func_level_script_parse);
|
smlua_bind_function(L, "level_script_parse", smlua_func_level_script_parse);
|
||||||
smlua_bind_function(L, "smlua_anim_util_register_animation", smlua_func_smlua_anim_util_register_animation);
|
smlua_bind_function(L, "smlua_anim_util_register_animation", smlua_func_smlua_anim_util_register_animation);
|
||||||
smlua_bind_function(L, "set_exclamation_box_new_contents", smlua_func_set_exclamation_box_new_contents);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29939,21 +29939,6 @@ int smlua_func_obj_set_vel(lua_State* L) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int smlua_func_restore_exclamation_box_original_contents(UNUSED lua_State* L) {
|
|
||||||
if (L == NULL) { return 0; }
|
|
||||||
|
|
||||||
int top = lua_gettop(L);
|
|
||||||
if (top != 0) {
|
|
||||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "restore_exclamation_box_original_contents", 0, top);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
restore_exclamation_box_original_contents();
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int smlua_func_set_whirlpools(lua_State* L) {
|
int smlua_func_set_whirlpools(lua_State* L) {
|
||||||
if (L == NULL) { return 0; }
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
@ -32625,7 +32610,6 @@ void smlua_bind_functions_autogen(void) {
|
||||||
smlua_bind_function(L, "obj_move_xyz", smlua_func_obj_move_xyz);
|
smlua_bind_function(L, "obj_move_xyz", smlua_func_obj_move_xyz);
|
||||||
smlua_bind_function(L, "obj_set_model_extended", smlua_func_obj_set_model_extended);
|
smlua_bind_function(L, "obj_set_model_extended", smlua_func_obj_set_model_extended);
|
||||||
smlua_bind_function(L, "obj_set_vel", smlua_func_obj_set_vel);
|
smlua_bind_function(L, "obj_set_vel", smlua_func_obj_set_vel);
|
||||||
smlua_bind_function(L, "restore_exclamation_box_original_contents", smlua_func_restore_exclamation_box_original_contents);
|
|
||||||
smlua_bind_function(L, "set_whirlpools", smlua_func_set_whirlpools);
|
smlua_bind_function(L, "set_whirlpools", smlua_func_set_whirlpools);
|
||||||
smlua_bind_function(L, "spawn_non_sync_object", smlua_func_spawn_non_sync_object);
|
smlua_bind_function(L, "spawn_non_sync_object", smlua_func_spawn_non_sync_object);
|
||||||
smlua_bind_function(L, "spawn_sync_object", smlua_func_spawn_sync_object);
|
smlua_bind_function(L, "spawn_sync_object", smlua_func_spawn_sync_object);
|
||||||
|
|
|
@ -1752,6 +1752,107 @@ int smlua_hook_on_sync_table_change(lua_State* L) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////
|
||||||
|
// hooked exclamation box //
|
||||||
|
////////////////////////////
|
||||||
|
|
||||||
|
struct LuaHookedExclamationBox {
|
||||||
|
int readFuncReference;
|
||||||
|
int writeFuncReference;
|
||||||
|
struct Mod* mod;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAX_HOOKED_EXCLAMATION_BOXES 255 // Way more than needed, but better safe than sorry
|
||||||
|
|
||||||
|
static struct LuaHookedExclamationBox sHookedExclamationBoxes[MAX_HOOKED_EXCLAMATION_BOXES] = { 0 };
|
||||||
|
static int sHookedExclamationBoxesCount = 0;
|
||||||
|
|
||||||
|
// Bind to lua
|
||||||
|
int smlua_hook_exclamation_box(lua_State* L) {
|
||||||
|
if (L == NULL) { return 0; }
|
||||||
|
if (!smlua_functions_valid_param_count(L, 2)) { return 0; }
|
||||||
|
|
||||||
|
if (gLuaLoadingMod == NULL) {
|
||||||
|
LOG_LUA_LINE("hook_exclamation_box() can only be called on load.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sHookedBehaviorsCount > MAX_HOOKED_EXCLAMATION_BOXES) {
|
||||||
|
LOG_LUA_LINE("hook_exclamation_box() calls exceeded maximum references");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int readReference = 0;
|
||||||
|
int readReferenceType = lua_type(L, 1);
|
||||||
|
if (readReferenceType == LUA_TNIL) {
|
||||||
|
// nothing
|
||||||
|
} else if (readReferenceType == LUA_TFUNCTION) {
|
||||||
|
// get reference
|
||||||
|
lua_pushvalue(L, 1);
|
||||||
|
readReference = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||||
|
} else {
|
||||||
|
LOG_LUA_LINE("Hook exclamation box: tried to reference non-function for read function");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int writeReference = 0;
|
||||||
|
int writeReferenceType = lua_type(L, 2);
|
||||||
|
if (writeReferenceType == LUA_TNIL) {
|
||||||
|
// nothing
|
||||||
|
} else if (writeReferenceType == LUA_TFUNCTION) {
|
||||||
|
// get reference
|
||||||
|
lua_pushvalue(L, 2);
|
||||||
|
writeReference = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||||
|
} else {
|
||||||
|
LOG_LUA_LINE("Hook exclamation box: tried to reference non-function for write function");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LuaHookedExclamationBox* hooked = &sHookedExclamationBoxes[sHookedExclamationBoxesCount];
|
||||||
|
hooked->readFuncReference = readReference;
|
||||||
|
hooked->writeFuncReference = writeReference;
|
||||||
|
hooked->mod = gLuaActiveMod;
|
||||||
|
|
||||||
|
if (!gSmLuaConvertSuccess) { return 0; }
|
||||||
|
sHookedBehaviorsCount++;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called from the exclamation boxes
|
||||||
|
struct Object* smlua_call_exclamation_box_hook(struct Object* obj, bool write) {
|
||||||
|
lua_State* L = gLuaState;
|
||||||
|
if (L == NULL) { return NULL; }
|
||||||
|
for (int i = 0; i < sHookedBehaviorsCount; i++) {
|
||||||
|
struct LuaHookedExclamationBox* hook = &sHookedExclamationBoxes[i];
|
||||||
|
|
||||||
|
// Push 2 potential callbacks
|
||||||
|
int reference = write ? hook->writeFuncReference : hook->readFuncReference;
|
||||||
|
lua_rawgeti(L, LUA_REGISTRYINDEX, reference);
|
||||||
|
|
||||||
|
// push object
|
||||||
|
smlua_push_object(L, LOT_OBJECT, obj);
|
||||||
|
|
||||||
|
// call the callback
|
||||||
|
if (reference != 0 && 0 != smlua_call_hook(L, 1, 1, 0, hook->mod)) {
|
||||||
|
LOG_LUA("Failed to call the exclamation box callback: %s", (write ? "writeFunction" : "readFunction"));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// output the return value
|
||||||
|
struct Object* returnObject = NULL;
|
||||||
|
if (write) {
|
||||||
|
returnObject = (struct Object*)smlua_to_cobject(L, 1, LOT_OBJECT);
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
if (!gSmLuaConvertSuccess) { return NULL; }
|
||||||
|
|
||||||
|
return returnObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////
|
//////////
|
||||||
// misc //
|
// misc //
|
||||||
|
@ -1828,4 +1929,5 @@ void smlua_bind_hooks(void) {
|
||||||
smlua_bind_function(L, "hook_on_sync_table_change", smlua_hook_on_sync_table_change);
|
smlua_bind_function(L, "hook_on_sync_table_change", smlua_hook_on_sync_table_change);
|
||||||
smlua_bind_function(L, "hook_behavior", smlua_hook_behavior);
|
smlua_bind_function(L, "hook_behavior", smlua_hook_behavior);
|
||||||
smlua_bind_function(L, "update_chat_command_description", smlua_update_chat_command_description);
|
smlua_bind_function(L, "update_chat_command_description", smlua_update_chat_command_description);
|
||||||
|
smlua_bind_function(L, "hook_exclamation_box", smlua_hook_exclamation_box);
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,6 +133,9 @@ bool smlua_call_event_hooks_mario_param_and_int_ret_int(enum LuaHookedEventType
|
||||||
bool smlua_call_event_hooks_mario_param_and_int_and_int_ret_int(enum LuaHookedEventType hookType, struct MarioState* m, s32 param, u32 args, s32* returnValue);
|
bool smlua_call_event_hooks_mario_param_and_int_and_int_ret_int(enum LuaHookedEventType hookType, struct MarioState* m, s32 param, u32 args, s32* returnValue);
|
||||||
void smlua_call_event_hooks_graph_node_object_and_int_param(enum LuaHookedEventType hookType, struct GraphNodeObject* node, s32 param);
|
void smlua_call_event_hooks_graph_node_object_and_int_param(enum LuaHookedEventType hookType, struct GraphNodeObject* node, s32 param);
|
||||||
|
|
||||||
|
int smlua_hook_exclamation_box(lua_State* L);
|
||||||
|
struct Object* smlua_call_exclamation_box_hook(struct Object* obj, bool write);
|
||||||
|
|
||||||
enum BehaviorId smlua_get_original_behavior_id(const BehaviorScript* behavior);
|
enum BehaviorId smlua_get_original_behavior_id(const BehaviorScript* behavior);
|
||||||
const BehaviorScript* smlua_override_behavior(const BehaviorScript* behavior);
|
const BehaviorScript* smlua_override_behavior(const BehaviorScript* behavior);
|
||||||
const BehaviorScript* smlua_get_hooked_behavior_from_id(enum BehaviorId id, bool returnOriginal);
|
const BehaviorScript* smlua_get_hooked_behavior_from_id(enum BehaviorId id, bool returnOriginal);
|
||||||
|
|
|
@ -407,27 +407,6 @@ void set_whirlpools(f32 x, f32 y, f32 z, s16 strength, s16 area, s32 index) {
|
||||||
gAreas[area].whirlpools[index]->strength = strength;
|
gAreas[area].whirlpools[index]->strength = strength;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Struct802C0DF0 *newContents = NULL;
|
|
||||||
u8 newContentsSize = 16;
|
|
||||||
|
|
||||||
struct Struct802C0DF0* get_exclamation_box_new_contents_pointer(void) {
|
|
||||||
return newContents;
|
|
||||||
}
|
|
||||||
|
|
||||||
u8 get_exclamation_box_new_contents_size(void) {
|
|
||||||
return newContentsSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_exclamation_box_new_contents(struct Struct802C0DF0 contents[], u8 size) {
|
|
||||||
newContents = contents;
|
|
||||||
newContentsSize = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void restore_exclamation_box_original_contents(void) {
|
|
||||||
newContents = NULL;
|
|
||||||
newContentsSize = 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEVELOPMENT
|
#ifdef DEVELOPMENT
|
||||||
void obj_randomize(struct Object* o) {
|
void obj_randomize(struct Object* o) {
|
||||||
if (!o) { return; }
|
if (!o) { return; }
|
||||||
|
|
|
@ -5,14 +5,6 @@
|
||||||
#include "smlua_model_utils.h"
|
#include "smlua_model_utils.h"
|
||||||
#include "game/object_list_processor.h"
|
#include "game/object_list_processor.h"
|
||||||
|
|
||||||
struct Struct802C0DF0 {
|
|
||||||
u8 unk0; // Index
|
|
||||||
u8 unk1; // Unused
|
|
||||||
u8 unk2; // oBehParams1stByte
|
|
||||||
u16 model;
|
|
||||||
const BehaviorScript *behavior;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Object* spawn_sync_object(enum BehaviorId behaviorId, enum ModelExtendedId modelId, f32 x, f32 y, f32 z, LuaFunction objSetupFunction);
|
struct Object* spawn_sync_object(enum BehaviorId behaviorId, enum ModelExtendedId modelId, f32 x, f32 y, f32 z, LuaFunction objSetupFunction);
|
||||||
struct Object* spawn_non_sync_object(enum BehaviorId behaviorId, enum ModelExtendedId modelId, f32 x, f32 y, f32 z, LuaFunction objSetupFunction);
|
struct Object* spawn_non_sync_object(enum BehaviorId behaviorId, enum ModelExtendedId modelId, f32 x, f32 y, f32 z, LuaFunction objSetupFunction);
|
||||||
|
|
||||||
|
@ -65,9 +57,4 @@ void obj_move_xyz(struct Object *o, f32 dx, f32 dy, f32 dz);
|
||||||
|
|
||||||
void set_whirlpools(f32 x, f32 y, f32 z, s16 strength, s16 area, s32 index);
|
void set_whirlpools(f32 x, f32 y, f32 z, s16 strength, s16 area, s32 index);
|
||||||
|
|
||||||
struct Struct802C0DF0* get_exclamation_box_new_contents_pointer(void);
|
|
||||||
u8 get_exclamation_box_new_contents_size(void);
|
|
||||||
void set_exclamation_box_new_contents(struct Struct802C0DF0 contents[], u8 size);
|
|
||||||
void restore_exclamation_box_original_contents(void);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue