diff --git a/actors/bowser_key/bowser_key_left.rgba16.png b/actors/bowser_key/bowser_key_left.rgba16.png new file mode 100644 index 00000000..2f9ca909 Binary files /dev/null and b/actors/bowser_key/bowser_key_left.rgba16.png differ diff --git a/actors/bowser_key/bowser_key_right.rgba16.png b/actors/bowser_key/bowser_key_right.rgba16.png new file mode 100644 index 00000000..acd881e7 Binary files /dev/null and b/actors/bowser_key/bowser_key_right.rgba16.png differ diff --git a/actors/bowser_key/model.inc.c b/actors/bowser_key/model.inc.c index 7cee5952..c726fe95 100644 --- a/actors/bowser_key/model.inc.c +++ b/actors/bowser_key/model.inc.c @@ -6,6 +6,14 @@ static const Lights1 bowser_key_lights = gdSPDefLights1( 0xff, 0xb2, 0x00, 0x28, 0x28, 0x28 ); +ALIGNED8 const Texture bowser_key_left_texture[] = { +#include "actors/bowser_key/bowser_key_left.rgba16.inc.c" +}; + +ALIGNED8 const Texture bowser_key_right_texture[] = { +#include "actors/bowser_key/bowser_key_right.rgba16.inc.c" +}; + // 0x030156F8 static const Vtx bowser_key_dl_vertex_group1[] = { {{{ 219, 22, -17}, 0, { 0, 0}, {0x88, 0x26, 0x00, 0x00}}}, diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua index bf1a4e97..72b2e8ff 100644 --- a/autogen/lua_definitions/constants.lua +++ b/autogen/lua_definitions/constants.lua @@ -1989,7 +1989,13 @@ id_RM_Scroll_Texture = 535 id_editor_Scroll_Texture = 536 --- @type BehaviorId -id_bhv_max_count = 537 +id_bhvBlueCoinNumber = 537 + +--- @type BehaviorId +id_bhvStarNumber = 538 + +--- @type BehaviorId +id_bhv_max_count = 539 --- @type integer CAMERA_MODE_8_DIRECTIONS = 0x0E @@ -4946,6 +4952,9 @@ BLUE_COIN_SWITCH_ACT_IDLE = 0 --- @type integer BLUE_COIN_SWITCH_ACT_RECEDING = 1 +--- @type integer +BLUE_COIN_SWITCH_ACT_RESPAWNING = 3 + --- @type integer BLUE_COIN_SWITCH_ACT_TICKING = 2 @@ -11429,4 +11438,4 @@ MAX_VERSION_LENGTH = 10 MINOR_VERSION_NUMBER = 0 --- @type integer -VERSION_NUMBER = 31 +VERSION_NUMBER = 32 diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua index 30d53d64..af7a8f1d 100644 --- a/autogen/lua_definitions/functions.lua +++ b/autogen/lua_definitions/functions.lua @@ -286,6 +286,11 @@ function bhv_blue_coin_jumping_loop() -- ... end +--- @return nil +function bhv_blue_coin_number_loop() + -- ... +end + --- @return nil function bhv_blue_coin_sliding_jumping_init() -- ... @@ -296,6 +301,11 @@ function bhv_blue_coin_sliding_loop() -- ... end +--- @return nil +function bhv_blue_coin_switch_init() + -- ... +end + --- @return nil function bhv_blue_coin_switch_loop() -- ... @@ -2169,6 +2179,11 @@ function bhv_star_key_collection_puff_spawner_loop() -- ... end +--- @return nil +function bhv_star_number_loop() + -- ... +end + --- @return nil function bhv_star_spawn_init() -- ... @@ -2833,6 +2848,11 @@ function spawn_red_coin_cutscene_star(x, y, z) -- ... end +--- @return nil +function spawn_star_number() + -- ... +end + --- @param numTris integer --- @param triModel integer --- @param triSize number diff --git a/autogen/lua_definitions/structs.lua b/autogen/lua_definitions/structs.lua index 496abcb8..543af7ff 100644 --- a/autogen/lua_definitions/structs.lua +++ b/autogen/lua_definitions/structs.lua @@ -640,22 +640,33 @@ --- @field public exitCastleArea integer --- @field public exitCastleLevel LevelNum --- @field public exitCastleWarpNode integer +--- @field public extendedPauseDisplay integer --- @field public fixCollisionBugs integer ---- @field public fixVanishFloors boolean +--- @field public fixVanishFloors integer +--- @field public floatingStarDance integer --- @field public floorLowerLimit integer --- @field public floorLowerLimitMisc integer --- @field public floorLowerLimitShadow integer +--- @field public hudCapTimer integer +--- @field public hudRedCoinsRadar integer +--- @field public hudSecretsRadar integer --- @field public metalCapDuration integer --- @field public metalCapDurationCotmc integer --- @field public metalCapSequence integer +--- @field public mushroom1UpHeal integer --- @field public pauseExitAnywhere boolean +--- @field public previewBlueCoins integer --- @field public pssSlideStarIndex integer --- @field public pssSlideStarTime integer +--- @field public respawnBlueCoinsSwitch integer +--- @field public showStarNumber integer --- @field public skipCreditsAt LevelNum +--- @field public starHeal integer --- @field public starPositions StarPositions --- @field public vanishCapDuration integer --- @field public vanishCapDurationVcutm integer --- @field public vanishCapSequence integer +--- @field public visibleSecrets integer --- @field public wingCapDuration integer --- @field public wingCapDurationTotwc integer --- @field public wingCapLookUpReq integer @@ -760,7 +771,6 @@ --- @field public unkC4 number --- @field public usedObj Object --- @field public vel Vec3f ---- @field public visibleToEnemies integer --- @field public wall Surface --- @field public wallKickTimer integer --- @field public wallNormal Vec3f diff --git a/data/behavior_data.c b/data/behavior_data.c index 69939380..ad675f1a 100644 --- a/data/behavior_data.c +++ b/data/behavior_data.c @@ -2805,11 +2805,22 @@ const BehaviorScript bhvPurpleSwitchHiddenBoxes[] = { GOTO(bhvFloorSwitchHardcodedModel + 1 + 1), }; +const BehaviorScript bhvBlueCoinNumber[] = { + BEGIN(OBJ_LIST_DEFAULT), + ID(id_bhvBlueCoinNumber), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + BILLBOARD(), + BEGIN_LOOP(), + CALL_NATIVE(bhv_blue_coin_number_loop), + END_LOOP(), +}; + const BehaviorScript bhvBlueCoinSwitch[] = { BEGIN(OBJ_LIST_SURFACE), ID(id_bhvBlueCoinSwitch), OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), LOAD_COLLISION_DATA(blue_coin_switch_seg8_collision_08000E98), + CALL_NATIVE(bhv_blue_coin_switch_init), BEGIN_LOOP(), CALL_NATIVE(bhv_blue_coin_switch_loop), END_LOOP(), @@ -4738,6 +4749,16 @@ const BehaviorScript bhvVanishCap[] = { END_LOOP(), }; +const BehaviorScript bhvStarNumber[] = { + BEGIN(OBJ_LIST_DEFAULT), + ID(id_bhvStarNumber), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + BILLBOARD(), + BEGIN_LOOP(), + CALL_NATIVE(bhv_star_number_loop), + END_LOOP(), +}; + const BehaviorScript bhvStar[] = { BEGIN(OBJ_LIST_LEVEL), ID(id_bhvStar), diff --git a/data/behavior_table.c b/data/behavior_table.c index f325f581..c383ef58 100644 --- a/data/behavior_table.c +++ b/data/behavior_table.c @@ -61,6 +61,7 @@ const struct BehaviorTableEntry gBehaviorTable[id_bhv_max_count] = { BHV_ENTRY(bhvBlueBowserFlame), BHV_ENTRY(bhvBlueCoinJumping), BHV_ENTRY(bhvBlueCoinSliding), + BHV_ENTRY(bhvBlueCoinNumber), BHV_ENTRY(bhvBlueCoinSwitch), BHV_ENTRY(bhvBlueFish), BHV_ENTRY(bhvBlueFlamesGroup), @@ -423,6 +424,7 @@ const struct BehaviorTableEntry gBehaviorTable[id_bhv_max_count] = { BHV_ENTRY(bhvStar), BHV_ENTRY(bhvStarDoor), BHV_ENTRY(bhvStarKeyCollectionPuffSpawner), + BHV_ENTRY(bhvStarNumber), BHV_ENTRY(bhvStarSpawnCoordinates), BHV_ENTRY(bhvStaticCheckeredPlatform), BHV_ENTRY(bhvStaticObject), diff --git a/data/dynos_bin_behavior.cpp b/data/dynos_bin_behavior.cpp index a93d283f..f148c94d 100644 --- a/data/dynos_bin_behavior.cpp +++ b/data/dynos_bin_behavior.cpp @@ -286,6 +286,7 @@ s64 DynOS_Bhv_ParseBehaviorScriptConstants(const String &_Arg, bool *found) { bhv_constant(id_bhvBlueBowserFlame); bhv_constant(id_bhvBlueCoinJumping); bhv_constant(id_bhvBlueCoinSliding); + bhv_constant(id_bhvBlueCoinNumber); bhv_constant(id_bhvBlueCoinSwitch); bhv_constant(id_bhvBlueFish); bhv_constant(id_bhvBlueFlamesGroup); @@ -648,6 +649,7 @@ s64 DynOS_Bhv_ParseBehaviorScriptConstants(const String &_Arg, bool *found) { bhv_constant(id_bhvStar); bhv_constant(id_bhvStarDoor); bhv_constant(id_bhvStarKeyCollectionPuffSpawner); + bhv_constant(id_bhvStarNumber); bhv_constant(id_bhvStarSpawnCoordinates); bhv_constant(id_bhvStaticCheckeredPlatform); bhv_constant(id_bhvStaticObject); diff --git a/data/dynos_bin_common.cpp b/data/dynos_bin_common.cpp index abdf9464..15b76a82 100644 --- a/data/dynos_bin_common.cpp +++ b/data/dynos_bin_common.cpp @@ -246,6 +246,7 @@ s64 DynOS_Common_ParseBhvConstants(const String &_Arg, bool *found) { common_constant(bhvWhitePuff2); common_constant(bhvWhitePuffSmoke2); common_constant(bhvPurpleSwitchHiddenBoxes); + common_constant(bhvBlueCoinNumber); common_constant(bhvBlueCoinSwitch); common_constant(bhvHiddenBlueCoin); common_constant(bhvOpenableCageDoor); @@ -415,6 +416,7 @@ s64 DynOS_Common_ParseBhvConstants(const String &_Arg, bool *found) { common_constant(bhvNormalCap); common_constant(bhvVanishCap); common_constant(bhvStar); + common_constant(bhvStarNumber); common_constant(bhvStarSpawnCoordinates); common_constant(bhvHiddenRedCoinStar); common_constant(bhvRedCoin); diff --git a/data/dynos_mgr_builtin.cpp b/data/dynos_mgr_builtin.cpp index b6fa23ce..b9156f3d 100644 --- a/data/dynos_mgr_builtin.cpp +++ b/data/dynos_mgr_builtin.cpp @@ -1290,6 +1290,14 @@ static void *geo_rotate_3d_coin(s32 callContext, void *node, UNUSED void *c) { return NULL; } +///////////////////////////////////////////////////////////////////////////////////////////////////////// +// // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// !! IMPORTANT: ADD NEW ENTRIES AT THE END OF THE sDynosBuiltinFuncs LIST TO PRESERVE INDEXING !! // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// // +///////////////////////////////////////////////////////////////////////////////////////////////////////// + static const void* sDynosBuiltinFuncs[] = { define_builtin(geo_mirror_mario_set_alpha), define_builtin(geo_switch_mario_stand_run), @@ -1911,6 +1919,12 @@ static const void* sDynosBuiltinFuncs[] = { define_builtin(geo_intro_tm_copyright), define_builtin(geo_intro_regular_backdrop), define_builtin(geo_draw_mario_head_goddard), + + // Custom + define_builtin(bhv_blue_coin_number_loop), + define_builtin(bhv_blue_coin_switch_init), + define_builtin(bhv_star_number_loop), + define_builtin(spawn_star_number), }; const void* DynOS_Builtin_Func_GetFromName(const char* aDataName) { diff --git a/data/dynos_mgr_builtin_externs.h b/data/dynos_mgr_builtin_externs.h index 6c7095a9..740a5af9 100644 --- a/data/dynos_mgr_builtin_externs.h +++ b/data/dynos_mgr_builtin_externs.h @@ -68,6 +68,8 @@ extern ALIGNED8 const Texture flame_seg6_texture_06014000[]; extern ALIGNED8 const Texture flame_seg6_texture_06016000[]; extern ALIGNED8 const Texture flame_seg6_texture_06018000[]; extern ALIGNED8 const Texture flame_seg6_texture_0601A000[]; +extern ALIGNED8 const Texture bowser_key_left_texture[]; +extern ALIGNED8 const Texture bowser_key_right_texture[]; extern ALIGNED8 const Texture breakable_box_seg8_texture_08011A90[]; extern ALIGNED8 const Texture breakable_box_seg8_texture_08012290[]; extern ALIGNED8 const Texture bub_seg6_texture_0600E2A8[]; diff --git a/data/dynos_mgr_builtin_tex.cpp b/data/dynos_mgr_builtin_tex.cpp index 726a08c2..80704e24 100644 --- a/data/dynos_mgr_builtin_tex.cpp +++ b/data/dynos_mgr_builtin_tex.cpp @@ -81,6 +81,8 @@ static const struct BuiltinTexInfo sDynosBuiltinTexs[] = { define_builtin_tex(flame_seg6_texture_06016000, "actors/bowser_flame/bowser_flame_11.rgba16.png", 64, 64, 16), define_builtin_tex(flame_seg6_texture_06018000, "actors/bowser_flame/bowser_flame_12.rgba16.png", 64, 64, 16), define_builtin_tex(flame_seg6_texture_0601A000, "actors/bowser_flame/bowser_flame_13.rgba16.png", 64, 64, 16), + define_builtin_tex(bowser_key_left_texture, "actors/bowser_key/bowser_key_left.rgba16.png", 32, 64, 16), + define_builtin_tex(bowser_key_right_texture, "actors/bowser_key/bowser_key_right.rgba16.png", 32, 64, 16), define_builtin_tex(breakable_box_seg8_texture_08011A90, "actors/breakable_box/crazy_box_surface.rgba16.png", 32, 32, 16), define_builtin_tex(breakable_box_seg8_texture_08012290, "actors/breakable_box/cork_box_surface.rgba16.png", 32, 32, 16), define_builtin_tex(bub_seg6_texture_0600E2A8, "actors/bub/bub_eye_border.rgba16.png", 32, 32, 16), diff --git a/docs/lua/constants.md b/docs/lua/constants.md index bc0fc846..cbcd6ed0 100644 --- a/docs/lua/constants.md +++ b/docs/lua/constants.md @@ -625,7 +625,9 @@ | id_bhvYoshi | 534 | | id_RM_Scroll_Texture | 535 | | id_editor_Scroll_Texture | 536 | -| id_bhv_max_count | 537 | +| id_bhvBlueCoinNumber | 537 | +| id_bhvStarNumber | 538 | +| id_bhv_max_count | 539 | [:arrow_up_small:](#) @@ -1773,6 +1775,7 @@ - BIRD_BP_SPAWNER - BLUE_COIN_SWITCH_ACT_IDLE - BLUE_COIN_SWITCH_ACT_RECEDING +- BLUE_COIN_SWITCH_ACT_RESPAWNING - BLUE_COIN_SWITCH_ACT_TICKING - BLUE_FISH_ACT_ASCEND - BLUE_FISH_ACT_DIVE diff --git a/docs/lua/functions-2.md b/docs/lua/functions-2.md index 31de55ce..cac33819 100644 --- a/docs/lua/functions-2.md +++ b/docs/lua/functions-2.md @@ -988,6 +988,24 @@
+## [bhv_blue_coin_number_loop](#bhv_blue_coin_number_loop) + +### Lua Example +`bhv_blue_coin_number_loop()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void bhv_blue_coin_number_loop(void);` + +[:arrow_up_small:](#) + +
+ ## [bhv_blue_coin_sliding_jumping_init](#bhv_blue_coin_sliding_jumping_init) ### Lua Example @@ -1024,6 +1042,24 @@
+## [bhv_blue_coin_switch_init](#bhv_blue_coin_switch_init) + +### Lua Example +`bhv_blue_coin_switch_init()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void bhv_blue_coin_switch_init(void);` + +[:arrow_up_small:](#) + +
+ ## [bhv_blue_coin_switch_loop](#bhv_blue_coin_switch_loop) ### Lua Example @@ -7760,6 +7796,24 @@
+## [bhv_star_number_loop](#bhv_star_number_loop) + +### Lua Example +`bhv_star_number_loop()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void bhv_star_number_loop(void);` + +[:arrow_up_small:](#) + +
+ ## [bhv_star_spawn_init](#bhv_star_spawn_init) ### Lua Example @@ -10097,6 +10151,24 @@
+## [spawn_star_number](#spawn_star_number) + +### Lua Example +`spawn_star_number()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void spawn_star_number(void);` + +[:arrow_up_small:](#) + +
+ ## [spawn_triangle_break_particles](#spawn_triangle_break_particles) ### Lua Example diff --git a/docs/lua/functions.md b/docs/lua/functions.md index cddbb6a0..7e9ae5ca 100644 --- a/docs/lua/functions.md +++ b/docs/lua/functions.md @@ -81,8 +81,10 @@ - [bhv_blue_bowser_flame_init](functions-2.md#bhv_blue_bowser_flame_init) - [bhv_blue_bowser_flame_loop](functions-2.md#bhv_blue_bowser_flame_loop) - [bhv_blue_coin_jumping_loop](functions-2.md#bhv_blue_coin_jumping_loop) + - [bhv_blue_coin_number_loop](functions-2.md#bhv_blue_coin_number_loop) - [bhv_blue_coin_sliding_jumping_init](functions-2.md#bhv_blue_coin_sliding_jumping_init) - [bhv_blue_coin_sliding_loop](functions-2.md#bhv_blue_coin_sliding_loop) + - [bhv_blue_coin_switch_init](functions-2.md#bhv_blue_coin_switch_init) - [bhv_blue_coin_switch_loop](functions-2.md#bhv_blue_coin_switch_loop) - [bhv_blue_fish_movement_loop](functions-2.md#bhv_blue_fish_movement_loop) - [bhv_blue_flames_group_loop](functions-2.md#bhv_blue_flames_group_loop) @@ -457,6 +459,7 @@ - [bhv_star_door_loop](functions-2.md#bhv_star_door_loop) - [bhv_star_door_loop_2](functions-2.md#bhv_star_door_loop_2) - [bhv_star_key_collection_puff_spawner_loop](functions-2.md#bhv_star_key_collection_puff_spawner_loop) + - [bhv_star_number_loop](functions-2.md#bhv_star_number_loop) - [bhv_star_spawn_init](functions-2.md#bhv_star_spawn_init) - [bhv_star_spawn_loop](functions-2.md#bhv_star_spawn_loop) - [bhv_static_checkered_platform_loop](functions-2.md#bhv_static_checkered_platform_loop) @@ -585,6 +588,7 @@ - [spawn_mist_particles_variable](functions-2.md#spawn_mist_particles_variable) - [spawn_no_exit_star](functions-2.md#spawn_no_exit_star) - [spawn_red_coin_cutscene_star](functions-2.md#spawn_red_coin_cutscene_star) + - [spawn_star_number](functions-2.md#spawn_star_number) - [spawn_triangle_break_particles](functions-2.md#spawn_triangle_break_particles) - [spawn_wind_particles](functions-2.md#spawn_wind_particles) - [tox_box_move](functions-2.md#tox_box_move) diff --git a/docs/lua/structs.md b/docs/lua/structs.md index 063f04eb..f64ac1c1 100644 --- a/docs/lua/structs.md +++ b/docs/lua/structs.md @@ -938,22 +938,33 @@ | exitCastleArea | `integer` | | | exitCastleLevel | [enum LevelNum](constants.md#enum-LevelNum) | | | exitCastleWarpNode | `integer` | | +| extendedPauseDisplay | `integer` | | | fixCollisionBugs | `integer` | | -| fixVanishFloors | `boolean` | | +| fixVanishFloors | `integer` | | +| floatingStarDance | `integer` | | | floorLowerLimit | `integer` | | | floorLowerLimitMisc | `integer` | | | floorLowerLimitShadow | `integer` | | +| hudCapTimer | `integer` | | +| hudRedCoinsRadar | `integer` | | +| hudSecretsRadar | `integer` | | | metalCapDuration | `integer` | | | metalCapDurationCotmc | `integer` | | | metalCapSequence | `integer` | | +| mushroom1UpHeal | `integer` | | | pauseExitAnywhere | `boolean` | | +| previewBlueCoins | `integer` | | | pssSlideStarIndex | `integer` | | | pssSlideStarTime | `integer` | | +| respawnBlueCoinsSwitch | `integer` | | +| showStarNumber | `integer` | | | skipCreditsAt | [enum LevelNum](constants.md#enum-LevelNum) | | +| starHeal | `integer` | | | starPositions | [StarPositions](structs.md#StarPositions) | read-only | | vanishCapDuration | `integer` | | | vanishCapDurationVcutm | `integer` | | | vanishCapSequence | `integer` | | +| visibleSecrets | `integer` | | | wingCapDuration | `integer` | | | wingCapDurationTotwc | `integer` | | | wingCapLookUpReq | `integer` | | @@ -1086,7 +1097,6 @@ | unkC4 | `number` | | | usedObj | [Object](structs.md#Object) | | | vel | [Vec3f](structs.md#Vec3f) | read-only | -| visibleToEnemies | `integer` | | | wall | [Surface](structs.md#Surface) | | | wallKickTimer | `integer` | | | wallNormal | [Vec3f](structs.md#Vec3f) | read-only | diff --git a/include/behavior_data.h b/include/behavior_data.h index 58cb9ffc..63f9262c 100644 --- a/include/behavior_data.h +++ b/include/behavior_data.h @@ -238,6 +238,7 @@ extern const BehaviorScript bhvWhitePuff1[]; extern const BehaviorScript bhvWhitePuff2[]; extern const BehaviorScript bhvWhitePuffSmoke2[]; extern const BehaviorScript bhvPurpleSwitchHiddenBoxes[]; +extern const BehaviorScript bhvBlueCoinNumber[]; extern const BehaviorScript bhvBlueCoinSwitch[]; extern const BehaviorScript bhvHiddenBlueCoin[]; extern const BehaviorScript bhvOpenableCageDoor[]; @@ -407,6 +408,7 @@ extern const BehaviorScript bhvMetalCap[]; extern const BehaviorScript bhvNormalCap[]; extern const BehaviorScript bhvVanishCap[]; extern const BehaviorScript bhvStar[]; +extern const BehaviorScript bhvStarNumber[]; extern const BehaviorScript bhvStarSpawnCoordinates[]; extern const BehaviorScript bhvHiddenRedCoinStar[]; extern const BehaviorScript bhvRedCoin[]; diff --git a/include/behavior_table.h b/include/behavior_table.h index a18b6710..15f9145c 100644 --- a/include/behavior_table.h +++ b/include/behavior_table.h @@ -541,6 +541,8 @@ enum BehaviorId { id_bhvYoshi, id_RM_Scroll_Texture, id_editor_Scroll_Texture, + id_bhvBlueCoinNumber, + id_bhvStarNumber, id_bhv_max_count // must be the last in the list }; diff --git a/include/object_constants.h b/include/object_constants.h index e0b33e8b..7c5d1128 100644 --- a/include/object_constants.h +++ b/include/object_constants.h @@ -157,6 +157,7 @@ #define BLUE_COIN_SWITCH_ACT_IDLE 0 #define BLUE_COIN_SWITCH_ACT_RECEDING 1 #define BLUE_COIN_SWITCH_ACT_TICKING 2 + #define BLUE_COIN_SWITCH_ACT_RESPAWNING 3 /* Moving Blue Coin */ /* oAction */ diff --git a/include/object_fields.h b/include/object_fields.h index f87b3574..16612909 100644 --- a/include/object_fields.h +++ b/include/object_fields.h @@ -914,6 +914,7 @@ #define /*0x0F4*/ oStarSpawnDisFromHome OBJECT_FIELD_F32(0x1B) #define /*0x0F8*/ oStarSpawnUnkFC OBJECT_FIELD_F32(0x1D) #define /*0x0FC*/ oStarSpawnExtCutsceneFlags OBJECT_FIELD_S16(0x1E, 0) +#define /*0x100*/ oStarBehavior OBJECT_FIELD_CVPTR(0x1F) /* Hidden Star */ // Secrets/Red Coins diff --git a/src/game/behavior_actions.h b/src/game/behavior_actions.h index 506bece5..d5356944 100644 --- a/src/game/behavior_actions.h +++ b/src/game/behavior_actions.h @@ -225,6 +225,8 @@ void bhv_ship_part_3_loop(void); void bhv_sunken_ship_part_loop(void); void bhv_white_puff_1_loop(void); void bhv_white_puff_2_loop(void); +void bhv_blue_coin_number_loop(void); +void bhv_blue_coin_switch_init(void); void bhv_blue_coin_switch_loop(void); void bhv_hidden_blue_coin_loop(void); void bhv_openable_cage_door_loop(void); @@ -387,6 +389,8 @@ void bhv_metal_cap_loop(void); void bhv_normal_cap_init(void); void bhv_normal_cap_loop(void); void bhv_vanish_cap_init(void); +void bhv_star_number_loop(void); +void spawn_star_number(void); void bhv_collect_star_init(void); void bhv_collect_star_loop(void); void bhv_star_spawn_init(void); diff --git a/src/game/behaviors/blue_coin.inc.c b/src/game/behaviors/blue_coin.inc.c index b52fddd5..ea6cf1c9 100644 --- a/src/game/behaviors/blue_coin.inc.c +++ b/src/game/behaviors/blue_coin.inc.c @@ -32,6 +32,17 @@ void bhv_hidden_blue_coin_loop(void) { o->oAction++; // Set to HIDDEN_BLUE_COIN_ACT_ACTIVE } + // Show blue coins if a Mario is standing on the blue coins switch + cur_obj_disable_rendering(); + if (gLevelValues.previewBlueCoins) { + for (s32 i = 0; i != MAX_PLAYERS; ++i) { + if (gMarioStates[i].marioObj && gMarioStates[i].marioObj->platform == blueCoinSwitch) { + cur_obj_enable_rendering(); + break; + } + } + } + break; case HIDDEN_BLUE_COIN_ACT_ACTIVE: // Become tangible @@ -47,7 +58,12 @@ void bhv_hidden_blue_coin_loop(void) { // After 200 frames of waiting and 20 2-frame blinks (for 240 frames total), // delete the object. if (cur_obj_wait_then_blink(200, 20)) { - obj_mark_for_deletion(o); + if (gLevelValues.respawnBlueCoinsSwitch) { + o->oAction = HIDDEN_BLUE_COIN_ACT_INACTIVE; + cur_obj_unhide(); + } else { + obj_mark_for_deletion(o); + } } break; @@ -56,6 +72,46 @@ void bhv_hidden_blue_coin_loop(void) { o->oInteractStatus = 0; } +/** + * Update function for bhvBlueCoinNumber. + */ +void bhv_blue_coin_number_loop(void) { + + // Check if the blue coins switch still exists + struct Object *blueCoinSwitch = o->oHiddenBlueCoinSwitch; + if (blueCoinSwitch == NULL || blueCoinSwitch->activeFlags == ACTIVE_FLAG_DEACTIVATED || blueCoinSwitch->behavior != smlua_override_behavior(bhvBlueCoinSwitch)) { + obj_mark_for_deletion(o); + return; + } + + // Show the number of blue coins remaining if a Mario is standing on the switch + cur_obj_disable_rendering(); + cur_obj_hide(); + if (gLevelValues.previewBlueCoins) { + for (s32 i = 0; i != MAX_PLAYERS; ++i) { + if (gMarioStates[i].marioObj && gMarioStates[i].marioObj->platform == blueCoinSwitch) { + cur_obj_enable_rendering(); + cur_obj_unhide(); + obj_set_pos(o, blueCoinSwitch->header.gfx.pos[0], blueCoinSwitch->header.gfx.pos[1] + 100.f * blueCoinSwitch->header.gfx.scale[1], blueCoinSwitch->header.gfx.pos[2]); + obj_set_angle(o, 0, 0, 0); + obj_scale(o, 1.f); + o->oAnimState = o->oBehParams2ndByte = count_objects_with_behavior(bhvHiddenBlueCoin); + break; + } + } + } +} + +/** + * Init function for bhvBlueCoinSwitch. + */ +void bhv_blue_coin_switch_init(void) { + struct Object *blueCoinNumber = spawn_object(o, MODEL_NUMBER, bhvBlueCoinNumber); + blueCoinNumber->activeFlags |= ACTIVE_FLAG_INITIATED_TIME_STOP; // to make sure it's updated even during time stop + blueCoinNumber->oHiddenBlueCoinSwitch = o; + o->oHomeY = o->oPosY; +} + /** * Update function for bhvBlueCoinSwitch. */ @@ -67,6 +123,7 @@ void bhv_blue_coin_switch_loop(void) { sync_object_init_field(o, &o->oGravity); sync_object_init_field(o, &o->oTimer); sync_object_init_field(o, &o->oPosY); + sync_object_init_field(o, &o->oHomeY); } // The switch's model is 1/3 size. @@ -128,10 +185,30 @@ void bhv_blue_coin_switch_loop(void) { // Delete the switch (which stops the sound) after the last coin is collected, // or after the coins unload after the 240-frame timer expires. - if (cur_obj_nearest_object_with_behavior(bhvHiddenBlueCoin) == NULL || o->oTimer > 240) { - obj_mark_for_deletion(o); + bool noBlueCoin = cur_obj_nearest_object_with_behavior(bhvHiddenBlueCoin) == NULL; + if (noBlueCoin || o->oTimer > 240) { + if (!noBlueCoin && gLevelValues.respawnBlueCoinsSwitch) { + o->oAction = BLUE_COIN_SWITCH_ACT_RESPAWNING; + o->oPosY = o->oHomeY - 120.0f; + o->oVelY = 20.0f; + o->oGravity = 0.0f; + cur_obj_play_sound_2(SOUND_GENERAL_SWITCH_DOOR_OPEN); + network_send_object(o); + } else { + obj_mark_for_deletion(o); + } } + break; + case BLUE_COIN_SWITCH_ACT_RESPAWNING: + cur_obj_move_using_fvel_and_gravity(); + if (o->oPosY >= o->oHomeY) { + o->oPosY = o->oHomeY; + o->oAction = BLUE_COIN_SWITCH_ACT_IDLE; + } + load_object_collision_model(); + cur_obj_unhide(); + break; } } diff --git a/src/game/behaviors/hidden_star.inc.c b/src/game/behaviors/hidden_star.inc.c index 5d97d24b..2d4a269a 100644 --- a/src/game/behaviors/hidden_star.inc.c +++ b/src/game/behaviors/hidden_star.inc.c @@ -89,6 +89,10 @@ void bhv_hidden_star_trigger_loop(void) { network_send_collect_item(o); } } + if (gLevelValues.visibleSecrets) { + obj_set_model(o, MODEL_PURPLE_MARBLE); + obj_set_billboard(o); + } } void bhv_bowser_course_red_coin_star_loop(void) { diff --git a/src/game/behaviors/mushroom_1up.inc.c b/src/game/behaviors/mushroom_1up.inc.c index 92d5c3dd..7f72a2dc 100644 --- a/src/game/behaviors/mushroom_1up.inc.c +++ b/src/game/behaviors/mushroom_1up.inc.c @@ -6,6 +6,10 @@ void bhv_1up_interact(void) { play_sound(SOUND_GENERAL_COLLECT_1UP, gGlobalSoundSource); marioState->numLives++; o->activeFlags = ACTIVE_FLAG_DEACTIVATED; + if (gLevelValues.mushroom1UpHeal) { + marioState->healCounter = 31; + marioState->hurtCounter = 0; + } #ifdef VERSION_SH queue_rumble_data(5, 80); #endif diff --git a/src/game/behaviors/sparkle_spawn_star.inc.c b/src/game/behaviors/sparkle_spawn_star.inc.c index 55b260bc..ef31f16b 100644 --- a/src/game/behaviors/sparkle_spawn_star.inc.c +++ b/src/game/behaviors/sparkle_spawn_star.inc.c @@ -30,6 +30,7 @@ void bhv_spawned_star_init(void) { u32 models[] = { MODEL_STAR }; network_send_spawn_objects(spawn_objects, models, 1); } + spawn_star_number(); } void set_sparkle_spawn_star_hitbox(void) { @@ -142,6 +143,7 @@ void bhv_spawned_star_loop(void) { cur_obj_move_using_fvel_and_gravity(); o->oFaceAngleYaw += o->oAngleVelYaw; o->oInteractStatus = 0; + spawn_star_number(); } void bhv_spawn_star_no_level_exit(struct Object* object, u32 params, u8 networkSendEvent) { diff --git a/src/game/behaviors/spawn_star.inc.c b/src/game/behaviors/spawn_star.inc.c index 203e29e0..011c443f 100644 --- a/src/game/behaviors/spawn_star.inc.c +++ b/src/game/behaviors/spawn_star.inc.c @@ -1,5 +1,47 @@ // spawn_default_star.c.inc +void bhv_star_number_loop(void) { + + // Check if the star still exists + struct Object *star = o->parentObj; + const BehaviorScript *starBhv = (const BehaviorScript *) o->oStarBehavior; + if (star == NULL || star->activeFlags == ACTIVE_FLAG_DEACTIVATED || starBhv != smlua_override_behavior(star->behavior)) { + obj_mark_for_deletion(o); + return; + } + + // Show the star number + if (gLevelValues.showStarNumber) { + obj_set_pos(o, star->header.gfx.pos[0], star->header.gfx.pos[1] + 150.f * star->header.gfx.scale[1], star->header.gfx.pos[2]); + obj_set_angle(o, 0, 0, 0); + obj_scale(o, 1.f); + o->oAnimState = o->oBehParams2ndByte = ((star->oBehParams >> 24) & 0xFF) + 1; + o->header.gfx.node.flags = star->header.gfx.node.flags; + } else { + cur_obj_disable_rendering(); + cur_obj_hide(); + } +} + +void spawn_star_number(void) { + + // Check if the star already has a number + struct Object *starNumber = obj_get_first_with_behavior_id(id_bhvStarNumber); + for (; starNumber; starNumber = obj_get_next_with_same_behavior_id(starNumber)) { + if (starNumber->parentObj == o) { + break; + } + } + + // If not, spawn a number + if (!starNumber) { + starNumber = spawn_object(o, MODEL_NUMBER, bhvStarNumber); + starNumber->parentObj = o; + starNumber->activeFlags |= ACTIVE_FLAG_INITIATED_TIME_STOP; // to make sure it's updated even during time stop + starNumber->oStarBehavior = (const void *) smlua_override_behavior(o->behavior); + } +} + static struct ObjectHitbox sCollectStarHitbox = { /* interactType: */ INTERACT_STAR_OR_KEY, /* downOffset: */ 0, @@ -25,6 +67,7 @@ void bhv_collect_star_init(void) { } obj_set_hitbox(o, &sCollectStarHitbox); + spawn_star_number(); } void bhv_collect_star_loop(void) { @@ -34,6 +77,7 @@ void bhv_collect_star_loop(void) { mark_obj_for_deletion(o); o->oInteractStatus = 0; } + spawn_star_number(); } void bhv_star_spawn_init(void) { @@ -54,6 +98,7 @@ void bhv_star_spawn_init(void) { o->activeFlags |= ACTIVE_FLAG_INITIATED_TIME_STOP; } cur_obj_become_intangible(); + spawn_star_number(); } void bhv_star_spawn_loop(void) { @@ -112,6 +157,7 @@ void bhv_star_spawn_loop(void) { } break; } + spawn_star_number(); } struct Object *spawn_star(struct Object *obj, f32 x, f32 y, f32 z) { diff --git a/src/game/camera.c b/src/game/camera.c index 96cfcc58..bc775111 100644 --- a/src/game/camera.c +++ b/src/game/camera.c @@ -5331,7 +5331,11 @@ u8 get_cutscene_from_mario_status(struct Camera *c) { cutscene = determine_dance_cutscene(c); break; case ACT_STAR_DANCE_WATER: - cutscene = determine_dance_cutscene(c); + if (gMarioStates[0].actionArg & 1) { // No exit + cutscene = CUTSCENE_DANCE_DEFAULT; + } else { + cutscene = determine_dance_cutscene(c); + } break; case ACT_STAR_DANCE_NO_EXIT: cutscene = CUTSCENE_DANCE_DEFAULT; diff --git a/src/game/hardcoded.c b/src/game/hardcoded.c index 59acaf00..8bb10077 100644 --- a/src/game/hardcoded.c +++ b/src/game/hardcoded.c @@ -44,6 +44,17 @@ extern Trajectory sThiTinyMetalBallTraj[]; struct LevelValues gDefaultLevelValues = { .fixCollisionBugs = 0, .fixVanishFloors = 0, + .hudCapTimer = 0, + .hudRedCoinsRadar = 0, + .hudSecretsRadar = 0, + .starHeal = 0, + .mushroom1UpHeal = 0, + .floatingStarDance = 0, + .previewBlueCoins = 0, + .respawnBlueCoinsSwitch = 0, + .visibleSecrets = 0, + .showStarNumber = 0, + .extendedPauseDisplay = 0, .entryLevel = LEVEL_CASTLE_GROUNDS, .exitCastleLevel = LEVEL_CASTLE, .exitCastleArea = 1, diff --git a/src/game/hardcoded.h b/src/game/hardcoded.h index 2b4434a6..20f6fa73 100644 --- a/src/game/hardcoded.h +++ b/src/game/hardcoded.h @@ -41,7 +41,18 @@ struct StarPositions { struct LevelValues { u8 fixCollisionBugs; u8 wingCapLookUpReq; - bool fixVanishFloors; + u8 fixVanishFloors; + u8 hudCapTimer; + u8 hudRedCoinsRadar; + u8 hudSecretsRadar; + u8 starHeal; + u8 mushroom1UpHeal; + u8 floatingStarDance; + u8 previewBlueCoins; + u8 respawnBlueCoinsSwitch; + u8 visibleSecrets; + u8 showStarNumber; + u8 extendedPauseDisplay; enum LevelNum entryLevel; enum LevelNum exitCastleLevel; s16 exitCastleArea; diff --git a/src/game/hud.c b/src/game/hud.c index e1a94156..3d66dcab 100644 --- a/src/game/hud.c +++ b/src/game/hud.c @@ -8,6 +8,7 @@ #include "level_update.h" #include "camera.h" #include "print.h" +#include "engine/math_util.h" #include "engine/surface_load.h" #include "ingame_menu.h" #include "hud.h" @@ -15,9 +16,13 @@ #include "area.h" #include "save_file.h" #include "print.h" +#include "hardcoded.h" #include "pc/configfile.h" #include "pc/network/network.h" #include "pc/utils/misc.h" +#include "pc/lua/smlua.h" +#include "pc/lua/utils/smlua_obj_utils.h" +#include "data/dynos_mgr_builtin_externs.h" extern bool gDjuiInMainMenu; u8 gOverrideHideHud; @@ -313,6 +318,131 @@ void render_hud_mario_lives(void) { print_text_fmt_int(GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(54), HUD_TOP_Y, "%d", gHudDisplay.lives); } +static void render_hud_icon(Vtx *vtx, const u8 *texture, u32 fmt, u32 siz, s32 texW, s32 texH, s32 x, s32 y, s32 w, s32 h, s32 tileX, s32 tileY, s32 tileW, s32 tileH) { + create_dl_ortho_matrix(); + if (!vtx) { + vtx = alloc_display_list(sizeof(Vtx) * 4); + vtx[0] = (Vtx) {{{ x, y - h, 0 }, 0, { tileX << 5, (tileY + tileH) << 5 }, { 0xFF, 0xFF, 0xFF, 0xFF }}}; + vtx[1] = (Vtx) {{{ x + w, y - h, 0 }, 0, { (tileX + tileW) << 5, (tileY + tileH) << 5 }, { 0xFF, 0xFF, 0xFF, 0xFF }}}; + vtx[2] = (Vtx) {{{ x + w, y, 0 }, 0, { (tileX + tileW) << 5, tileY << 5 }, { 0xFF, 0xFF, 0xFF, 0xFF }}}; + vtx[3] = (Vtx) {{{ x, y, 0 }, 0, { tileX << 5, tileY << 5 }, { 0xFF, 0xFF, 0xFF, 0xFF }}}; + } + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + gDPSetCombineMode(gDisplayListHead++, G_CC_FADEA, G_CC_FADEA); + gDPSetRenderMode(gDisplayListHead++, G_RM_XLU_SURF, G_RM_XLU_SURF2); + gDPSetTextureFilter(gDisplayListHead++, G_TF_POINT); + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + switch (siz) { + case G_IM_SIZ_4b: gDPLoadTextureBlock(gDisplayListHead++, texture, fmt, G_IM_SIZ_4b, texW, texH, 0, G_TX_CLAMP, G_TX_CLAMP, 0, 0, 0, 0); break; + case G_IM_SIZ_8b: gDPLoadTextureBlock(gDisplayListHead++, texture, fmt, G_IM_SIZ_8b, texW, texH, 0, G_TX_CLAMP, G_TX_CLAMP, 0, 0, 0, 0); break; + case G_IM_SIZ_16b: gDPLoadTextureBlock(gDisplayListHead++, texture, fmt, G_IM_SIZ_16b, texW, texH, 0, G_TX_CLAMP, G_TX_CLAMP, 0, 0, 0, 0); break; + case G_IM_SIZ_32b: gDPLoadTextureBlock(gDisplayListHead++, texture, fmt, G_IM_SIZ_32b, texW, texH, 0, G_TX_CLAMP, G_TX_CLAMP, 0, 0, 0, 0); break; + } + gSPVertex(gDisplayListHead++, vtx, 4, 0); + gSP2Triangles(gDisplayListHead++, 0, 1, 2, 0x0, 0, 2, 3, 0x0); + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF); + gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE); +} + +/** + * Renders the number of seconds remaining of the current cap power-ups. + */ +void render_hud_cap_timer(void) { + static const u8 *sHudCapIcons[][4] = { + [MARIO_WING_CAP ] = { exclamation_box_seg8_texture_08015E28, exclamation_box_seg8_texture_08015E28, exclamation_box_seg8_texture_08015E28, exclamation_box_seg8_texture_08015E28 }, + [ MARIO_METAL_CAP ] = { exclamation_box_seg8_texture_08014628, exclamation_box_seg8_texture_08014628, exclamation_box_seg8_texture_08014628, exclamation_box_seg8_texture_08014628 }, + [ MARIO_VANISH_CAP] = { exclamation_box_seg8_texture_08012E28, exclamation_box_seg8_texture_08012E28, exclamation_box_seg8_texture_08012E28, exclamation_box_seg8_texture_08012E28 }, + [MARIO_WING_CAP | MARIO_METAL_CAP ] = { exclamation_box_seg8_texture_08015E28, exclamation_box_seg8_texture_08015E28, exclamation_box_seg8_texture_08014628, exclamation_box_seg8_texture_08014628 }, + [MARIO_WING_CAP | MARIO_VANISH_CAP] = { exclamation_box_seg8_texture_08015E28, exclamation_box_seg8_texture_08015E28, exclamation_box_seg8_texture_08012E28, exclamation_box_seg8_texture_08012E28 }, + [ MARIO_METAL_CAP | MARIO_VANISH_CAP] = { exclamation_box_seg8_texture_08014628, exclamation_box_seg8_texture_08014628, exclamation_box_seg8_texture_08012E28, exclamation_box_seg8_texture_08012E28 }, + [MARIO_WING_CAP | MARIO_METAL_CAP | MARIO_VANISH_CAP] = { exclamation_box_seg8_texture_08015E28, exclamation_box_seg8_texture_08014628, exclamation_box_seg8_texture_08014628, exclamation_box_seg8_texture_08012E28 }, + }; + struct MarioState *m = &gMarioStates[0]; + u32 capFlags = m->flags & MARIO_SPECIAL_CAPS; + if (capFlags) { + s32 capTimer = m->capTimer; + if (capTimer > 0) { + s32 capSeconds = (capTimer + 29) / 30; + const u8 **capIcons = sHudCapIcons[capFlags]; + gDPSetEnvColor(gDisplayListHead++, 0xFF, 0xFF, 0xFF, 0xFF); + render_hud_icon(NULL, capIcons[0], G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 32, GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(22), HUD_TOP_Y - 4, 5, 16, 0, 0, 10, 32); + render_hud_icon(NULL, capIcons[1], G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 32, GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(27), HUD_TOP_Y - 4, 3, 16, 10, 0, 6, 32); + render_hud_icon(NULL, capIcons[2], G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 32, GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(30), HUD_TOP_Y - 4, 3, 16, 16, 0, 6, 32); + render_hud_icon(NULL, capIcons[3], G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 32, GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(33), HUD_TOP_Y - 4, 5, 16, 22, 0, 10, 32); + print_text(GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(38), HUD_TOP_Y - 20, "*"); // 'X' glyph + print_text_fmt_int(GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(54), HUD_TOP_Y - 20, "%d", capSeconds); + } + } +} + +static void render_hud_radar(struct MarioState *m, struct Object *target, const u8 *iconTexture, u32 fmt, u32 siz, s32 texW, s32 texH, s32 x, s32 y, s32 tileX, s32 tileY, s32 tileW, s32 tileH, u8 r, u8 g, u8 b) { + + // Icon + gDPSetEnvColor(gDisplayListHead++, r, g, b, 0xFF); + render_hud_icon(NULL, iconTexture, fmt, siz, texW, texH, x, y + 2, 12, 12, tileX, tileY, tileW, tileH); + + // Direction + s16 angle = atan2s( + target->oPosZ - m->pos[2], + target->oPosX - m->pos[0] + ) - atan2s( + m->pos[2] - gCamera->pos[2], + m->pos[0] - gCamera->pos[0] + ); + f32 invSqrt2 = 1.f / sqrtf(2.f); + Vtx *vtx = alloc_display_list(sizeof(Vtx) * 4); + for (s32 i = 0; i != 4; ++i) { + s16 a = angle + ((i * 0x4000) - 0x6000); + vtx[i] = (Vtx) { { { + x + 6 + 12 * coss(angle + 0x4000) + 8 * invSqrt2 * coss(a), + y - 4 + 12 * sins(angle + 0x4000) + 8 * invSqrt2 * sins(a), 0, + }, 0, { + 256 * (((i + 1) / 2) % 2), // 0, 256, 256, 0 + 256 * (((i + 2) / 2) % 2), // 256, 256, 0, 0 + }, { 0xFF, 0xFF, 0xFF, 0xFF } } }; + } + gDPSetEnvColor(gDisplayListHead++, 0xFF, 0xFF, 0xFF, 0xFF); + render_hud_icon(vtx, texture_hud_char_arrow_up, G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 8, 0, 0, 8, 8, 0, 0, 8, 8); + + // Distance + s32 dist = vec3f_dist(&target->oPosX, m->pos); + print_text_fmt_int(x + 24, y - 12, "%d", dist); +} + +/** + * Renders the direction and distance to the nearest red coin. + */ +void render_hud_red_coins_and_secrets_radar(void) { + struct MarioState *m = &gMarioStates[0]; + if (m->marioObj && gCamera) { + s32 y = 31; + + // Red coins radar + if (gLevelValues.hudRedCoinsRadar) { + static const u8 *sRedCoinTextures[] = { + coin_seg3_texture_03005780, + coin_seg3_texture_03005F80, + coin_seg3_texture_03006780, + coin_seg3_texture_03006F80, + }; + struct Object *redCoin = obj_get_nearest_object_with_behavior_id(m->marioObj, id_bhvRedCoin); + if (redCoin) { + render_hud_radar(m, redCoin, sRedCoinTextures[(gGlobalTimer / 2) % 4], G_IM_FMT_IA, G_IM_SIZ_16b, 32, 32, GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(24), y, 0, 0, 32, 32, 0xFF, 0x00, 0x00); + y += 30; + } + } + + // Secrets radar + if (gLevelValues.hudSecretsRadar) { + struct Object *secret = obj_get_nearest_object_with_behavior_id(m->marioObj, id_bhvHiddenStarTrigger); + if (secret) { + render_hud_radar(m, secret, texture_hud_char_S, G_IM_FMT_RGBA, G_IM_SIZ_16b, 16, 16, GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(24), y, 0, 0, 14, 16, 0xFF, 0xFF, 0xFF); + y += 30; + } + } + } +} + /** * Renders the amount of coins collected. */ @@ -502,6 +632,14 @@ void render_hud(void) { render_hud_mario_lives(); } + if (hudDisplayFlags & HUD_DISPLAY_FLAG_LIVES && showHud && gLevelValues.hudCapTimer) { + render_hud_cap_timer(); + } + + if (hudDisplayFlags & HUD_DISPLAY_FLAG_LIVES && showHud) { + render_hud_red_coins_and_secrets_radar(); + } + if (hudDisplayFlags & HUD_DISPLAY_FLAG_COIN_COUNT && showHud) { render_hud_coins(); } diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c index 39ea54e9..1e94b619 100644 --- a/src/game/ingame_menu.c +++ b/src/game/ingame_menu.c @@ -26,10 +26,12 @@ #include "text_strings.h" #include "types.h" #include "macros.h" +#include "hardcoded.h" #include "pc/cheats.h" #include "pc/network/network.h" #include "pc/djui/djui.h" #include "pc/utils/misc.h" +#include "data/dynos_mgr_builtin_externs.h" #ifdef BETTERCAMERA #include "bettercamera.h" #endif @@ -944,6 +946,14 @@ void handle_menu_scrolling(s8 scrollDirection, s8 *currentIndex, s8 minIndex, s8 } } + // Clamp currentIndex to prevent out of bounds access + if (currentIndex[0] < minIndex) { + currentIndex[0] = minIndex; + } + if (currentIndex[0] > maxIndex) { + currentIndex[0] = maxIndex; + } + if (gMenuHoldKeyTimer == 10) { gMenuHoldKeyTimer = 8; gMenuHoldKeyIndex = 0; @@ -2661,6 +2671,25 @@ void render_pause_castle_menu_box(s16 x, s16 y) { gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); } +void render_pause_castle_menu_box_extended(s16 x, s16 y) { + create_dl_translation_matrix(MENU_MTX_PUSH, x - 98, y - 32, 0); + create_dl_scale_matrix(MENU_MTX_NOPUSH, 1.5f, 0.8f, 1.0f); + gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 105); + gSPDisplayList(gDisplayListHead++, dl_draw_text_bg_box); + gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); + + create_dl_translation_matrix(MENU_MTX_PUSH, x + 6, y - 28, 0); + create_dl_rotation_matrix(MENU_MTX_NOPUSH, DEFAULT_DIALOG_BOX_ANGLE, 0, 0, 1.0f); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + gSPDisplayList(gDisplayListHead++, dl_draw_triangle); + gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); + + create_dl_translation_matrix(MENU_MTX_PUSH, x - 9, y - 101, 0); + create_dl_rotation_matrix(MENU_MTX_NOPUSH, 270.0f, 0, 0, 1.0f); + gSPDisplayList(gDisplayListHead++, dl_draw_triangle); + gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); +} + void highlight_last_course_complete_stars(void) { u8 courseDone; @@ -2824,6 +2853,186 @@ void render_pause_castle_main_strings(s16 x, s16 y) { gSPDisplayList(gDisplayListHead++, dl_ia_text_end); } +#define INDEX_CASTLE_STARS (COURSE_COUNT) +#define INDEX_FLAGS (COURSE_COUNT + 1) +#define INDEX_MIN (-1) +#define INDEX_MAX (INDEX_FLAGS + 1) + +static u32 pause_castle_get_stars(s32 index) { + + // Main courses (0-14), Secret courses (15-24) + if (index >= 0 && index < INDEX_CASTLE_STARS) { + return save_file_get_star_flags(gCurrSaveFileNum - 1, index); + } + + // Castle stars (25) + if (index == INDEX_CASTLE_STARS) { + return save_file_get_star_flags(gCurrSaveFileNum - 1, -1); + } + + // Flags (26) + if (index == INDEX_FLAGS) { + return save_file_get_flags(); + } + + return 0; +} + +static void render_pause_castle_course_name(const u8 *courseName, s16 x, s16 y) { + s16 width = 0; + for (const u8 *c = courseName; *c != DIALOG_CHAR_TERMINATOR; c++) { + width += gDialogCharWidths[*c]; + } + print_generic_string(x - width / 2, y, courseName); +} + +static void render_pause_castle_flag_icon(const u8 *texture, s16 texW, s16 texH, s16 x, s16 y, s16 w, s16 h) { + gDPLoadTextureBlock(gDisplayListHead++, texture, G_IM_FMT_RGBA, G_IM_SIZ_16b, texW, texH, 0, G_TX_CLAMP, G_TX_CLAMP, 0, 0, 0, 0); + gSPTextureRectangle(gDisplayListHead++, (x) << 2, (SCREEN_HEIGHT - h - y) << 2, (x + w) << 2, (SCREEN_HEIGHT - y) << 2, G_TX_RENDERTILE, 0, 0, ((0x400 * texW) / w), ((0x400 * texH) / h)); +} + +static void render_pause_castle_flag(s16 x, s16 y, u32 flag) { + if (save_file_get_flags() & flag) { + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + } else { + gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gDialogTextAlpha / 3); + } + switch (flag) { + case SAVE_FLAG_HAVE_WING_CAP: + render_pause_castle_flag_icon(exclamation_box_seg8_texture_08015E28, 32, 32, x, y, 12, 12); + break; + + case SAVE_FLAG_HAVE_METAL_CAP: + render_pause_castle_flag_icon(exclamation_box_seg8_texture_08014628, 32, 32, x, y, 12, 12); + break; + + case SAVE_FLAG_HAVE_VANISH_CAP: + render_pause_castle_flag_icon(exclamation_box_seg8_texture_08012E28, 32, 32, x, y, 12, 12); + break; + + case SAVE_FLAG_HAVE_KEY_1 | SAVE_FLAG_UNLOCKED_BASEMENT_DOOR: + case SAVE_FLAG_HAVE_KEY_2 | SAVE_FLAG_UNLOCKED_UPSTAIRS_DOOR: + render_pause_castle_flag_icon(bowser_key_left_texture, 32, 64, x, y, 6, 12); + render_pause_castle_flag_icon(bowser_key_right_texture, 32, 64, x + 6, y, 6, 12); + break; + } + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); +} + +static void render_pause_castle_course_stars_extended(s16 x, s16 y) { + bool isMainCourse = COURSE_IS_MAIN_COURSE(gDialogLineNum + 1); + u32 stars = pause_castle_get_stars(gDialogLineNum); + u8 str[32]; + + // Build the stars string + s32 lastCollectedStar = 0; + for (s32 i = 0; i != (isMainCourse ? 6 : 7); ++i) { + if (stars & (1 << i)) { + str[2 * i] = DIALOG_CHAR_STAR_FILLED; + lastCollectedStar = i + 1; + } else { + str[2 * i] = DIALOG_CHAR_STAR_OPEN; + } + str[2 * i + 1] = DIALOG_CHAR_SPACE; + str[2 * i + 2] = DIALOG_CHAR_TERMINATOR; + } + + // Hide the not collected ones after the last collected for secret courses + if (!isMainCourse) { + str[2 * lastCollectedStar] = DIALOG_CHAR_TERMINATOR; + } + + // Render the 100 coins star next to the coin counter for main courses + if (isMainCourse && (stars & 0x40)) { + const u8 textStar[] = { TEXT_STAR }; + print_generic_string(x + 89, y - 5, textStar); + } + + // Render the stars + print_generic_string(x + 14, y + 13, str); +} + +void render_pause_castle_main_strings_extended(s16 x, s16 y) { + + // Main courses (0-14), Secret courses (15-24), Castle stars (25), Flags (26) + // Indices -1 and 26 are used to loop back respectively to Flags and Course 1 + s8 prevIndex = gDialogLineNum; + handle_menu_scrolling(MENU_SCROLL_VERTICAL, &gDialogLineNum, INDEX_MIN, INDEX_MAX); + s8 scrollDir = (gDialogLineNum >= prevIndex ? +1 : -1); + if (gDialogLineNum >= INDEX_MAX) { + gDialogLineNum = 0; + scrollDir = +1; + } else if (gDialogLineNum <= INDEX_MIN) { + gDialogLineNum = INDEX_FLAGS; + scrollDir = -1; + } + + // Skip courses with 0 star collected + if (gDialogLineNum < INDEX_CASTLE_STARS) { + while (!pause_castle_get_stars(gDialogLineNum)) { + gDialogLineNum += scrollDir; + if (gDialogLineNum >= INDEX_CASTLE_STARS) { + gDialogLineNum = INDEX_CASTLE_STARS; + break; + } + if (gDialogLineNum <= INDEX_MIN) { + gDialogLineNum = INDEX_FLAGS; + break; + } + } + } + + gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + + // Main courses (0-14) + if (gDialogLineNum < COURSE_STAGES_COUNT) { + const u8 *courseName = seg2_course_name_table[gDialogLineNum]; + const u8 textCoin[] = { TEXT_COIN_X }; + u8 textCoinCount[8]; + render_pause_castle_course_name(courseName, 160, y + 30); + render_pause_castle_course_stars_extended(x + 20, y); + print_generic_string(x + 54, y - 5, textCoin); + int_to_str(save_file_get_course_coin_score(gCurrSaveFileNum - 1, gDialogLineNum), textCoinCount); + print_generic_string(x + 74, y - 5, textCoinCount); + } + + // Secret courses (15-24) + else if (gDialogLineNum >= COURSE_STAGES_COUNT && gDialogLineNum < INDEX_CASTLE_STARS) { + const u8 *courseName = seg2_course_name_table[gDialogLineNum]; + render_pause_castle_course_name(courseName + 3, 160, y + 30); + render_pause_castle_course_stars_extended(x + 20, y); + } + + // Castle stars (25) + else if (gDialogLineNum == INDEX_CASTLE_STARS) { + const u8 *courseName = seg2_course_name_table[COURSE_MAX]; + const u8 textStar[] = { TEXT_STAR_X }; + u8 textStarCount[8]; + render_pause_castle_course_name(courseName + 3, 160, y + 30); + print_generic_string(x + 60, y + 13, textStar); + int_to_str(save_file_get_course_star_count(gCurrSaveFileNum - 1, -1), textStarCount); + print_generic_string(x + 80, y + 13, textStarCount); + } + + // Flags (26) + else if (gDialogLineNum == INDEX_FLAGS) { + const u8 textFlags[] = { ASCII_TO_DIALOG('P'), ASCII_TO_DIALOG('R'), ASCII_TO_DIALOG('O'), ASCII_TO_DIALOG('G'), ASCII_TO_DIALOG('R'), ASCII_TO_DIALOG('E'), ASCII_TO_DIALOG('S'), ASCII_TO_DIALOG('S'), DIALOG_CHAR_TERMINATOR }; + const u8 textCaps[] = { ASCII_TO_DIALOG('C'), ASCII_TO_DIALOG('A'), ASCII_TO_DIALOG('P'), ASCII_TO_DIALOG('S'), 0xE6, DIALOG_CHAR_TERMINATOR }; + const u8 textKeys[] = { ASCII_TO_DIALOG('K'), ASCII_TO_DIALOG('E'), ASCII_TO_DIALOG('Y'), ASCII_TO_DIALOG('S'), 0xE6, DIALOG_CHAR_TERMINATOR }; + render_pause_castle_course_name(textFlags, 160, y + 30); + print_generic_string(x + 45, y + 13, textCaps); + render_pause_castle_flag(x + 80, y + 15, SAVE_FLAG_HAVE_WING_CAP); + render_pause_castle_flag(x + 96, y + 15, SAVE_FLAG_HAVE_METAL_CAP); + render_pause_castle_flag(x + 112, y + 15, SAVE_FLAG_HAVE_VANISH_CAP); + print_generic_string(x + 45, y - 5, textKeys); + render_pause_castle_flag(x + 80, y - 3, SAVE_FLAG_HAVE_KEY_1 | SAVE_FLAG_UNLOCKED_BASEMENT_DOOR); + render_pause_castle_flag(x + 96, y - 3, SAVE_FLAG_HAVE_KEY_2 | SAVE_FLAG_UNLOCKED_UPSTAIRS_DOOR); + } + + gSPDisplayList(gDisplayListHead++, dl_ia_text_end); +} + s8 gCourseCompleteCoinsEqual = 0; s32 gCourseDoneMenuTimer = 0; s32 gCourseCompleteCoins = 0; @@ -2888,8 +3097,13 @@ s16 render_pause_courses_and_castle(void) { case DIALOG_STATE_HORIZONTAL: shade_screen(); print_hud_pause_colorful_str(); - render_pause_castle_menu_box(160, 143); - render_pause_castle_main_strings(104, 60); + if (gLevelValues.extendedPauseDisplay) { + render_pause_castle_menu_box_extended(160, 143); + render_pause_castle_main_strings_extended(84, 60); + } else { + render_pause_castle_menu_box(160, 143); + render_pause_castle_main_strings(104, 60); + } #ifdef VERSION_EU if (gPlayer1Controller->buttonPressed & (A_BUTTON | Z_TRIG | START_BUTTON)) diff --git a/src/game/interaction.c b/src/game/interaction.c index a452541b..a65b6ece 100644 --- a/src/game/interaction.c +++ b/src/game/interaction.c @@ -909,6 +909,11 @@ u32 interact_star_or_key(struct MarioState *m, UNUSED u32 interactType, struct O } } + if (gLevelValues.starHeal) { + m->healCounter = 31; + m->hurtCounter = 0; + } + if (noExit) { starGrabAction = ACT_STAR_DANCE_NO_EXIT; } @@ -923,6 +928,9 @@ u32 interact_star_or_key(struct MarioState *m, UNUSED u32 interactType, struct O if (m->action & ACT_FLAG_AIR) { starGrabAction = ACT_FALL_AFTER_STAR_GRAB; + if (gLevelValues.floatingStarDance && m->pos[1] - m->floorHeight > 1000) { + starGrabAction = ACT_STAR_DANCE_WATER; + } } for (s32 i = 0; i < MAX_PLAYERS; i++) { diff --git a/src/game/mario_actions_cutscene.c b/src/game/mario_actions_cutscene.c index 68c5a0e0..f94a743f 100644 --- a/src/game/mario_actions_cutscene.c +++ b/src/game/mario_actions_cutscene.c @@ -719,7 +719,7 @@ void general_star_dance_handler(struct MarioState *m, s32 isInWater) { : gBehaviorValues.dialogs.CollectedStarDialog); m->actionState = 1; } else { - set_mario_action(m, isInWater ? ACT_WATER_IDLE : ACT_IDLE, 0); + set_mario_action(m, isInWater ? ACT_WATER_IDLE : (m->pos[1] <= m->floorHeight ? ACT_IDLE : ACT_FREEFALL), 0); } break; } @@ -738,7 +738,7 @@ void general_star_dance_handler(struct MarioState *m, s32 isInWater) { // look up for dialog set_mario_action(m, ACT_READING_AUTOMATIC_DIALOG, dialogID); } else { - set_mario_action(m, isInWater ? ACT_WATER_IDLE : ACT_IDLE, 0); + set_mario_action(m, isInWater ? ACT_WATER_IDLE : (m->pos[1] <= m->floorHeight ? ACT_IDLE : ACT_FREEFALL), 0); } if (gServerSettings.stayInLevelAfterStar) { soft_reset_camera(m->area->camera); @@ -766,7 +766,7 @@ s32 act_star_dance_water(struct MarioState *m) { set_mario_animation(m, m->actionState == 2 ? MARIO_ANIM_RETURN_FROM_WATER_STAR_DANCE : MARIO_ANIM_WATER_STAR_DANCE); vec3f_copy(m->marioObj->header.gfx.pos, m->pos); vec3s_set(m->marioObj->header.gfx.angle, 0, m->faceAngle[1], 0); - general_star_dance_handler(m, 1); + general_star_dance_handler(m, m->pos[1] < m->waterLevel - 100); if (m->actionState != 2 && m->actionTimer >= 62) { m->marioBodyState->handState = MARIO_HAND_PEACE_SIGN; } diff --git a/src/game/obj_behaviors.c b/src/game/obj_behaviors.c index f959dd8d..ad443fbe 100644 --- a/src/game/obj_behaviors.c +++ b/src/game/obj_behaviors.c @@ -36,7 +36,9 @@ #include "pc/network/network.h" #include "pc/network/network_player.h" #include "pc/network/reservation_area.h" +#include "pc/lua/smlua.h" #include "pc/lua/utils/smlua_model_utils.h" +#include "pc/lua/utils/smlua_obj_utils.h" #include "game/rng_position.h" #include "rumble_init.h" diff --git a/src/pc/lua/smlua_cobject_autogen.c b/src/pc/lua/smlua_cobject_autogen.c index a0c02515..ac43d332 100644 --- a/src/pc/lua/smlua_cobject_autogen.c +++ b/src/pc/lua/smlua_cobject_autogen.c @@ -733,7 +733,7 @@ static struct LuaObjectField sLakituStateFields[LUA_LAKITU_STATE_FIELD_COUNT] = { "yaw", LVT_S16, offsetof(struct LakituState, yaw), false, LOT_NONE }, }; -#define LUA_LEVEL_VALUES_FIELD_COUNT 27 +#define LUA_LEVEL_VALUES_FIELD_COUNT 38 static struct LuaObjectField sLevelValuesFields[LUA_LEVEL_VALUES_FIELD_COUNT] = { { "cellHeightLimit", LVT_S16, offsetof(struct LevelValues, cellHeightLimit), false, LOT_NONE }, { "coinsRequiredForCoinStar", LVT_S16, offsetof(struct LevelValues, coinsRequiredForCoinStar), false, LOT_NONE }, @@ -742,22 +742,33 @@ static struct LuaObjectField sLevelValuesFields[LUA_LEVEL_VALUES_FIELD_COUNT] = { "exitCastleArea", LVT_S16, offsetof(struct LevelValues, exitCastleArea), false, LOT_NONE }, { "exitCastleLevel", LVT_S32, offsetof(struct LevelValues, exitCastleLevel), false, LOT_NONE }, { "exitCastleWarpNode", LVT_U8, offsetof(struct LevelValues, exitCastleWarpNode), false, LOT_NONE }, + { "extendedPauseDisplay", LVT_U8, offsetof(struct LevelValues, extendedPauseDisplay), false, LOT_NONE }, { "fixCollisionBugs", LVT_U8, offsetof(struct LevelValues, fixCollisionBugs), false, LOT_NONE }, - { "fixVanishFloors", LVT_BOOL, offsetof(struct LevelValues, fixVanishFloors), false, LOT_NONE }, + { "fixVanishFloors", LVT_U8, offsetof(struct LevelValues, fixVanishFloors), false, LOT_NONE }, + { "floatingStarDance", LVT_U8, offsetof(struct LevelValues, floatingStarDance), false, LOT_NONE }, { "floorLowerLimit", LVT_S16, offsetof(struct LevelValues, floorLowerLimit), false, LOT_NONE }, { "floorLowerLimitMisc", LVT_S16, offsetof(struct LevelValues, floorLowerLimitMisc), false, LOT_NONE }, { "floorLowerLimitShadow", LVT_S16, offsetof(struct LevelValues, floorLowerLimitShadow), false, LOT_NONE }, + { "hudCapTimer", LVT_U8, offsetof(struct LevelValues, hudCapTimer), false, LOT_NONE }, + { "hudRedCoinsRadar", LVT_U8, offsetof(struct LevelValues, hudRedCoinsRadar), false, LOT_NONE }, + { "hudSecretsRadar", LVT_U8, offsetof(struct LevelValues, hudSecretsRadar), false, LOT_NONE }, { "metalCapDuration", LVT_U16, offsetof(struct LevelValues, metalCapDuration), false, LOT_NONE }, { "metalCapDurationCotmc", LVT_U16, offsetof(struct LevelValues, metalCapDurationCotmc), false, LOT_NONE }, { "metalCapSequence", LVT_U8, offsetof(struct LevelValues, metalCapSequence), false, LOT_NONE }, + { "mushroom1UpHeal", LVT_U8, offsetof(struct LevelValues, mushroom1UpHeal), false, LOT_NONE }, { "pauseExitAnywhere", LVT_BOOL, offsetof(struct LevelValues, pauseExitAnywhere), false, LOT_NONE }, + { "previewBlueCoins", LVT_U8, offsetof(struct LevelValues, previewBlueCoins), false, LOT_NONE }, { "pssSlideStarIndex", LVT_U8, offsetof(struct LevelValues, pssSlideStarIndex), false, LOT_NONE }, { "pssSlideStarTime", LVT_U16, offsetof(struct LevelValues, pssSlideStarTime), false, LOT_NONE }, + { "respawnBlueCoinsSwitch", LVT_U8, offsetof(struct LevelValues, respawnBlueCoinsSwitch), false, LOT_NONE }, + { "showStarNumber", LVT_U8, offsetof(struct LevelValues, showStarNumber), false, LOT_NONE }, { "skipCreditsAt", LVT_S32, offsetof(struct LevelValues, skipCreditsAt), false, LOT_NONE }, + { "starHeal", LVT_U8, offsetof(struct LevelValues, starHeal), false, LOT_NONE }, { "starPositions", LVT_COBJECT, offsetof(struct LevelValues, starPositions), true, LOT_STARPOSITIONS }, { "vanishCapDuration", LVT_U16, offsetof(struct LevelValues, vanishCapDuration), false, LOT_NONE }, { "vanishCapDurationVcutm", LVT_U16, offsetof(struct LevelValues, vanishCapDurationVcutm), false, LOT_NONE }, { "vanishCapSequence", LVT_U8, offsetof(struct LevelValues, vanishCapSequence), false, LOT_NONE }, + { "visibleSecrets", LVT_U8, offsetof(struct LevelValues, visibleSecrets), false, LOT_NONE }, { "wingCapDuration", LVT_U16, offsetof(struct LevelValues, wingCapDuration), false, LOT_NONE }, { "wingCapDurationTotwc", LVT_U16, offsetof(struct LevelValues, wingCapDurationTotwc), false, LOT_NONE }, { "wingCapLookUpReq", LVT_U8, offsetof(struct LevelValues, wingCapLookUpReq), false, LOT_NONE }, @@ -800,7 +811,7 @@ static struct LuaObjectField sMarioBodyStateFields[LUA_MARIO_BODY_STATE_FIELD_CO { "wingFlutter", LVT_S8, offsetof(struct MarioBodyState, wingFlutter), false, LOT_NONE }, }; -#define LUA_MARIO_STATE_FIELD_COUNT 77 +#define LUA_MARIO_STATE_FIELD_COUNT 76 static struct LuaObjectField sMarioStateFields[LUA_MARIO_STATE_FIELD_COUNT] = { { "action", LVT_U32, offsetof(struct MarioState, action), false, LOT_NONE }, { "actionArg", LVT_U32, offsetof(struct MarioState, actionArg), false, LOT_NONE }, @@ -873,7 +884,6 @@ static struct LuaObjectField sMarioStateFields[LUA_MARIO_STATE_FIELD_COUNT] = { { "unkC4", LVT_F32, offsetof(struct MarioState, unkC4), false, LOT_NONE }, { "usedObj", LVT_COBJECT_P, offsetof(struct MarioState, usedObj), false, LOT_OBJECT }, { "vel", LVT_COBJECT, offsetof(struct MarioState, vel), true, LOT_VEC3F }, - { "visibleToEnemies", LVT_U8, offsetof(struct MarioState, visibleToEnemies), false, LOT_NONE }, { "wall", LVT_COBJECT_P, offsetof(struct MarioState, wall), false, LOT_SURFACE }, { "wallKickTimer", LVT_U8, offsetof(struct MarioState, wallKickTimer), false, LOT_NONE }, { "wallNormal", LVT_COBJECT, offsetof(struct MarioState, wallNormal), true, LOT_VEC3F }, @@ -1544,6 +1554,7 @@ static struct LuaObjectField sObjectFields[LUA_OBJECT_FIELD_COUNT] = { { "oSpinyTargetYaw", LVT_S32, offsetof(struct Object, oSpinyTargetYaw), false, LOT_NONE }, { "oSpinyTimeUntilTurn", LVT_S32, offsetof(struct Object, oSpinyTimeUntilTurn), false, LOT_NONE }, { "oSpinyTurningAwayFromWall", LVT_S32, offsetof(struct Object, oSpinyTurningAwayFromWall), false, LOT_NONE }, +// { "oStarBehavior", LVT_???, offsetof(struct Object, oStarBehavior), true, LOT_??? }, <--- UNIMPLEMENTED { "oStarSelectorSize", LVT_F32, offsetof(struct Object, oStarSelectorSize), false, LOT_NONE }, { "oStarSelectorTimer", LVT_S32, offsetof(struct Object, oStarSelectorTimer), false, LOT_NONE }, { "oStarSelectorType", LVT_S32, offsetof(struct Object, oStarSelectorType), false, LOT_NONE }, diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c index 0e5ee625..0c54bada 100644 --- a/src/pc/lua/smlua_constants_autogen.c +++ b/src/pc/lua/smlua_constants_autogen.c @@ -857,7 +857,9 @@ char gSmluaConstants[] = "" "id_bhvYoshi = 534\n" "id_RM_Scroll_Texture = 535\n" "id_editor_Scroll_Texture = 536\n" -"id_bhv_max_count = 537\n" +"id_bhvBlueCoinNumber = 537\n" +"id_bhvStarNumber = 538\n" +"id_bhv_max_count = 539\n" "CAM_MODE_MARIO_ACTIVE = 0x01\n" "CAM_MODE_LAKITU_WAS_ZOOMED_OUT = 0x02\n" "CAM_MODE_MARIO_SELECTED = 0x04\n" @@ -1872,6 +1874,7 @@ char gSmluaConstants[] = "" "BLUE_COIN_SWITCH_ACT_IDLE = 0\n" "BLUE_COIN_SWITCH_ACT_RECEDING = 1\n" "BLUE_COIN_SWITCH_ACT_TICKING = 2\n" +"BLUE_COIN_SWITCH_ACT_RESPAWNING = 3\n" "MOV_BCOIN_ACT_STILL = 0\n" "MOV_BCOIN_ACT_MOVING = 1\n" "MOV_YCOIN_ACT_IDLE = 0\n" @@ -3983,7 +3986,7 @@ char gSmluaConstants[] = "" "COOP_OBJ_FLAG_NETWORK = (1 << 0)\n" "COOP_OBJ_FLAG_LUA = (1 << 1)\n" "COOP_OBJ_FLAG_NON_SYNC = (1 << 2)\n" -"VERSION_NUMBER = 31\n" +"VERSION_NUMBER = 32\n" "MINOR_VERSION_NUMBER = 0\n" "MAX_VERSION_LENGTH = 10\n" ; \ No newline at end of file diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index 79431e2e..9cb90305 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -915,6 +915,21 @@ int smlua_func_bhv_blue_coin_jumping_loop(UNUSED lua_State* L) { return 1; } +int smlua_func_bhv_blue_coin_number_loop(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", "bhv_blue_coin_number_loop", 0, top); + return 0; + } + + + bhv_blue_coin_number_loop(); + + return 1; +} + int smlua_func_bhv_blue_coin_sliding_jumping_init(UNUSED lua_State* L) { if (L == NULL) { return 0; } @@ -945,6 +960,21 @@ int smlua_func_bhv_blue_coin_sliding_loop(UNUSED lua_State* L) { return 1; } +int smlua_func_bhv_blue_coin_switch_init(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", "bhv_blue_coin_switch_init", 0, top); + return 0; + } + + + bhv_blue_coin_switch_init(); + + return 1; +} + int smlua_func_bhv_blue_coin_switch_loop(UNUSED lua_State* L) { if (L == NULL) { return 0; } @@ -6561,6 +6591,21 @@ int smlua_func_bhv_star_key_collection_puff_spawner_loop(UNUSED lua_State* L) { return 1; } +int smlua_func_bhv_star_number_loop(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", "bhv_star_number_loop", 0, top); + return 0; + } + + + bhv_star_number_loop(); + + return 1; +} + int smlua_func_bhv_star_spawn_init(UNUSED lua_State* L) { if (L == NULL) { return 0; } @@ -8838,6 +8883,21 @@ int smlua_func_spawn_red_coin_cutscene_star(lua_State* L) { return 1; } +int smlua_func_spawn_star_number(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", "spawn_star_number", 0, top); + return 0; + } + + + spawn_star_number(); + + return 1; +} + int smlua_func_spawn_triangle_break_particles(lua_State* L) { if (L == NULL) { return 0; } @@ -28881,8 +28941,10 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "bhv_blue_bowser_flame_init", smlua_func_bhv_blue_bowser_flame_init); smlua_bind_function(L, "bhv_blue_bowser_flame_loop", smlua_func_bhv_blue_bowser_flame_loop); smlua_bind_function(L, "bhv_blue_coin_jumping_loop", smlua_func_bhv_blue_coin_jumping_loop); + smlua_bind_function(L, "bhv_blue_coin_number_loop", smlua_func_bhv_blue_coin_number_loop); smlua_bind_function(L, "bhv_blue_coin_sliding_jumping_init", smlua_func_bhv_blue_coin_sliding_jumping_init); smlua_bind_function(L, "bhv_blue_coin_sliding_loop", smlua_func_bhv_blue_coin_sliding_loop); + smlua_bind_function(L, "bhv_blue_coin_switch_init", smlua_func_bhv_blue_coin_switch_init); smlua_bind_function(L, "bhv_blue_coin_switch_loop", smlua_func_bhv_blue_coin_switch_loop); smlua_bind_function(L, "bhv_blue_fish_movement_loop", smlua_func_bhv_blue_fish_movement_loop); smlua_bind_function(L, "bhv_blue_flames_group_loop", smlua_func_bhv_blue_flames_group_loop); @@ -29257,6 +29319,7 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "bhv_star_door_loop", smlua_func_bhv_star_door_loop); smlua_bind_function(L, "bhv_star_door_loop_2", smlua_func_bhv_star_door_loop_2); smlua_bind_function(L, "bhv_star_key_collection_puff_spawner_loop", smlua_func_bhv_star_key_collection_puff_spawner_loop); + smlua_bind_function(L, "bhv_star_number_loop", smlua_func_bhv_star_number_loop); smlua_bind_function(L, "bhv_star_spawn_init", smlua_func_bhv_star_spawn_init); smlua_bind_function(L, "bhv_star_spawn_loop", smlua_func_bhv_star_spawn_loop); smlua_bind_function(L, "bhv_static_checkered_platform_loop", smlua_func_bhv_static_checkered_platform_loop); @@ -29394,6 +29457,7 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "spawn_mist_particles_variable", smlua_func_spawn_mist_particles_variable); smlua_bind_function(L, "spawn_no_exit_star", smlua_func_spawn_no_exit_star); smlua_bind_function(L, "spawn_red_coin_cutscene_star", smlua_func_spawn_red_coin_cutscene_star); + smlua_bind_function(L, "spawn_star_number", smlua_func_spawn_star_number); smlua_bind_function(L, "spawn_triangle_break_particles", smlua_func_spawn_triangle_break_particles); smlua_bind_function(L, "spawn_wind_particles", smlua_func_spawn_wind_particles); smlua_bind_function(L, "tox_box_move", smlua_func_tox_box_move);