Fix cutscenes, syncing issues, and more (Yoshi!) (#1109)

* Fixes

* Lots more changes

* Yoshi :D

* Remove some unecessary changes

* Oops

* Remove temp code

* Revert changes made to king bobomb, will be handled in #1196

* copied from main not dev, oops

* Address review and do a minor improvement

* Nuke that
This commit is contained in:
EmeraldLockdown 2026-04-21 22:37:30 -05:00 committed by GitHub
parent f04106325e
commit 6510f3928c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 312 additions and 174 deletions

View file

@ -148,7 +148,7 @@ override_field_immutable = {
}
override_field_version_excludes = {
"oCameraLakituUnk104": "VERSION_JP",
"oCameraLakituMusicPlayed": "VERSION_JP",
"oCoinUnk1B0": "VERSION_JP",
}

View file

@ -5635,6 +5635,12 @@ YOSHI_ACT_FINISH_JUMPING_AND_DESPAWN = 4
--- @type integer
YOSHI_ACT_GIVE_PRESENT = 5
--- @type integer
YOSHI_ACT_GONE = 6
--- @type integer
YOSHI_ACT_REAPPEAR = 7
--- @type integer
YOSHI_ACT_CREDITS = 10

View file

@ -7992,7 +7992,7 @@ function network_discord_id_from_local_index(localIndex)
-- ...
end
--- Resets Yoshi as being alive
--- Marks Yoshi as alive
function set_yoshi_as_not_dead()
-- ...
end

View file

@ -1724,7 +1724,7 @@
--- @field public oCameraLakituSpeed number
--- @field public oCameraLakituCircleRadius number
--- @field public oCameraLakituFinishedDialog integer
--- @field public oCameraLakituUnk104 integer
--- @field public oCameraLakituMusicPlayed integer
--- @field public oCameraLakituPitchVel integer
--- @field public oCameraLakituYawVel integer
--- @field public oEnemyLakituNumSpinies integer

View file

@ -1374,7 +1374,7 @@ s64 DynOS_Bhv_ParseBehaviorScriptConstants(const String &_Arg, bool *found) {
bhv_constant(oCameraLakituCircleRadius);
bhv_constant(oCameraLakituFinishedDialog);
#ifndef VERSION_JP
bhv_constant(oCameraLakituUnk104);
bhv_constant(oCameraLakituMusicPlayed);
#endif
bhv_constant(oCameraLakituPitchVel);
bhv_constant(oCameraLakituYawVel);

View file

@ -2556,6 +2556,8 @@
- YOSHI_ACT_WALK_JUMP_OFF_ROOF
- YOSHI_ACT_FINISH_JUMPING_AND_DESPAWN
- YOSHI_ACT_GIVE_PRESENT
- YOSHI_ACT_GONE
- YOSHI_ACT_REAPPEAR
- YOSHI_ACT_CREDITS
- KOOPA_UNSHELLED_ACT_RUN
- KOOPA_UNSHELLED_ACT_DIVE

View file

@ -2882,7 +2882,7 @@ Gets a Discord ID corresponding to the network player with `localIndex`
## [set_yoshi_as_not_dead](#set_yoshi_as_not_dead)
### Description
Resets Yoshi as being alive
Marks Yoshi as alive
### Lua Example
`set_yoshi_as_not_dead()`

View file

@ -2322,7 +2322,7 @@
| oCameraLakituSpeed | `number` | |
| oCameraLakituCircleRadius | `number` | |
| oCameraLakituFinishedDialog | `integer` | |
| oCameraLakituUnk104 | `integer` | |
| oCameraLakituMusicPlayed | `integer` | |
| oCameraLakituPitchVel | `integer` | |
| oCameraLakituYawVel | `integer` | |
| oEnemyLakituNumSpinies | `integer` | |

View file

@ -197,7 +197,7 @@
/* oAction */
#define FISH_SPAWNER_ACT_SPAWN 0
#define FISH_SPAWNER_ACT_IDLE 1
#define FISH_SPAWNER_ACT_RESPAWN 2
#define FISH_SPAWNER_ACT_RESPAWN 2
/* oBehParams2ndByte */
#define FISH_SPAWNER_BP_MANY_BLUE 0
#define FISH_SPAWNER_BP_FEW_BLUE 1
@ -437,6 +437,8 @@
#define YOSHI_ACT_WALK_JUMP_OFF_ROOF 3
#define YOSHI_ACT_FINISH_JUMPING_AND_DESPAWN 4
#define YOSHI_ACT_GIVE_PRESENT 5
#define YOSHI_ACT_GONE 6
#define YOSHI_ACT_REAPPEAR 7
#define YOSHI_ACT_CREDITS 10
/* Koopa */

View file

@ -643,7 +643,7 @@
#define /*0x0FC*/ oCameraLakituCircleRadius OBJECT_FIELD_F32(0x1D)
#define /*0x100*/ oCameraLakituFinishedDialog OBJECT_FIELD_S32(0x1E)
#ifndef VERSION_JP
#define /*0x104*/ oCameraLakituUnk104 OBJECT_FIELD_S32(0x1F)
#define /*0x104*/ oCameraLakituMusicPlayed OBJECT_FIELD_S32(0x1F)
#endif
#define /*0x1AC*/ oCameraLakituPitchVel OBJECT_FIELD_S16(0x49, 0)
#define /*0x1AE*/ oCameraLakituYawVel OBJECT_FIELD_S16(0x49, + 1)

View file

@ -297,7 +297,7 @@ const u8 sBackgroundMusicDefaultVolumeDefault[35] = {
80, // SEQ_EVENT_CUTSCENE_VICTORY
70, // SEQ_EVENT_CUTSCENE_ENDING
65, // SEQ_MENU_FILE_SELECT
0, // SEQ_EVENT_CUTSCENE_LAKITU (not in JP)
80, // SEQ_EVENT_CUTSCENE_LAKITU (not in JP)
};
// Default volume for background music sequences (playing on player 0).
@ -336,7 +336,7 @@ u8 sBackgroundMusicDefaultVolume[MAX_AUDIO_OVERRIDE] = {
80, // SEQ_EVENT_CUTSCENE_VICTORY
70, // SEQ_EVENT_CUTSCENE_ENDING
65, // SEQ_MENU_FILE_SELECT
0, // SEQ_EVENT_CUTSCENE_LAKITU (not in JP)
80, // SEQ_EVENT_CUTSCENE_LAKITU (not in JP)
75, // SEQ_???
75, // SEQ_???
75, // SEQ_???
@ -838,27 +838,27 @@ extern f32 *smlua_get_vec3f_for_play_sound(f32 *pos);
void play_sound(s32 soundBits, f32 *pos) {
MUTEX_LOCK(gAudioThread);
pos = smlua_get_vec3f_for_play_sound(pos);
smlua_call_event_hooks(HOOK_ON_PLAY_SOUND, soundBits, pos, &soundBits);
sSoundRequests[sSoundRequestCount].soundBits = soundBits;
sSoundRequests[sSoundRequestCount].position = pos;
sSoundRequests[sSoundRequestCount].customFreqScale = 0;
sSoundRequestCount++;
MUTEX_UNLOCK(gAudioThread);
}
void play_sound_with_freq_scale(s32 soundBits, f32* pos, f32 freqScale) {
MUTEX_LOCK(gAudioThread);
pos = smlua_get_vec3f_for_play_sound(pos);
smlua_call_event_hooks(HOOK_ON_PLAY_SOUND, soundBits, pos, &soundBits);
sSoundRequests[sSoundRequestCount].soundBits = soundBits;
sSoundRequests[sSoundRequestCount].position = pos;
sSoundRequests[sSoundRequestCount].customFreqScale = freqScale;
sSoundRequestCount++;
MUTEX_UNLOCK(gAudioThread);
}
@ -997,13 +997,13 @@ static void delete_sound_from_bank(u8 bank, u8 soundIndex) {
*/
static void update_background_music_after_sound(u8 bank, u8 soundIndex) {
MUTEX_LOCK(gAudioThread);
if (bank >= SOUND_BANK_COUNT || soundIndex >= SOUND_INDEX_COUNT) { return; }
if (sSoundBanks[bank][soundIndex].soundBits & SOUND_LOWER_BACKGROUND_MUSIC) {
sSoundBanksThatLowerBackgroundMusic &= (1 << bank) ^ 0xffff;
begin_background_music_fade(50);
}
MUTEX_UNLOCK(gAudioThread);
}
@ -1779,7 +1779,7 @@ static void update_game_sound(void) {
*/
static void seq_player_play_sequence(u8 player, u8 seqId, u16 arg2) {
MUTEX_LOCK(gAudioThread);
if (player >= SEQUENCE_PLAYERS) { return; }
u8 targetVolume;
u8 i;
@ -1829,7 +1829,7 @@ static void seq_player_play_sequence(u8 player, u8 seqId, u16 arg2) {
*/
void seq_player_fade_out(u8 player, u16 fadeDuration) {
MUTEX_LOCK(gAudioThread);
if (player >= SEQUENCE_PLAYERS) { return; }
#if defined(VERSION_EU) || defined(VERSION_SH)
#ifdef VERSION_EU
@ -1866,7 +1866,7 @@ void fade_volume_scale(u8 player, u8 targetScale, u16 fadeDuration) {
*/
static void fade_channel_volume_scale(u8 player, u8 channelIndex, u8 targetScale, u16 fadeDuration) {
MUTEX_LOCK(gAudioThread);
struct ChannelVolumeScaleFade *temp;
if (player >= SEQUENCE_PLAYERS) { return; }
if (channelIndex >= CHANNELS_MAX) { return; }
@ -1880,7 +1880,7 @@ static void fade_channel_volume_scale(u8 player, u8 channelIndex, u8 targetScale
temp->target = targetScale;
temp->current = gSequencePlayers[player].channels[channelIndex]->volumeScale;
}
MUTEX_UNLOCK(gAudioThread);
}
@ -2089,7 +2089,7 @@ void unused_8031FED0(u8 player, u32 bits, s8 arg2) {
*/
void seq_player_lower_volume(u8 player, u16 fadeDuration, u8 percentage) {
MUTEX_LOCK(gAudioThread);
if (player >= SEQUENCE_PLAYERS) { return; }
if (player == SEQ_PLAYER_LEVEL) {
sLowerBackgroundMusicVolume = TRUE;
@ -2097,7 +2097,7 @@ void seq_player_lower_volume(u8 player, u16 fadeDuration, u8 percentage) {
} else if (gSequencePlayers[player].enabled == TRUE) {
seq_player_fade_to_percentage_of_volume(player, fadeDuration, percentage);
}
MUTEX_UNLOCK(gAudioThread);
}
@ -2111,7 +2111,7 @@ void seq_player_lower_volume(u8 player, u16 fadeDuration, u8 percentage) {
*/
void seq_player_unlower_volume(u8 player, u16 fadeDuration) {
MUTEX_LOCK(gAudioThread);
if (player >= SEQUENCE_PLAYERS) { return; }
sLowerBackgroundMusicVolume = FALSE;
if (player == SEQ_PLAYER_LEVEL) {
@ -2123,7 +2123,7 @@ void seq_player_unlower_volume(u8 player, u16 fadeDuration) {
seq_player_fade_to_normal_volume(player, fadeDuration);
}
}
MUTEX_UNLOCK(gAudioThread);
}
@ -2143,7 +2143,7 @@ static u8 begin_background_music_fade(u16 fadeDuration) {
|| sCurrentBackgroundMusicSeqId == SEQ_EVENT_CUTSCENE_CREDITS) {
return 0xff;
}
MUTEX_LOCK(gAudioThread);
if (gSequencePlayers[SEQ_PLAYER_LEVEL].volume == 0.0f && fadeDuration) {
@ -2180,7 +2180,7 @@ static u8 begin_background_music_fade(u16 fadeDuration) {
seq_player_fade_to_normal_volume(SEQ_PLAYER_LEVEL, fadeDuration);
}
}
MUTEX_UNLOCK(gAudioThread);
return targetVolume;
@ -2191,7 +2191,7 @@ static u8 begin_background_music_fade(u16 fadeDuration) {
*/
void set_audio_muted(u8 muted) {
MUTEX_LOCK(gAudioThread);
u8 i;
for (i = 0; i < SEQUENCE_PLAYERS; i++) {
@ -2204,7 +2204,7 @@ void set_audio_muted(u8 muted) {
gSequencePlayers[i].muted = muted;
#endif
}
MUTEX_UNLOCK(gAudioThread);
}
@ -2213,7 +2213,7 @@ void set_audio_muted(u8 muted) {
*/
void sound_init(void) {
MUTEX_LOCK(gAudioThread);
u8 i;
u8 j;
@ -2272,7 +2272,7 @@ void sound_init(void) {
sCurrentSecondaryMusicVolume = 0;
sNumProcessedSoundRequests = 0;
sSoundRequestCount = 0;
MUTEX_UNLOCK(gAudioThread);
}
@ -2303,7 +2303,7 @@ void get_currently_playing_sound(u8 bank, u8 *numPlayingSounds, u8 *numSoundsInB
*/
void stop_sound(u32 soundBits, f32 *pos) {
MUTEX_LOCK(gAudioThread);
pos = smlua_get_vec3f_for_play_sound(pos);
u8 bank = (soundBits & SOUNDARGS_MASK_BANK) >> SOUNDARGS_SHIFT_BANK;
if (bank >= SOUND_BANK_COUNT) { return; }
@ -2326,7 +2326,7 @@ void stop_sound(u32 soundBits, f32 *pos) {
soundIndex = sSoundBanks[bank][soundIndex].next;
}
}
MUTEX_UNLOCK(gAudioThread);
}
@ -2335,7 +2335,7 @@ void stop_sound(u32 soundBits, f32 *pos) {
*/
void stop_sounds_from_source(f32 *pos) {
MUTEX_LOCK(gAudioThread);
pos = smlua_get_vec3f_for_play_sound(pos);
u8 bank;
u8 soundIndex;
@ -2350,7 +2350,7 @@ void stop_sounds_from_source(f32 *pos) {
soundIndex = sSoundBanks[bank][soundIndex].next;
}
}
MUTEX_UNLOCK(gAudioThread);
}
@ -2359,7 +2359,7 @@ void stop_sounds_from_source(f32 *pos) {
*/
static void stop_sounds_in_bank(u8 bank) {
MUTEX_LOCK(gAudioThread);
if (bank >= SOUND_BANK_COUNT) { return; }
u8 soundIndex = sSoundBanks[bank][0].next;
@ -2368,7 +2368,7 @@ static void stop_sounds_in_bank(u8 bank) {
sSoundBanks[bank][soundIndex].soundBits = NO_SOUND;
soundIndex = sSoundBanks[bank][soundIndex].next;
}
MUTEX_UNLOCK(gAudioThread);
}
@ -2390,7 +2390,7 @@ void stop_sounds_in_continuous_banks(void) {
*/
void sound_banks_disable(UNUSED u8 player, u16 bankMask) {
MUTEX_LOCK(gAudioThread);
u8 i;
for (i = 0; i < SOUND_BANK_COUNT; i++) {
@ -2399,7 +2399,7 @@ void sound_banks_disable(UNUSED u8 player, u16 bankMask) {
}
bankMask = bankMask >> 1;
}
MUTEX_UNLOCK(gAudioThread);
}
@ -2408,13 +2408,13 @@ void sound_banks_disable(UNUSED u8 player, u16 bankMask) {
*/
static void disable_all_sequence_players(void) {
MUTEX_LOCK(gAudioThread);
u8 i;
for (i = 0; i < SEQUENCE_PLAYERS; i++) {
sequence_player_disable(&gSequencePlayers[i]);
}
MUTEX_UNLOCK(gAudioThread);
}
@ -2423,7 +2423,7 @@ static void disable_all_sequence_players(void) {
*/
void sound_banks_enable(UNUSED u8 player, u16 bankMask) {
MUTEX_LOCK(gAudioThread);
u8 i;
for (i = 0; i < SOUND_BANK_COUNT; i++) {
@ -2432,7 +2432,7 @@ void sound_banks_enable(UNUSED u8 player, u16 bankMask) {
}
bankMask = bankMask >> 1;
}
MUTEX_UNLOCK(gAudioThread);
}
@ -2511,7 +2511,7 @@ void set_sequence_player_volume(s32 player, f32 volume) {
*/
void play_music(u8 player, u16 seqArgs, u16 fadeTimer) {
MUTEX_LOCK(gAudioThread);
if (player >= SEQUENCE_PLAYERS) { return; }
u8 seqId = seqArgs & 0xff;
u8 priority = seqArgs >> 8;
@ -2574,7 +2574,7 @@ void play_music(u8 player, u16 seqArgs, u16 fadeTimer) {
// Insert item into queue.
sBackgroundMusicQueue[foundIndex].priority = priority;
sBackgroundMusicQueue[foundIndex].seqId = seqId;
MUTEX_UNLOCK(gAudioThread);
}
@ -2583,7 +2583,7 @@ void play_music(u8 player, u16 seqArgs, u16 fadeTimer) {
*/
void stop_background_music(u16 seqId) {
MUTEX_LOCK(gAudioThread);
u8 foundIndex;
u8 i;
@ -2639,7 +2639,7 @@ void stop_background_music(u16 seqId) {
// @bug? If the sequence queue is full and we attempt to stop a sequence
// that isn't in the queue, this writes out of bounds. Can that happen?
sBackgroundMusicQueue[i].priority = 0;
MUTEX_UNLOCK(gAudioThread);
}
@ -2725,7 +2725,7 @@ void fade_in_env_music(void) {
*/
void play_secondary_music(u8 seqId, u8 bgMusicVolume, u8 volume, u16 fadeTimer) {
MUTEX_LOCK(gAudioThread);
UNUSED u32 dummy;
sUnused80332118 = 0;
@ -2748,7 +2748,7 @@ void play_secondary_music(u8 seqId, u8 bgMusicVolume, u8 volume, u16 fadeTimer)
seq_player_fade_to_target_volume(SEQ_PLAYER_ENV, fadeTimer, volume);
sCurrentSecondaryMusicVolume = volume;
}
MUTEX_UNLOCK(gAudioThread);
}
@ -2770,7 +2770,7 @@ void stop_secondary_music(u16 fadeTimer) {
*/
void set_audio_fadeout(u16 fadeDuration) {
MUTEX_LOCK(gAudioThread);
if (sHasStartedFadeOut) {
return;
}
@ -2798,7 +2798,7 @@ void set_audio_fadeout(u16 fadeDuration) {
}
sHasStartedFadeOut = TRUE;
MUTEX_UNLOCK(gAudioThread);
}
@ -2898,7 +2898,7 @@ void play_toads_jingle(void) {
*/
void sound_reset(u8 presetId) {
MUTEX_LOCK(gAudioThread);
#ifndef VERSION_JP
if (presetId >= 8) {
presetId = 0;
@ -2926,7 +2926,7 @@ void sound_reset(u8 presetId) {
D_80332108 = (D_80332108 & 0xf0) + presetId;
gSoundMode = D_80332108 >> 4;
sHasStartedFadeOut = FALSE;
MUTEX_UNLOCK(gAudioThread);
}

View file

@ -245,7 +245,7 @@ void bowser_act_intro_walk(void) {
}
}
static void bowser_debug_actions(void) // unused
UNUSED static void bowser_debug_actions(void) // unused
{
if (gDebugInfo[5][1] != 0) {
o->oAction = D_8032F4FC[gDebugInfo[5][2] & 0xf];
@ -778,7 +778,7 @@ void bowser_act_thrown_dropped(void)
o->oAction = 4;
else
o->oAction = 12;
if (is_nearest_mario_state_to_object(gMarioState, o)) {
network_send_object(o);
}
@ -887,9 +887,9 @@ void bowser_spawn_grand_star_key(void) {
reward->oHomeX = reward->oPosX;
reward->oHomeY = reward->oPosY;
reward->oHomeZ = reward->oPosZ;
sync_object_set_id(reward);
struct Object* spawn_objects[] = { reward };
u32 models[] = { MODEL_STAR };
network_send_spawn_objects(spawn_objects, models, 1);
@ -1015,7 +1015,7 @@ u8 bowser_dead_bits_end_continue_dialog(void) { return o->oAction == 4 && o->oBo
s32 bowser_dead_bits_end(void) {
struct MarioState *marioState = nearest_mario_state_to_object(o);
if (o->oBowserUnkF8 < 2) {
s32 dialogID = gBehaviorValues.dialogs.Bowser3Defeated120StarsDialog;
if (gHudDisplay.stars < 120) {
@ -1382,7 +1382,7 @@ void bhv_bowser_override_ownership(u8* shouldOverride, u8* shouldOwn) {
*shouldOwn = FALSE;
return;
}
// tilting platform
static u8 tiltingTimer = 0;
if (o->oAction == 19) { tiltingTimer = 5; }
@ -1426,7 +1426,7 @@ void bhv_bowser_init(void) {
o->oBowserUnk1AE = 0;
o->oBowserEyesShut = 0;
bowserCutscenePlayed = FALSE;
// Make sure we're the first to trigger Bowser.
if (!is_other_player_active()) {
bowserIsCutscenePlayer = TRUE;
@ -1437,7 +1437,7 @@ void bhv_bowser_init(void) {
bowserCutsceneGlobalIndex = UNKNOWN_GLOBAL_INDEX;
o->oAction = 20; // bowser_act_nothing
}
if (!sync_object_is_initialized(o->oSyncID)) {
struct SyncObject* so = sync_object_init(o, 8000.0f);
if (so) {

View file

@ -53,15 +53,13 @@ void bhv_camera_lakitu_init(void) {
sync_object_init_field(o, o->oCameraLakituFinishedDialog);
sync_object_init_field(o, o->oCameraLakituPitchVel);
#ifndef VERSION_JP
sync_object_init_field(o, o->oCameraLakituUnk104);
sync_object_init_field(o, o->oCameraLakituMusicPlayed);
#endif
}
}
}
static u8 camera_lakitu_intro_act_trigger_cutscene_continue_dialog(void) {
return (o->oAction == CAMERA_LAKITU_INTRO_ACT_TRIGGER_CUTSCENE);
}
u8 camera_lakitu_intro_act_show_dialog_continue_dialog(void) { return o->oCameraLakituFinishedDialog != TRUE; }
/**
* Wait for mario to stand on the bridge, then interrupt his action and enter
@ -77,21 +75,18 @@ static void camera_lakitu_intro_act_trigger_cutscene(void) {
if (player->oPosX > -544.0f && player->oPosX < 545.0f && player->oPosY > 800.0f
&& player->oPosZ > -2000.0f && player->oPosZ < -177.0f)
{
if (should_start_or_continue_dialog(marioState, o) && set_mario_npc_dialog(&gMarioStates[0], 2, camera_lakitu_intro_act_trigger_cutscene_continue_dialog) == 1) {
if (should_start_or_continue_dialog(marioState, o) && set_mario_npc_dialog(&gMarioStates[0], 2, camera_lakitu_intro_act_show_dialog_continue_dialog) == 1) {
o->oAction = CAMERA_LAKITU_INTRO_ACT_SPAWN_CLOUD;
}
}
}
static u8 camera_lakitu_intro_act_spawn_cloud_continue_dialog(void) {
return (o->oAction == CAMERA_LAKITU_INTRO_ACT_SPAWN_CLOUD);
}
/**
* Warp up into the air and spawn cloud, then enter the TODO action.
*/
static void camera_lakitu_intro_act_spawn_cloud(void) {
struct MarioState* marioState = nearest_mario_state_to_object(o);
if (marioState && should_start_or_continue_dialog(marioState, o) && set_mario_npc_dialog(&gMarioStates[0], 2, camera_lakitu_intro_act_spawn_cloud_continue_dialog) == 2) {
if (marioState && should_start_or_continue_dialog(marioState, o) && set_mario_npc_dialog(&gMarioStates[0], 2, camera_lakitu_intro_act_show_dialog_continue_dialog) == 2) {
o->oAction = CAMERA_LAKITU_INTRO_ACT_UNK2;
o->oPosX = 1800.0f;
@ -106,8 +101,6 @@ static void camera_lakitu_intro_act_spawn_cloud(void) {
}
}
u8 camera_lakitu_intro_act_show_dialog_continue_dialog(void) { return o->oCameraLakituFinishedDialog != TRUE; }
/**
* Circle down to mario, show the dialog, then fly away.
*/
@ -131,6 +124,8 @@ static void camera_lakitu_intro_act_show_dialog(void) {
}
o->oFaceAngleYaw = angleToPlayer;
should_start_or_continue_dialog(marioState, o);
// After finishing dialog, fly away and despawn
if (o->oCameraLakituFinishedDialog) {
approach_f32_ptr(&o->oCameraLakituSpeed, 60.0f, 3.0f);
@ -167,9 +162,9 @@ static void camera_lakitu_intro_act_show_dialog(void) {
approach_f32_ptr(&o->oCameraLakituCircleRadius, 200.0f, 50.0f);
if (distanceToPlayer < 1000.0f) {
#ifndef VERSION_JP
if (!o->oCameraLakituUnk104) {
if (!o->oCameraLakituMusicPlayed) {
play_music(SEQ_PLAYER_LEVEL, SEQUENCE_ARGS(15, SEQ_EVENT_CUTSCENE_LAKITU), 0);
o->oCameraLakituUnk104 = TRUE;
o->oCameraLakituMusicPlayed = TRUE;
}
#endif

View file

@ -91,7 +91,7 @@ void bhv_star_spawn_init(void) {
o->oForwardVel = o->oStarSpawnDisFromHome / 30.0f;
o->oStarSpawnUnkFC = o->oPosY;
if (o->oStarSpawnExtCutsceneFlags && ((gMarioStates[0].action & ACT_GROUP_MASK) != ACT_GROUP_CUTSCENE)) {
if (o->oStarSpawnExtCutsceneFlags) {
if (o->oBehParams2ndByte == 0 || gCurrCourseNum == COURSE_BBH)
cutscene_object(CUTSCENE_STAR_SPAWN, o);
else

View file

@ -531,7 +531,7 @@ void ukiki_free_loop(void) {
*
* Possibly unused so AnimState could be used for wearing a cap?
*/
static void ukiki_blink_timer(void) {
UNUSED static void ukiki_blink_timer(void) {
if (gGlobalTimer % 50 < 7) {
o->oAnimState = UKIKI_ANIM_STATE_EYE_CLOSED;
} else {

View file

@ -48,7 +48,9 @@ void bhv_jet_stream_water_ring_init(void) {
// sp2c = ringManager
void water_ring_check_collection(f32 avgScale, struct Object *ringManager) {
struct Object* player = nearest_player_to_object(o);
struct MarioState* marioState = nearest_mario_state_to_object(o);
if (!marioState) { return; }
struct Object* player = marioState->marioObj;
if (!player) { return; }
f32 marioDistInFront = water_ring_calc_mario_dist();
struct Object *ringSpawner;
@ -75,6 +77,9 @@ void water_ring_check_collection(f32 avgScale, struct Object *ringManager) {
+ (((u8) ringSpawner->oWaterRingSpawnerRingsCollected - 1) << 16),
gGlobalSoundSource);
#endif
if (ringSpawner->oWaterRingSpawnerRingsCollected == 5) {
ringSpawner->globalPlayerIndex = gNetworkPlayers[marioState->playerIndex].globalIndex;
}
}
ringManager->oWaterRingMgrLastRingCollected = o->oWaterRingIndex;
@ -196,7 +201,7 @@ void bhv_jet_stream_ring_spawner_loop(void) {
case JS_RING_SPAWNER_ACT_ACTIVE:
water_ring_spawner_act_inactive();
if (o->oWaterRingSpawnerRingsCollected == 5) {
if (o->oWaterRingSpawnerRingsCollected == 5 && o->globalPlayerIndex == gNetworkPlayerLocal->globalIndex) {
spawn_mist_particles();
f32* starPos = gLevelValues.starPositions.JetstreamRingStarPos;

View file

@ -4,48 +4,69 @@
// Note that this doesn't contain the Y coordinate since the castle roof is flat,
// so o->oHomeY is never updated.
static s16 sYoshiHomeLocations[] = { 0, -5625, -1364, -5912, -1403, -4609, -1004, -5308 };
static s16 sYoshiRespawnPos[] = { -12406, 1076, -8567 };
static u8 sYoshiRespawnDuration = 2 * 30;
static u8 sYoshiTalkingState = 0;
static bool sYoshiNeeded = false;
extern void push_mario_out_of_object(struct MarioState *m, struct Object *o, f32 padding);
static u8 yoshi_talk_loop_continue_dialog(void) {
return sYoshiTalkingState == 0;
return sYoshiTalkingState == 0 || sYoshiTalkingState == 1;
}
void bhv_yoshi_override_ownership(u8* shouldOverride, u8* shouldOwn) {
*shouldOverride = o->oAction == YOSHI_ACT_TALK;
*shouldOwn = false;
if (*shouldOverride) {
*shouldOwn = (gNetworkPlayerLocal->globalIndex == o->globalPlayerIndex);
}
}
void bhv_yoshi_init(void) {
sOverrideYoshiAlive = false;
sYoshiTalkingState = 0;
o->oGravity = 2.0f;
o->oFriction = 0.9f;
o->oBuoyancy = 1.3f;
o->oInteractionSubtype = INT_SUBTYPE_NPC;
if (save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_MIN - 1, COURSE_MAX - 1) < 120
|| sYoshiDead == TRUE) {
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
if (save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_MIN - 1, COURSE_MAX - 1) < 120) {
o->oAction = YOSHI_ACT_GONE;
}
sync_object_init(o, 4000.0f);
sync_object_init_field(o, o->oYoshiBlinkTimer);
sync_object_init_field(o, o->oYoshiChosenHome);
sync_object_init_field(o, o->oYoshiTargetYaw);
sync_object_init_field(o, o->oHomeX);
sync_object_init_field(o, o->oHomeY);
sync_object_init_field(o, o->oHomeZ);
struct SyncObject* so = sync_object_init(o, 4000.0f);
if (so != NULL) {
so->override_ownership = bhv_yoshi_override_ownership;
sync_object_init_field(o, o->oYoshiBlinkTimer);
sync_object_init_field(o, o->oYoshiChosenHome);
sync_object_init_field(o, o->oYoshiTargetYaw);
sync_object_init_field(o, o->oHomeX);
sync_object_init_field(o, o->oHomeY);
sync_object_init_field(o, o->oHomeZ);
sync_object_init_field(o, o->oAction);
sync_object_init_field(o, o->globalPlayerIndex);
}
}
void yoshi_walk_loop(void) {
UNUSED s16 sp26;
s16 sp24 = o->header.gfx.animInfo.animFrame;
sYoshiTalkingState = 0;
cur_obj_become_tangible();
s16 animFrame = o->header.gfx.animInfo.animFrame;
o->oForwardVel = 10.0f;
sp26 = object_step();
object_step();
o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, o->oYoshiTargetYaw, 0x500);
if (is_point_close_to_object(o, o->oHomeX, 3174.0f, o->oHomeZ, 200))
o->oAction = YOSHI_ACT_IDLE;
cur_obj_init_animation(1);
if (sp24 == 0 || sp24 == 15)
if (animFrame == 0 || animFrame == 15)
cur_obj_play_sound_2(SOUND_GENERAL_YOSHI_WALK);
if (o->oInteractStatus == INT_STATUS_INTERACTED && sYoshiTalkingState == 0) {
if (o->oInteractStatus == INT_STATUS_INTERACTED) {
struct MarioState* marioState = nearest_mario_state_to_object(o);
o->globalPlayerIndex = gNetworkPlayers[marioState->playerIndex].globalIndex;
o->oAction = YOSHI_ACT_TALK;
}
@ -56,8 +77,9 @@ void yoshi_walk_loop(void) {
}
void yoshi_idle_loop(void) {
sYoshiTalkingState = 0;
cur_obj_become_tangible();
s16 chosenHome;
UNUSED s16 sp1C = o->header.gfx.animInfo.animFrame;
if (o->oTimer > 90) {
chosenHome = random_float() * 3.99;
@ -75,7 +97,9 @@ void yoshi_idle_loop(void) {
}
cur_obj_init_animation(0);
if (o->oInteractStatus == INT_STATUS_INTERACTED && sYoshiTalkingState == 0) {
if (o->oInteractStatus == INT_STATUS_INTERACTED) {
struct MarioState* marioState = nearest_mario_state_to_object(o);
o->globalPlayerIndex = gNetworkPlayers[marioState->playerIndex].globalIndex;
o->oAction = YOSHI_ACT_TALK;
}
@ -91,32 +115,50 @@ void yoshi_idle_loop(void) {
}
void yoshi_talk_loop(void) {
struct MarioState* marioState = nearest_mario_state_to_object(o);
cur_obj_become_intangible();
sYoshiTalkingState = 1;
push_mario_out_of_object(&gMarioStates[0], o, -10.0f);
struct NetworkPlayer* np = network_player_from_global_index(o->globalPlayerIndex);
struct MarioState* marioState = &gMarioStates[np->localIndex];
struct Object* player = marioState ? marioState->marioObj : NULL;
s32 angleToPlayer = player ? obj_angle_to_object(o, player) : 0;
if (marioState != &gMarioStates[0]) {
if (np->localIndex != 0) {
cur_obj_init_animation((s16) o->oMoveAngleYaw == angleToPlayer ? 0 : 1);
return;
}
if ((s16) o->oMoveAngleYaw == angleToPlayer) {
if (sYoshiTalkingState == 0) {
play_puzzle_jingle();
sYoshiTalkingState = 1;
cur_obj_init_animation(0);
if (set_mario_npc_dialog(&gMarioStates[0], 1, yoshi_talk_loop_continue_dialog) == 2) {
if (cutscene_object_with_dialog(CUTSCENE_DIALOG, o, gBehaviorValues.dialogs.YoshiDialog)) {
o->oInteractStatus = 0;
o->oHomeX = sYoshiHomeLocations[2];
o->oHomeZ = sYoshiHomeLocations[3];
o->oYoshiTargetYaw = atan2s(o->oHomeZ - o->oPosZ, o->oHomeX - o->oPosX);
o->oAction = YOSHI_ACT_GIVE_PRESENT;
}
}
} else {
cur_obj_init_animation(1);
play_puzzle_jingle();
o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, angleToPlayer, 0x500);
}
}
void yoshi_walk_and_jump_off_roof_loop(void) {
s16 sp26 = o->header.gfx.animInfo.animFrame;
push_mario_out_of_object(&gMarioStates[0], o, -10.0f);
cur_obj_become_intangible();
s16 animFrame = o->header.gfx.animInfo.animFrame;
o->oForwardVel = 10.0f;
object_step();
cur_obj_init_animation(1);
if (o->oTimer == 0)
if (o->oTimer == 0
&& o->globalPlayerIndex == gNetworkPlayerLocal->globalIndex
&& gMarioStates[0].interactObj == o
&& (gMarioStates[0].action == ACT_READING_NPC_DIALOG
|| gMarioStates[0].action == ACT_WAITING_FOR_DIALOG))
cutscene_object(CUTSCENE_STAR_SPAWN, o);
o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, o->oYoshiTargetYaw, 0x500);
@ -129,36 +171,101 @@ void yoshi_walk_and_jump_off_roof_loop(void) {
o->oAction = YOSHI_ACT_FINISH_JUMPING_AND_DESPAWN;
}
if (sp26 == 0 || sp26 == 15) {
if (animFrame == 0 || animFrame == 15) {
cur_obj_play_sound_2(SOUND_GENERAL_YOSHI_WALK);
}
}
void yoshi_finish_jumping_and_despawn_loop(void) {
push_mario_out_of_object(&gMarioStates[0], o, -10.0f);
cur_obj_become_intangible();
cur_obj_extend_animation_if_at_end();
obj_move_xyz_using_fvel_and_yaw(o);
o->oVelY -= 2.0;
if (o->oPosY < 2100.0f) {
set_mario_npc_dialog(&gMarioStates[0], 0, yoshi_talk_loop_continue_dialog);
sYoshiTalkingState = 2;
gObjCutsceneDone = TRUE;
sYoshiDead = TRUE;
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
o->oAction = YOSHI_ACT_GONE;
}
}
void yoshi_give_present_loop(void) {
s32 sp1C = gGlobalTimer;
cur_obj_become_intangible();
push_mario_out_of_object(&gMarioStates[0], o, -10.0f);
if (gNetworkPlayerLocal->globalIndex == o->globalPlayerIndex) {
if (gHudDisplay.lives == 100) {
play_sound(SOUND_GENERAL_COLLECT_1UP, gGlobalSoundSource);
gMarioStates[0].specialTripleJump = true;
if (sYoshiNeeded) {
sYoshiTalkingState = 2;
o->oAction = YOSHI_ACT_IDLE;
} else {
o->oAction = YOSHI_ACT_WALK_JUMP_OFF_ROOF;
}
return;
}
if (gHudDisplay.lives == 100) {
play_sound(SOUND_GENERAL_COLLECT_1UP, gGlobalSoundSource);
gMarioStates[0].specialTripleJump = true;
o->oAction = YOSHI_ACT_WALK_JUMP_OFF_ROOF;
if ((gGlobalTimer & 0x03) == 0) {
play_sound(SOUND_MENU_YOSHI_GAIN_LIVES, gGlobalSoundSource);
gMarioState->numLives++;
}
}
}
void yoshi_gone(void) {
cur_obj_become_intangible();
cur_obj_hide();
}
void yoshi_reappear(void) {
if (gCurrLevelNum != LEVEL_CASTLE_GROUNDS || !dynos_level_is_vanilla_level(gCurrLevelNum)) {
o->oHomeX = sYoshiHomeLocations[2];
o->oHomeY = 3174.0f;
o->oHomeZ = sYoshiHomeLocations[3];
o->oPosX = o->oHomeX;
o->oPosY = o->oHomeY;
o->oPosZ = o->oHomeZ;
o->oForwardVel = 0.0f;
o->oVelY = 0.0f;
cur_obj_init_animation(0);
spawn_mist_particles();
cur_obj_play_sound_2(SOUND_GENERAL_YOSHI_WALK);
o->oAction = YOSHI_ACT_IDLE;
return;
}
if ((sp1C & 0x03) == 0) {
play_sound(SOUND_MENU_YOSHI_GAIN_LIVES, gGlobalSoundSource);
gMarioState->numLives++;
u8 decAmount = 4;
if (o->oTimer == 0) {
o->oHomeX = sYoshiHomeLocations[2];
o->oHomeY = 3174.0f;
o->oHomeZ = sYoshiHomeLocations[3];
o->oPosX = sYoshiRespawnPos[0];
o->oPosY = sYoshiRespawnPos[1];
o->oPosZ = sYoshiRespawnPos[2];
cur_obj_init_animation(2);
cur_obj_play_sound_2(SOUND_GENERAL_ENEMY_ALERT1);
spawn_mist_particles();
o->oVelY = 160;
}
s16 dx = o->oHomeX - sYoshiRespawnPos[0];
s16 dz = o->oHomeZ - sYoshiRespawnPos[2];
s16 distXZ = sqrtf(dx * dx + dz * dz);
o->oForwardVel = distXZ / sYoshiRespawnDuration;
o->oVelY -= decAmount;
o->oMoveAngleYaw = cur_obj_angle_to_home();
obj_move_xyz_using_fvel_and_yaw(o);
cur_obj_extend_animation_if_at_end();
if (o->oPosY < o->oHomeY && o->oVelY < 0) { o->oPosY = o->oHomeY; }
if (o->oTimer >= sYoshiRespawnDuration) {
o->oPosX = o->oHomeX;
o->oPosY = 3174.0f;
o->oPosZ = o->oHomeZ;
cur_obj_init_animation(0);
spawn_mist_particles();
cur_obj_play_sound_2(SOUND_GENERAL_YOSHI_WALK);
o->oForwardVel = 0.0f;
o->oVelY = 0.0f;
o->oAction = YOSHI_ACT_IDLE;
}
}
@ -188,58 +295,56 @@ void bhv_yoshi_loop(void) {
yoshi_give_present_loop();
break;
case YOSHI_ACT_GONE:
yoshi_gone();
break;
case YOSHI_ACT_REAPPEAR:
yoshi_reappear();
break;
case YOSHI_ACT_CREDITS:
cur_obj_init_animation(0);
break;
}
switch (sYoshiTalkingState) {
case 1:
cur_obj_init_animation(0);
if (set_mario_npc_dialog(&gMarioStates[0], 1, yoshi_talk_loop_continue_dialog) == 2) {
sYoshiTalkingState = 2;
}
break;
case 2:
if (cutscene_object_with_dialog(CUTSCENE_DIALOG, o, gBehaviorValues.dialogs.YoshiDialog)) {
sYoshiTalkingState = 3;
o->oInteractStatus = 0;
o->oHomeX = sYoshiHomeLocations[2];
o->oHomeZ = sYoshiHomeLocations[3];
o->oYoshiTargetYaw = atan2s(o->oHomeZ - o->oPosZ, o->oHomeX - o->oPosX);
o->oAction = YOSHI_ACT_WALK;
}
break;
case 3:
o->oInteractStatus = 0;
break;
default:
break;
// sanity check reading dialog
if (gMarioStates[0].interactObj == o
&& gNetworkPlayerLocal->globalIndex != o->globalPlayerIndex
&& o->oAction != YOSHI_ACT_IDLE
&& o->oAction != YOSHI_ACT_WALK
&& (gMarioStates[0].action == ACT_READING_NPC_DIALOG
|| gMarioStates[0].action == ACT_WAITING_FOR_DIALOG)) {
set_mario_action(&gMarioStates[0], ACT_IDLE, 0);
}
if (sYoshiTalkingState > 0) {
extern void push_mario_out_of_object(struct MarioState *m, struct Object *o, f32 padding);
push_mario_out_of_object(&gMarioStates[0], o, -10.0f);
}
if (sYoshiTalkingState > 2) {
if (gHudDisplay.lives >= 100) {
gMarioStates[0].specialTripleJump = true;
sYoshiTalkingState = 3;
} else if ((gGlobalTimer & 0x03) == 0) {
play_sound(SOUND_MENU_YOSHI_GAIN_LIVES, gGlobalSoundSource);
gMarioStates[0].numLives++;
if (sOverrideYoshiAlive) {
sYoshiNeeded = true;
} else if (save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_MIN - 1, COURSE_MAX - 1) < 120) {
sYoshiNeeded = false;
} else {
sYoshiNeeded = false;
for (u8 i = 0; i < MAX_PLAYERS; i++) {
if (gNetworkPlayers[i].currLevelNum == LEVEL_CASTLE_GROUNDS && !gMarioStates[i].specialTripleJump) {
sYoshiNeeded = true;
break;
}
}
}
if (gMarioStates[0].action == ACT_WAITING_FOR_DIALOG) {
if (gMarioStates[0].interactObj == o) {
set_mario_action(&gMarioStates[0], ACT_IDLE, 0);
o->oInteractStatus = 0;
}
if (!sYoshiNeeded
&& o->oAction != YOSHI_ACT_GONE
&& o->oAction != YOSHI_ACT_WALK_JUMP_OFF_ROOF
&& o->oAction != YOSHI_ACT_FINISH_JUMPING_AND_DESPAWN
&& o->oAction != YOSHI_ACT_REAPPEAR) {
o->oAction = YOSHI_ACT_WALK_JUMP_OFF_ROOF;
} else if (sYoshiNeeded && o->oAction == YOSHI_ACT_GONE) {
o->oAction = YOSHI_ACT_REAPPEAR;
}
if (o->oAction != YOSHI_ACT_GONE) {
cur_obj_unhide();
}
curr_obj_random_blink(&o->oYoshiBlinkTimer);
}

View file

@ -1938,7 +1938,6 @@ s32 lvl_init_from_save_file(UNUSED s16 arg0, s16 levelNum) {
disable_warp_checkpoint();
save_file_move_cap_to_default_location();
select_mario_cam_mode();
set_yoshi_as_not_dead();
return levelNum;
}
@ -2028,7 +2027,6 @@ void fake_lvl_init_from_save_file(void) {
disable_warp_checkpoint();
save_file_move_cap_to_default_location();
select_mario_cam_mode();
set_yoshi_as_not_dead();
fadeout_music(30);
gChangeLevel = gLevelValues.entryLevel;

View file

@ -236,13 +236,6 @@ s32 geo_switch_peach_eyes(s32 run, struct GraphNode *node, UNUSED s32 a2) {
return 0;
}
// unused
static void stub_is_textbox_active(u16 *a0) {
if (get_dialog_id() == DIALOG_NONE) {
*a0 = 0;
}
}
/**
* get_star_collection_dialog: Determine what dialog should show when Mario
* collects a star.
@ -1278,6 +1271,7 @@ s32 act_spawn_spin_airborne(struct MarioState *m) {
if (m == &gMarioStates[0]) {
load_level_init_text(0);
}
m->freeze = 2;
return set_water_plunge_action(m);
}
@ -1310,6 +1304,7 @@ s32 act_spawn_spin_landing(struct MarioState *m) {
if (m == &gMarioStates[0]) {
load_level_init_text(0);
}
m->freeze = 2;
set_mario_action(m, ACT_IDLE, 0);
}
return FALSE;
@ -1562,6 +1557,7 @@ s32 act_spawn_no_spin_landing(struct MarioState *m) {
if (m == &gMarioStates[0]) {
load_level_init_text(0);
}
m->freeze = 2;
set_mario_action(m, ACT_IDLE, 0);
}
return FALSE;
@ -2191,7 +2187,7 @@ static s32 act_intro_cutscene(struct MarioState *m) {
return FALSE;
}
static void jumbo_star_offset(struct MarioState* m) {
UNUSED static void jumbo_star_offset(struct MarioState* m) {
if (!m) { return; }
m->pos[0] += 300.0f * sins(m->faceAngle[1] + 0x4000 * m->playerIndex);
m->pos[2] += 300.0f * coss(m->faceAngle[1] + 0x4000 * m->playerIndex);

View file

@ -73,13 +73,13 @@ static s8 sOrientObjWithFloor = TRUE;
s16 sPrevCheckMarioRoom = 0;
/**
* Tracks whether or not Yoshi has walked/jumped off the roof.
* Override for whether or not Yoshi has walked/jumped off the roof.
*/
s8 sYoshiDead = FALSE;
s8 sOverrideYoshiAlive = FALSE;
/* |description|Resets Yoshi as being alive|descriptionEnd| */
/* |description|Marks Yoshi as alive|descriptionEnd| */
void set_yoshi_as_not_dead(void) {
sYoshiDead = FALSE;
sOverrideYoshiAlive = FALSE;
}
/**

View file

@ -1736,11 +1736,11 @@ static struct LuaObjectField sObjectFields[LUA_OBJECT_FIELD_COUNT] = {
{ "oCameraLakituBlinkTimer", LVT_S32, offsetof(struct Object, oCameraLakituBlinkTimer), false, LOT_NONE, 1, sizeof(s32) },
{ "oCameraLakituCircleRadius", LVT_F32, offsetof(struct Object, oCameraLakituCircleRadius), false, LOT_NONE, 1, sizeof(f32) },
{ "oCameraLakituFinishedDialog", LVT_S32, offsetof(struct Object, oCameraLakituFinishedDialog), false, LOT_NONE, 1, sizeof(s32) },
#ifndef VERSION_JP
{ "oCameraLakituMusicPlayed", LVT_S32, offsetof(struct Object, oCameraLakituMusicPlayed), false, LOT_NONE, 1, sizeof(s32) },
#endif
{ "oCameraLakituPitchVel", LVT_S16, offsetof(struct Object, oCameraLakituPitchVel), false, LOT_NONE, 1, sizeof(s16) },
{ "oCameraLakituSpeed", LVT_F32, offsetof(struct Object, oCameraLakituSpeed), false, LOT_NONE, 1, sizeof(f32) },
#ifndef VERSION_JP
{ "oCameraLakituUnk104", LVT_S32, offsetof(struct Object, oCameraLakituUnk104), false, LOT_NONE, 1, sizeof(s32) },
#endif
{ "oCameraLakituYawVel", LVT_S16, offsetof(struct Object, oCameraLakituYawVel), false, LOT_NONE, 1, sizeof(s16) },
{ "oCannonBarrelBubblesUnkF4", LVT_F32, offsetof(struct Object, oCannonBarrelBubblesUnkF4), false, LOT_NONE, 1, sizeof(f32) },
{ "oCannonPlayerIndex", LVT_S32, offsetof(struct Object, oCannonPlayerIndex), false, LOT_NONE, 1, sizeof(s32) },

View file

@ -2632,6 +2632,8 @@ char gSmluaConstants[] = ""
"YOSHI_ACT_WALK_JUMP_OFF_ROOF=3\n"
"YOSHI_ACT_FINISH_JUMPING_AND_DESPAWN=4\n"
"YOSHI_ACT_GIVE_PRESENT=5\n"
"YOSHI_ACT_GONE=6\n"
"YOSHI_ACT_REAPPEAR=7\n"
"YOSHI_ACT_CREDITS=10\n"
"KOOPA_UNSHELLED_ACT_RUN=0\n"
"KOOPA_UNSHELLED_ACT_DIVE=1\n"

View file

@ -18017,6 +18017,26 @@ int smlua_func_stuck_in_ground_handler(lua_State* L) {
return 1;
}
/*
int smlua_func_jumbo_star_offset(lua_State* L) {
if (L == NULL) { return 0; }
int top = lua_gettop(L);
if (top != 1) {
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "jumbo_star_offset", 1, top);
return 0;
}
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIOSTATE);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "jumbo_star_offset"); return 0; }
extern UNUSED static void jumbo_star_offset(struct MarioState* m);
UNIMPLEMENTED -->(L, jumbo_star_offset(m));
return 1;
}
*/
int smlua_func_generate_yellow_sparkles(lua_State* L) {
if (L == NULL) { return 0; }
@ -37921,6 +37941,7 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "common_death_handler", smlua_func_common_death_handler);
smlua_bind_function(L, "launch_mario_until_land", smlua_func_launch_mario_until_land);
smlua_bind_function(L, "stuck_in_ground_handler", smlua_func_stuck_in_ground_handler);
//smlua_bind_function(L, "jumbo_star_offset", smlua_func_jumbo_star_offset); <--- UNIMPLEMENTED
smlua_bind_function(L, "generate_yellow_sparkles", smlua_func_generate_yellow_sparkles);
smlua_bind_function(L, "mario_execute_cutscene_action", smlua_func_mario_execute_cutscene_action);

View file

@ -4,6 +4,7 @@
#include "game/interaction.h"
#include "game/level_update.h"
#include "game/ingame_menu.h"
#include "course_table.h"
#include "behavior_table.h"
#include "object_constants.h"
#include "object_fields.h"
@ -79,7 +80,9 @@ void network_receive_level(struct Packet* p) {
packet_read(p, &gMarioStates[0].numCoins, sizeof(s16));
packet_read(p, &gPssSlideStarted, sizeof(u8));
packet_read(p, &gTTCSpeedSetting, sizeof(s16));
gHudDisplay.coins = gMarioStates[0].numCoins;
if (gCurrCourseNum != COURSE_NONE) {
gHudDisplay.coins = gMarioStates[0].numCoins;
}
// fix TTC objects by reinitializing values pertaining to speed
if (levelNum == LEVEL_TTC) {

View file

@ -50,6 +50,7 @@ struct PacketPlayerData {
u8 framesSinceB;
u8 wallKickTimer;
u8 doubleJumpTimer;
u8 specialTripleJump;
Vec3s faceAngle;
Vec3s angleVel;
s16 slideYaw;
@ -120,6 +121,7 @@ static void read_packet_data(struct PacketPlayerData* data, struct MarioState* m
data->framesSinceB = m->framesSinceB;
data->wallKickTimer = m->wallKickTimer;
data->doubleJumpTimer = m->doubleJumpTimer;
data->specialTripleJump = m->specialTripleJump;
memcpy(data->faceAngle, m->faceAngle, sizeof(s16) * 3);
memcpy(data->angleVel, m->angleVel, sizeof(s16) * 3);
data->slideYaw = m->slideYaw;
@ -185,6 +187,7 @@ static void write_packet_data(struct PacketPlayerData* data, struct MarioState*
m->framesSinceB = data->framesSinceB;
m->wallKickTimer = data->wallKickTimer;
m->doubleJumpTimer = data->doubleJumpTimer;
m->specialTripleJump = data->specialTripleJump;
memcpy(m->faceAngle, data->faceAngle, sizeof(s16) * 3);
memcpy(m->angleVel, data->angleVel, sizeof(s16) * 3);
m->slideYaw = data->slideYaw;