diff --git a/include/dialog_ids.h b/include/dialog_ids.h index 6feadafb..02922a56 100644 --- a/include/dialog_ids.h +++ b/include/dialog_ids.h @@ -172,6 +172,7 @@ enum DialogId { DIALOG_167, DIALOG_168, DIALOG_169, + DIALOG_170, DIALOG_COUNT }; diff --git a/levels/castle_inside/script.c b/levels/castle_inside/script.c index aa2a18ec..b119549f 100644 --- a/levels/castle_inside/script.c +++ b/levels/castle_inside/script.c @@ -261,9 +261,9 @@ const LevelScript level_castle_inside_entry[] = { OBJECT(/*model*/ MODEL_NONE, /*pos*/ 3748, 507, 773, /*angle*/ 0, -45, 0, /*behParam*/ 0x00000000, /*beh*/ bhvTankFishGroup), OBJECT(/*model*/ MODEL_NONE, /*pos*/ 2778, 507, 1255, /*angle*/ 0, -90, 0, /*behParam*/ 0x00000000, /*beh*/ bhvTankFishGroup), OBJECT(/*model*/ MODEL_BOO_CASTLE, /*pos*/ -1000, 50, -3500, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvBooInCastle), - OBJECT(/*model*/ MODEL_TOAD, /*pos*/ -1671, 0, 1313, /*angle*/ 0, 83, 0, /*behParam*/ DIALOG_133 << 24, /*beh*/ bhvToadMessage), - OBJECT(/*model*/ MODEL_TOAD, /*pos*/ 1524, 307, 458, /*angle*/ 0, 110, 0, /*behParam*/ DIALOG_134 << 24, /*beh*/ bhvToadMessage), - OBJECT(/*model*/ MODEL_TOAD, /*pos*/ 596, -306, -2637, /*angle*/ 0, 152, 0, /*behParam*/ DIALOG_135 << 24, /*beh*/ bhvToadMessage), + OBJECT(/*model*/ MODEL_TOAD, /*pos*/ -1671, 0, 1313, /*angle*/ 0, 83, 0, /*behParam*/ (DIALOG_133 << 24) | (0 << 16), /*beh*/ bhvToadMessage), + OBJECT(/*model*/ MODEL_TOAD, /*pos*/ 1524, 307, 458, /*angle*/ 0, 110, 0, /*behParam*/ (DIALOG_134 << 24) | (1 << 16), /*beh*/ bhvToadMessage), + OBJECT(/*model*/ MODEL_TOAD, /*pos*/ 596, -306, -2637, /*angle*/ 0, 152, 0, /*behParam*/ (DIALOG_135 << 24) | (2 << 16), /*beh*/ bhvToadMessage), JUMP_LINK(script_func_local_1), WARP_NODE(/*id*/ 0xF1, /*destLevel*/ LEVEL_CASTLE_GROUNDS, /*destArea*/ 0x01, /*destNode*/ 0x03, /*flags*/ WARP_NO_CHECKPOINT), TERRAIN(/*terrainData*/ inside_castle_seg7_area_1_collision), @@ -278,9 +278,9 @@ const LevelScript level_castle_inside_entry[] = { OBJECT(/*model*/ MODEL_CASTLE_CLOCK_HOUR_HAND, /*pos*/ -205, 2918, 7222, /*angle*/ 0, 180, 0, /*behParam*/ 0x00000000, /*beh*/ bhvClockHourHand), OBJECT(/*model*/ MODEL_CASTLE_CLOCK_PENDULUM, /*pos*/ -205, 2611, 7140, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvDecorativePendulum), OBJECT(/*model*/ MODEL_LAKITU, /*pos*/ 4231, 1408, 1601, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvCameraLakitu), - OBJECT(/*model*/ MODEL_TOAD, /*pos*/ -977, 1203, 2569, /*angle*/ 0, 0, 0, /*behParam*/ DIALOG_076 << 24, /*beh*/ bhvToadMessage), - OBJECT(/*model*/ MODEL_TOAD, /*pos*/ -1584, 2253, 7157, /*angle*/ 0, 136, 0, /*behParam*/ DIALOG_083 << 24, /*beh*/ bhvToadMessage), - OBJECT(/*model*/ MODEL_TOAD, /*pos*/ 837, 1203, 3020, /*angle*/ 0, 180, 0, /*behParam*/ DIALOG_137 << 24, /*beh*/ bhvToadMessage), + OBJECT(/*model*/ MODEL_TOAD, /*pos*/ -977, 1203, 2569, /*angle*/ 0, 0, 0, /*behParam*/ (DIALOG_076 << 24) | (3 << 16), /*beh*/ bhvToadMessage), + OBJECT(/*model*/ MODEL_TOAD, /*pos*/ -1584, 2253, 7157, /*angle*/ 0, 136, 0, /*behParam*/ (DIALOG_083 << 24) | (4 << 16), /*beh*/ bhvToadMessage), + OBJECT(/*model*/ MODEL_TOAD, /*pos*/ 837, 1203, 3020, /*angle*/ 0, 180, 0, /*behParam*/ (DIALOG_137 << 24) | (5 << 16), /*beh*/ bhvToadMessage), JUMP_LINK(script_func_local_2), WARP_NODE(/*id*/ 0xF1, /*destLevel*/ LEVEL_CASTLE_GROUNDS, /*destArea*/ 0x01, /*destNode*/ 0x03, /*flags*/ WARP_NO_CHECKPOINT), TERRAIN(/*terrainData*/ inside_castle_seg7_area_2_collision), @@ -296,8 +296,8 @@ const LevelScript level_castle_inside_entry[] = { OBJECT(/*model*/ MODEL_CASTLE_WATER_LEVEL_PILLAR, /*pos*/ 7066, -1178, -205, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvWaterLevelPillar), OBJECT(/*model*/ MODEL_NONE, /*pos*/ 0, 0, 0, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvDddWarp), OBJECT(/*model*/ MODEL_MIPS, /*pos*/ -1509, -1177, -1564, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvMips), - OBJECT(/*model*/ MODEL_TOAD, /*pos*/ 1787, -1381, -1957, /*angle*/ 0, 126, 0, /*behParam*/ DIALOG_082 << 24, /*beh*/ bhvToadMessage), - OBJECT(/*model*/ MODEL_TOAD, /*pos*/ -4048, -1381, -1334, /*angle*/ 0, 30, 0, /*behParam*/ DIALOG_136 << 24, /*beh*/ bhvToadMessage), + OBJECT(/*model*/ MODEL_TOAD, /*pos*/ 1787, -1381, -1957, /*angle*/ 0, 126, 0, /*behParam*/ (DIALOG_082 << 24) | (6 << 16), /*beh*/ bhvToadMessage), + OBJECT(/*model*/ MODEL_TOAD, /*pos*/ -4048, -1381, -1334, /*angle*/ 0, 30, 0, /*behParam*/ (DIALOG_136 << 24) | (7 << 16), /*beh*/ bhvToadMessage), JUMP_LINK(script_func_local_3), JUMP_LINK(script_func_local_4), WARP_NODE(/*id*/ 0xF1, /*destLevel*/ LEVEL_CASTLE_GROUNDS, /*destArea*/ 0x01, /*destNode*/ 0x03, /*flags*/ WARP_NO_CHECKPOINT), diff --git a/src/audio/external.c b/src/audio/external.c index 608b1494..e32fb6ff 100644 --- a/src/audio/external.c +++ b/src/audio/external.c @@ -253,7 +253,8 @@ u8 sDialogSpeaker[] = { /*13*/ _, _, TUXIE, _, _, _, _, _, _, _, /*14*/ _, _, _, _, _, _, _, _, _, _, /*15*/ WIGLR, WIGLR, WIGLR, _, _, _, _, _, _, _, - /*16*/ _, YOSHI, _, _, _, _, _, _, WIGLR, _ + /*16*/ _, YOSHI, _, _, _, _, _, _, WIGLR, _, + /*17*/ _, }; #undef _ STATIC_ASSERT(ARRAY_COUNT(sDialogSpeaker) == DIALOG_COUNT, "change this array if you are adding dialogs"); diff --git a/src/game/level_update.c b/src/game/level_update.c index ef58ac02..11fba8c0 100644 --- a/src/game/level_update.c +++ b/src/game/level_update.c @@ -744,7 +744,7 @@ s16 level_trigger_warp(struct MarioState *m, s32 warpOp) { case WARP_OP_DEATH: if (m->numLives == 0) { - sDelayedWarpOp = WARP_OP_GAME_OVER; + if (save_file_get_flags() & SAVE_FLAG_TALKED_TO_ALL_TOADS) sDelayedWarpOp = WARP_OP_GAME_OVER; } sDelayedWarpTimer = 48; sSourceWarpNodeId = WARP_NODE_DEATH; @@ -756,7 +756,8 @@ s16 level_trigger_warp(struct MarioState *m, s32 warpOp) { sSourceWarpNodeId = WARP_NODE_WARP_FLOOR; if (area_get_warp_node(sSourceWarpNodeId) == NULL) { if (m->numLives == 0) { - sDelayedWarpOp = WARP_OP_GAME_OVER; + if (save_file_get_flags() & SAVE_FLAG_TALKED_TO_ALL_TOADS) sDelayedWarpOp = WARP_OP_GAME_OVER; + else sSourceWarpNodeId = WARP_NODE_DEATH; } else { sSourceWarpNodeId = WARP_NODE_DEATH; } diff --git a/src/game/mario_actions_cutscene.c b/src/game/mario_actions_cutscene.c index 4dedf313..ffdaf308 100644 --- a/src/game/mario_actions_cutscene.c +++ b/src/game/mario_actions_cutscene.c @@ -1181,6 +1181,7 @@ s32 act_death_exit(struct MarioState *m) { #endif queue_rumble_data(5, 80); m->numLives--; + if (m->numLives == -1) m->numLives = 4; // restore 7.75 units of health m->healCounter = 31; } @@ -1197,6 +1198,7 @@ s32 act_unused_death_exit(struct MarioState *m) { play_sound(SOUND_MARIO_OOOF2, m->marioObj->header.gfx.cameraToObject); #endif m->numLives--; + if (m->numLives == -1) m->numLives = 4; // restore 7.75 units of health m->healCounter = 31; } @@ -1214,6 +1216,7 @@ s32 act_falling_death_exit(struct MarioState *m) { #endif queue_rumble_data(5, 80); m->numLives--; + if (m->numLives == -1) m->numLives = 4; // restore 7.75 units of health m->healCounter = 31; } @@ -1259,6 +1262,7 @@ s32 act_special_death_exit(struct MarioState *m) { if (launch_mario_until_land(m, ACT_HARD_BACKWARD_GROUND_KB, MARIO_ANIM_BACKWARD_AIR_KB, -24.0f)) { queue_rumble_data(5, 80); m->numLives--; + if (m->numLives == -1) m->numLives = 4; m->healCounter = 31; } // show Mario diff --git a/src/game/mario_misc.c b/src/game/mario_misc.c index 57cd8b0a..eead74d4 100644 --- a/src/game/mario_misc.c +++ b/src/game/mario_misc.c @@ -25,6 +25,8 @@ #include "sound_init.h" #include "saturn/saturn_textures.h" +#include "saturn/saturn.h" + #define TOAD_STAR_1_REQUIREMENT 12 #define TOAD_STAR_2_REQUIREMENT 25 #define TOAD_STAR_3_REQUIREMENT 35 @@ -129,6 +131,13 @@ static void toad_message_talking(void) { != 0) { gCurrentObject->oToadMessageRecentlyTalked = 1; gCurrentObject->oToadMessageState = TOAD_MESSAGE_FADING; + activatedToads |= 1 << ((gCurrentObject->oBehParams >> 16) & 0xFF); + if (activatedToads == 0xFF && !(save_file_get_flags() & SAVE_FLAG_TALKED_TO_ALL_TOADS)) { + save_file_set_flags(SAVE_FLAG_TALKED_TO_ALL_TOADS); + set_mario_action(gMarioState, ACT_READING_AUTOMATIC_DIALOG, DIALOG_170); + play_puzzle_jingle(); + save_file_do_save(gCurrSaveFileNum - 1); + } switch (gCurrentObject->oToadMessageDialogId) { case TOAD_STAR_1_DIALOG: gCurrentObject->oToadMessageDialogId = TOAD_STAR_1_DIALOG_AFTER; diff --git a/src/game/save_file.h b/src/game/save_file.h index 26a0e476..1d0e6f1a 100644 --- a/src/game/save_file.h +++ b/src/game/save_file.h @@ -104,6 +104,7 @@ extern s8 gLevelToCourseNumTable[]; #define SAVE_FLAG_CAP_ON_UKIKI /* 0x040000 */ (1 << 18) #define SAVE_FLAG_CAP_ON_MR_BLIZZARD /* 0x080000 */ (1 << 19) #define SAVE_FLAG_UNLOCKED_50_STAR_DOOR /* 0x100000 */ (1 << 20) +#define SAVE_FLAG_TALKED_TO_ALL_TOADS /* 0x200000 */ (1 << 21) // Variable for setting a warp checkpoint. diff --git a/src/saturn/saturn.cpp b/src/saturn/saturn.cpp index 169d4799..eb697e10 100644 --- a/src/saturn/saturn.cpp +++ b/src/saturn/saturn.cpp @@ -112,6 +112,8 @@ bool is_cc_editing; bool autoChroma; +u8 activatedToads = 0; + extern "C" { #include "game/camera.h" #include "game/area.h" diff --git a/src/saturn/saturn.h b/src/saturn/saturn.h index 2fbf43c9..ac746cac 100644 --- a/src/saturn/saturn.h +++ b/src/saturn/saturn.h @@ -68,6 +68,8 @@ extern bool autoChroma; extern bool should_update_cam_from_keyframes; +extern u8 activatedToads; + #ifdef __cplusplus #include #include diff --git a/text/us/dialogs.h b/text/us/dialogs.h index fc847e13..b2082e91 100644 --- a/text/us/dialogs.h +++ b/text/us/dialogs.h @@ -2100,3 +2100,12 @@ Arrgghh!\n\ Anyone entering this cave\n\ without permission will\n\ meet certain disaster.")) + +DEFINE_DIALOG(DIALOG_170, 1, 4, 30, 205, _("\ +Wow! You unlocked a super\n\ +secret easter egg that\n\ +allows you to duplicate\n\ +your DynOS models!\n\ +Just game over and see how\n\ +the model count increases\n\ +each and every time!"))