Prevented hundreds of additional crashes from the Mod API

This commit is contained in:
MysterD 2023-05-11 13:05:06 -07:00
parent 82945f9c0f
commit cc1ec3e81f
30 changed files with 842 additions and 5647 deletions

View file

@ -61,6 +61,8 @@ OPT_LEVEL ?= -1
DEBUG_INFO_LEVEL ?= 2 DEBUG_INFO_LEVEL ?= 2
# Enable profiling # Enable profiling
PROFILE ?= 0 PROFILE ?= 0
# Enable address sanitizer
ASAN ?= 0
# Compile headless # Compile headless
HEADLESS ?= 0 HEADLESS ?= 0
# Enable Game ICON # Enable Game ICON
@ -949,6 +951,12 @@ ifeq ($(WINDOWS_BUILD),999)
endif endif
endif endif
ifeq ($(ASAN),1)
EXTRA_CFLAGS += -fsanitize=address -fsanitize=bounds-strict -fsanitize=undefined -ggdb
EXTRA_CPP_FLAGS += -fsanitize=address -fsanitize=bounds-strict -fsanitize=undefined -ggdb
LDFLAGS += -fsanitize=address -fsanitize=bounds-strict -fsanitize=undefined -static-libasan
endif
# Coop specific libraries # Coop specific libraries
# Zlib # Zlib

View file

@ -806,7 +806,7 @@ def output_fuzz_function(fname, function):
comment = ' -- ' comment = ' -- '
fid = function['identifier'] fid = function['identifier']
line = ' ' + fid + '(' line = ' function() return ' + fid + '('
for param in function['params']: for param in function['params']:
if first: if first:
@ -822,18 +822,13 @@ def output_fuzz_function(fname, function):
ptype = 'integer' ptype = 'integer'
line += 'rnd_' + ptype.strip().replace('`', '').replace(' ', '').split('<')[-1].split('>')[0].split('(')[0] + '()' line += 'rnd_' + ptype.strip().replace('`', '').replace(' ', '').split('<')[-1].split('>')[0].split('(')[0] + '()'
#if ptype == '`integer`' or ptype == '`number`' or 'enum' in ptype:
# print('0', end='')
#else:
# print('nil', end='')
comment += ptype comment += ptype
line += ')' line += ') end,\n'
if len(line) >= 80: #if len(line) >= 80:
line = line + '\n ' + comment + '\n' # line = line + '\n ' + comment + '\n'
else: #else:
line = line.ljust(80) + comment + '\n' # line = line.ljust(80) + comment + '\n'
global fuzz_functions global fuzz_functions
fuzz_functions += line fuzz_functions += line

View file

@ -50,7 +50,7 @@ end
-------- --------
function rnd_string() function rnd_string()
t = { 0, "test", "this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string" } t = { 0, "test", "this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string" }
return t[math.random(#t)] return t[math.random(#t)]
end end
@ -65,7 +65,7 @@ function rnd_number()
end end
function rnd_boolean() function rnd_boolean()
t = { nil, false, true } t = { false, true }
return t[math.random(#t)] return t[math.random(#t)]
end end
@ -100,12 +100,12 @@ function rnd_Object()
end end
function rnd_MarioState() function rnd_MarioState()
t = { nil, gMarioStates[math.random(0, MAX_PLAYERS)] } t = { nil, gMarioStates[0], gMarioStates[math.random(0, MAX_PLAYERS)] }
return t[math.random(#t)] return t[math.random(#t)]
end end
function rnd_NetworkPlayer() function rnd_NetworkPlayer()
t = { nil, gNetworkPlayers[math.random(0, MAX_PLAYERS)] } t = { nil, gNetworkPlayers[0], gNetworkPlayers[math.random(0, MAX_PLAYERS)] }
return t[math.random(#t)] return t[math.random(#t)]
end end
@ -137,7 +137,18 @@ end
-------- --------
function fuzz_functions() function fuzz_functions()
local funcs = {
-- $[FUNCS] -- $[FUNCS]
}
for i = #funcs, 2, -1 do
local j = math.random(i)
funcs[i], funcs[j] = funcs[j], funcs[i]
end
for k,v in pairs(funcs) do
v()
end
end end
id_bhvFuncs = hook_behavior(nil, OBJ_LIST_DEFAULT, true, fuzz_functions, nil, 'id_bhvFuncs') id_bhvFuncs = hook_behavior(nil, OBJ_LIST_DEFAULT, true, fuzz_functions, nil, 'id_bhvFuncs')
@ -147,12 +158,33 @@ id_bhvFuncs = hook_behavior(nil, OBJ_LIST_DEFAULT, true, fuzz_functions, nil, 'i
function fuzz_structs() function fuzz_structs()
end end
function update() --------
local sCountDown = 0
local sLevel = 15
function on_sync_valid()
fuzz_functions() fuzz_functions()
for i=0,10 do
spawn_non_sync_object(id_bhvFuncs, E_MODEL_SPINY_BALL, 0, 0, 0, nil)
end
end
function update()
sCountDown = sCountDown - 1
if sCountDown <= 0 then
print('warping to ', sLevel)
warp_to_level(sLevel, 1, 1)
sLevel = sLevel + 1
if sLevel > LEVEL_COUNT then
sLevel = 0
end
sCountDown = 10
end
end end
hook_chat_command('fuzz-funcs', 'funcs', fuzz_functions) hook_chat_command('fuzz-funcs', 'funcs', fuzz_functions)
hook_chat_command('fuzz-structs', 'structs', fuzz_structs) hook_chat_command('fuzz-structs', 'structs', fuzz_structs)
hook_event(HOOK_UPDATE, update) hook_event(HOOK_UPDATE, update)
hook_event(HOOK_ON_SYNC_VALID, on_sync_valid)
spawn_non_sync_object(id_bhvFuncs, E_MODEL_SPINY_BALL, 0, 0, 0, nil) print('!')

View file

@ -238,7 +238,9 @@ const s32 *DynOS_Level_GetList() {
} }
s32 DynOS_Level_GetCourse(s32 aLevel) { s32 DynOS_Level_GetCourse(s32 aLevel) {
return (s32) gLevelToCourseNumTable[aLevel - 1]; u32 index = aLevel - 1;
if (index >= LEVEL_COUNT) { return COURSE_NONE; }
return (s32) gLevelToCourseNumTable[index];
} }
void DynOS_Level_Override(void* originalScript, void* newScript, s32 modIndex) { void DynOS_Level_Override(void* originalScript, void* newScript, s32 modIndex) {
@ -908,7 +910,7 @@ s16 *DynOS_Level_GetWarp(s32 aLevel, s32 aArea, u8 aWarpId) {
} }
DynOS_Level_Init(); DynOS_Level_Init();
if (aLevel < LEVEL_COUNT) { if (aLevel >= 0 && aLevel < LEVEL_COUNT) {
for (const auto &_Warp : sDynosLevelWarps[aLevel]) { for (const auto &_Warp : sDynosLevelWarps[aLevel]) {
if (_Warp.mArea == aArea) { if (_Warp.mArea == aArea) {
if (_Warp.mId == aWarpId) { if (_Warp.mId == aWarpId) {
@ -925,7 +927,7 @@ s16 *DynOS_Level_GetWarpEntry(s32 aLevel, s32 aArea) {
if (aLevel == LEVEL_TTM && aArea > 2) return NULL; if (aLevel == LEVEL_TTM && aArea > 2) return NULL;
// override vanilla castle warps // override vanilla castle warps
if (DynOS_Level_GetCourse(aLevel) == COURSE_NONE) { if (DynOS_Level_GetCourse(aLevel) == COURSE_NONE && aLevel >= 0 && aLevel < LEVEL_COUNT) {
extern const LevelScript level_castle_grounds_entry[]; extern const LevelScript level_castle_grounds_entry[];
extern const LevelScript level_castle_inside_entry[]; extern const LevelScript level_castle_inside_entry[];
extern const LevelScript level_castle_courtyard_entry[]; extern const LevelScript level_castle_courtyard_entry[];

View file

@ -2,9 +2,9 @@
set -e set -e
if [ $# -eq 0 ]; then if [ $# -eq 0 ]; then
make DEBUG=1 DEVELOPMENT=1 STRICT=1 -j make DEBUG=1 DEVELOPMENT=1 STRICT=1 ASAN=1 -j
else else
make DEBUG=1 DEVELOPMENT=1 -j make DEBUG=1 DEVELOPMENT=1 ASAN=1 -j
fi fi
# find file # find file

5582
grind.log

File diff suppressed because it is too large Load diff

View file

@ -453,7 +453,8 @@ OSPiHandle DriveRomHandle; // used in osDriveRomInit.c. Why here?
s8 D_SH_80343E48_pad[0x8]; s8 D_SH_80343E48_pad[0x8];
#endif #endif
struct Sound sSoundRequests[0x100] = { 0 }; #define MAX_SOUND_REQUESTS 0x100
struct Sound sSoundRequests[MAX_SOUND_REQUESTS] = { 0 };
struct ChannelVolumeScaleFade sVolumeScaleFades[SEQUENCE_PLAYERS][CHANNELS_MAX] = { 0 }; struct ChannelVolumeScaleFade sVolumeScaleFades[SEQUENCE_PLAYERS][CHANNELS_MAX] = { 0 };
u8 sUsedChannelsForSoundBank[SOUND_BANK_COUNT] = { 0 }; u8 sUsedChannelsForSoundBank[SOUND_BANK_COUNT] = { 0 };
u8 sCurrentSound[SOUND_BANK_COUNT][MAX_CHANNELS_PER_SOUND_BANK] = { 0 }; // index into sSoundBanks u8 sCurrentSound[SOUND_BANK_COUNT][MAX_CHANNELS_PER_SOUND_BANK] = { 0 }; // index into sSoundBanks
@ -669,6 +670,7 @@ void audio_reset_session_eu(s32 presetId) {
* Called from threads: thread3_main, thread5_game_loop * Called from threads: thread3_main, thread5_game_loop
*/ */
static void seq_player_fade_to_zero_volume(s32 player, FadeT fadeDuration) { static void seq_player_fade_to_zero_volume(s32 player, FadeT fadeDuration) {
if (player >= SEQUENCE_PLAYERS) { return; }
struct SequencePlayer *seqPlayer = &gSequencePlayers[player]; struct SequencePlayer *seqPlayer = &gSequencePlayers[player];
#ifndef VERSION_JP #ifndef VERSION_JP
@ -687,6 +689,7 @@ static void seq_player_fade_to_zero_volume(s32 player, FadeT fadeDuration) {
* Called from threads: thread4_sound, thread5_game_loop * Called from threads: thread4_sound, thread5_game_loop
*/ */
static void seq_player_fade_from_zero_volume(s32 player, FadeT fadeInTime) { static void seq_player_fade_from_zero_volume(s32 player, FadeT fadeInTime) {
if (player >= SEQUENCE_PLAYERS) { return; }
struct SequencePlayer *seqPlayer = &gSequencePlayers[player]; struct SequencePlayer *seqPlayer = &gSequencePlayers[player];
if (fadeInTime == 0 || seqPlayer->state == SEQUENCE_PLAYER_STATE_FADE_OUT) { if (fadeInTime == 0 || seqPlayer->state == SEQUENCE_PLAYER_STATE_FADE_OUT) {
@ -704,6 +707,7 @@ static void seq_player_fade_from_zero_volume(s32 player, FadeT fadeInTime) {
* Called from threads: thread5_game_loop * Called from threads: thread5_game_loop
*/ */
static void seq_player_fade_to_percentage_of_volume(s32 player, FadeT fadeDuration, u8 percentage) { static void seq_player_fade_to_percentage_of_volume(s32 player, FadeT fadeDuration, u8 percentage) {
if (player >= SEQUENCE_PLAYERS) { return; }
struct SequencePlayer *seqPlayer = &gSequencePlayers[player]; struct SequencePlayer *seqPlayer = &gSequencePlayers[player];
f32 targetVolume; f32 targetVolume;
@ -739,6 +743,7 @@ static void seq_player_fade_to_percentage_of_volume(s32 player, FadeT fadeDurati
* Called from threads: thread3_main, thread4_sound, thread5_game_loop * Called from threads: thread3_main, thread4_sound, thread5_game_loop
*/ */
static void seq_player_fade_to_normal_volume(s32 player, FadeT fadeDuration) { static void seq_player_fade_to_normal_volume(s32 player, FadeT fadeDuration) {
if (player >= SEQUENCE_PLAYERS) { return; }
struct SequencePlayer *seqPlayer = &gSequencePlayers[player]; struct SequencePlayer *seqPlayer = &gSequencePlayers[player];
#if defined(VERSION_EU) || defined(VERSION_SH) #if defined(VERSION_EU) || defined(VERSION_SH)
@ -770,6 +775,7 @@ static void seq_player_fade_to_normal_volume(s32 player, FadeT fadeDuration) {
* Called from threads: thread3_main, thread4_sound, thread5_game_loop * Called from threads: thread3_main, thread4_sound, thread5_game_loop
*/ */
static void seq_player_fade_to_target_volume(s32 player, FadeT fadeDuration, u8 targetVolume) { static void seq_player_fade_to_target_volume(s32 player, FadeT fadeDuration, u8 targetVolume) {
if (player >= SEQUENCE_PLAYERS) { return; }
struct SequencePlayer *seqPlayer = &gSequencePlayers[player]; struct SequencePlayer *seqPlayer = &gSequencePlayers[player];
#if defined(VERSION_JP) || defined(VERSION_US) #if defined(VERSION_JP) || defined(VERSION_US)
@ -871,6 +877,7 @@ void play_sound_with_freq_scale(s32 soundBits, f32* pos, f32 freqScale) {
* Called from threads: thread4_sound, thread5_game_loop (EU only) * Called from threads: thread4_sound, thread5_game_loop (EU only)
*/ */
static void process_sound_request(u32 bits, f32 *pos, f32 freqScale) { static void process_sound_request(u32 bits, f32 *pos, f32 freqScale) {
if (!pos) { return; }
u8 bank; u8 bank;
u8 soundIndex; u8 soundIndex;
u8 counter = 0; u8 counter = 0;
@ -881,6 +888,8 @@ static void process_sound_request(u32 bits, f32 *pos, f32 freqScale) {
bank = (bits & SOUNDARGS_MASK_BANK) >> SOUNDARGS_SHIFT_BANK; bank = (bits & SOUNDARGS_MASK_BANK) >> SOUNDARGS_SHIFT_BANK;
soundId = (bits & SOUNDARGS_MASK_SOUNDID) >> SOUNDARGS_SHIFT_SOUNDID; soundId = (bits & SOUNDARGS_MASK_SOUNDID) >> SOUNDARGS_SHIFT_SOUNDID;
if (bank >= SOUND_BANK_COUNT) { return; }
if (soundId >= sNumSoundsPerBank[bank] || sSoundBankDisabled[bank]) { if (soundId >= sNumSoundsPerBank[bank] || sSoundBankDisabled[bank]) {
return; return;
} }
@ -975,6 +984,7 @@ static void process_all_sound_requests(void) {
* Called from threads: thread4_sound, thread5_game_loop (EU only) * Called from threads: thread4_sound, thread5_game_loop (EU only)
*/ */
static void delete_sound_from_bank(u8 bank, u8 soundIndex) { static void delete_sound_from_bank(u8 bank, u8 soundIndex) {
if (bank >= SOUND_BANK_COUNT || soundIndex >= SOUND_INDEX_COUNT) { return; }
if (sSoundBankUsedListBack[bank] == soundIndex) { if (sSoundBankUsedListBack[bank] == soundIndex) {
// Remove from end of used list // Remove from end of used list
sSoundBankUsedListBack[bank] = sSoundBanks[bank][soundIndex].prev; sSoundBankUsedListBack[bank] = sSoundBanks[bank][soundIndex].prev;
@ -997,6 +1007,7 @@ static void delete_sound_from_bank(u8 bank, u8 soundIndex) {
* Called from threads: thread3_main, thread4_sound, thread5_game_loop * Called from threads: thread3_main, thread4_sound, thread5_game_loop
*/ */
static void update_background_music_after_sound(u8 bank, u8 soundIndex) { static void update_background_music_after_sound(u8 bank, u8 soundIndex) {
if (bank >= SOUND_BANK_COUNT || soundIndex >= SOUND_INDEX_COUNT) { return; }
if (sSoundBanks[bank][soundIndex].soundBits & SOUND_LOWER_BACKGROUND_MUSIC) { if (sSoundBanks[bank][soundIndex].soundBits & SOUND_LOWER_BACKGROUND_MUSIC) {
sSoundBanksThatLowerBackgroundMusic &= (1 << bank) ^ 0xffff; sSoundBanksThatLowerBackgroundMusic &= (1 << bank) ^ 0xffff;
begin_background_music_fade(50); begin_background_music_fade(50);
@ -1007,6 +1018,7 @@ static void update_background_music_after_sound(u8 bank, u8 soundIndex) {
* Called from threads: thread4_sound, thread5_game_loop (EU only) * Called from threads: thread4_sound, thread5_game_loop (EU only)
*/ */
static void select_current_sounds(u8 bank) { static void select_current_sounds(u8 bank) {
if (bank >= SOUND_BANK_COUNT) { return; }
u32 isDiscreteAndStatus; u32 isDiscreteAndStatus;
u8 latestSoundIndex; u8 latestSoundIndex;
u8 i; u8 i;
@ -1252,6 +1264,7 @@ f32 get_sound_pan(f32 x, f32 z) {
* Called from threads: thread4_sound, thread5_game_loop (EU only) * Called from threads: thread4_sound, thread5_game_loop (EU only)
*/ */
static f32 get_sound_volume(u8 bank, u8 soundIndex, f32 volumeRange) { static f32 get_sound_volume(u8 bank, u8 soundIndex, f32 volumeRange) {
if (bank >= SOUND_BANK_COUNT || soundIndex >= SOUND_INDEX_COUNT) { return 0; }
f32 maxSoundDistance; f32 maxSoundDistance;
f32 intensity; f32 intensity;
#ifndef VERSION_JP #ifndef VERSION_JP
@ -1307,6 +1320,7 @@ static f32 get_sound_volume(u8 bank, u8 soundIndex, f32 volumeRange) {
* Called from threads: thread4_sound, thread5_game_loop (EU only) * Called from threads: thread4_sound, thread5_game_loop (EU only)
*/ */
static f32 get_sound_freq_scale(u8 bank, u8 item) { static f32 get_sound_freq_scale(u8 bank, u8 item) {
if (bank >= SOUND_BANK_COUNT || item >= SOUND_INDEX_COUNT) { return 0; }
f32 amount; f32 amount;
if (!(sSoundBanks[bank][item].soundBits & SOUND_CONSTANT_FREQUENCY)) { if (!(sSoundBanks[bank][item].soundBits & SOUND_CONSTANT_FREQUENCY)) {
@ -1327,6 +1341,7 @@ static f32 get_sound_freq_scale(u8 bank, u8 item) {
* Called from threads: thread4_sound, thread5_game_loop (EU only) * Called from threads: thread4_sound, thread5_game_loop (EU only)
*/ */
static u8 get_sound_reverb(UNUSED u8 bank, UNUSED u8 soundIndex, u8 channelIndex) { static u8 get_sound_reverb(UNUSED u8 bank, UNUSED u8 soundIndex, u8 channelIndex) {
if (bank >= SOUND_BANK_COUNT || soundIndex >= SOUND_INDEX_COUNT || channelIndex >= CHANNELS_MAX) { return 0; }
u8 area; u8 area;
u8 level; u8 level;
u8 reverb; u8 reverb;
@ -1808,6 +1823,7 @@ static void seq_player_play_sequence(u8 player, u8 seqId, u16 arg2) {
* Called from threads: thread5_game_loop * Called from threads: thread5_game_loop
*/ */
void seq_player_fade_out(u8 player, u16 fadeDuration) { void seq_player_fade_out(u8 player, u16 fadeDuration) {
if (player >= SEQUENCE_PLAYERS) { return; }
#if defined(VERSION_EU) || defined(VERSION_SH) #if defined(VERSION_EU) || defined(VERSION_SH)
#ifdef VERSION_EU #ifdef VERSION_EU
u32 fd = fadeDuration; u32 fd = fadeDuration;
@ -2059,6 +2075,7 @@ void unused_8031FED0(u8 player, u32 bits, s8 arg2) {
* Called from threads: thread5_game_loop * Called from threads: thread5_game_loop
*/ */
void seq_player_lower_volume(u8 player, u16 fadeDuration, u8 percentage) { void seq_player_lower_volume(u8 player, u16 fadeDuration, u8 percentage) {
if (player >= SEQUENCE_PLAYERS) { return; }
if (player == SEQ_PLAYER_LEVEL) { if (player == SEQ_PLAYER_LEVEL) {
sLowerBackgroundMusicVolume = TRUE; sLowerBackgroundMusicVolume = TRUE;
begin_background_music_fade(fadeDuration); begin_background_music_fade(fadeDuration);
@ -2076,6 +2093,7 @@ void seq_player_lower_volume(u8 player, u16 fadeDuration, u8 percentage) {
* Called from threads: thread5_game_loop * Called from threads: thread5_game_loop
*/ */
void seq_player_unlower_volume(u8 player, u16 fadeDuration) { void seq_player_unlower_volume(u8 player, u16 fadeDuration) {
if (player >= SEQUENCE_PLAYERS) { return; }
sLowerBackgroundMusicVolume = FALSE; sLowerBackgroundMusicVolume = FALSE;
if (player == SEQ_PLAYER_LEVEL) { if (player == SEQ_PLAYER_LEVEL) {
if (gSequencePlayers[player].state != SEQUENCE_PLAYER_STATE_FADE_OUT) { if (gSequencePlayers[player].state != SEQUENCE_PLAYER_STATE_FADE_OUT) {
@ -2170,7 +2188,7 @@ void sound_init(void) {
for (i = 0; i < SOUND_BANK_COUNT; i++) { for (i = 0; i < SOUND_BANK_COUNT; i++) {
// Set each sound in the bank to STOPPED // Set each sound in the bank to STOPPED
for (j = 0; j < 40; j++) { for (j = 0; j < SOUND_INDEX_COUNT; j++) {
sSoundBanks[i][j].soundStatus = SOUND_STATUS_STOPPED; sSoundBanks[i][j].soundStatus = SOUND_STATUS_STOPPED;
} }
@ -2198,7 +2216,7 @@ void sound_init(void) {
sSoundBanks[i][j].next = 0xff; sSoundBanks[i][j].next = 0xff;
} }
for (j = 0; j < 3; j++) { for (j = 0; j < SEQUENCE_PLAYERS; j++) {
for (i = 0; i < CHANNELS_MAX; i++) { for (i = 0; i < CHANNELS_MAX; i++) {
sVolumeScaleFades[j][i].remainingFrames = 0; sVolumeScaleFades[j][i].remainingFrames = 0;
} }
@ -2227,6 +2245,7 @@ void sound_init(void) {
// (unused) // (unused)
void get_currently_playing_sound(u8 bank, u8 *numPlayingSounds, u8 *numSoundsInBank, u8 *soundId) { void get_currently_playing_sound(u8 bank, u8 *numPlayingSounds, u8 *numSoundsInBank, u8 *soundId) {
if (bank >= SOUND_BANK_COUNT || !numPlayingSounds || !numSoundsInBank || !soundId) { return; }
u8 i; u8 i;
u8 count = 0; u8 count = 0;
@ -2251,6 +2270,7 @@ void get_currently_playing_sound(u8 bank, u8 *numPlayingSounds, u8 *numSoundsInB
*/ */
void stop_sound(u32 soundBits, f32 *pos) { void stop_sound(u32 soundBits, f32 *pos) {
u8 bank = (soundBits & SOUNDARGS_MASK_BANK) >> SOUNDARGS_SHIFT_BANK; u8 bank = (soundBits & SOUNDARGS_MASK_BANK) >> SOUNDARGS_SHIFT_BANK;
if (bank >= SOUND_BANK_COUNT) { return; }
u8 soundIndex = sSoundBanks[bank][0].next; u8 soundIndex = sSoundBanks[bank][0].next;
while (soundIndex != 0xff) { while (soundIndex != 0xff) {
@ -2295,6 +2315,7 @@ void stop_sounds_from_source(f32 *pos) {
* Called from threads: thread3_main, thread5_game_loop * Called from threads: thread3_main, thread5_game_loop
*/ */
static void stop_sounds_in_bank(u8 bank) { static void stop_sounds_in_bank(u8 bank) {
if (bank >= SOUND_BANK_COUNT) { return; }
u8 soundIndex = sSoundBanks[bank][0].next; u8 soundIndex = sSoundBanks[bank][0].next;
while (soundIndex != 0xff) { while (soundIndex != 0xff) {
@ -2357,6 +2378,7 @@ void sound_banks_enable(UNUSED u8 player, u16 bankMask) {
} }
u8 unused_803209D8(u8 player, u8 channelIndex, u8 arg2) { u8 unused_803209D8(u8 player, u8 channelIndex, u8 arg2) {
if (player >= SEQUENCE_PLAYERS || channelIndex >= CHANNELS_MAX) { return 0; }
u8 ret = 0; u8 ret = 0;
if (gSequencePlayers[player].channels[channelIndex] != &gSequenceChannelNone) { if (gSequencePlayers[player].channels[channelIndex] != &gSequenceChannelNone) {
gSequencePlayers[player].channels[channelIndex]->stopSomething2 = arg2; gSequencePlayers[player].channels[channelIndex]->stopSomething2 = arg2;
@ -2372,6 +2394,7 @@ u8 unused_803209D8(u8 player, u8 channelIndex, u8 arg2) {
* Called from threads: thread5_game_loop * Called from threads: thread5_game_loop
*/ */
void set_sound_moving_speed(u8 bank, u8 speed) { void set_sound_moving_speed(u8 bank, u8 speed) {
if (bank >= SOUND_BANK_COUNT) { return; }
sSoundMovingSpeed[bank] = speed; sSoundMovingSpeed[bank] = speed;
} }
@ -2427,6 +2450,7 @@ void set_sequence_player_volume(s32 player, f32 volume) {
* Called from threads: thread5_game_loop * Called from threads: thread5_game_loop
*/ */
void play_music(u8 player, u16 seqArgs, u16 fadeTimer) { void play_music(u8 player, u16 seqArgs, u16 fadeTimer) {
if (player >= SEQUENCE_PLAYERS) { return; }
u8 seqId = seqArgs & 0xff; u8 seqId = seqArgs & 0xff;
u8 priority = seqArgs >> 8; u8 priority = seqArgs >> 8;
u8 i; u8 i;
@ -2842,6 +2866,7 @@ void unused_80321474(UNUSED s32 arg0) {
} }
void sound_reset_background_music_default_volume(u8 seqId) { void sound_reset_background_music_default_volume(u8 seqId) {
if (seqId >= sizeof(sBackgroundMusicDefaultVolume) / sizeof(sBackgroundMusicDefaultVolume[0])) { return; }
if (seqId >= SEQ_EVENT_CUTSCENE_LAKITU) { if (seqId >= SEQ_EVENT_CUTSCENE_LAKITU) {
sBackgroundMusicDefaultVolume[seqId] = 75; sBackgroundMusicDefaultVolume[seqId] = 75;
return; return;

View file

@ -2303,8 +2303,10 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
#ifdef VERSION_EU #ifdef VERSION_EU
if (1) {} if (1) {}
#endif #endif
if (loBits < LAYERS_MAX) {
seqChannel->layers[loBits]->scriptState.pc = seqPlayer->seqData + sp5A; seqChannel->layers[loBits]->scriptState.pc = seqPlayer->seqData + sp5A;
} }
}
break; break;
case 0xa0: // chan_freelayer case 0xa0: // chan_freelayer
@ -2315,8 +2317,10 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
if (value != -1 && seq_channel_set_layer(seqChannel, loBits) != -1) { if (value != -1 && seq_channel_set_layer(seqChannel, loBits) != -1) {
seqData = (*seqChannel->dynTable)[value]; seqData = (*seqChannel->dynTable)[value];
sp5A = ((seqData[0] << 8) + seqData[1]); sp5A = ((seqData[0] << 8) + seqData[1]);
if (loBits < LAYERS_MAX) {
seqChannel->layers[loBits]->scriptState.pc = seqPlayer->seqData + sp5A; seqChannel->layers[loBits]->scriptState.pc = seqPlayer->seqData + sp5A;
} }
}
break; break;
#ifndef VERSION_EU #ifndef VERSION_EU

View file

@ -915,6 +915,7 @@ f32 atan2f(f32 y, f32 x) {
* TODO: verify the classification of the spline / figure out how polynomials were computed * TODO: verify the classification of the spline / figure out how polynomials were computed
*/ */
void spline_get_weights(struct MarioState* m, Vec4f result, f32 t, UNUSED s32 c) { void spline_get_weights(struct MarioState* m, Vec4f result, f32 t, UNUSED s32 c) {
if (!m) { return; }
f32 tinv = 1 - t; f32 tinv = 1 - t;
f32 tinv2 = tinv * tinv; f32 tinv2 = tinv * tinv;
f32 tinv3 = tinv2 * tinv; f32 tinv3 = tinv2 * tinv;
@ -964,6 +965,7 @@ void spline_get_weights(struct MarioState* m, Vec4f result, f32 t, UNUSED s32 c)
* That's because the spline has a 3rd degree polynomial, so it looks 3 points ahead. * That's because the spline has a 3rd degree polynomial, so it looks 3 points ahead.
*/ */
void anim_spline_init(struct MarioState* m, Vec4s *keyFrames) { void anim_spline_init(struct MarioState* m, Vec4s *keyFrames) {
if (!m) { return; }
m->splineKeyframe = keyFrames; m->splineKeyframe = keyFrames;
m->splineKeyframeFraction = 0; m->splineKeyframeFraction = 0;
m->splineState = 1; m->splineState = 1;
@ -975,6 +977,7 @@ void anim_spline_init(struct MarioState* m, Vec4s *keyFrames) {
* Returns TRUE when the last point is reached, FALSE otherwise. * Returns TRUE when the last point is reached, FALSE otherwise.
*/ */
s32 anim_spline_poll(struct MarioState* m, Vec3f result) { s32 anim_spline_poll(struct MarioState* m, Vec3f result) {
if (!m) { return 0; }
Vec4f weights = { 0 }; Vec4f weights = { 0 };
s32 i; s32 i;
s32 hasEnded = FALSE; s32 hasEnded = FALSE;

View file

@ -33,7 +33,7 @@ SpatialPartitionCell gDynamicSurfacePartition[NUM_CELLS][NUM_CELLS];
/** /**
* Pools of data to contain either surface nodes or surfaces. * Pools of data to contain either surface nodes or surfaces.
*/ */
struct SurfaceNode *sSurfaceNodePool; struct SurfaceNode *sSurfaceNodePool = NULL;
struct Surface *sSurfacePool; struct Surface *sSurfacePool;
/** /**
@ -688,6 +688,7 @@ static void unused_80383604(void) {
* Applies an object's transformation to the object's vertices. * Applies an object's transformation to the object's vertices.
*/ */
void transform_object_vertices(s16 **data, s16 *vertexData) { void transform_object_vertices(s16 **data, s16 *vertexData) {
if (!gCurrentObject) { return; }
register s16 *vertices; register s16 *vertices;
register f32 vx, vy, vz; register f32 vx, vy, vz;
register s32 numVertices; register s32 numVertices;
@ -728,6 +729,7 @@ void transform_object_vertices(s16 **data, s16 *vertexData) {
* Load in the surfaces for the gCurrentObject. This includes setting the flags, exertion, and room. * Load in the surfaces for the gCurrentObject. This includes setting the flags, exertion, and room.
*/ */
void load_object_surfaces(s16** data, s16* vertexData) { void load_object_surfaces(s16** data, s16* vertexData) {
if (!gCurrentObject) { return; }
s32 surfaceType; s32 surfaceType;
s32 i; s32 i;
s32 numSurfaces; s32 numSurfaces;
@ -784,6 +786,7 @@ void load_object_surfaces(s16** data, s16* vertexData) {
* Transform an object's vertices, reload them, and render the object. * Transform an object's vertices, reload them, and render the object.
*/ */
void load_object_collision_model(void) { void load_object_collision_model(void) {
if (!gCurrentObject) { return; }
if (gCurrentObject->collisionData == NULL) { return; } if (gCurrentObject->collisionData == NULL) { return; }
UNUSED s32 unused; UNUSED s32 unused;

View file

@ -1,7 +1,7 @@
// sound_birds.inc.c // sound_birds.inc.c
void bhv_birds_sound_loop(void) { void bhv_birds_sound_loop(void) {
if (gCamera->mode == CAMERA_MODE_BEHIND_MARIO) if (gCamera && gCamera->mode == CAMERA_MODE_BEHIND_MARIO)
return; return;
switch (o->oBehParams2ndByte) { switch (o->oBehParams2ndByte) {

File diff suppressed because it is too large Load diff

View file

@ -706,6 +706,7 @@ s32 mario_facing_downhill(struct MarioState *m, s32 turnYaw) {
*/ */
u32 mario_floor_is_slippery(struct MarioState *m) { u32 mario_floor_is_slippery(struct MarioState *m) {
if (!m) { return FALSE; } if (!m) { return FALSE; }
if (!m->floor) { return FALSE; }
f32 normY; f32 normY;
@ -741,6 +742,7 @@ u32 mario_floor_is_slippery(struct MarioState *m) {
*/ */
s32 mario_floor_is_slope(struct MarioState *m) { s32 mario_floor_is_slope(struct MarioState *m) {
if (!m) { return FALSE; } if (!m) { return FALSE; }
if (!m->floor) { return FALSE; }
f32 normY; f32 normY;
if ((m->area->terrainType & TERRAIN_MASK) == TERRAIN_SLIDE if ((m->area->terrainType & TERRAIN_MASK) == TERRAIN_SLIDE
@ -774,6 +776,7 @@ s32 mario_floor_is_slope(struct MarioState *m) {
*/ */
s32 mario_floor_is_steep(struct MarioState *m) { s32 mario_floor_is_steep(struct MarioState *m) {
if (!m) { return FALSE; } if (!m) { return FALSE; }
if (!m->floor) { return FALSE; }
f32 normY; f32 normY;
s32 result = FALSE; s32 result = FALSE;

View file

@ -25,6 +25,7 @@
#include "pc/cheats.h" #include "pc/cheats.h"
void play_flip_sounds(struct MarioState *m, s16 frame1, s16 frame2, s16 frame3) { void play_flip_sounds(struct MarioState *m, s16 frame1, s16 frame2, s16 frame3) {
if (!m) { return; }
s32 animFrame = m->marioObj->header.gfx.animInfo.animFrame; s32 animFrame = m->marioObj->header.gfx.animInfo.animFrame;
if (animFrame == frame1 || animFrame == frame2 || animFrame == frame3) { if (animFrame == frame1 || animFrame == frame2 || animFrame == frame3) {
play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject); play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
@ -32,6 +33,7 @@ void play_flip_sounds(struct MarioState *m, s16 frame1, s16 frame2, s16 frame3)
} }
void play_far_fall_sound(struct MarioState *m) { void play_far_fall_sound(struct MarioState *m) {
if (!m) { return; }
u32 action = m->action; u32 action = m->action;
if (!(action & ACT_FLAG_INVULNERABLE) && action != ACT_TWIRLING && action != ACT_FLYING if (!(action & ACT_FLAG_INVULNERABLE) && action != ACT_TWIRLING && action != ACT_FLYING
&& !(m->flags & MARIO_UNKNOWN_18)) { && !(m->flags & MARIO_UNKNOWN_18)) {
@ -44,6 +46,7 @@ void play_far_fall_sound(struct MarioState *m) {
#ifndef VERSION_JP #ifndef VERSION_JP
void play_knockback_sound(struct MarioState *m) { void play_knockback_sound(struct MarioState *m) {
if (!m) { return; }
if (m->actionArg == 0 && (m->forwardVel <= -28.0f || m->forwardVel >= 28.0f)) { if (m->actionArg == 0 && (m->forwardVel <= -28.0f || m->forwardVel >= 28.0f)) {
play_character_sound_if_no_flag(m, CHAR_SOUND_DOH, MARIO_MARIO_SOUND_PLAYED); play_character_sound_if_no_flag(m, CHAR_SOUND_DOH, MARIO_MARIO_SOUND_PLAYED);
} else { } else {
@ -53,6 +56,7 @@ void play_knockback_sound(struct MarioState *m) {
#endif #endif
s32 lava_boost_on_wall(struct MarioState *m) { s32 lava_boost_on_wall(struct MarioState *m) {
if (!m) { return 0; }
bool allow = true; bool allow = true;
smlua_call_event_hooks_mario_param_and_int_ret_bool(HOOK_ALLOW_HAZARD_SURFACE, m, HAZARD_TYPE_LAVA_WALL, &allow); smlua_call_event_hooks_mario_param_and_int_ret_bool(HOOK_ALLOW_HAZARD_SURFACE, m, HAZARD_TYPE_LAVA_WALL, &allow);
if ((gServerSettings.enableCheats && gCheats.godMode) || (!allow)) { return FALSE; } if ((gServerSettings.enableCheats && gCheats.godMode) || (!allow)) { return FALSE; }
@ -72,6 +76,7 @@ s32 lava_boost_on_wall(struct MarioState *m) {
} }
s32 check_fall_damage(struct MarioState *m, u32 hardFallAction) { s32 check_fall_damage(struct MarioState *m, u32 hardFallAction) {
if (!m) { return 0; }
if (gServerSettings.enableCheats && gCheats.godMode && m->playerIndex == 0) { return FALSE; } if (gServerSettings.enableCheats && gCheats.godMode && m->playerIndex == 0) { return FALSE; }
f32 fallHeight; f32 fallHeight;
@ -114,6 +119,7 @@ s32 check_fall_damage(struct MarioState *m, u32 hardFallAction) {
} }
s32 check_kick_or_dive_in_air(struct MarioState *m) { s32 check_kick_or_dive_in_air(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_B_PRESSED) { if (m->input & INPUT_B_PRESSED) {
return set_mario_action(m, m->forwardVel > 28.0f ? ACT_DIVE : ACT_JUMP_KICK, 0); return set_mario_action(m, m->forwardVel > 28.0f ? ACT_DIVE : ACT_JUMP_KICK, 0);
} }
@ -121,6 +127,7 @@ s32 check_kick_or_dive_in_air(struct MarioState *m) {
} }
s32 should_get_stuck_in_ground(struct MarioState *m) { s32 should_get_stuck_in_ground(struct MarioState *m) {
if (!m) { return 0; }
if (m->floor == NULL) { return FALSE; } if (m->floor == NULL) { return FALSE; }
u32 terrainType = m->area->terrainType & TERRAIN_MASK; u32 terrainType = m->area->terrainType & TERRAIN_MASK;
@ -139,6 +146,7 @@ s32 should_get_stuck_in_ground(struct MarioState *m) {
} }
s32 check_fall_damage_or_get_stuck(struct MarioState *m, u32 hardFallAction) { s32 check_fall_damage_or_get_stuck(struct MarioState *m, u32 hardFallAction) {
if (!m) { return 0; }
if (should_get_stuck_in_ground(m)) { if (should_get_stuck_in_ground(m)) {
#ifdef VERSION_JP #ifdef VERSION_JP
play_character_sound(m, CHAR_SOUND_OOOF); play_character_sound(m, CHAR_SOUND_OOOF);
@ -156,13 +164,14 @@ s32 check_fall_damage_or_get_stuck(struct MarioState *m, u32 hardFallAction) {
} }
s32 check_horizontal_wind(struct MarioState *m) { s32 check_horizontal_wind(struct MarioState *m) {
if (!m) { return 0; }
struct Surface *floor; struct Surface *floor;
f32 speed; f32 speed;
s16 pushAngle; s16 pushAngle;
floor = m->floor; floor = m->floor;
if (floor->type == SURFACE_HORIZONTAL_WIND) { if (floor && floor->type == SURFACE_HORIZONTAL_WIND) {
pushAngle = floor->force << 8; pushAngle = floor->force << 8;
m->slideVelX += 1.2f * sins(pushAngle); m->slideVelX += 1.2f * sins(pushAngle);
@ -193,6 +202,7 @@ s32 check_horizontal_wind(struct MarioState *m) {
} }
void update_air_with_turn(struct MarioState *m) { void update_air_with_turn(struct MarioState *m) {
if (!m) { return; }
f32 dragThreshold; f32 dragThreshold;
s16 intendedDYaw; s16 intendedDYaw;
f32 intendedMag; f32 intendedMag;
@ -223,6 +233,7 @@ void update_air_with_turn(struct MarioState *m) {
} }
void update_air_without_turn(struct MarioState *m) { void update_air_without_turn(struct MarioState *m) {
if (!m) { return; }
f32 sidewaysSpeed = 0.0f; f32 sidewaysSpeed = 0.0f;
f32 dragThreshold; f32 dragThreshold;
s16 intendedDYaw; s16 intendedDYaw;
@ -260,6 +271,7 @@ void update_air_without_turn(struct MarioState *m) {
} }
void update_lava_boost_or_twirling(struct MarioState *m) { void update_lava_boost_or_twirling(struct MarioState *m) {
if (!m) { return; }
s16 intendedDYaw; s16 intendedDYaw;
f32 intendedMag; f32 intendedMag;
@ -285,6 +297,7 @@ void update_lava_boost_or_twirling(struct MarioState *m) {
} }
void update_flying_yaw(struct MarioState *m) { void update_flying_yaw(struct MarioState *m) {
if (!m) { return; }
s16 targetYawVel = -(s16)(m->controller->stickX * (m->forwardVel / 4.0f)); s16 targetYawVel = -(s16)(m->controller->stickX * (m->forwardVel / 4.0f));
if (targetYawVel > 0) { if (targetYawVel > 0) {
@ -314,6 +327,7 @@ void update_flying_yaw(struct MarioState *m) {
} }
void update_flying_pitch(struct MarioState *m) { void update_flying_pitch(struct MarioState *m) {
if (!m) { return; }
s16 targetPitchVel = -(s16)(m->controller->stickY * (m->forwardVel / 5.0f)); s16 targetPitchVel = -(s16)(m->controller->stickY * (m->forwardVel / 5.0f));
if (targetPitchVel > 0) { if (targetPitchVel > 0) {
@ -340,6 +354,7 @@ void update_flying_pitch(struct MarioState *m) {
} }
void update_flying(struct MarioState *m) { void update_flying(struct MarioState *m) {
if (!m) { return; }
UNUSED u32 unused; UNUSED u32 unused;
update_flying_pitch(m); update_flying_pitch(m);
@ -378,6 +393,7 @@ void update_flying(struct MarioState *m) {
} }
u32 common_air_action_step(struct MarioState *m, u32 landAction, s32 animation, u32 stepArg) { u32 common_air_action_step(struct MarioState *m, u32 landAction, s32 animation, u32 stepArg) {
if (!m) { return 0; }
u32 stepResult; u32 stepResult;
update_air_without_turn(m); update_air_without_turn(m);
@ -455,6 +471,7 @@ u32 common_air_action_step(struct MarioState *m, u32 landAction, s32 animation,
} }
s32 act_jump(struct MarioState *m) { s32 act_jump(struct MarioState *m) {
if (!m) { return 0; }
if (check_kick_or_dive_in_air(m)) { if (check_kick_or_dive_in_air(m)) {
return TRUE; return TRUE;
} }
@ -470,6 +487,7 @@ s32 act_jump(struct MarioState *m) {
} }
s32 act_double_jump(struct MarioState *m) { s32 act_double_jump(struct MarioState *m) {
if (!m) { return 0; }
s32 animation = (m->vel[1] >= 0.0f) s32 animation = (m->vel[1] >= 0.0f)
? MARIO_ANIM_DOUBLE_JUMP_RISE ? MARIO_ANIM_DOUBLE_JUMP_RISE
: MARIO_ANIM_DOUBLE_JUMP_FALL; : MARIO_ANIM_DOUBLE_JUMP_FALL;
@ -489,6 +507,7 @@ s32 act_double_jump(struct MarioState *m) {
} }
s32 act_triple_jump(struct MarioState *m) { s32 act_triple_jump(struct MarioState *m) {
if (!m) { return 0; }
if (m == &gMarioStates[0] && m->specialTripleJump) { if (m == &gMarioStates[0] && m->specialTripleJump) {
return set_mario_action(m, ACT_SPECIAL_TRIPLE_JUMP, 0); return set_mario_action(m, ACT_SPECIAL_TRIPLE_JUMP, 0);
} }
@ -516,6 +535,7 @@ s32 act_triple_jump(struct MarioState *m) {
} }
s32 act_backflip(struct MarioState *m) { s32 act_backflip(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_Z_PRESSED) { if (m->input & INPUT_Z_PRESSED) {
return set_mario_action(m, ACT_GROUND_POUND, 0); return set_mario_action(m, ACT_GROUND_POUND, 0);
} }
@ -531,6 +551,7 @@ s32 act_backflip(struct MarioState *m) {
} }
s32 act_freefall(struct MarioState *m) { s32 act_freefall(struct MarioState *m) {
if (!m) { return 0; }
s32 animation = 0; s32 animation = 0;
if (m->input & INPUT_B_PRESSED) { if (m->input & INPUT_B_PRESSED) {
@ -558,6 +579,7 @@ s32 act_freefall(struct MarioState *m) {
} }
s32 act_hold_jump(struct MarioState *m) { s32 act_hold_jump(struct MarioState *m) {
if (!m) { return 0; }
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) { if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
return drop_and_set_mario_action(m, ACT_FREEFALL, 0); return drop_and_set_mario_action(m, ACT_FREEFALL, 0);
} }
@ -577,6 +599,7 @@ s32 act_hold_jump(struct MarioState *m) {
} }
s32 act_hold_freefall(struct MarioState *m) { s32 act_hold_freefall(struct MarioState *m) {
if (!m) { return 0; }
s32 animation; s32 animation;
if (m->actionArg == 0) { if (m->actionArg == 0) {
animation = MARIO_ANIM_FALL_WITH_LIGHT_OBJ; animation = MARIO_ANIM_FALL_WITH_LIGHT_OBJ;
@ -601,6 +624,7 @@ s32 act_hold_freefall(struct MarioState *m) {
} }
s32 act_side_flip(struct MarioState *m) { s32 act_side_flip(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_B_PRESSED) { if (m->input & INPUT_B_PRESSED) {
return set_mario_action(m, ACT_DIVE, 0); return set_mario_action(m, ACT_DIVE, 0);
} }
@ -624,6 +648,7 @@ s32 act_side_flip(struct MarioState *m) {
} }
s32 act_wall_kick_air(struct MarioState *m) { s32 act_wall_kick_air(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_B_PRESSED) { if (m->input & INPUT_B_PRESSED) {
return set_mario_action(m, ACT_DIVE, 0); return set_mario_action(m, ACT_DIVE, 0);
} }
@ -638,6 +663,7 @@ s32 act_wall_kick_air(struct MarioState *m) {
} }
s32 act_long_jump(struct MarioState *m) { s32 act_long_jump(struct MarioState *m) {
if (!m) { return 0; }
s32 animation; s32 animation;
if (!m->marioObj->oMarioLongJumpIsSlow) { if (!m->marioObj->oMarioLongJumpIsSlow) {
animation = MARIO_ANIM_FAST_LONGJUMP; animation = MARIO_ANIM_FAST_LONGJUMP;
@ -661,6 +687,7 @@ s32 act_long_jump(struct MarioState *m) {
} }
s32 act_riding_shell_air(struct MarioState *m) { s32 act_riding_shell_air(struct MarioState *m) {
if (!m) { return 0; }
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0); play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0);
set_mario_animation(m, MARIO_ANIM_JUMP_RIDING_SHELL); set_mario_animation(m, MARIO_ANIM_JUMP_RIDING_SHELL);
@ -685,6 +712,7 @@ s32 act_riding_shell_air(struct MarioState *m) {
} }
s32 act_twirling(struct MarioState *m) { s32 act_twirling(struct MarioState *m) {
if (!m) { return 0; }
s16 startTwirlYaw = m->twirlYaw; s16 startTwirlYaw = m->twirlYaw;
s16 yawVelTarget; s16 yawVelTarget;
@ -730,6 +758,7 @@ s32 act_twirling(struct MarioState *m) {
} }
s32 act_dive(struct MarioState *m) { s32 act_dive(struct MarioState *m) {
if (!m) { return 0; }
if (m->actionArg == 0) { if (m->actionArg == 0) {
play_mario_sound(m, SOUND_ACTION_THROW, CHAR_SOUND_HOOHOO); play_mario_sound(m, SOUND_ACTION_THROW, CHAR_SOUND_HOOHOO);
} else { } else {
@ -801,6 +830,7 @@ s32 act_dive(struct MarioState *m) {
} }
s32 act_air_throw(struct MarioState *m) { s32 act_air_throw(struct MarioState *m) {
if (!m) { return 0; }
if (++(m->actionTimer) == 4) { if (++(m->actionTimer) == 4) {
mario_throw_held_object(m); mario_throw_held_object(m);
} }
@ -829,6 +859,7 @@ s32 act_air_throw(struct MarioState *m) {
} }
s32 act_water_jump(struct MarioState *m) { s32 act_water_jump(struct MarioState *m) {
if (!m) { return 0; }
if (m->forwardVel < 15.0f) { if (m->forwardVel < 15.0f) {
mario_set_forward_vel(m, 15.0f); mario_set_forward_vel(m, 15.0f);
} }
@ -863,6 +894,7 @@ s32 act_water_jump(struct MarioState *m) {
} }
s32 act_hold_water_jump(struct MarioState *m) { s32 act_hold_water_jump(struct MarioState *m) {
if (!m) { return 0; }
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) { if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
return drop_and_set_mario_action(m, ACT_FREEFALL, 0); return drop_and_set_mario_action(m, ACT_FREEFALL, 0);
} }
@ -893,6 +925,7 @@ s32 act_hold_water_jump(struct MarioState *m) {
} }
s32 act_steep_jump(struct MarioState *m) { s32 act_steep_jump(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_B_PRESSED) { if (m->input & INPUT_B_PRESSED) {
return set_mario_action(m, ACT_DIVE, 0); return set_mario_action(m, ACT_DIVE, 0);
} }
@ -923,6 +956,7 @@ s32 act_steep_jump(struct MarioState *m) {
} }
s32 act_ground_pound(struct MarioState *m) { s32 act_ground_pound(struct MarioState *m) {
if (!m) { return 0; }
u32 stepResult; u32 stepResult;
f32 yOffset; f32 yOffset;
@ -989,6 +1023,7 @@ s32 act_ground_pound(struct MarioState *m) {
} }
s32 act_burning_jump(struct MarioState *m) { s32 act_burning_jump(struct MarioState *m) {
if (!m) { return 0; }
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, m->actionArg == 0 ? 0 : -1); play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, m->actionArg == 0 ? 0 : -1);
mario_set_forward_vel(m, m->forwardVel); mario_set_forward_vel(m, m->forwardVel);
@ -1018,6 +1053,7 @@ s32 act_burning_jump(struct MarioState *m) {
} }
s32 act_burning_fall(struct MarioState *m) { s32 act_burning_fall(struct MarioState *m) {
if (!m) { return 0; }
mario_set_forward_vel(m, m->forwardVel); mario_set_forward_vel(m, m->forwardVel);
if (perform_air_step(m, 0) == AIR_STEP_LANDED) { if (perform_air_step(m, 0) == AIR_STEP_LANDED) {
@ -1044,6 +1080,7 @@ s32 act_burning_fall(struct MarioState *m) {
} }
s32 act_crazy_box_bounce(struct MarioState *m) { s32 act_crazy_box_bounce(struct MarioState *m) {
if (!m) { return 0; }
f32 minSpeed = 32; f32 minSpeed = 32;
if (m->actionTimer == 0) { if (m->actionTimer == 0) {
@ -1109,6 +1146,7 @@ s32 act_crazy_box_bounce(struct MarioState *m) {
u32 common_air_knockback_step(struct MarioState *m, u32 landAction, u32 hardFallAction, s32 animation, u32 common_air_knockback_step(struct MarioState *m, u32 landAction, u32 hardFallAction, s32 animation,
f32 speed) { f32 speed) {
if (!m) { return 0; }
u32 stepResult; u32 stepResult;
if (m->knockbackTimer == 0) { if (m->knockbackTimer == 0) {
@ -1162,6 +1200,7 @@ u32 common_air_knockback_step(struct MarioState *m, u32 landAction, u32 hardFall
} }
s32 check_wall_kick(struct MarioState *m) { s32 check_wall_kick(struct MarioState *m) {
if (!m) { return 0; }
if ((m->input & INPUT_A_PRESSED) && m->wallKickTimer != 0 && m->prevAction == ACT_AIR_HIT_WALL) { if ((m->input & INPUT_A_PRESSED) && m->wallKickTimer != 0 && m->prevAction == ACT_AIR_HIT_WALL) {
m->faceAngle[1] += 0x8000; m->faceAngle[1] += 0x8000;
return set_mario_action(m, ACT_WALL_KICK_AIR, 0); return set_mario_action(m, ACT_WALL_KICK_AIR, 0);
@ -1220,6 +1259,7 @@ s32 act_hard_forward_air_kb(struct MarioState *m) {
} }
s32 act_thrown_backward(struct MarioState *m) { s32 act_thrown_backward(struct MarioState *m) {
if (!m) { return 0; }
u32 landAction; u32 landAction;
if (m->actionArg != 0) { if (m->actionArg != 0) {
landAction = ACT_HARD_BACKWARD_GROUND_KB; landAction = ACT_HARD_BACKWARD_GROUND_KB;
@ -1236,6 +1276,7 @@ s32 act_thrown_backward(struct MarioState *m) {
} }
s32 act_thrown_forward(struct MarioState *m) { s32 act_thrown_forward(struct MarioState *m) {
if (!m) { return 0; }
s16 pitch; s16 pitch;
u32 landAction; u32 landAction;
@ -1277,6 +1318,7 @@ s32 act_soft_bonk(struct MarioState *m) {
} }
s32 act_getting_blown(struct MarioState *m) { s32 act_getting_blown(struct MarioState *m) {
if (!m) { return 0; }
if (m->actionState == 0) { if (m->actionState == 0) {
if (m->forwardVel > -60.0f) { if (m->forwardVel > -60.0f) {
m->forwardVel -= 6.0f; m->forwardVel -= 6.0f;
@ -1324,6 +1366,7 @@ s32 act_getting_blown(struct MarioState *m) {
} }
s32 act_air_hit_wall(struct MarioState *m) { s32 act_air_hit_wall(struct MarioState *m) {
if (!m) { return 0; }
if (m->heldObj != NULL) { if (m->heldObj != NULL) {
mario_drop_held_object(m); mario_drop_held_object(m);
} }
@ -1368,6 +1411,7 @@ s32 act_air_hit_wall(struct MarioState *m) {
} }
s32 act_forward_rollout(struct MarioState *m) { s32 act_forward_rollout(struct MarioState *m) {
if (!m) { return 0; }
if (m->actionState == 0) { if (m->actionState == 0) {
m->vel[1] = 30.0f; m->vel[1] = 30.0f;
m->actionState = 1; m->actionState = 1;
@ -1409,6 +1453,7 @@ s32 act_forward_rollout(struct MarioState *m) {
} }
s32 act_backward_rollout(struct MarioState *m) { s32 act_backward_rollout(struct MarioState *m) {
if (!m) { return 0; }
if (m->actionState == 0) { if (m->actionState == 0) {
m->vel[1] = 30.0f; m->vel[1] = 30.0f;
m->actionState = 1; m->actionState = 1;
@ -1450,6 +1495,7 @@ s32 act_backward_rollout(struct MarioState *m) {
} }
s32 act_butt_slide_air(struct MarioState *m) { s32 act_butt_slide_air(struct MarioState *m) {
if (!m) { return 0; }
if (++(m->actionTimer) > 30 && m->pos[1] - m->floorHeight > 500.0f) { if (++(m->actionTimer) > 30 && m->pos[1] - m->floorHeight > 500.0f) {
return set_mario_action(m, ACT_FREEFALL, 1); return set_mario_action(m, ACT_FREEFALL, 1);
} }
@ -1485,6 +1531,7 @@ s32 act_butt_slide_air(struct MarioState *m) {
} }
s32 act_hold_butt_slide_air(struct MarioState *m) { s32 act_hold_butt_slide_air(struct MarioState *m) {
if (!m) { return 0; }
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) { if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
return drop_and_set_mario_action(m, ACT_HOLD_FREEFALL, 1); return drop_and_set_mario_action(m, ACT_HOLD_FREEFALL, 1);
} }
@ -1526,6 +1573,7 @@ s32 act_hold_butt_slide_air(struct MarioState *m) {
} }
s32 act_lava_boost(struct MarioState *m) { s32 act_lava_boost(struct MarioState *m) {
if (!m) { return 0; }
if (!(m->flags & MARIO_MARIO_SOUND_PLAYED)) { if (!(m->flags & MARIO_MARIO_SOUND_PLAYED)) {
play_character_sound_if_no_flag(m, CHAR_SOUND_ON_FIRE, MARIO_MARIO_SOUND_PLAYED); play_character_sound_if_no_flag(m, CHAR_SOUND_ON_FIRE, MARIO_MARIO_SOUND_PLAYED);
queue_rumble_data_mario(m, 5, 80); queue_rumble_data_mario(m, 5, 80);
@ -1606,6 +1654,7 @@ s32 act_lava_boost(struct MarioState *m) {
} }
s32 act_slide_kick(struct MarioState *m) { s32 act_slide_kick(struct MarioState *m) {
if (!m) { return 0; }
if (m->actionTimer == 0) { if (m->actionTimer == 0) {
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, CHAR_SOUND_HOOHOO); play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, CHAR_SOUND_HOOHOO);
set_mario_animation(m, MARIO_ANIM_SLIDE_KICK); set_mario_animation(m, MARIO_ANIM_SLIDE_KICK);
@ -1657,6 +1706,7 @@ s32 act_slide_kick(struct MarioState *m) {
} }
s32 act_jump_kick(struct MarioState *m) { s32 act_jump_kick(struct MarioState *m) {
if (!m) { return 0; }
s32 animFrame; s32 animFrame;
if (m->actionState == 0) { if (m->actionState == 0) {
@ -1692,6 +1742,7 @@ s32 act_jump_kick(struct MarioState *m) {
} }
s32 act_shot_from_cannon(struct MarioState *m) { s32 act_shot_from_cannon(struct MarioState *m) {
if (!m) { return 0; }
// only allow for local player // only allow for local player
u8 allowCameraChange = (m->playerIndex == 0); u8 allowCameraChange = (m->playerIndex == 0);
@ -1776,6 +1827,7 @@ s32 act_shot_from_cannon(struct MarioState *m) {
} }
s32 act_flying(struct MarioState *m) { s32 act_flying(struct MarioState *m) {
if (!m) { return 0; }
s16 startPitch = m->faceAngle[0]; s16 startPitch = m->faceAngle[0];
if (m->input & INPUT_Z_PRESSED) { if (m->input & INPUT_Z_PRESSED) {
@ -1961,6 +2013,7 @@ s32 act_flying(struct MarioState *m) {
} }
s32 act_riding_hoot(struct MarioState *m) { s32 act_riding_hoot(struct MarioState *m) {
if (!m) { return 0; }
if (m->usedObj == NULL || m->usedObj->behavior != smlua_override_behavior(bhvHoot)) { if (m->usedObj == NULL || m->usedObj->behavior != smlua_override_behavior(bhvHoot)) {
m->usedObj = cur_obj_nearest_object_with_behavior(bhvHoot); m->usedObj = cur_obj_nearest_object_with_behavior(bhvHoot);
if (m->usedObj == NULL) { return FALSE; } if (m->usedObj == NULL) { return FALSE; }
@ -1999,6 +2052,7 @@ s32 act_riding_hoot(struct MarioState *m) {
} }
s32 act_flying_triple_jump(struct MarioState *m) { s32 act_flying_triple_jump(struct MarioState *m) {
if (!m) { return 0; }
#ifndef VERSION_JP #ifndef VERSION_JP
if (m->input & (INPUT_B_PRESSED | INPUT_Z_PRESSED)) { if (m->input & (INPUT_B_PRESSED | INPUT_Z_PRESSED)) {
if (m->playerIndex == 0 && m->area->camera->mode == CAMERA_MODE_BEHIND_MARIO) { if (m->playerIndex == 0 && m->area->camera->mode == CAMERA_MODE_BEHIND_MARIO) {
@ -2105,6 +2159,7 @@ s32 act_top_of_pole_jump(struct MarioState *m) {
} }
s32 act_vertical_wind(struct MarioState *m) { s32 act_vertical_wind(struct MarioState *m) {
if (!m) { return 0; }
s16 intendedDYaw = m->intendedYaw - m->faceAngle[1]; s16 intendedDYaw = m->intendedYaw - m->faceAngle[1];
f32 intendedMag = m->intendedMag / 32.0f; f32 intendedMag = m->intendedMag / 32.0f;
@ -2141,6 +2196,7 @@ s32 act_vertical_wind(struct MarioState *m) {
} }
s32 act_special_triple_jump(struct MarioState *m) { s32 act_special_triple_jump(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_B_PRESSED) { if (m->input & INPUT_B_PRESSED) {
return set_mario_action(m, ACT_DIVE, 0); return set_mario_action(m, ACT_DIVE, 0);
} }
@ -2181,6 +2237,7 @@ s32 act_special_triple_jump(struct MarioState *m) {
} }
s32 check_common_airborne_cancels(struct MarioState *m) { s32 check_common_airborne_cancels(struct MarioState *m) {
if (!m) { return 0; }
if (m->pos[1] < m->waterLevel - 100) { if (m->pos[1] < m->waterLevel - 100) {
return set_water_plunge_action(m); return set_water_plunge_action(m);
} }
@ -2189,7 +2246,7 @@ s32 check_common_airborne_cancels(struct MarioState *m) {
return drop_and_set_mario_action(m, ACT_SQUISHED, 0); return drop_and_set_mario_action(m, ACT_SQUISHED, 0);
} }
if (m->floor->type == SURFACE_VERTICAL_WIND && (m->action & ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION)) { if (m->floor && m->floor->type == SURFACE_VERTICAL_WIND && (m->action & ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION)) {
return drop_and_set_mario_action(m, ACT_VERTICAL_WIND, 0); return drop_and_set_mario_action(m, ACT_VERTICAL_WIND, 0);
} }

View file

@ -35,6 +35,7 @@
#define HANG_LEFT_CEIL 2 #define HANG_LEFT_CEIL 2
void add_tree_leaf_particles(struct MarioState *m) { void add_tree_leaf_particles(struct MarioState *m) {
if (!m) { return; }
f32 leafHeight; f32 leafHeight;
if (m->usedObj != NULL && m->usedObj->behavior == segmented_to_virtual(smlua_override_behavior(bhvTree))) { if (m->usedObj != NULL && m->usedObj->behavior == segmented_to_virtual(smlua_override_behavior(bhvTree))) {
@ -51,6 +52,7 @@ void add_tree_leaf_particles(struct MarioState *m) {
} }
void play_climbing_sounds(struct MarioState *m, s32 b) { void play_climbing_sounds(struct MarioState *m, s32 b) {
if (!m) { return; }
s32 isOnTree = (m->usedObj != NULL && m->usedObj->behavior == segmented_to_virtual(smlua_override_behavior(bhvTree))); s32 isOnTree = (m->usedObj != NULL && m->usedObj->behavior == segmented_to_virtual(smlua_override_behavior(bhvTree)));
if (b == 1) { if (b == 1) {
@ -65,6 +67,7 @@ void play_climbing_sounds(struct MarioState *m, s32 b) {
} }
s32 set_pole_position(struct MarioState *m, f32 offsetY) { s32 set_pole_position(struct MarioState *m, f32 offsetY) {
if (!m) { return 0; }
if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); } if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); }
// This is here so if somehow a pole despawns while you are on it. // This is here so if somehow a pole despawns while you are on it.
@ -132,6 +135,7 @@ s32 set_pole_position(struct MarioState *m, f32 offsetY) {
} }
s32 act_holding_pole(struct MarioState *m) { s32 act_holding_pole(struct MarioState *m) {
if (!m) { return 0; }
struct Object *marioObj = m->marioObj; struct Object *marioObj = m->marioObj;
if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); } if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); }
if (m->usedObj == NULL) { return FALSE; } if (m->usedObj == NULL) { return FALSE; }
@ -207,6 +211,7 @@ s32 act_holding_pole(struct MarioState *m) {
} }
s32 act_climbing_pole(struct MarioState *m) { s32 act_climbing_pole(struct MarioState *m) {
if (!m) { return 0; }
if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); } if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); }
s32 sp24; s32 sp24;
struct Object *marioObj = m->marioObj; struct Object *marioObj = m->marioObj;
@ -245,6 +250,7 @@ s32 act_climbing_pole(struct MarioState *m) {
} }
s32 act_grab_pole_slow(struct MarioState *m) { s32 act_grab_pole_slow(struct MarioState *m) {
if (!m) { return 0; }
if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); } if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); }
play_character_sound_if_no_flag(m, CHAR_SOUND_WHOA, MARIO_MARIO_SOUND_PLAYED); play_character_sound_if_no_flag(m, CHAR_SOUND_WHOA, MARIO_MARIO_SOUND_PLAYED);
@ -260,6 +266,7 @@ s32 act_grab_pole_slow(struct MarioState *m) {
} }
s32 act_grab_pole_fast(struct MarioState *m) { s32 act_grab_pole_fast(struct MarioState *m) {
if (!m) { return 0; }
struct Object *marioObj = m->marioObj; struct Object *marioObj = m->marioObj;
if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); } if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); }
@ -284,6 +291,7 @@ s32 act_grab_pole_fast(struct MarioState *m) {
} }
s32 act_top_of_pole_transition(struct MarioState *m) { s32 act_top_of_pole_transition(struct MarioState *m) {
if (!m) { return 0; }
struct Object *marioObj = m->marioObj; struct Object *marioObj = m->marioObj;
if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); } if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); }
@ -305,6 +313,7 @@ s32 act_top_of_pole_transition(struct MarioState *m) {
} }
s32 act_top_of_pole(struct MarioState *m) { s32 act_top_of_pole(struct MarioState *m) {
if (!m) { return 0; }
UNUSED struct Object *marioObj = m->marioObj; UNUSED struct Object *marioObj = m->marioObj;
if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); } if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); }
@ -380,8 +389,9 @@ s32 perform_hanging_step(struct MarioState *m, Vec3f nextPos) {
} }
s32 update_hang_moving(struct MarioState *m) { s32 update_hang_moving(struct MarioState *m) {
if (!m) { return 0; }
s32 stepResult; s32 stepResult;
Vec3f nextPos; Vec3f nextPos = { 0 };
f32 maxSpeed = 4.0f; f32 maxSpeed = 4.0f;
m->forwardVel += 1.0f; m->forwardVel += 1.0f;
@ -400,9 +410,11 @@ s32 update_hang_moving(struct MarioState *m) {
m->vel[1] = 0.0f; m->vel[1] = 0.0f;
m->vel[2] = m->slideVelZ; m->vel[2] = m->slideVelZ;
if (m->ceil) {
nextPos[0] = m->pos[0] - m->ceil->normal.y * m->vel[0]; nextPos[0] = m->pos[0] - m->ceil->normal.y * m->vel[0];
nextPos[2] = m->pos[2] - m->ceil->normal.y * m->vel[2]; nextPos[2] = m->pos[2] - m->ceil->normal.y * m->vel[2];
nextPos[1] = m->pos[1]; nextPos[1] = m->pos[1];
}
stepResult = perform_hanging_step(m, nextPos); stepResult = perform_hanging_step(m, nextPos);
@ -412,6 +424,7 @@ s32 update_hang_moving(struct MarioState *m) {
} }
void update_hang_stationary(struct MarioState *m) { void update_hang_stationary(struct MarioState *m) {
if (!m) { return; }
m->forwardVel = 0.0f; m->forwardVel = 0.0f;
m->slideVelX = 0.0f; m->slideVelX = 0.0f;
m->slideVelZ = 0.0f; m->slideVelZ = 0.0f;
@ -422,6 +435,7 @@ void update_hang_stationary(struct MarioState *m) {
} }
s32 act_start_hanging(struct MarioState *m) { s32 act_start_hanging(struct MarioState *m) {
if (!m) { return 0; }
if (m->actionTimer++ == 0) { if (m->actionTimer++ == 0) {
queue_rumble_data_mario(m, 5, 80); queue_rumble_data_mario(m, 5, 80);
} }
@ -454,6 +468,7 @@ s32 act_start_hanging(struct MarioState *m) {
} }
s32 act_hanging(struct MarioState *m) { s32 act_hanging(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_NONZERO_ANALOG) { if (m->input & INPUT_NONZERO_ANALOG) {
return set_mario_action(m, ACT_HANG_MOVING, m->actionArg); return set_mario_action(m, ACT_HANG_MOVING, m->actionArg);
} }
@ -482,6 +497,7 @@ s32 act_hanging(struct MarioState *m) {
} }
s32 act_hang_moving(struct MarioState *m) { s32 act_hang_moving(struct MarioState *m) {
if (!m) { return 0; }
if (!(m->input & INPUT_A_DOWN)) { if (!(m->input & INPUT_A_DOWN)) {
return set_mario_action(m, ACT_FREEFALL, 0); return set_mario_action(m, ACT_FREEFALL, 0);
} }
@ -520,6 +536,7 @@ s32 act_hang_moving(struct MarioState *m) {
} }
s32 let_go_of_ledge(struct MarioState *m) { s32 let_go_of_ledge(struct MarioState *m) {
if (!m) { return 0; }
f32 floorHeight; f32 floorHeight;
struct Surface *floor; struct Surface *floor;
@ -539,6 +556,7 @@ s32 let_go_of_ledge(struct MarioState *m) {
} }
void climb_up_ledge(struct MarioState *m) { void climb_up_ledge(struct MarioState *m) {
if (!m) { return; }
set_mario_animation(m, MARIO_ANIM_IDLE_HEAD_LEFT); set_mario_animation(m, MARIO_ANIM_IDLE_HEAD_LEFT);
m->pos[0] += 14.0f * sins(m->faceAngle[1]); m->pos[0] += 14.0f * sins(m->faceAngle[1]);
m->pos[2] += 14.0f * coss(m->faceAngle[1]); m->pos[2] += 14.0f * coss(m->faceAngle[1]);
@ -546,6 +564,7 @@ void climb_up_ledge(struct MarioState *m) {
} }
void update_ledge_climb_camera(struct MarioState *m) { void update_ledge_climb_camera(struct MarioState *m) {
if (!m) { return; }
f32 sp4; f32 sp4;
if (m->actionTimer < 14) { if (m->actionTimer < 14) {
@ -573,6 +592,7 @@ void update_ledge_climb(struct MarioState *m, s32 animation, u32 endAction) {
} }
s32 act_ledge_grab(struct MarioState *m) { s32 act_ledge_grab(struct MarioState *m) {
if (!m) { return 0; }
f32 heightAboveFloor; f32 heightAboveFloor;
s16 intendedDYaw = m->intendedYaw - m->faceAngle[1]; s16 intendedDYaw = m->intendedYaw - m->faceAngle[1];
s32 hasSpaceForMario = (m->ceilHeight - m->floorHeight >= 160.0f); s32 hasSpaceForMario = (m->ceilHeight - m->floorHeight >= 160.0f);
@ -631,6 +651,7 @@ s32 act_ledge_grab(struct MarioState *m) {
} }
s32 act_ledge_climb_slow(struct MarioState *m) { s32 act_ledge_climb_slow(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_OFF_FLOOR) { if (m->input & INPUT_OFF_FLOOR) {
return let_go_of_ledge(m); return let_go_of_ledge(m);
} }
@ -657,6 +678,7 @@ s32 act_ledge_climb_slow(struct MarioState *m) {
} }
s32 act_ledge_climb_down(struct MarioState *m) { s32 act_ledge_climb_down(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_OFF_FLOOR) { if (m->input & INPUT_OFF_FLOOR) {
return let_go_of_ledge(m); return let_go_of_ledge(m);
} }
@ -670,6 +692,7 @@ s32 act_ledge_climb_down(struct MarioState *m) {
} }
s32 act_ledge_climb_fast(struct MarioState *m) { s32 act_ledge_climb_fast(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_OFF_FLOOR) { if (m->input & INPUT_OFF_FLOOR) {
return let_go_of_ledge(m); return let_go_of_ledge(m);
} }
@ -687,6 +710,7 @@ s32 act_ledge_climb_fast(struct MarioState *m) {
} }
s32 act_grabbed(struct MarioState *m) { s32 act_grabbed(struct MarioState *m) {
if (!m) { return 0; }
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_UNK2) { if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_UNK2) {
s32 thrown = (m->marioObj->oInteractStatus & INT_STATUS_MARIO_UNK6) == 0; s32 thrown = (m->marioObj->oInteractStatus & INT_STATUS_MARIO_UNK6) == 0;
@ -728,6 +752,7 @@ s32 act_grabbed(struct MarioState *m) {
} }
s32 act_in_cannon(struct MarioState *m) { s32 act_in_cannon(struct MarioState *m) {
if (!m) { return 0; }
struct Object *marioObj = m->marioObj; struct Object *marioObj = m->marioObj;
s16 startFacePitch = m->faceAngle[0]; s16 startFacePitch = m->faceAngle[0];
s16 startFaceYaw = m->faceAngle[1]; s16 startFaceYaw = m->faceAngle[1];
@ -822,6 +847,7 @@ s32 act_in_cannon(struct MarioState *m) {
} }
s32 act_tornado_twirling(struct MarioState *m) { s32 act_tornado_twirling(struct MarioState *m) {
if (!m) { return 0; }
if (m->usedObj == NULL) { return FALSE; } if (m->usedObj == NULL) { return FALSE; }
struct Surface *floor; struct Surface *floor;
@ -904,6 +930,7 @@ s32 act_tornado_twirling(struct MarioState *m) {
static void bubbled_offset_visual(struct MarioState* m) { static void bubbled_offset_visual(struct MarioState* m) {
if (!m) { return; }
// scary 3d trig ahead // scary 3d trig ahead
f32 forwardOffset = 25; f32 forwardOffset = 25;
@ -941,6 +968,7 @@ static void bubbled_offset_visual(struct MarioState* m) {
} }
s32 act_bubbled(struct MarioState* m) { s32 act_bubbled(struct MarioState* m) {
if (!m) { return 0; }
if (m->playerIndex == 0 && m->area->camera->mode == CAMERA_MODE_WATER_SURFACE) { if (m->playerIndex == 0 && m->area->camera->mode == CAMERA_MODE_WATER_SURFACE) {
set_camera_mode(m->area->camera, CAMERA_MODE_FREE_ROAM, 1); set_camera_mode(m->area->camera, CAMERA_MODE_FREE_ROAM, 1);
} }
@ -1068,6 +1096,7 @@ s32 act_bubbled(struct MarioState* m) {
} }
s32 check_common_automatic_cancels(struct MarioState *m) { s32 check_common_automatic_cancels(struct MarioState *m) {
if (!m) { return 0; }
if (m->pos[1] < m->waterLevel - 100) { if (m->pos[1] < m->waterLevel - 100) {
return set_water_plunge_action(m); return set_water_plunge_action(m);
} }
@ -1076,6 +1105,7 @@ s32 check_common_automatic_cancels(struct MarioState *m) {
} }
s32 mario_execute_automatic_action(struct MarioState *m) { s32 mario_execute_automatic_action(struct MarioState *m) {
if (!m) { return 0; }
if (!m) { return FALSE; } if (!m) { return FALSE; }
s32 cancel; s32 cancel;

View file

@ -195,6 +195,7 @@ void bhv_end_peach_loop(void) {
} }
void bhv_end_toad_loop(void) { void bhv_end_toad_loop(void) {
if (!gCurrentObject) { return; }
s32 toadAnimIndex = (gCurrentObject->oPosX >= 0.0f); s32 toadAnimIndex = (gCurrentObject->oPosX >= 0.0f);
cur_obj_init_animation_with_sound(sEndToadAnims[toadAnimIndex]); cur_obj_init_animation_with_sound(sEndToadAnims[toadAnimIndex]);
@ -435,7 +436,7 @@ s32 set_mario_npc_dialog(struct MarioState* m, s32 actionArg, u8 (*inContinueDia
// 9 - 22: looking away from npc // 9 - 22: looking away from npc
// 23: end // 23: end
s32 act_reading_npc_dialog(struct MarioState *m) { s32 act_reading_npc_dialog(struct MarioState *m) {
if (!m) { return 23; } if (!m || !gCurrentObject) { return 23; }
s32 headTurnAmount = 0; s32 headTurnAmount = 0;
s16 angleToNPC; s16 angleToNPC;
@ -759,6 +760,7 @@ void general_star_dance_handler(struct MarioState *m, s32 isInWater) {
} }
s32 act_star_dance(struct MarioState *m) { s32 act_star_dance(struct MarioState *m) {
if (!m) { return 0; }
if (m == &gMarioStates[0]) { if (m == &gMarioStates[0]) {
m->faceAngle[1] = m->area->camera->yaw; m->faceAngle[1] = m->area->camera->yaw;
} }
@ -772,6 +774,7 @@ s32 act_star_dance(struct MarioState *m) {
} }
s32 act_star_dance_water(struct MarioState *m) { s32 act_star_dance_water(struct MarioState *m) {
if (!m) { return 0; }
if (m == &gMarioStates[0]) { if (m == &gMarioStates[0]) {
m->faceAngle[1] = m->area->camera->yaw; m->faceAngle[1] = m->area->camera->yaw;
} }
@ -786,6 +789,7 @@ s32 act_star_dance_water(struct MarioState *m) {
} }
s32 act_fall_after_star_grab(struct MarioState *m) { s32 act_fall_after_star_grab(struct MarioState *m) {
if (!m) { return 0; }
if (m->pos[1] < m->waterLevel - 130) { if (m->pos[1] < m->waterLevel - 130) {
play_sound(SOUND_ACTION_UNKNOWN430, m->marioObj->header.gfx.cameraToObject); play_sound(SOUND_ACTION_UNKNOWN430, m->marioObj->header.gfx.cameraToObject);
set_mario_particle_flags(m, PARTICLE_WATER_SPLASH, FALSE); set_mario_particle_flags(m, PARTICLE_WATER_SPLASH, FALSE);
@ -800,6 +804,7 @@ s32 act_fall_after_star_grab(struct MarioState *m) {
} }
s32 common_death_handler(struct MarioState *m, s32 animation, s32 frameToDeathWarp) { s32 common_death_handler(struct MarioState *m, s32 animation, s32 frameToDeathWarp) {
if (!m) { return 0; }
s32 animFrame = set_mario_animation(m, animation); s32 animFrame = set_mario_animation(m, animation);
if (animFrame == frameToDeathWarp) { if (animFrame == frameToDeathWarp) {
if (m->playerIndex != 0) { if (m->playerIndex != 0) {
@ -822,6 +827,7 @@ s32 common_death_handler(struct MarioState *m, s32 animation, s32 frameToDeathWa
} }
s32 act_standing_death(struct MarioState *m) { s32 act_standing_death(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_IN_POISON_GAS) { if (m->input & INPUT_IN_POISON_GAS) {
return set_mario_action(m, ACT_SUFFOCATION, 0); return set_mario_action(m, ACT_SUFFOCATION, 0);
} }
@ -863,6 +869,7 @@ s32 act_death_on_stomach(struct MarioState *m) {
} }
s32 act_quicksand_death(struct MarioState *m) { s32 act_quicksand_death(struct MarioState *m) {
if (!m) { return 0; }
if (m->actionState == 0) { if (m->actionState == 0) {
set_mario_animation(m, MARIO_ANIM_DYING_IN_QUICKSAND); set_mario_animation(m, MARIO_ANIM_DYING_IN_QUICKSAND);
set_anim_to_frame(m, 60); set_anim_to_frame(m, 60);
@ -895,6 +902,7 @@ s32 act_quicksand_death(struct MarioState *m) {
} }
s32 act_eaten_by_bubba(struct MarioState *m) { s32 act_eaten_by_bubba(struct MarioState *m) {
if (!m) { return 0; }
play_character_sound_if_no_flag(m, CHAR_SOUND_DYING, MARIO_ACTION_SOUND_PLAYED); play_character_sound_if_no_flag(m, CHAR_SOUND_DYING, MARIO_ACTION_SOUND_PLAYED);
set_mario_animation(m, MARIO_ANIM_A_POSE); set_mario_animation(m, MARIO_ANIM_A_POSE);
@ -932,6 +940,7 @@ s32 launch_mario_until_land(struct MarioState *m, s32 endAction, s32 animation,
} }
s32 act_unlocking_key_door(struct MarioState *m) { s32 act_unlocking_key_door(struct MarioState *m) {
if (!m) { return 0; }
if (m->usedObj != NULL) { if (m->usedObj != NULL) {
m->faceAngle[1] = m->usedObj->oMoveAngleYaw; m->faceAngle[1] = m->usedObj->oMoveAngleYaw;
@ -943,7 +952,7 @@ s32 act_unlocking_key_door(struct MarioState *m) {
m->faceAngle[1] += 0x8000; m->faceAngle[1] += 0x8000;
} }
if ((m->actionTimer == 0) || (m->playerIndex != 0 && gCurrentObject->header.gfx.animInfo.animID == -1)) { if ((m->actionTimer == 0) || (m->playerIndex != 0 && gCurrentObject && gCurrentObject->header.gfx.animInfo.animID == -1)) {
spawn_obj_at_mario_rel_yaw(m, MODEL_BOWSER_KEY_CUTSCENE, bhvBowserKeyUnlockDoor, 0); spawn_obj_at_mario_rel_yaw(m, MODEL_BOWSER_KEY_CUTSCENE, bhvBowserKeyUnlockDoor, 0);
set_mario_animation(m, MARIO_ANIM_UNLOCK_DOOR); set_mario_animation(m, MARIO_ANIM_UNLOCK_DOOR);
} }
@ -976,6 +985,7 @@ s32 act_unlocking_key_door(struct MarioState *m) {
} }
s32 act_unlocking_star_door(struct MarioState *m) { s32 act_unlocking_star_door(struct MarioState *m) {
if (!m) { return 0; }
static u8 allowRemoteStarSpawn = TRUE; static u8 allowRemoteStarSpawn = TRUE;
switch (m->actionState) { switch (m->actionState) {
case 0: case 0:
@ -1025,6 +1035,7 @@ s32 act_unlocking_star_door(struct MarioState *m) {
} }
s32 act_entering_star_door(struct MarioState *m) { s32 act_entering_star_door(struct MarioState *m) {
if (!m) { return 0; }
f32 targetDX = 0; f32 targetDX = 0;
f32 targetDZ = 0; f32 targetDZ = 0;
s16 targetAngle = 0; s16 targetAngle = 0;
@ -1087,6 +1098,7 @@ s32 act_entering_star_door(struct MarioState *m) {
} }
s32 act_going_through_door(struct MarioState *m) { s32 act_going_through_door(struct MarioState *m) {
if (!m) { return 0; }
if (m->actionTimer == 0) { if (m->actionTimer == 0) {
if (m->actionArg & 1) { if (m->actionArg & 1) {
if (m->interactObj != NULL) { if (m->interactObj != NULL) {
@ -1125,6 +1137,7 @@ s32 act_going_through_door(struct MarioState *m) {
} }
s32 act_warp_door_spawn(struct MarioState *m) { s32 act_warp_door_spawn(struct MarioState *m) {
if (!m) { return 0; }
if (m->actionState == 0) { if (m->actionState == 0) {
m->actionState = 1; m->actionState = 1;
if (m->usedObj != NULL) { if (m->usedObj != NULL) {
@ -1149,6 +1162,7 @@ s32 act_warp_door_spawn(struct MarioState *m) {
} }
static s32 launch_mario_until_land_no_collision(struct MarioState *m, s32 endAction, s32 animation, f32 forwardVel) { static s32 launch_mario_until_land_no_collision(struct MarioState *m, s32 endAction, s32 animation, f32 forwardVel) {
if (!m) { return 0; }
mario_set_forward_vel(m, forwardVel); mario_set_forward_vel(m, forwardVel);
set_mario_animation(m, animation); set_mario_animation(m, animation);
m->pos[0] += m->vel[0]; m->pos[0] += m->vel[0];
@ -1170,6 +1184,7 @@ static s32 launch_mario_until_land_no_collision(struct MarioState *m, s32 endAct
} }
s32 act_emerge_from_pipe(struct MarioState *m) { s32 act_emerge_from_pipe(struct MarioState *m) {
if (!m) { return 0; }
struct Object *marioObj = m->marioObj; struct Object *marioObj = m->marioObj;
if (m->actionTimer++ < 11) { if (m->actionTimer++ < 11) {
@ -1207,6 +1222,7 @@ s32 act_emerge_from_pipe(struct MarioState *m) {
} }
s32 act_spawn_spin_airborne(struct MarioState *m) { s32 act_spawn_spin_airborne(struct MarioState *m) {
if (!m) { return 0; }
// entered water, exit action // entered water, exit action
if (m->pos[1] < m->waterLevel - 100) { if (m->pos[1] < m->waterLevel - 100) {
if (m == &gMarioStates[0]) { if (m == &gMarioStates[0]) {
@ -1260,6 +1276,7 @@ s32 act_spawn_spin_landing(struct MarioState *m) {
* particle flag that generates sparkles. * particle flag that generates sparkles.
*/ */
s32 act_exit_airborne(struct MarioState *m) { s32 act_exit_airborne(struct MarioState *m) {
if (!m) { return 0; }
if (15 < m->actionTimer++ if (15 < m->actionTimer++
&& launch_mario_until_land(m, ACT_EXIT_LAND_SAVE_DIALOG, MARIO_ANIM_GENERAL_FALL, -32.0f)) { && launch_mario_until_land(m, ACT_EXIT_LAND_SAVE_DIALOG, MARIO_ANIM_GENERAL_FALL, -32.0f)) {
// heal Mario // heal Mario
@ -1272,6 +1289,7 @@ s32 act_exit_airborne(struct MarioState *m) {
} }
s32 act_falling_exit_airborne(struct MarioState *m) { s32 act_falling_exit_airborne(struct MarioState *m) {
if (!m) { return 0; }
if (launch_mario_until_land(m, ACT_EXIT_LAND_SAVE_DIALOG, MARIO_ANIM_GENERAL_FALL, 0.0f)) { if (launch_mario_until_land(m, ACT_EXIT_LAND_SAVE_DIALOG, MARIO_ANIM_GENERAL_FALL, 0.0f)) {
// heal Mario // heal Mario
m->healCounter = 31; m->healCounter = 31;
@ -1283,6 +1301,7 @@ s32 act_falling_exit_airborne(struct MarioState *m) {
} }
s32 act_exit_land_save_dialog(struct MarioState *m) { s32 act_exit_land_save_dialog(struct MarioState *m) {
if (!m) { return 0; }
s32 animFrame; s32 animFrame;
stationary_ground_step(m); stationary_ground_step(m);
play_mario_landing_sound_once(m, SOUND_ACTION_TERRAIN_LANDING); play_mario_landing_sound_once(m, SOUND_ACTION_TERRAIN_LANDING);
@ -1368,6 +1387,7 @@ s32 act_exit_land_save_dialog(struct MarioState *m) {
} }
s32 act_death_exit(struct MarioState *m) { s32 act_death_exit(struct MarioState *m) {
if (!m) { return 0; }
if (15 < m->actionTimer++ if (15 < m->actionTimer++
&& launch_mario_until_land(m, ACT_DEATH_EXIT_LAND, MARIO_ANIM_GENERAL_FALL, -32.0f)) { && launch_mario_until_land(m, ACT_DEATH_EXIT_LAND, MARIO_ANIM_GENERAL_FALL, -32.0f)) {
#ifdef VERSION_JP #ifdef VERSION_JP
@ -1385,6 +1405,7 @@ s32 act_death_exit(struct MarioState *m) {
} }
s32 act_unused_death_exit(struct MarioState *m) { s32 act_unused_death_exit(struct MarioState *m) {
if (!m) { return 0; }
if (launch_mario_until_land(m, ACT_FREEFALL_LAND_STOP, MARIO_ANIM_GENERAL_FALL, 0.0f)) { if (launch_mario_until_land(m, ACT_FREEFALL_LAND_STOP, MARIO_ANIM_GENERAL_FALL, 0.0f)) {
#ifdef VERSION_JP #ifdef VERSION_JP
play_character_sound(m, CHAR_SOUND_OOOF); play_character_sound(m, CHAR_SOUND_OOOF);
@ -1400,6 +1421,7 @@ s32 act_unused_death_exit(struct MarioState *m) {
} }
s32 act_falling_death_exit(struct MarioState *m) { s32 act_falling_death_exit(struct MarioState *m) {
if (!m) { return 0; }
if (launch_mario_until_land(m, ACT_DEATH_EXIT_LAND, MARIO_ANIM_GENERAL_FALL, 0.0f)) { if (launch_mario_until_land(m, ACT_DEATH_EXIT_LAND, MARIO_ANIM_GENERAL_FALL, 0.0f)) {
#ifdef VERSION_JP #ifdef VERSION_JP
play_character_sound(m, CHAR_SOUND_OOOF); play_character_sound(m, CHAR_SOUND_OOOF);
@ -1417,6 +1439,7 @@ s32 act_falling_death_exit(struct MarioState *m) {
// waits 11 frames before actually executing, also has reduced fvel // waits 11 frames before actually executing, also has reduced fvel
s32 act_special_exit_airborne(struct MarioState *m) { s32 act_special_exit_airborne(struct MarioState *m) {
if (!m) { return 0; }
struct Object *marioObj = m->marioObj; struct Object *marioObj = m->marioObj;
play_character_sound_if_no_flag(m, CHAR_SOUND_YAHOO, MARIO_MARIO_SOUND_PLAYED); play_character_sound_if_no_flag(m, CHAR_SOUND_YAHOO, MARIO_MARIO_SOUND_PLAYED);
@ -1442,6 +1465,7 @@ s32 act_special_exit_airborne(struct MarioState *m) {
} }
s32 act_special_death_exit(struct MarioState *m) { s32 act_special_death_exit(struct MarioState *m) {
if (!m) { return 0; }
struct Object *marioObj = m->marioObj; struct Object *marioObj = m->marioObj;
if (m->actionTimer++ < 11) { if (m->actionTimer++ < 11) {
@ -1462,6 +1486,7 @@ s32 act_special_death_exit(struct MarioState *m) {
} }
s32 act_spawn_no_spin_airborne(struct MarioState *m) { s32 act_spawn_no_spin_airborne(struct MarioState *m) {
if (!m) { return 0; }
launch_mario_until_land(m, ACT_SPAWN_NO_SPIN_LANDING, MARIO_ANIM_GENERAL_FALL, 0.0f); launch_mario_until_land(m, ACT_SPAWN_NO_SPIN_LANDING, MARIO_ANIM_GENERAL_FALL, 0.0f);
if (m->pos[1] < m->waterLevel - 100) { if (m->pos[1] < m->waterLevel - 100) {
set_water_plunge_action(m); set_water_plunge_action(m);
@ -1483,6 +1508,7 @@ s32 act_spawn_no_spin_landing(struct MarioState *m) {
} }
s32 act_bbh_enter_spin(struct MarioState *m) { s32 act_bbh_enter_spin(struct MarioState *m) {
if (!m) { return 0; }
f32 cageDX = 0.0f; f32 cageDX = 0.0f;
f32 cageDZ = 0.0f; f32 cageDZ = 0.0f;
f32 forwardVel = 0.0f; f32 forwardVel = 0.0f;
@ -1569,6 +1595,7 @@ s32 act_bbh_enter_spin(struct MarioState *m) {
} }
s32 act_bbh_enter_jump(struct MarioState *m) { s32 act_bbh_enter_jump(struct MarioState *m) {
if (!m) { return 0; }
play_mario_action_sound(m, m->flags & MARIO_METAL_CAP ? SOUND_ACTION_METAL_JUMP : SOUND_ACTION_TERRAIN_JUMP, 1); play_mario_action_sound(m, m->flags & MARIO_METAL_CAP ? SOUND_ACTION_METAL_JUMP : SOUND_ACTION_TERRAIN_JUMP, 1);
play_mario_jump_sound(m); play_mario_jump_sound(m);
@ -1600,6 +1627,7 @@ s32 act_bbh_enter_jump(struct MarioState *m) {
} }
s32 act_teleport_fade_out(struct MarioState *m) { s32 act_teleport_fade_out(struct MarioState *m) {
if (!m) { return 0; }
play_sound_if_no_flag(m, SOUND_ACTION_TELEPORT, MARIO_ACTION_SOUND_PLAYED); play_sound_if_no_flag(m, SOUND_ACTION_TELEPORT, MARIO_ACTION_SOUND_PLAYED);
set_mario_animation(m, m->prevAction == ACT_CROUCHING ? MARIO_ANIM_CROUCHING : MARIO_ANIM_FIRST_PERSON); set_mario_animation(m, m->prevAction == ACT_CROUCHING ? MARIO_ANIM_CROUCHING : MARIO_ANIM_FIRST_PERSON);
@ -1629,6 +1657,7 @@ s32 act_teleport_fade_out(struct MarioState *m) {
} }
s32 act_teleport_fade_in(struct MarioState *m) { s32 act_teleport_fade_in(struct MarioState *m) {
if (!m) { return 0; }
play_sound_if_no_flag(m, SOUND_ACTION_TELEPORT, MARIO_ACTION_SOUND_PLAYED); play_sound_if_no_flag(m, SOUND_ACTION_TELEPORT, MARIO_ACTION_SOUND_PLAYED);
set_mario_animation(m, MARIO_ANIM_FIRST_PERSON); set_mario_animation(m, MARIO_ANIM_FIRST_PERSON);
@ -1664,6 +1693,7 @@ s32 act_teleport_fade_in(struct MarioState *m) {
} }
s32 act_shocked(struct MarioState *m) { s32 act_shocked(struct MarioState *m) {
if (!m) { return 0; }
play_character_sound_if_no_flag(m, CHAR_SOUND_WAAAOOOW, MARIO_MARIO_SOUND_PLAYED); play_character_sound_if_no_flag(m, CHAR_SOUND_WAAAOOOW, MARIO_MARIO_SOUND_PLAYED);
play_sound(SOUND_MOVING_SHOCKED, m->marioObj->header.gfx.cameraToObject); play_sound(SOUND_MOVING_SHOCKED, m->marioObj->header.gfx.cameraToObject);
if (m->playerIndex == 0) { set_camera_shake_from_hit(SHAKE_SHOCK); } if (m->playerIndex == 0) { set_camera_shake_from_hit(SHAKE_SHOCK); }
@ -1880,12 +1910,14 @@ s32 act_feet_stuck_in_ground(struct MarioState *m) {
* for keeping track of what step of the cutscene Mario is in.) * for keeping track of what step of the cutscene Mario is in.)
*/ */
static void advance_cutscene_step(struct MarioState *m) { static void advance_cutscene_step(struct MarioState *m) {
if (!m) { return; }
m->actionState = 0; m->actionState = 0;
m->actionTimer = 0; m->actionTimer = 0;
m->actionArg++; m->actionArg++;
} }
static void intro_cutscene_hide_hud_and_mario(struct MarioState *m) { static void intro_cutscene_hide_hud_and_mario(struct MarioState *m) {
if (!m) { return; }
gHudDisplay.flags = HUD_DISPLAY_NONE; gHudDisplay.flags = HUD_DISPLAY_NONE;
m->statusForCamera->cameraEvent = CAM_EVENT_START_INTRO; m->statusForCamera->cameraEvent = CAM_EVENT_START_INTRO;
m->marioObj->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE; m->marioObj->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
@ -1900,6 +1932,7 @@ static void intro_cutscene_hide_hud_and_mario(struct MarioState *m) {
#endif #endif
static void intro_cutscene_peach_lakitu_scene(struct MarioState *m) { static void intro_cutscene_peach_lakitu_scene(struct MarioState *m) {
if (!m) { return; }
if ((s16) m->statusForCamera->cameraEvent != CAM_EVENT_START_INTRO) { if ((s16) m->statusForCamera->cameraEvent != CAM_EVENT_START_INTRO) {
if (m->actionTimer++ == TIMER_SPAWN_PIPE) { if (m->actionTimer++ == TIMER_SPAWN_PIPE) {
u8 globalIndex = gNetworkPlayers[m->playerIndex].globalIndex; u8 globalIndex = gNetworkPlayers[m->playerIndex].globalIndex;
@ -1921,6 +1954,7 @@ static void intro_cutscene_peach_lakitu_scene(struct MarioState *m) {
#endif #endif
static void intro_cutscene_raise_pipe(struct MarioState* m) { static void intro_cutscene_raise_pipe(struct MarioState* m) {
if (!m) { return; }
u8 globalIndex = gNetworkPlayers[m->playerIndex].globalIndex; u8 globalIndex = gNetworkPlayers[m->playerIndex].globalIndex;
if (globalIndex == UNKNOWN_GLOBAL_INDEX) { globalIndex = 0; } if (globalIndex == UNKNOWN_GLOBAL_INDEX) { globalIndex = 0; }
@ -1939,6 +1973,7 @@ static void intro_cutscene_raise_pipe(struct MarioState* m) {
} }
static void intro_cutscene_raise_pipe_main_menu(struct MarioState* m) { static void intro_cutscene_raise_pipe_main_menu(struct MarioState* m) {
if (!m) { return; }
u8 globalIndex = gNetworkPlayers[m->playerIndex].globalIndex; u8 globalIndex = gNetworkPlayers[m->playerIndex].globalIndex;
if (globalIndex == UNKNOWN_GLOBAL_INDEX) { globalIndex = 0; } if (globalIndex == UNKNOWN_GLOBAL_INDEX) { globalIndex = 0; }
if (sIntroWarpPipeObj[globalIndex] == NULL) { if (sIntroWarpPipeObj[globalIndex] == NULL) {
@ -1958,6 +1993,7 @@ static void intro_cutscene_raise_pipe_main_menu(struct MarioState* m) {
#undef TIMER_RAISE_PIPE #undef TIMER_RAISE_PIPE
static void intro_cutscene_jump_out_of_pipe(struct MarioState *m) { static void intro_cutscene_jump_out_of_pipe(struct MarioState *m) {
if (!m) { return; }
if (m->actionTimer <= 1) { if (m->actionTimer <= 1) {
u8 globalIndex = gNetworkPlayers[m->playerIndex].globalIndex; u8 globalIndex = gNetworkPlayers[m->playerIndex].globalIndex;
if (globalIndex == UNKNOWN_GLOBAL_INDEX) { globalIndex = 0; } if (globalIndex == UNKNOWN_GLOBAL_INDEX) { globalIndex = 0; }
@ -2010,6 +2046,7 @@ static void intro_cutscene_land_outside_pipe(struct MarioState *m) {
} }
static void intro_cutscene_lower_pipe(struct MarioState *m) { static void intro_cutscene_lower_pipe(struct MarioState *m) {
if (!m) { return; }
u8 globalIndex = gNetworkPlayers[m->playerIndex].globalIndex; u8 globalIndex = gNetworkPlayers[m->playerIndex].globalIndex;
if (globalIndex == UNKNOWN_GLOBAL_INDEX) { globalIndex = 0; } if (globalIndex == UNKNOWN_GLOBAL_INDEX) { globalIndex = 0; }
if (m->actionTimer++ == 0) { if (m->actionTimer++ == 0) {
@ -2033,6 +2070,7 @@ static void intro_cutscene_lower_pipe(struct MarioState *m) {
} }
static void intro_cutscene_set_mario_to_idle(struct MarioState *m) { static void intro_cutscene_set_mario_to_idle(struct MarioState *m) {
if (!m || !gCamera) { return; }
if (gCamera->cutscene == 0) { if (gCamera->cutscene == 0) {
if (m->playerIndex == 0) { if (m->playerIndex == 0) {
gCameraMovementFlags &= ~CAM_MOVE_C_UP_MODE; gCameraMovementFlags &= ~CAM_MOVE_C_UP_MODE;
@ -2055,6 +2093,7 @@ enum {
}; };
static s32 act_intro_cutscene(struct MarioState *m) { static s32 act_intro_cutscene(struct MarioState *m) {
if (!m) { return 0; }
switch (m->actionArg) { switch (m->actionArg) {
case INTRO_CUTSCENE_HIDE_HUD_AND_MARIO: case INTRO_CUTSCENE_HIDE_HUD_AND_MARIO:
intro_cutscene_hide_hud_and_mario(m); intro_cutscene_hide_hud_and_mario(m);
@ -2085,12 +2124,14 @@ static s32 act_intro_cutscene(struct MarioState *m) {
} }
static void jumbo_star_offset(struct MarioState* m) { 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[0] += 300.0f * sins(m->faceAngle[1] + 0x4000 * m->playerIndex);
m->pos[2] += 300.0f * coss(m->faceAngle[1] + 0x4000 * m->playerIndex); m->pos[2] += 300.0f * coss(m->faceAngle[1] + 0x4000 * m->playerIndex);
} }
// jumbo star cutscene: Mario lands after grabbing the jumbo star // jumbo star cutscene: Mario lands after grabbing the jumbo star
static void jumbo_star_cutscene_falling(struct MarioState *m) { static void jumbo_star_cutscene_falling(struct MarioState *m) {
if (!m) { return; }
if (m->actionState == 0) { if (m->actionState == 0) {
m->input |= INPUT_A_DOWN; m->input |= INPUT_A_DOWN;
m->flags |= (MARIO_WING_CAP | MARIO_CAP_ON_HEAD); m->flags |= (MARIO_WING_CAP | MARIO_CAP_ON_HEAD);
@ -2118,6 +2159,7 @@ static void jumbo_star_cutscene_falling(struct MarioState *m) {
// jumbo star cutscene: Mario takes off // jumbo star cutscene: Mario takes off
static s32 jumbo_star_cutscene_taking_off(struct MarioState *m) { static s32 jumbo_star_cutscene_taking_off(struct MarioState *m) {
if (!m) { return 0; }
struct Object *marioObj = m->marioObj; struct Object *marioObj = m->marioObj;
if (m->actionState == 0) { if (m->actionState == 0) {
@ -2171,6 +2213,7 @@ static s32 jumbo_star_cutscene_taking_off(struct MarioState *m) {
// jumbo star cutscene: Mario flying // jumbo star cutscene: Mario flying
static s32 jumbo_star_cutscene_flying(struct MarioState *m) { static s32 jumbo_star_cutscene_flying(struct MarioState *m) {
if (!m) { return 0; }
Vec3f targetPos; Vec3f targetPos;
switch (m->actionState) { switch (m->actionState) {
@ -2221,6 +2264,7 @@ static s32 jumbo_star_cutscene_flying(struct MarioState *m) {
enum { JUMBO_STAR_CUTSCENE_FALLING, JUMBO_STAR_CUTSCENE_TAKING_OFF, JUMBO_STAR_CUTSCENE_FLYING }; enum { JUMBO_STAR_CUTSCENE_FALLING, JUMBO_STAR_CUTSCENE_TAKING_OFF, JUMBO_STAR_CUTSCENE_FLYING };
static s32 act_jumbo_star_cutscene(struct MarioState *m) { static s32 act_jumbo_star_cutscene(struct MarioState *m) {
if (!m) { return 0; }
switch (m->actionArg) { switch (m->actionArg) {
case JUMBO_STAR_CUTSCENE_FALLING: case JUMBO_STAR_CUTSCENE_FALLING:
jumbo_star_cutscene_falling(m); jumbo_star_cutscene_falling(m);
@ -2275,6 +2319,7 @@ static f32 end_obj_set_visual_pos(struct Object *o) {
// make Mario fall and soften wing cap gravity // make Mario fall and soften wing cap gravity
static void end_peach_cutscene_mario_falling(struct MarioState *m) { static void end_peach_cutscene_mario_falling(struct MarioState *m) {
if (!m) { return; }
if (m->actionTimer == 1) { if (m->actionTimer == 1) {
m->statusForCamera->cameraEvent = CAM_EVENT_START_ENDING; m->statusForCamera->cameraEvent = CAM_EVENT_START_ENDING;
} }
@ -2293,6 +2338,7 @@ static void end_peach_cutscene_mario_falling(struct MarioState *m) {
// set Mario on the ground, wait and spawn the jumbo star outside the castle. // set Mario on the ground, wait and spawn the jumbo star outside the castle.
static void end_peach_cutscene_mario_landing(struct MarioState *m) { static void end_peach_cutscene_mario_landing(struct MarioState *m) {
if (!m) { return; }
set_mario_animation(m, MARIO_ANIM_GENERAL_LAND); set_mario_animation(m, MARIO_ANIM_GENERAL_LAND);
stop_and_set_height_to_floor(m); stop_and_set_height_to_floor(m);
@ -2313,6 +2359,7 @@ static void end_peach_cutscene_mario_landing(struct MarioState *m) {
// raise hand animation, lower hand animation, do some special effects // raise hand animation, lower hand animation, do some special effects
static void end_peach_cutscene_summon_jumbo_star(struct MarioState *m) { static void end_peach_cutscene_summon_jumbo_star(struct MarioState *m) {
if (!m) { return; }
set_mario_animation(m, m->actionState == 0 ? MARIO_ANIM_CREDITS_RAISE_HAND set_mario_animation(m, m->actionState == 0 ? MARIO_ANIM_CREDITS_RAISE_HAND
: MARIO_ANIM_CREDITS_LOWER_HAND); : MARIO_ANIM_CREDITS_LOWER_HAND);
if (m->playerIndex != 0) { return; } if (m->playerIndex != 0) { return; }
@ -2348,6 +2395,7 @@ static void end_peach_cutscene_summon_jumbo_star(struct MarioState *m) {
// free peach from the stained glass window // free peach from the stained glass window
static void end_peach_cutscene_spawn_peach(struct MarioState *m) { static void end_peach_cutscene_spawn_peach(struct MarioState *m) {
if (!m) { return; }
if (m->playerIndex != 0) { return; } if (m->playerIndex != 0) { return; }
if (m->actionTimer == 1) { if (m->actionTimer == 1) {
play_transition(WARP_TRANSITION_FADE_INTO_COLOR, 14, 255, 255, 255); play_transition(WARP_TRANSITION_FADE_INTO_COLOR, 14, 255, 255, 255);
@ -2407,6 +2455,7 @@ static void end_peach_cutscene_spawn_peach(struct MarioState *m) {
// descend peach // descend peach
static void end_peach_cutscene_descend_peach(struct MarioState *m) { static void end_peach_cutscene_descend_peach(struct MarioState *m) {
if (!m) { return; }
if (m->playerIndex != 0) { return; } if (m->playerIndex != 0) { return; }
generate_yellow_sparkles(0, sEndPeachObj->oPosY, -1300, 150.0f); generate_yellow_sparkles(0, sEndPeachObj->oPosY, -1300, 150.0f);
@ -2436,6 +2485,7 @@ static void end_peach_cutscene_descend_peach(struct MarioState *m) {
// Mario runs to peach // Mario runs to peach
static void end_peach_cutscene_run_to_peach(struct MarioState *m) { static void end_peach_cutscene_run_to_peach(struct MarioState *m) {
if (!m) { return; }
struct Surface *surf; struct Surface *surf;
if (m->actionTimer == 22) { if (m->actionTimer == 22) {
@ -2460,6 +2510,7 @@ static void end_peach_cutscene_run_to_peach(struct MarioState *m) {
// "Mario!" // "Mario!"
// "The power of the Stars is restored to the castle..." // "The power of the Stars is restored to the castle..."
static void end_peach_cutscene_dialog_1(struct MarioState *m) { static void end_peach_cutscene_dialog_1(struct MarioState *m) {
if (!m) { return; }
s32 animFrame = set_mario_animation(m, m->actionState == 0 ? MARIO_ANIM_CREDITS_TAKE_OFF_CAP s32 animFrame = set_mario_animation(m, m->actionState == 0 ? MARIO_ANIM_CREDITS_TAKE_OFF_CAP
: MARIO_ANIM_CREDITS_LOOK_UP); : MARIO_ANIM_CREDITS_LOOK_UP);
@ -2569,6 +2620,7 @@ static void end_peach_cutscene_dialog_1(struct MarioState *m) {
// "Thank you Mario!" // "Thank you Mario!"
// "We have to do something special for you..." // "We have to do something special for you..."
static void end_peach_cutscene_dialog_2(struct MarioState *m) { static void end_peach_cutscene_dialog_2(struct MarioState *m) {
if (!m) { return; }
if (m->playerIndex != 0) { return; } if (m->playerIndex != 0) { return; }
sEndPeachAnimation = 9; sEndPeachAnimation = 9;
@ -2629,6 +2681,7 @@ static u8 sMarioBlinkOverride[20] = {
}; };
static void end_peach_cutscene_kiss_from_peach(struct MarioState *m) { static void end_peach_cutscene_kiss_from_peach(struct MarioState *m) {
if (!m) { return; }
sEndPeachAnimation = 10; sEndPeachAnimation = 10;
if (m->actionTimer >= 90) { if (m->actionTimer >= 90) {
@ -2672,6 +2725,7 @@ static void end_peach_cutscene_kiss_from_peach(struct MarioState *m) {
} }
static void end_peach_cutscene_star_dance(struct MarioState *m) { static void end_peach_cutscene_star_dance(struct MarioState *m) {
if (!m) { return; }
u8 nonMario = (gNetworkPlayers[m->playerIndex].globalIndex != 0); u8 nonMario = (gNetworkPlayers[m->playerIndex].globalIndex != 0);
s32 animFrame = set_mario_animation(m, nonMario ? MARIO_ANIM_START_SLEEP_SITTING : MARIO_ANIM_CREDITS_PEACE_SIGN); s32 animFrame = set_mario_animation(m, nonMario ? MARIO_ANIM_START_SLEEP_SITTING : MARIO_ANIM_CREDITS_PEACE_SIGN);
@ -2726,6 +2780,7 @@ static void end_peach_cutscene_star_dance(struct MarioState *m) {
// "let's bake a delicious cake..." // "let's bake a delicious cake..."
// "...for Mario..." // "...for Mario..."
static void end_peach_cutscene_dialog_3(struct MarioState *m) { static void end_peach_cutscene_dialog_3(struct MarioState *m) {
if (!m) { return; }
u8 nonMario = (gNetworkPlayers[m->playerIndex].globalIndex != 0); u8 nonMario = (gNetworkPlayers[m->playerIndex].globalIndex != 0);
set_mario_animation(m, nonMario ? MARIO_ANIM_SLEEP_IDLE : MARIO_ANIM_FIRST_PERSON); set_mario_animation(m, nonMario ? MARIO_ANIM_SLEEP_IDLE : MARIO_ANIM_FIRST_PERSON);
if (m->playerIndex != 0) { return; } if (m->playerIndex != 0) { return; }
@ -2764,6 +2819,7 @@ static void end_peach_cutscene_dialog_3(struct MarioState *m) {
// "Mario!" // "Mario!"
static void end_peach_cutscene_run_to_castle(struct MarioState *m) { static void end_peach_cutscene_run_to_castle(struct MarioState *m) {
if (!m) { return; }
u8 nonMario = (gNetworkPlayers[m->playerIndex].globalIndex != 0); u8 nonMario = (gNetworkPlayers[m->playerIndex].globalIndex != 0);
if (nonMario) { if (nonMario) {
set_mario_animation(m, m->actionState == 0 ? MARIO_ANIM_SLEEP_START_LYING set_mario_animation(m, m->actionState == 0 ? MARIO_ANIM_SLEEP_START_LYING
@ -2790,6 +2846,7 @@ static void end_peach_cutscene_run_to_castle(struct MarioState *m) {
} }
static void end_peach_cutscene_fade_out(struct MarioState *m) { static void end_peach_cutscene_fade_out(struct MarioState *m) {
if (!m) { return; }
if (m->actionState == 0 && m->playerIndex == 0) { if (m->actionState == 0 && m->playerIndex == 0) {
level_trigger_warp(m, WARP_OP_CREDITS_NEXT); level_trigger_warp(m, WARP_OP_CREDITS_NEXT);
gPaintingMarioYEntry = 1500.0f; // ensure medium water level in WDW credits cutscene gPaintingMarioYEntry = 1500.0f; // ensure medium water level in WDW credits cutscene
@ -2814,6 +2871,7 @@ enum {
}; };
static s32 act_end_peach_cutscene(struct MarioState *m) { static s32 act_end_peach_cutscene(struct MarioState *m) {
if (!m) { return 0; }
switch (m->actionArg) { switch (m->actionArg) {
case END_PEACH_CUTSCENE_MARIO_FALLING: case END_PEACH_CUTSCENE_MARIO_FALLING:
end_peach_cutscene_mario_falling(m); end_peach_cutscene_mario_falling(m);
@ -2887,6 +2945,7 @@ static s32 act_end_peach_cutscene(struct MarioState *m) {
#endif #endif
static s32 act_credits_cutscene(struct MarioState *m) { static s32 act_credits_cutscene(struct MarioState *m) {
if (!m) { return 0; }
m->statusForCamera->cameraEvent = CAM_EVENT_START_CREDITS; m->statusForCamera->cameraEvent = CAM_EVENT_START_CREDITS;
// checks if Mario is underwater (JRB, DDD, SA, etc.) // checks if Mario is underwater (JRB, DDD, SA, etc.)
if (m->pos[1] < m->waterLevel - 100) { if (m->pos[1] < m->waterLevel - 100) {
@ -2944,6 +3003,7 @@ static s32 act_credits_cutscene(struct MarioState *m) {
} }
static s32 act_end_waving_cutscene(struct MarioState *m) { static s32 act_end_waving_cutscene(struct MarioState *m) {
if (!m) { return 0; }
if (m->actionState == 0) { if (m->actionState == 0) {
m->statusForCamera->cameraEvent = CAM_EVENT_START_END_WAVING; m->statusForCamera->cameraEvent = CAM_EVENT_START_END_WAVING;
@ -2982,6 +3042,7 @@ static s32 act_end_waving_cutscene(struct MarioState *m) {
} }
static s32 check_for_instant_quicksand(struct MarioState *m) { static s32 check_for_instant_quicksand(struct MarioState *m) {
if (!m) { return 0; }
if (m != &gMarioStates[0]) { if (m != &gMarioStates[0]) {
// never kill remote marios // never kill remote marios
return FALSE; return FALSE;

View file

@ -31,6 +31,7 @@ void animated_stationary_ground_step(struct MarioState *m, s32 animation, u32 en
} }
s32 mario_update_punch_sequence(struct MarioState *m) { s32 mario_update_punch_sequence(struct MarioState *m) {
if (!m) { return 0; }
u32 endAction, crouchEndAction; u32 endAction, crouchEndAction;
s32 animFrame; s32 animFrame;
@ -151,6 +152,7 @@ s32 mario_update_punch_sequence(struct MarioState *m) {
} }
s32 act_punching(struct MarioState *m) { s32 act_punching(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_UNKNOWN_10) { if (m->input & INPUT_UNKNOWN_10) {
return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0);
} }
@ -179,6 +181,7 @@ s32 act_punching(struct MarioState *m) {
} }
s32 act_picking_up(struct MarioState *m) { s32 act_picking_up(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_UNKNOWN_10) { if (m->input & INPUT_UNKNOWN_10) {
return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0);
} }
@ -222,6 +225,7 @@ s32 act_picking_up(struct MarioState *m) {
} }
s32 act_dive_picking_up(struct MarioState *m) { s32 act_dive_picking_up(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_UNKNOWN_10) { if (m->input & INPUT_UNKNOWN_10) {
return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0);
} }
@ -242,6 +246,7 @@ s32 act_dive_picking_up(struct MarioState *m) {
} }
s32 act_placing_down(struct MarioState *m) { s32 act_placing_down(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_UNKNOWN_10) { if (m->input & INPUT_UNKNOWN_10) {
return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0);
} }
@ -259,6 +264,7 @@ s32 act_placing_down(struct MarioState *m) {
} }
s32 act_throwing(struct MarioState *m) { s32 act_throwing(struct MarioState *m) {
if (!m) { return 0; }
if (m->heldObj && (m->heldObj->oInteractionSubtype & INT_SUBTYPE_HOLDABLE_NPC)) { if (m->heldObj && (m->heldObj->oInteractionSubtype & INT_SUBTYPE_HOLDABLE_NPC)) {
return set_mario_action(m, ACT_PLACING_DOWN, 0); return set_mario_action(m, ACT_PLACING_DOWN, 0);
} }
@ -283,6 +289,7 @@ s32 act_throwing(struct MarioState *m) {
} }
s32 act_heavy_throw(struct MarioState *m) { s32 act_heavy_throw(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_UNKNOWN_10) { if (m->input & INPUT_UNKNOWN_10) {
return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0);
} }
@ -303,6 +310,7 @@ s32 act_heavy_throw(struct MarioState *m) {
} }
s32 act_stomach_slide_stop(struct MarioState *m) { s32 act_stomach_slide_stop(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_UNKNOWN_10) { if (m->input & INPUT_UNKNOWN_10) {
return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0);
} }
@ -320,6 +328,7 @@ s32 act_stomach_slide_stop(struct MarioState *m) {
} }
s32 act_picking_up_bowser(struct MarioState *m) { s32 act_picking_up_bowser(struct MarioState *m) {
if (!m) { return 0; }
if (m->playerIndex != 0) { if (m->playerIndex != 0) {
m->usedObj = cur_obj_nearest_object_with_behavior(bhvBowser); m->usedObj = cur_obj_nearest_object_with_behavior(bhvBowser);
} }
@ -350,6 +359,7 @@ s32 act_picking_up_bowser(struct MarioState *m) {
} }
s32 act_holding_bowser(struct MarioState *m) { s32 act_holding_bowser(struct MarioState *m) {
if (!m) { return 0; }
if (m->playerIndex != 0) { if (m->playerIndex != 0) {
if (m->marioBodyState->grabPos != GRAB_POS_BOWSER) { if (m->marioBodyState->grabPos != GRAB_POS_BOWSER) {
m->usedObj = cur_obj_nearest_object_with_behavior(bhvBowser); m->usedObj = cur_obj_nearest_object_with_behavior(bhvBowser);
@ -448,6 +458,7 @@ s32 act_holding_bowser(struct MarioState *m) {
} }
s32 act_releasing_bowser(struct MarioState *m) { s32 act_releasing_bowser(struct MarioState *m) {
if (!m) { return 0; }
if (++m->actionTimer == 1 && m->playerIndex == 0) { if (++m->actionTimer == 1 && m->playerIndex == 0) {
if (m->actionArg == 0) { if (m->actionArg == 0) {
queue_rumble_data_mario(m, 5, 50); queue_rumble_data_mario(m, 5, 50);
@ -464,6 +475,7 @@ s32 act_releasing_bowser(struct MarioState *m) {
} }
s32 check_common_object_cancels(struct MarioState *m) { s32 check_common_object_cancels(struct MarioState *m) {
if (!m) { return 0; }
if (m->playerIndex != 0) { return FALSE; } if (m->playerIndex != 0) { return FALSE; }
f32 waterSurface = m->waterLevel - 100; f32 waterSurface = m->waterLevel - 100;

View file

@ -23,6 +23,7 @@
#include "hardcoded.h" #include "hardcoded.h"
s32 check_common_idle_cancels(struct MarioState *m) { s32 check_common_idle_cancels(struct MarioState *m) {
if (!m) { return 0; }
mario_drop_held_object(m); mario_drop_held_object(m);
if (m->floor->normal.y < 0.29237169f) { if (m->floor->normal.y < 0.29237169f) {
return mario_push_off_steep_floor(m, ACT_FREEFALL, 0); return mario_push_off_steep_floor(m, ACT_FREEFALL, 0);
@ -65,7 +66,8 @@ s32 check_common_idle_cancels(struct MarioState *m) {
} }
s32 check_common_hold_idle_cancels(struct MarioState *m) { s32 check_common_hold_idle_cancels(struct MarioState *m) {
if (m->floor->normal.y < 0.29237169f) { if (!m) { return 0; }
if (m->floor && m->floor->normal.y < 0.29237169f) {
return mario_push_off_steep_floor(m, ACT_HOLD_FREEFALL, 0); return mario_push_off_steep_floor(m, ACT_HOLD_FREEFALL, 0);
} }
@ -108,6 +110,7 @@ s32 check_common_hold_idle_cancels(struct MarioState *m) {
} }
s32 act_idle(struct MarioState *m) { s32 act_idle(struct MarioState *m) {
if (!m) { return 0; }
if (m->quicksandDepth > 30.0f) { if (m->quicksandDepth > 30.0f) {
return set_mario_action(m, ACT_IN_QUICKSAND, 0); return set_mario_action(m, ACT_IN_QUICKSAND, 0);
} }
@ -184,12 +187,14 @@ s32 act_idle(struct MarioState *m) {
} }
void play_anim_sound(struct MarioState *m, u32 actionState, s32 animFrame, u32 sound) { void play_anim_sound(struct MarioState *m, u32 actionState, s32 animFrame, u32 sound) {
if (!m) { return; }
if (m->actionState == actionState && m->marioObj->header.gfx.animInfo.animFrame == animFrame) { if (m->actionState == actionState && m->marioObj->header.gfx.animInfo.animFrame == animFrame) {
play_sound(sound, m->marioObj->header.gfx.cameraToObject); play_sound(sound, m->marioObj->header.gfx.cameraToObject);
} }
} }
s32 act_start_sleeping(struct MarioState *m) { s32 act_start_sleeping(struct MarioState *m) {
if (!m) { return 0; }
#ifndef VERSION_JP #ifndef VERSION_JP
s32 animFrame = 0; s32 animFrame = 0;
#endif #endif
@ -265,6 +270,7 @@ s32 act_start_sleeping(struct MarioState *m) {
} }
s32 act_sleeping(struct MarioState *m) { s32 act_sleeping(struct MarioState *m) {
if (!m) { return 0; }
s32 animFrame; s32 animFrame;
if (m->playerIndex == 0) { if (m->playerIndex == 0) {
if (m->input if (m->input
@ -342,6 +348,7 @@ s32 act_sleeping(struct MarioState *m) {
} }
s32 act_waking_up(struct MarioState *m) { s32 act_waking_up(struct MarioState *m) {
if (!m) { return 0; }
if (!m->actionTimer) { if (!m->actionTimer) {
stop_sound(get_character(m)->soundSnoring1, m->marioObj->header.gfx.cameraToObject); stop_sound(get_character(m)->soundSnoring1, m->marioObj->header.gfx.cameraToObject);
stop_sound(get_character(m)->soundSnoring2, m->marioObj->header.gfx.cameraToObject); stop_sound(get_character(m)->soundSnoring2, m->marioObj->header.gfx.cameraToObject);
@ -379,6 +386,7 @@ s32 act_waking_up(struct MarioState *m) {
} }
s32 act_shivering(struct MarioState *m) { s32 act_shivering(struct MarioState *m) {
if (!m) { return 0; }
s32 animFrame; s32 animFrame;
if (m->input & INPUT_UNKNOWN_10) { if (m->input & INPUT_UNKNOWN_10) {
@ -433,6 +441,7 @@ s32 act_shivering(struct MarioState *m) {
} }
s32 act_coughing(struct MarioState *m) { s32 act_coughing(struct MarioState *m) {
if (!m) { return 0; }
s32 animFrame; s32 animFrame;
if (check_common_idle_cancels(m)) { if (check_common_idle_cancels(m)) {
@ -457,6 +466,7 @@ s32 act_coughing(struct MarioState *m) {
} }
s32 act_hold_idle(struct MarioState *m) { s32 act_hold_idle(struct MarioState *m) {
if (!m) { return 0; }
if (m->heldObj != NULL && segmented_to_virtual(&bhvJumpingBox) == m->heldObj->behavior) { if (m->heldObj != NULL && segmented_to_virtual(&bhvJumpingBox) == m->heldObj->behavior) {
return set_mario_action(m, ACT_CRAZY_BOX_BOUNCE, 0); return set_mario_action(m, ACT_CRAZY_BOX_BOUNCE, 0);
} }
@ -479,6 +489,7 @@ s32 act_hold_idle(struct MarioState *m) {
} }
s32 act_hold_heavy_idle(struct MarioState *m) { s32 act_hold_heavy_idle(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_UNKNOWN_10) { if (m->input & INPUT_UNKNOWN_10) {
return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0);
} }
@ -505,6 +516,7 @@ s32 act_hold_heavy_idle(struct MarioState *m) {
} }
s32 act_standing_against_wall(struct MarioState *m) { s32 act_standing_against_wall(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_UNKNOWN_10) { if (m->input & INPUT_UNKNOWN_10) {
return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0);
} }
@ -527,6 +539,7 @@ s32 act_standing_against_wall(struct MarioState *m) {
} }
s32 act_in_quicksand(struct MarioState *m) { s32 act_in_quicksand(struct MarioState *m) {
if (!m) { return 0; }
if (m->quicksandDepth < 30.0f) { if (m->quicksandDepth < 30.0f) {
return set_mario_action(m, ACT_IDLE, 0); return set_mario_action(m, ACT_IDLE, 0);
} }
@ -546,6 +559,7 @@ s32 act_in_quicksand(struct MarioState *m) {
} }
s32 act_crouching(struct MarioState *m) { s32 act_crouching(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_UNKNOWN_10) { if (m->input & INPUT_UNKNOWN_10) {
return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0);
} }
@ -584,6 +598,7 @@ s32 act_crouching(struct MarioState *m) {
} }
s32 act_panting(struct MarioState *m) { s32 act_panting(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_UNKNOWN_10) { if (m->input & INPUT_UNKNOWN_10) {
return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0);
} }
@ -606,6 +621,7 @@ s32 act_panting(struct MarioState *m) {
} }
s32 act_hold_panting_unused(struct MarioState *m) { s32 act_hold_panting_unused(struct MarioState *m) {
if (!m) { return 0; }
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) { if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
return drop_and_set_mario_action(m, ACT_PANTING, 0); return drop_and_set_mario_action(m, ACT_PANTING, 0);
} }
@ -637,6 +653,7 @@ void stopping_step(struct MarioState *m, s32 animID, u32 action) {
} }
s32 act_braking_stop(struct MarioState *m) { s32 act_braking_stop(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_UNKNOWN_10) { if (m->input & INPUT_UNKNOWN_10) {
return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0);
} }
@ -659,6 +676,7 @@ s32 act_braking_stop(struct MarioState *m) {
} }
s32 act_butt_slide_stop(struct MarioState *m) { s32 act_butt_slide_stop(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_UNKNOWN_10) { if (m->input & INPUT_UNKNOWN_10) {
return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0);
} }
@ -676,6 +694,7 @@ s32 act_butt_slide_stop(struct MarioState *m) {
} }
s32 act_hold_butt_slide_stop(struct MarioState *m) { s32 act_hold_butt_slide_stop(struct MarioState *m) {
if (!m) { return 0; }
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) { if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
return drop_and_set_mario_action(m, ACT_IDLE, 0); return drop_and_set_mario_action(m, ACT_IDLE, 0);
} }
@ -697,6 +716,7 @@ s32 act_hold_butt_slide_stop(struct MarioState *m) {
} }
s32 act_slide_kick_slide_stop(struct MarioState *m) { s32 act_slide_kick_slide_stop(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_UNKNOWN_10) { if (m->input & INPUT_UNKNOWN_10) {
return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0);
} }
@ -710,6 +730,7 @@ s32 act_slide_kick_slide_stop(struct MarioState *m) {
} }
s32 act_start_crouching(struct MarioState *m) { s32 act_start_crouching(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_UNKNOWN_10) { if (m->input & INPUT_UNKNOWN_10) {
return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0);
} }
@ -735,6 +756,7 @@ s32 act_start_crouching(struct MarioState *m) {
} }
s32 act_stop_crouching(struct MarioState *m) { s32 act_stop_crouching(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_UNKNOWN_10) { if (m->input & INPUT_UNKNOWN_10) {
return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0);
} }
@ -760,6 +782,7 @@ s32 act_stop_crouching(struct MarioState *m) {
} }
s32 act_start_crawling(struct MarioState *m) { s32 act_start_crawling(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_FIRST_PERSON) { if (m->input & INPUT_FIRST_PERSON) {
return set_mario_action(m, ACT_STOP_CROUCHING, 0); return set_mario_action(m, ACT_STOP_CROUCHING, 0);
} }
@ -786,6 +809,7 @@ s32 act_start_crawling(struct MarioState *m) {
} }
s32 act_stop_crawling(struct MarioState *m) { s32 act_stop_crawling(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_UNKNOWN_10) { if (m->input & INPUT_UNKNOWN_10) {
return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0);
} }
@ -807,6 +831,7 @@ s32 act_stop_crawling(struct MarioState *m) {
} }
s32 act_shockwave_bounce(struct MarioState *m) { s32 act_shockwave_bounce(struct MarioState *m) {
if (!m) { return 0; }
s16 sp1E; s16 sp1E;
f32 sp18; f32 sp18;
@ -852,6 +877,7 @@ s32 landing_step(struct MarioState *m, s32 arg1, u32 action) {
} }
s32 check_common_landing_cancels(struct MarioState *m, u32 action) { s32 check_common_landing_cancels(struct MarioState *m, u32 action) {
if (!m) { return 0; }
if (m->input & INPUT_UNKNOWN_10) { if (m->input & INPUT_UNKNOWN_10) {
return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0);
} }
@ -880,6 +906,7 @@ s32 check_common_landing_cancels(struct MarioState *m, u32 action) {
} }
s32 act_jump_land_stop(struct MarioState *m) { s32 act_jump_land_stop(struct MarioState *m) {
if (!m) { return 0; }
if (check_common_landing_cancels(m, 0)) { if (check_common_landing_cancels(m, 0)) {
return TRUE; return TRUE;
} }
@ -889,6 +916,7 @@ s32 act_jump_land_stop(struct MarioState *m) {
} }
s32 act_double_jump_land_stop(struct MarioState *m) { s32 act_double_jump_land_stop(struct MarioState *m) {
if (!m) { return 0; }
if (check_common_landing_cancels(m, 0)) { if (check_common_landing_cancels(m, 0)) {
return TRUE; return TRUE;
} }
@ -898,6 +926,7 @@ s32 act_double_jump_land_stop(struct MarioState *m) {
} }
s32 act_side_flip_land_stop(struct MarioState *m) { s32 act_side_flip_land_stop(struct MarioState *m) {
if (!m) { return 0; }
if (check_common_landing_cancels(m, 0)) { if (check_common_landing_cancels(m, 0)) {
return TRUE; return TRUE;
} }
@ -908,6 +937,7 @@ s32 act_side_flip_land_stop(struct MarioState *m) {
} }
s32 act_freefall_land_stop(struct MarioState *m) { s32 act_freefall_land_stop(struct MarioState *m) {
if (!m) { return 0; }
if (check_common_landing_cancels(m, 0)) { if (check_common_landing_cancels(m, 0)) {
return TRUE; return TRUE;
} }
@ -917,6 +947,7 @@ s32 act_freefall_land_stop(struct MarioState *m) {
} }
s32 act_triple_jump_land_stop(struct MarioState *m) { s32 act_triple_jump_land_stop(struct MarioState *m) {
if (!m) { return 0; }
if (check_common_landing_cancels(m, ACT_JUMP)) { if (check_common_landing_cancels(m, ACT_JUMP)) {
return TRUE; return TRUE;
} }
@ -926,6 +957,7 @@ s32 act_triple_jump_land_stop(struct MarioState *m) {
} }
s32 act_backflip_land_stop(struct MarioState *m) { s32 act_backflip_land_stop(struct MarioState *m) {
if (!m) { return 0; }
if (!(m->input & INPUT_Z_DOWN) || m->marioObj->header.gfx.animInfo.animFrame >= 6) { if (!(m->input & INPUT_Z_DOWN) || m->marioObj->header.gfx.animInfo.animFrame >= 6) {
m->input &= ~INPUT_A_PRESSED; m->input &= ~INPUT_A_PRESSED;
} }
@ -939,6 +971,7 @@ s32 act_backflip_land_stop(struct MarioState *m) {
} }
s32 act_lava_boost_land(struct MarioState *m) { s32 act_lava_boost_land(struct MarioState *m) {
if (!m) { return 0; }
m->input &= ~(INPUT_FIRST_PERSON | INPUT_B_PRESSED); m->input &= ~(INPUT_FIRST_PERSON | INPUT_B_PRESSED);
if (check_common_landing_cancels(m, 0)) { if (check_common_landing_cancels(m, 0)) {
@ -950,6 +983,7 @@ s32 act_lava_boost_land(struct MarioState *m) {
} }
s32 act_long_jump_land_stop(struct MarioState *m) { s32 act_long_jump_land_stop(struct MarioState *m) {
if (!m) { return 0; }
m->input &= ~INPUT_B_PRESSED; m->input &= ~INPUT_B_PRESSED;
if (check_common_landing_cancels(m, ACT_JUMP)) { if (check_common_landing_cancels(m, ACT_JUMP)) {
return TRUE; return TRUE;
@ -962,6 +996,7 @@ s32 act_long_jump_land_stop(struct MarioState *m) {
} }
s32 act_hold_jump_land_stop(struct MarioState *m) { s32 act_hold_jump_land_stop(struct MarioState *m) {
if (!m) { return 0; }
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) { if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
return drop_and_set_mario_action(m, ACT_IDLE, 0); return drop_and_set_mario_action(m, ACT_IDLE, 0);
} }
@ -983,6 +1018,7 @@ s32 act_hold_jump_land_stop(struct MarioState *m) {
} }
s32 act_hold_freefall_land_stop(struct MarioState *m) { s32 act_hold_freefall_land_stop(struct MarioState *m) {
if (!m) { return 0; }
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) { if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
return drop_and_set_mario_action(m, ACT_IDLE, 0); return drop_and_set_mario_action(m, ACT_IDLE, 0);
} }
@ -1003,6 +1039,7 @@ s32 act_hold_freefall_land_stop(struct MarioState *m) {
} }
s32 act_air_throw_land(struct MarioState *m) { s32 act_air_throw_land(struct MarioState *m) {
if (!m) { return 0; }
if (m->input & INPUT_UNKNOWN_10) { if (m->input & INPUT_UNKNOWN_10) {
return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0);
} }
@ -1020,6 +1057,7 @@ s32 act_air_throw_land(struct MarioState *m) {
} }
s32 act_twirl_land(struct MarioState *m) { s32 act_twirl_land(struct MarioState *m) {
if (!m) { return 0; }
m->actionState = 1; m->actionState = 1;
if (m->input & INPUT_UNKNOWN_10) { if (m->input & INPUT_UNKNOWN_10) {
return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0);
@ -1050,6 +1088,7 @@ s32 act_twirl_land(struct MarioState *m) {
} }
s32 act_ground_pound_land(struct MarioState *m) { s32 act_ground_pound_land(struct MarioState *m) {
if (!m) { return 0; }
m->actionState = 1; m->actionState = 1;
if (m->input & INPUT_UNKNOWN_10) { if (m->input & INPUT_UNKNOWN_10) {
return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0);
@ -1068,6 +1107,7 @@ s32 act_ground_pound_land(struct MarioState *m) {
} }
s32 act_first_person(struct MarioState *m) { s32 act_first_person(struct MarioState *m) {
if (!m) { return 0; }
s32 sp1C = (m->input & (INPUT_OFF_FLOOR | INPUT_ABOVE_SLIDE | INPUT_UNKNOWN_10)) != 0; s32 sp1C = (m->input & (INPUT_OFF_FLOOR | INPUT_ABOVE_SLIDE | INPUT_UNKNOWN_10)) != 0;
if (m->actionState == 0) { if (m->actionState == 0) {
@ -1100,6 +1140,7 @@ s32 act_first_person(struct MarioState *m) {
} }
s32 check_common_stationary_cancels(struct MarioState *m) { s32 check_common_stationary_cancels(struct MarioState *m) {
if (!m) { return 0; }
if (m->playerIndex != 0) { return FALSE; } if (m->playerIndex != 0) { return FALSE; }
if (m->pos[1] < m->waterLevel - 100) { if (m->pos[1] < m->waterLevel - 100) {

View file

@ -42,6 +42,7 @@ static s16 D_80339FD2;
static f32 D_80339FD4; static f32 D_80339FD4;
void set_swimming_at_surface_particles(struct MarioState *m, u32 particleFlag) { void set_swimming_at_surface_particles(struct MarioState *m, u32 particleFlag) {
if (!m) { return; }
s16 atSurface = m->pos[1] >= m->waterLevel - 130; s16 atSurface = m->pos[1] >= m->waterLevel - 130;
u16 pIndex = m->playerIndex; u16 pIndex = m->playerIndex;
@ -56,6 +57,7 @@ void set_swimming_at_surface_particles(struct MarioState *m, u32 particleFlag) {
} }
static s32 swimming_near_surface(struct MarioState *m) { static s32 swimming_near_surface(struct MarioState *m) {
if (!m) { return 0; }
if (m->flags & MARIO_METAL_CAP) { if (m->flags & MARIO_METAL_CAP) {
return FALSE; return FALSE;
} }
@ -64,6 +66,7 @@ static s32 swimming_near_surface(struct MarioState *m) {
} }
static f32 get_buoyancy(struct MarioState *m) { static f32 get_buoyancy(struct MarioState *m) {
if (!m) { return 0; }
f32 buoyancy = 0.0f; f32 buoyancy = 0.0f;
if (m->flags & MARIO_METAL_CAP) { if (m->flags & MARIO_METAL_CAP) {
@ -82,6 +85,7 @@ static f32 get_buoyancy(struct MarioState *m) {
} }
u32 perform_water_full_step(struct MarioState *m, Vec3f nextPos) { u32 perform_water_full_step(struct MarioState *m, Vec3f nextPos) {
if (!m) { return 0; }
struct WallCollisionData wcd = { 0 }; struct WallCollisionData wcd = { 0 };
struct Surface *ceil; struct Surface *ceil;
struct Surface *floor; struct Surface *floor;
@ -131,6 +135,7 @@ u32 perform_water_full_step(struct MarioState *m, Vec3f nextPos) {
} }
void apply_water_current(struct MarioState *m, Vec3f step) { void apply_water_current(struct MarioState *m, Vec3f step) {
if (!m) { return; }
s32 i; s32 i;
f32 whirlpoolRadius = 2000.0f; f32 whirlpoolRadius = 2000.0f;
@ -217,6 +222,7 @@ u32 perform_water_step(struct MarioState *m) {
} }
static BAD_RETURN(u32) update_water_pitch(struct MarioState *m) { static BAD_RETURN(u32) update_water_pitch(struct MarioState *m) {
if (!m) { return; }
struct Object *marioObj = m->marioObj; struct Object *marioObj = m->marioObj;
if (marioObj->header.gfx.angle[0] > 0) { if (marioObj->header.gfx.angle[0] > 0) {
@ -234,6 +240,7 @@ static BAD_RETURN(u32) update_water_pitch(struct MarioState *m) {
} }
static void stationary_slow_down(struct MarioState *m) { static void stationary_slow_down(struct MarioState *m) {
if (!m) { return; }
f32 buoyancy = get_buoyancy(m); f32 buoyancy = get_buoyancy(m);
m->angleVel[0] = 0; m->angleVel[0] = 0;
@ -250,6 +257,7 @@ static void stationary_slow_down(struct MarioState *m) {
} }
static void update_swimming_speed(struct MarioState *m, f32 decelThreshold) { static void update_swimming_speed(struct MarioState *m, f32 decelThreshold) {
if (!m) { return; }
f32 buoyancy = get_buoyancy(m); f32 buoyancy = get_buoyancy(m);
f32 maxSpeed = 28.0f; f32 maxSpeed = 28.0f;
@ -275,6 +283,7 @@ static void update_swimming_speed(struct MarioState *m, f32 decelThreshold) {
} }
static void update_swimming_yaw(struct MarioState *m) { static void update_swimming_yaw(struct MarioState *m) {
if (!m) { return; }
s16 targetYawVel = -(s16)(10.0f * m->controller->stickX); s16 targetYawVel = -(s16)(10.0f * m->controller->stickX);
if (targetYawVel > 0) { if (targetYawVel > 0) {
@ -304,6 +313,7 @@ static void update_swimming_yaw(struct MarioState *m) {
} }
static void update_swimming_pitch(struct MarioState *m) { static void update_swimming_pitch(struct MarioState *m) {
if (!m) { return; }
s16 targetPitch = -(s16)(252.0f * m->controller->stickY); s16 targetPitch = -(s16)(252.0f * m->controller->stickY);
s16 pitchVel; s16 pitchVel;
@ -325,6 +335,7 @@ static void update_swimming_pitch(struct MarioState *m) {
} }
static void common_idle_step(struct MarioState *m, s32 animation, s32 arg) { static void common_idle_step(struct MarioState *m, s32 animation, s32 arg) {
if (!m) { return; }
s16 *val = &m->marioBodyState->headAngle[0]; s16 *val = &m->marioBodyState->headAngle[0];
update_swimming_yaw(m); update_swimming_yaw(m);
@ -349,6 +360,7 @@ static void common_idle_step(struct MarioState *m, s32 animation, s32 arg) {
} }
static s32 act_water_idle(struct MarioState *m) { static s32 act_water_idle(struct MarioState *m) {
if (!m) { return 0; }
u32 val = 0x10000; u32 val = 0x10000;
if (m->flags & MARIO_METAL_CAP) { if (m->flags & MARIO_METAL_CAP) {
@ -372,6 +384,7 @@ static s32 act_water_idle(struct MarioState *m) {
} }
static s32 act_hold_water_idle(struct MarioState *m) { static s32 act_hold_water_idle(struct MarioState *m) {
if (!m) { return 0; }
if (m->flags & MARIO_METAL_CAP) { if (m->flags & MARIO_METAL_CAP) {
return set_mario_action(m, ACT_HOLD_METAL_WATER_FALLING, 0); return set_mario_action(m, ACT_HOLD_METAL_WATER_FALLING, 0);
} }
@ -393,6 +406,7 @@ static s32 act_hold_water_idle(struct MarioState *m) {
} }
static s32 act_water_action_end(struct MarioState *m) { static s32 act_water_action_end(struct MarioState *m) {
if (!m) { return 0; }
if (m->flags & MARIO_METAL_CAP) { if (m->flags & MARIO_METAL_CAP) {
return set_mario_action(m, ACT_METAL_WATER_FALLING, 1); return set_mario_action(m, ACT_METAL_WATER_FALLING, 1);
} }
@ -413,6 +427,7 @@ static s32 act_water_action_end(struct MarioState *m) {
} }
static s32 act_hold_water_action_end(struct MarioState *m) { static s32 act_hold_water_action_end(struct MarioState *m) {
if (!m) { return 0; }
if (m->flags & MARIO_METAL_CAP) { if (m->flags & MARIO_METAL_CAP) {
return set_mario_action(m, ACT_HOLD_METAL_WATER_FALLING, 0); return set_mario_action(m, ACT_HOLD_METAL_WATER_FALLING, 0);
} }
@ -439,12 +454,14 @@ static s32 act_hold_water_action_end(struct MarioState *m) {
} }
static void reset_float_globals(struct MarioState *m) { static void reset_float_globals(struct MarioState *m) {
if (!m) { return; }
D_80339FD0 = 0; D_80339FD0 = 0;
D_80339FD2 = 0x800; D_80339FD2 = 0x800;
D_80339FD4 = m->faceAngle[0] / 256.0f + 20.0f; D_80339FD4 = m->faceAngle[0] / 256.0f + 20.0f;
} }
void float_surface_gfx(struct MarioState *m) { void float_surface_gfx(struct MarioState *m) {
if (!m) { return; }
if (D_80339FD2 != 0 && m->pos[1] > m->waterLevel - 85 && m->faceAngle[0] >= 0) { if (D_80339FD2 != 0 && m->pos[1] > m->waterLevel - 85 && m->faceAngle[0] >= 0) {
if ((D_80339FD0 += D_80339FD2) >= 0) { if ((D_80339FD0 += D_80339FD2) >= 0) {
m->marioObj->header.gfx.pos[1] += D_80339FD4 * sins(D_80339FD0); m->marioObj->header.gfx.pos[1] += D_80339FD4 * sins(D_80339FD0);
@ -456,6 +473,7 @@ void float_surface_gfx(struct MarioState *m) {
} }
static void common_swimming_step(struct MarioState *m, s16 swimStrength) { static void common_swimming_step(struct MarioState *m, s16 swimStrength) {
if (!m) { return; }
s16 floorPitch; s16 floorPitch;
UNUSED struct Object *marioObj = m->marioObj; UNUSED struct Object *marioObj = m->marioObj;
@ -502,6 +520,7 @@ static void common_swimming_step(struct MarioState *m, s16 swimStrength) {
} }
static void play_swimming_noise(struct MarioState *m) { static void play_swimming_noise(struct MarioState *m) {
if (!m) { return; }
s16 animFrame = m->marioObj->header.gfx.animInfo.animFrame; s16 animFrame = m->marioObj->header.gfx.animInfo.animFrame;
// This must be one line to match on -O2 // This must be one line to match on -O2
@ -509,6 +528,7 @@ static void play_swimming_noise(struct MarioState *m) {
} }
static s32 check_water_jump(struct MarioState *m) { static s32 check_water_jump(struct MarioState *m) {
if (!m) { return 0; }
s32 probe = (s32)(m->pos[1] + 1.5f); s32 probe = (s32)(m->pos[1] + 1.5f);
if (m->input & INPUT_A_PRESSED) { if (m->input & INPUT_A_PRESSED) {
@ -529,6 +549,7 @@ static s32 check_water_jump(struct MarioState *m) {
} }
static s32 act_breaststroke(struct MarioState *m) { static s32 act_breaststroke(struct MarioState *m) {
if (!m) { return 0; }
u16 pIndex = m->playerIndex; u16 pIndex = m->playerIndex;
if (m->actionArg == 0) { if (m->actionArg == 0) {
@ -589,6 +610,7 @@ static s32 act_breaststroke(struct MarioState *m) {
} }
static s32 act_swimming_end(struct MarioState *m) { static s32 act_swimming_end(struct MarioState *m) {
if (!m) { return 0; }
u16 pIndex = m->playerIndex; u16 pIndex = m->playerIndex;
if (m->flags & MARIO_METAL_CAP) { if (m->flags & MARIO_METAL_CAP) {
@ -628,6 +650,7 @@ static s32 act_swimming_end(struct MarioState *m) {
} }
static s32 act_flutter_kick(struct MarioState *m) { static s32 act_flutter_kick(struct MarioState *m) {
if (!m) { return 0; }
u16 pIndex = m->playerIndex; u16 pIndex = m->playerIndex;
if (m->flags & MARIO_METAL_CAP) { if (m->flags & MARIO_METAL_CAP) {
@ -659,6 +682,7 @@ static s32 act_flutter_kick(struct MarioState *m) {
} }
static s32 act_hold_breaststroke(struct MarioState *m) { static s32 act_hold_breaststroke(struct MarioState *m) {
if (!m) { return 0; }
if (m->flags & MARIO_METAL_CAP) { if (m->flags & MARIO_METAL_CAP) {
return set_mario_action(m, ACT_HOLD_METAL_WATER_FALLING, 0); return set_mario_action(m, ACT_HOLD_METAL_WATER_FALLING, 0);
} }
@ -710,6 +734,7 @@ static s32 act_hold_breaststroke(struct MarioState *m) {
} }
static s32 act_hold_swimming_end(struct MarioState *m) { static s32 act_hold_swimming_end(struct MarioState *m) {
if (!m) { return 0; }
if (m->flags & MARIO_METAL_CAP) { if (m->flags & MARIO_METAL_CAP) {
return set_mario_action(m, ACT_HOLD_METAL_WATER_FALLING, 0); return set_mario_action(m, ACT_HOLD_METAL_WATER_FALLING, 0);
} }
@ -743,6 +768,7 @@ static s32 act_hold_swimming_end(struct MarioState *m) {
} }
static s32 act_hold_flutter_kick(struct MarioState *m) { static s32 act_hold_flutter_kick(struct MarioState *m) {
if (!m) { return 0; }
if (m->flags & MARIO_METAL_CAP) { if (m->flags & MARIO_METAL_CAP) {
return set_mario_action(m, ACT_HOLD_METAL_WATER_FALLING, 0); return set_mario_action(m, ACT_HOLD_METAL_WATER_FALLING, 0);
} }
@ -769,6 +795,7 @@ static s32 act_hold_flutter_kick(struct MarioState *m) {
} }
static s32 act_water_shell_swimming(struct MarioState *m) { static s32 act_water_shell_swimming(struct MarioState *m) {
if (!m) { return 0; }
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) { if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
return drop_and_set_mario_action(m, ACT_WATER_IDLE, 0); return drop_and_set_mario_action(m, ACT_WATER_IDLE, 0);
} }
@ -796,6 +823,7 @@ static s32 act_water_shell_swimming(struct MarioState *m) {
} }
static s32 check_water_grab(struct MarioState *m) { static s32 check_water_grab(struct MarioState *m) {
if (!m) { return 0; }
//! Heave hos have the grabbable interaction type but are not normally //! Heave hos have the grabbable interaction type but are not normally
// grabbable. Since water grabbing doesn't check the appropriate input flag, // grabbable. Since water grabbing doesn't check the appropriate input flag,
// you can use water grab to pick up heave ho. // you can use water grab to pick up heave ho.
@ -820,6 +848,7 @@ static s32 check_water_grab(struct MarioState *m) {
} }
static s32 act_water_throw(struct MarioState *m) { static s32 act_water_throw(struct MarioState *m) {
if (!m) { return 0; }
update_swimming_yaw(m); update_swimming_yaw(m);
update_swimming_pitch(m); update_swimming_pitch(m);
update_swimming_speed(m, MIN_SWIM_SPEED); update_swimming_speed(m, MIN_SWIM_SPEED);
@ -844,6 +873,7 @@ static s32 act_water_throw(struct MarioState *m) {
} }
static s32 act_water_punch(struct MarioState *m) { static s32 act_water_punch(struct MarioState *m) {
if (!m) { return 0; }
if (m->forwardVel < 7.0f) { if (m->forwardVel < 7.0f) {
m->forwardVel += 1.0f; m->forwardVel += 1.0f;
} }
@ -890,6 +920,7 @@ static s32 act_water_punch(struct MarioState *m) {
} }
static void common_water_knockback_step(struct MarioState *m, s32 animation, u32 endAction, s32 arg3) { static void common_water_knockback_step(struct MarioState *m, s32 animation, u32 endAction, s32 arg3) {
if (!m) { return; }
stationary_slow_down(m); stationary_slow_down(m);
perform_water_step(m); perform_water_step(m);
set_mario_animation(m, animation); set_mario_animation(m, animation);
@ -906,16 +937,19 @@ static void common_water_knockback_step(struct MarioState *m, s32 animation, u32
} }
static s32 act_backward_water_kb(struct MarioState *m) { static s32 act_backward_water_kb(struct MarioState *m) {
if (!m) { return 0; }
common_water_knockback_step(m, MARIO_ANIM_BACKWARDS_WATER_KB, ACT_WATER_IDLE, m->actionArg); common_water_knockback_step(m, MARIO_ANIM_BACKWARDS_WATER_KB, ACT_WATER_IDLE, m->actionArg);
return FALSE; return FALSE;
} }
static s32 act_forward_water_kb(struct MarioState *m) { static s32 act_forward_water_kb(struct MarioState *m) {
if (!m) { return 0; }
common_water_knockback_step(m, MARIO_ANIM_WATER_FORWARD_KB, ACT_WATER_IDLE, m->actionArg); common_water_knockback_step(m, MARIO_ANIM_WATER_FORWARD_KB, ACT_WATER_IDLE, m->actionArg);
return FALSE; return FALSE;
} }
static s32 act_water_shocked(struct MarioState *m) { static s32 act_water_shocked(struct MarioState *m) {
if (!m) { return 0; }
play_character_sound_if_no_flag(m, CHAR_SOUND_WAAAOOOW, MARIO_MARIO_SOUND_PLAYED); play_character_sound_if_no_flag(m, CHAR_SOUND_WAAAOOOW, MARIO_MARIO_SOUND_PLAYED);
play_sound(SOUND_MOVING_SHOCKED, m->marioObj->header.gfx.cameraToObject); play_sound(SOUND_MOVING_SHOCKED, m->marioObj->header.gfx.cameraToObject);
if (m->playerIndex == 0) { set_camera_shake_from_hit(SHAKE_SHOCK); } if (m->playerIndex == 0) { set_camera_shake_from_hit(SHAKE_SHOCK); }
@ -937,6 +971,7 @@ static s32 act_water_shocked(struct MarioState *m) {
} }
static s32 act_drowning(struct MarioState *m) { static s32 act_drowning(struct MarioState *m) {
if (!m) { return 0; }
switch (m->actionState) { switch (m->actionState) {
case 0: case 0:
set_mario_animation(m, MARIO_ANIM_DROWNING_PART1); set_mario_animation(m, MARIO_ANIM_DROWNING_PART1);
@ -976,6 +1011,7 @@ static s32 act_drowning(struct MarioState *m) {
} }
static s32 act_water_death(struct MarioState *m) { static s32 act_water_death(struct MarioState *m) {
if (!m) { return 0; }
stationary_slow_down(m); stationary_slow_down(m);
perform_water_step(m); perform_water_step(m);
@ -1003,6 +1039,7 @@ static s32 act_water_death(struct MarioState *m) {
} }
static s32 act_water_plunge(struct MarioState *m) { static s32 act_water_plunge(struct MarioState *m) {
if (!m) { return 0; }
u32 stepResult; u32 stepResult;
s32 stateFlags = m->heldObj != NULL; s32 stateFlags = m->heldObj != NULL;
@ -1088,6 +1125,7 @@ static s32 act_water_plunge(struct MarioState *m) {
} }
static s32 act_caught_in_whirlpool(struct MarioState *m) { static s32 act_caught_in_whirlpool(struct MarioState *m) {
if (!m) { return 0; }
f32 sinAngleChange; f32 sinAngleChange;
f32 cosAngleChange; f32 cosAngleChange;
f32 newDistance; f32 newDistance;
@ -1163,6 +1201,7 @@ static s32 act_caught_in_whirlpool(struct MarioState *m) {
} }
static void play_metal_water_jumping_sound(struct MarioState *m, u32 landing) { static void play_metal_water_jumping_sound(struct MarioState *m, u32 landing) {
if (!m) { return; }
if (!(m->flags & MARIO_ACTION_SOUND_PLAYED)) { if (!(m->flags & MARIO_ACTION_SOUND_PLAYED)) {
set_mario_particle_flags(m, PARTICLE_MIST_CIRCLE, FALSE); set_mario_particle_flags(m, PARTICLE_MIST_CIRCLE, FALSE);
} }
@ -1179,6 +1218,7 @@ static void play_metal_water_walking_sound(struct MarioState *m) {
} }
static void update_metal_water_walking_speed(struct MarioState *m) { static void update_metal_water_walking_speed(struct MarioState *m) {
if (!m) { return; }
f32 val = m->intendedMag / 1.5f; f32 val = m->intendedMag / 1.5f;
if (m->forwardVel <= 0.0f) { if (m->forwardVel <= 0.0f) {
@ -1205,6 +1245,7 @@ static void update_metal_water_walking_speed(struct MarioState *m) {
} }
static s32 update_metal_water_jump_speed(struct MarioState *m) { static s32 update_metal_water_jump_speed(struct MarioState *m) {
if (!m) { return 0; }
UNUSED f32 nextY = m->pos[1] + m->vel[1]; UNUSED f32 nextY = m->pos[1] + m->vel[1];
f32 waterSurface = m->waterLevel - 100; f32 waterSurface = m->waterLevel - 100;
@ -1234,6 +1275,7 @@ static s32 update_metal_water_jump_speed(struct MarioState *m) {
} }
static s32 act_metal_water_standing(struct MarioState *m) { static s32 act_metal_water_standing(struct MarioState *m) {
if (!m) { return 0; }
if (!(m->flags & MARIO_METAL_CAP)) { if (!(m->flags & MARIO_METAL_CAP)) {
return set_mario_action(m, ACT_WATER_IDLE, 0); return set_mario_action(m, ACT_WATER_IDLE, 0);
} }
@ -1271,6 +1313,7 @@ static s32 act_metal_water_standing(struct MarioState *m) {
} }
static s32 act_hold_metal_water_standing(struct MarioState *m) { static s32 act_hold_metal_water_standing(struct MarioState *m) {
if (!m) { return 0; }
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) { if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
return drop_and_set_mario_action(m, ACT_METAL_WATER_STANDING, 0); return drop_and_set_mario_action(m, ACT_METAL_WATER_STANDING, 0);
} }
@ -1293,6 +1336,7 @@ static s32 act_hold_metal_water_standing(struct MarioState *m) {
} }
static s32 act_metal_water_walking(struct MarioState *m) { static s32 act_metal_water_walking(struct MarioState *m) {
if (!m) { return 0; }
s32 val04; s32 val04;
if (!(m->flags & MARIO_METAL_CAP)) { if (!(m->flags & MARIO_METAL_CAP)) {
@ -1333,6 +1377,7 @@ static s32 act_metal_water_walking(struct MarioState *m) {
} }
static s32 act_hold_metal_water_walking(struct MarioState *m) { static s32 act_hold_metal_water_walking(struct MarioState *m) {
if (!m) { return 0; }
s32 val04; s32 val04;
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) { if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
@ -1375,6 +1420,7 @@ static s32 act_hold_metal_water_walking(struct MarioState *m) {
} }
static s32 act_metal_water_jump(struct MarioState *m) { static s32 act_metal_water_jump(struct MarioState *m) {
if (!m) { return 0; }
if (!(m->flags & MARIO_METAL_CAP)) { if (!(m->flags & MARIO_METAL_CAP)) {
return set_mario_action(m, ACT_WATER_IDLE, 0); return set_mario_action(m, ACT_WATER_IDLE, 0);
} }
@ -1400,6 +1446,7 @@ static s32 act_metal_water_jump(struct MarioState *m) {
} }
static s32 act_hold_metal_water_jump(struct MarioState *m) { static s32 act_hold_metal_water_jump(struct MarioState *m) {
if (!m) { return 0; }
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) { if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
return drop_and_set_mario_action(m, ACT_METAL_WATER_FALLING, 0); return drop_and_set_mario_action(m, ACT_METAL_WATER_FALLING, 0);
} }
@ -1429,6 +1476,7 @@ static s32 act_hold_metal_water_jump(struct MarioState *m) {
} }
static s32 act_metal_water_falling(struct MarioState *m) { static s32 act_metal_water_falling(struct MarioState *m) {
if (!m) { return 0; }
if (!(m->flags & MARIO_METAL_CAP)) { if (!(m->flags & MARIO_METAL_CAP)) {
return set_mario_action(m, ACT_WATER_IDLE, 0); return set_mario_action(m, ACT_WATER_IDLE, 0);
} }
@ -1448,6 +1496,7 @@ static s32 act_metal_water_falling(struct MarioState *m) {
} }
static s32 act_hold_metal_water_falling(struct MarioState *m) { static s32 act_hold_metal_water_falling(struct MarioState *m) {
if (!m) { return 0; }
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) { if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
return drop_and_set_mario_action(m, ACT_METAL_WATER_FALLING, 0); return drop_and_set_mario_action(m, ACT_METAL_WATER_FALLING, 0);
} }
@ -1471,6 +1520,7 @@ static s32 act_hold_metal_water_falling(struct MarioState *m) {
} }
static s32 act_metal_water_jump_land(struct MarioState *m) { static s32 act_metal_water_jump_land(struct MarioState *m) {
if (!m) { return 0; }
play_metal_water_jumping_sound(m, TRUE); play_metal_water_jumping_sound(m, TRUE);
if (!(m->flags & MARIO_METAL_CAP)) { if (!(m->flags & MARIO_METAL_CAP)) {
@ -1492,6 +1542,7 @@ static s32 act_metal_water_jump_land(struct MarioState *m) {
} }
static s32 act_hold_metal_water_jump_land(struct MarioState *m) { static s32 act_hold_metal_water_jump_land(struct MarioState *m) {
if (!m) { return 0; }
play_metal_water_jumping_sound(m, TRUE); play_metal_water_jumping_sound(m, TRUE);
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) { if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
@ -1517,6 +1568,7 @@ static s32 act_hold_metal_water_jump_land(struct MarioState *m) {
} }
static s32 act_metal_water_fall_land(struct MarioState *m) { static s32 act_metal_water_fall_land(struct MarioState *m) {
if (!m) { return 0; }
play_metal_water_jumping_sound(m, TRUE); play_metal_water_jumping_sound(m, TRUE);
if (!(m->flags & MARIO_METAL_CAP)) { if (!(m->flags & MARIO_METAL_CAP)) {
@ -1538,6 +1590,7 @@ static s32 act_metal_water_fall_land(struct MarioState *m) {
} }
static s32 act_hold_metal_water_fall_land(struct MarioState *m) { static s32 act_hold_metal_water_fall_land(struct MarioState *m) {
if (!m) { return 0; }
play_metal_water_jumping_sound(m, TRUE); play_metal_water_jumping_sound(m, TRUE);
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) { if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
@ -1563,6 +1616,7 @@ static s32 act_hold_metal_water_fall_land(struct MarioState *m) {
} }
static s32 check_common_submerged_cancels(struct MarioState *m) { static s32 check_common_submerged_cancels(struct MarioState *m) {
if (!m) { return 0; }
if (m->pos[1] > m->waterLevel - 80) { if (m->pos[1] > m->waterLevel - 80) {
if (m->waterLevel - 80 > m->floorHeight) { if (m->waterLevel - 80 > m->floorHeight) {
m->pos[1] = m->waterLevel - 80; m->pos[1] = m->waterLevel - 80;

View file

@ -107,6 +107,7 @@ Gfx *geo_draw_mario_head_goddard(s32 callContext, struct GraphNode *node, Mat4 *
} }
static void toad_message_faded(void) { static void toad_message_faded(void) {
if (!gCurrentObject) { return; }
if (gCurrentObject->oDistanceToMario > 700.0f) { if (gCurrentObject->oDistanceToMario > 700.0f) {
gCurrentObject->oToadMessageRecentlyTalked = FALSE; gCurrentObject->oToadMessageRecentlyTalked = FALSE;
} }
@ -116,6 +117,7 @@ static void toad_message_faded(void) {
} }
static void toad_message_opaque(void) { static void toad_message_opaque(void) {
if (!gCurrentObject) { return; }
if (gCurrentObject->oDistanceToMario > 700.0f) { if (gCurrentObject->oDistanceToMario > 700.0f) {
gCurrentObject->oToadMessageState = TOAD_MESSAGE_FADING; gCurrentObject->oToadMessageState = TOAD_MESSAGE_FADING;
} else if (!gCurrentObject->oToadMessageRecentlyTalked) { } else if (!gCurrentObject->oToadMessageRecentlyTalked) {
@ -129,6 +131,7 @@ static void toad_message_opaque(void) {
} }
static void toad_message_talking(void) { static void toad_message_talking(void) {
if (!gCurrentObject) { return; }
if (cur_obj_update_dialog_with_cutscene(&gMarioStates[0], 3, 1, CUTSCENE_DIALOG, gCurrentObject->oToadMessageDialogId, NULL) if (cur_obj_update_dialog_with_cutscene(&gMarioStates[0], 3, 1, CUTSCENE_DIALOG, gCurrentObject->oToadMessageDialogId, NULL)
!= 0) { != 0) {
gCurrentObject->oToadMessageRecentlyTalked = TRUE; gCurrentObject->oToadMessageRecentlyTalked = TRUE;
@ -149,18 +152,21 @@ static void toad_message_talking(void) {
} }
static void toad_message_opacifying(void) { static void toad_message_opacifying(void) {
if (!gCurrentObject) { return; }
if ((gCurrentObject->oOpacity += 6) == 255) { if ((gCurrentObject->oOpacity += 6) == 255) {
gCurrentObject->oToadMessageState = TOAD_MESSAGE_OPAQUE; gCurrentObject->oToadMessageState = TOAD_MESSAGE_OPAQUE;
} }
} }
static void toad_message_fading(void) { static void toad_message_fading(void) {
if (!gCurrentObject) { return; }
if ((gCurrentObject->oOpacity -= 6) == 81) { if ((gCurrentObject->oOpacity -= 6) == 81) {
gCurrentObject->oToadMessageState = TOAD_MESSAGE_FADED; gCurrentObject->oToadMessageState = TOAD_MESSAGE_FADED;
} }
} }
void bhv_toad_message_loop(void) { void bhv_toad_message_loop(void) {
if (!gCurrentObject) { return; }
if (gCurrentObject->header.gfx.node.flags & GRAPH_RENDER_ACTIVE) { if (gCurrentObject->header.gfx.node.flags & GRAPH_RENDER_ACTIVE) {
gCurrentObject->oInteractionSubtype = 0; gCurrentObject->oInteractionSubtype = 0;
switch (gCurrentObject->oToadMessageState) { switch (gCurrentObject->oToadMessageState) {
@ -184,6 +190,7 @@ void bhv_toad_message_loop(void) {
} }
void bhv_toad_message_init(void) { void bhv_toad_message_init(void) {
if (!gCurrentObject) { return; }
s32 saveFlags = save_file_get_flags(); s32 saveFlags = save_file_get_flags();
s32 starCount = save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_MIN - 1, COURSE_MAX - 1); s32 starCount = save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_MIN - 1, COURSE_MAX - 1);
s32 dialogId = (gCurrentObject->oBehParams >> 24) & 0xFF; s32 dialogId = (gCurrentObject->oBehParams >> 24) & 0xFF;
@ -217,6 +224,7 @@ void bhv_toad_message_init(void) {
} }
static void star_door_unlock_spawn_particles(s16 angleOffset) { static void star_door_unlock_spawn_particles(s16 angleOffset) {
if (!gCurrentObject) { return; }
struct Object *sparkleParticle = spawn_object(gCurrentObject, 0, bhvSparkleSpawn); struct Object *sparkleParticle = spawn_object(gCurrentObject, 0, bhvSparkleSpawn);
if (sparkleParticle == NULL) { return; } if (sparkleParticle == NULL) { return; }
@ -229,6 +237,7 @@ static void star_door_unlock_spawn_particles(s16 angleOffset) {
} }
void bhv_unlock_door_star_init(void) { void bhv_unlock_door_star_init(void) {
if (!gCurrentObject) { return; }
gCurrentObject->oUnlockDoorStarState = UNLOCK_DOOR_STAR_RISING; gCurrentObject->oUnlockDoorStarState = UNLOCK_DOOR_STAR_RISING;
gCurrentObject->oUnlockDoorStarTimer = 0; gCurrentObject->oUnlockDoorStarTimer = 0;
gCurrentObject->oUnlockDoorStarYawVel = 0x1000; gCurrentObject->oUnlockDoorStarYawVel = 0x1000;
@ -240,6 +249,7 @@ void bhv_unlock_door_star_init(void) {
} }
void bhv_unlock_door_star_loop(void) { void bhv_unlock_door_star_loop(void) {
if (!gCurrentObject) { return; }
UNUSED u8 unused1[4]; UNUSED u8 unused1[4];
s16 prevYaw = gCurrentObject->oMoveAngleYaw; s16 prevYaw = gCurrentObject->oMoveAngleYaw;
UNUSED u8 unused2[4]; UNUSED u8 unused2[4];

View file

@ -91,6 +91,7 @@ BAD_RETURN(s32) init_bully_collision_data(struct BullyCollisionData *data, f32 p
} }
void mario_bonk_reflection(struct MarioState *m, u32 negateSpeed) { void mario_bonk_reflection(struct MarioState *m, u32 negateSpeed) {
if (!m) { return; }
if (m->wall != NULL) { if (m->wall != NULL) {
s16 wallAngle = atan2s(m->wallNormal[2], m->wallNormal[0]); s16 wallAngle = atan2s(m->wallNormal[2], m->wallNormal[0]);
m->faceAngle[1] = wallAngle - (s16)(m->faceAngle[1] - wallAngle); m->faceAngle[1] = wallAngle - (s16)(m->faceAngle[1] - wallAngle);
@ -109,6 +110,7 @@ void mario_bonk_reflection(struct MarioState *m, u32 negateSpeed) {
} }
u32 mario_update_quicksand(struct MarioState *m, f32 sinkingSpeed) { u32 mario_update_quicksand(struct MarioState *m, f32 sinkingSpeed) {
if (!m) { return 0; }
bool allow = true; bool allow = true;
smlua_call_event_hooks_mario_param_and_int_ret_bool(HOOK_ALLOW_HAZARD_SURFACE, m, HAZARD_TYPE_QUICKSAND, &allow); smlua_call_event_hooks_mario_param_and_int_ret_bool(HOOK_ALLOW_HAZARD_SURFACE, m, HAZARD_TYPE_QUICKSAND, &allow);
if (m->action & ACT_FLAG_RIDING_SHELL || (gServerSettings.enableCheats && gCheats.godMode && m->playerIndex == 0) || (!allow)) { if (m->action & ACT_FLAG_RIDING_SHELL || (gServerSettings.enableCheats && gCheats.godMode && m->playerIndex == 0) || (!allow)) {
@ -162,6 +164,7 @@ u32 mario_update_quicksand(struct MarioState *m, f32 sinkingSpeed) {
} }
u32 mario_push_off_steep_floor(struct MarioState *m, u32 action, u32 actionArg) { u32 mario_push_off_steep_floor(struct MarioState *m, u32 action, u32 actionArg) {
if (!m) { return 0; }
s16 floorDYaw = m->floorAngle - m->faceAngle[1]; s16 floorDYaw = m->floorAngle - m->faceAngle[1];
if (floorDYaw > -0x4000 && floorDYaw < 0x4000) { if (floorDYaw > -0x4000 && floorDYaw < 0x4000) {
@ -176,7 +179,9 @@ u32 mario_push_off_steep_floor(struct MarioState *m, u32 action, u32 actionArg)
} }
u32 mario_update_moving_sand(struct MarioState *m) { u32 mario_update_moving_sand(struct MarioState *m) {
if (!m) { return 0; }
struct Surface *floor = m->floor; struct Surface *floor = m->floor;
if (!floor) { return 0; }
s32 floorType = floor->type; s32 floorType = floor->type;
if (floorType == SURFACE_DEEP_MOVING_QUICKSAND || floorType == SURFACE_SHALLOW_MOVING_QUICKSAND if (floorType == SURFACE_DEEP_MOVING_QUICKSAND || floorType == SURFACE_SHALLOW_MOVING_QUICKSAND
@ -194,7 +199,9 @@ u32 mario_update_moving_sand(struct MarioState *m) {
} }
u32 mario_update_windy_ground(struct MarioState *m) { u32 mario_update_windy_ground(struct MarioState *m) {
if (!m) { return 0; }
struct Surface *floor = m->floor; struct Surface *floor = m->floor;
if (!floor) { return 0; }
extern bool gDjuiInMainMenu; extern bool gDjuiInMainMenu;
if (floor->type == SURFACE_HORIZONTAL_WIND && !gDjuiInMainMenu) { if (floor->type == SURFACE_HORIZONTAL_WIND && !gDjuiInMainMenu) {
@ -228,6 +235,7 @@ u32 mario_update_windy_ground(struct MarioState *m) {
} }
void stop_and_set_height_to_floor(struct MarioState *m) { void stop_and_set_height_to_floor(struct MarioState *m) {
if (!m) { return; }
struct Object *marioObj = m->marioObj; struct Object *marioObj = m->marioObj;
mario_set_forward_vel(m, 0.0f); mario_set_forward_vel(m, 0.0f);
@ -241,6 +249,7 @@ void stop_and_set_height_to_floor(struct MarioState *m) {
} }
s32 stationary_ground_step(struct MarioState *m) { s32 stationary_ground_step(struct MarioState *m) {
if (!m) { return 0; }
u32 takeStep; u32 takeStep;
struct Object *marioObj = m->marioObj; struct Object *marioObj = m->marioObj;
u32 stepResult = GROUND_STEP_NONE; u32 stepResult = GROUND_STEP_NONE;
@ -263,6 +272,7 @@ s32 stationary_ground_step(struct MarioState *m) {
} }
static s32 perform_ground_quarter_step(struct MarioState *m, Vec3f nextPos) { static s32 perform_ground_quarter_step(struct MarioState *m, Vec3f nextPos) {
if (!m) { return 0; }
struct WallCollisionData lowerWcd = { 0 }; struct WallCollisionData lowerWcd = { 0 };
struct WallCollisionData upperWcd = { 0 }; struct WallCollisionData upperWcd = { 0 };
struct Surface *ceil; struct Surface *ceil;
@ -379,6 +389,7 @@ s32 perform_ground_step(struct MarioState *m) {
} }
u32 check_ledge_grab(struct MarioState *m, struct Surface *wall, Vec3f intendedPos, Vec3f nextPos) { u32 check_ledge_grab(struct MarioState *m, struct Surface *wall, Vec3f intendedPos, Vec3f nextPos) {
if (!m) { return 0; }
struct Surface *ledgeFloor; struct Surface *ledgeFloor;
Vec3f ledgePos; Vec3f ledgePos;
f32 displacementX; f32 displacementX;
@ -419,6 +430,7 @@ u32 check_ledge_grab(struct MarioState *m, struct Surface *wall, Vec3f intendedP
} }
s32 perform_air_quarter_step(struct MarioState *m, Vec3f intendedPos, u32 stepArg) { s32 perform_air_quarter_step(struct MarioState *m, Vec3f intendedPos, u32 stepArg) {
if (!m) { return 0; }
s16 wallDYaw; s16 wallDYaw;
Vec3f nextPos; Vec3f nextPos;
struct WallCollisionData lowerWcd = { 0 }; struct WallCollisionData lowerWcd = { 0 };
@ -572,6 +584,7 @@ s32 perform_air_quarter_step(struct MarioState *m, Vec3f intendedPos, u32 stepAr
} }
void apply_twirl_gravity(struct MarioState *m) { void apply_twirl_gravity(struct MarioState *m) {
if (!m) { return; }
f32 terminalVelocity; f32 terminalVelocity;
f32 heaviness = 1.0f; f32 heaviness = 1.0f;
@ -588,6 +601,7 @@ void apply_twirl_gravity(struct MarioState *m) {
} }
u32 should_strengthen_gravity_for_jump_ascent(struct MarioState *m) { u32 should_strengthen_gravity_for_jump_ascent(struct MarioState *m) {
if (!m) { return 0; }
if (!(m->flags & MARIO_UNKNOWN_08)) { if (!(m->flags & MARIO_UNKNOWN_08)) {
return FALSE; return FALSE;
} }
@ -604,6 +618,7 @@ u32 should_strengthen_gravity_for_jump_ascent(struct MarioState *m) {
} }
void apply_gravity(struct MarioState *m) { void apply_gravity(struct MarioState *m) {
if (!m) { return; }
s32 result; s32 result;
if (m->action == ACT_TWIRLING && m->vel[1] < 0.0f) { if (m->action == ACT_TWIRLING && m->vel[1] < 0.0f) {
@ -656,6 +671,7 @@ void apply_gravity(struct MarioState *m) {
} }
void apply_vertical_wind(struct MarioState *m) { void apply_vertical_wind(struct MarioState *m) {
if (!m) { return; }
f32 maxVelY; f32 maxVelY;
f32 offsetY; f32 offsetY;
@ -751,12 +767,14 @@ s32 perform_air_step(struct MarioState *m, u32 stepArg) {
// They had these functions the whole time and never used them? Lol // They had these functions the whole time and never used them? Lol
void set_vel_from_pitch_and_yaw(struct MarioState *m) { void set_vel_from_pitch_and_yaw(struct MarioState *m) {
if (!m) { return; }
m->vel[0] = m->forwardVel * coss(m->faceAngle[0]) * sins(m->faceAngle[1]); m->vel[0] = m->forwardVel * coss(m->faceAngle[0]) * sins(m->faceAngle[1]);
m->vel[1] = m->forwardVel * sins(m->faceAngle[0]); m->vel[1] = m->forwardVel * sins(m->faceAngle[0]);
m->vel[2] = m->forwardVel * coss(m->faceAngle[0]) * coss(m->faceAngle[1]); m->vel[2] = m->forwardVel * coss(m->faceAngle[0]) * coss(m->faceAngle[1]);
} }
void set_vel_from_yaw(struct MarioState *m) { void set_vel_from_yaw(struct MarioState *m) {
if (!m) { return; }
m->vel[0] = m->slideVelX = m->forwardVel * sins(m->faceAngle[1]); m->vel[0] = m->slideVelX = m->forwardVel * sins(m->faceAngle[1]);
m->vel[1] = 0.0f; m->vel[1] = 0.0f;
m->vel[2] = m->slideVelZ = m->forwardVel * coss(m->faceAngle[1]); m->vel[2] = m->slideVelZ = m->forwardVel * coss(m->faceAngle[1]);

View file

@ -157,6 +157,7 @@ void turn_obj_away_from_surface(f32 velX, f32 velZ, f32 nX, UNUSED f32 nY, f32 n
* Finds any wall collisions, applies them, and turns away from the surface. * Finds any wall collisions, applies them, and turns away from the surface.
*/ */
s8 obj_find_wall(f32 objNewX, f32 objY, f32 objNewZ, f32 objVelX, f32 objVelZ) { s8 obj_find_wall(f32 objNewX, f32 objY, f32 objNewZ, f32 objVelX, f32 objVelZ) {
if (!o) { return 0; }
struct WallCollisionData hitbox; struct WallCollisionData hitbox;
f32 wall_nX, wall_nY, wall_nZ, objVelXCopy, objVelZCopy, objYawX, objYawZ; f32 wall_nX, wall_nY, wall_nZ, objVelXCopy, objVelZCopy, objYawX, objYawZ;
@ -198,6 +199,7 @@ s8 obj_find_wall(f32 objNewX, f32 objY, f32 objNewZ, f32 objVelX, f32 objVelZ) {
* Turns an object away from steep floors, similarly to walls. * Turns an object away from steep floors, similarly to walls.
*/ */
s8 turn_obj_away_from_steep_floor(struct Surface *objFloor, f32 floorY, f32 objVelX, f32 objVelZ) { s8 turn_obj_away_from_steep_floor(struct Surface *objFloor, f32 floorY, f32 objVelX, f32 objVelZ) {
if (!o) { return 0; }
f32 floor_nX, floor_nY, floor_nZ, objVelXCopy, objVelZCopy, objYawX, objYawZ; f32 floor_nX, floor_nY, floor_nZ, objVelXCopy, objVelZCopy, objYawX, objYawZ;
if (objFloor == NULL) { if (objFloor == NULL) {
@ -264,6 +266,7 @@ void obj_orient_graph(struct Object *obj, f32 normalX, f32 normalY, f32 normalZ)
* Determines an object's forward speed multiplier. * Determines an object's forward speed multiplier.
*/ */
void calc_obj_friction(f32 *objFriction, f32 floor_nY) { void calc_obj_friction(f32 *objFriction, f32 floor_nY) {
if (!o) { return; }
if (!objFriction) { return; } if (!objFriction) { return; }
if (floor_nY < 0.2 && o->oFriction < 0.9999) { if (floor_nY < 0.2 && o->oFriction < 0.9999) {
*objFriction = 0; *objFriction = 0;
@ -276,6 +279,7 @@ void calc_obj_friction(f32 *objFriction, f32 floor_nY) {
* Updates an objects speed for gravity and updates Y position. * Updates an objects speed for gravity and updates Y position.
*/ */
void calc_new_obj_vel_and_pos_y(struct Surface *objFloor, f32 objFloorY, f32 objVelX, f32 objVelZ) { void calc_new_obj_vel_and_pos_y(struct Surface *objFloor, f32 objFloorY, f32 objVelX, f32 objVelZ) {
if (!o) { return; }
if (!objFloor) { return; } if (!objFloor) { return; }
f32 floor_nX = objFloor->normal.x; f32 floor_nX = objFloor->normal.x;
f32 floor_nY = objFloor->normal.y; f32 floor_nY = objFloor->normal.y;
@ -335,6 +339,7 @@ void calc_new_obj_vel_and_pos_y(struct Surface *objFloor, f32 objFloorY, f32 obj
void calc_new_obj_vel_and_pos_y_underwater(struct Surface *objFloor, f32 floorY, f32 objVelX, f32 objVelZ, void calc_new_obj_vel_and_pos_y_underwater(struct Surface *objFloor, f32 floorY, f32 objVelX, f32 objVelZ,
f32 waterY) { f32 waterY) {
if (!o) { return; }
if (!objFloor) { return; } if (!objFloor) { return; }
f32 floor_nX = objFloor->normal.x; f32 floor_nX = objFloor->normal.x;
f32 floor_nY = objFloor->normal.y; f32 floor_nY = objFloor->normal.y;
@ -405,6 +410,7 @@ void calc_new_obj_vel_and_pos_y_underwater(struct Surface *objFloor, f32 floorY,
* Updates an objects position from oForwardVel and oMoveAngleYaw. * Updates an objects position from oForwardVel and oMoveAngleYaw.
*/ */
void obj_update_pos_vel_xz(void) { void obj_update_pos_vel_xz(void) {
if (!o) { return; }
f32 xVel = o->oForwardVel * sins(o->oMoveAngleYaw); f32 xVel = o->oForwardVel * sins(o->oMoveAngleYaw);
f32 zVel = o->oForwardVel * coss(o->oMoveAngleYaw); f32 zVel = o->oForwardVel * coss(o->oMoveAngleYaw);
@ -417,6 +423,7 @@ void obj_update_pos_vel_xz(void) {
* if underwater. * if underwater.
*/ */
void obj_splash(s32 waterY, s32 objY) { void obj_splash(s32 waterY, s32 objY) {
if (!o) { return; }
u32 globalTimer = gGlobalTimer; u32 globalTimer = gGlobalTimer;
// Spawns waves if near surface of water and plays a noise if entering. // Spawns waves if near surface of water and plays a noise if entering.
@ -439,6 +446,7 @@ void obj_splash(s32 waterY, s32 objY) {
* Returns flags for certain interactions. * Returns flags for certain interactions.
*/ */
s16 object_step(void) { s16 object_step(void) {
if (!o) { return 0; }
f32 objX = o->oPosX; f32 objX = o->oPosX;
f32 objY = o->oPosY; f32 objY = o->oPosY;
f32 objZ = o->oPosZ; f32 objZ = o->oPosZ;
@ -506,7 +514,7 @@ s16 object_step_without_floor_orient(void) {
* position. * position.
*/ */
void obj_move_xyz_using_fvel_and_yaw(struct Object *obj) { void obj_move_xyz_using_fvel_and_yaw(struct Object *obj) {
if (!obj) { return; } if (!o || !obj) { return; }
o->oVelX = obj->oForwardVel * sins(obj->oMoveAngleYaw); o->oVelX = obj->oForwardVel * sins(obj->oMoveAngleYaw);
o->oVelZ = obj->oForwardVel * coss(obj->oMoveAngleYaw); o->oVelZ = obj->oForwardVel * coss(obj->oMoveAngleYaw);
@ -705,6 +713,7 @@ u8 is_nearest_mario_state_to_object(struct MarioState *m, struct Object *obj) {
u8 is_nearest_player_to_object(struct Object *m, struct Object *obj) { u8 is_nearest_player_to_object(struct Object *m, struct Object *obj) {
if (m == NULL || obj == NULL) { return FALSE; } if (m == NULL || obj == NULL) { return FALSE; }
struct MarioState *nearest = nearest_mario_state_to_object(obj); struct MarioState *nearest = nearest_mario_state_to_object(obj);
if (!nearest) { return FALSE; }
return m == nearest->marioObj; return m == nearest->marioObj;
} }
@ -818,6 +827,7 @@ s8 obj_find_wall_displacement(Vec3f dist, f32 x, f32 y, f32 z, f32 radius) {
* with a random forward velocity, y velocity, and direction. * with a random forward velocity, y velocity, and direction.
*/ */
void obj_spawn_yellow_coins(struct Object *obj, s8 nCoins) { void obj_spawn_yellow_coins(struct Object *obj, s8 nCoins) {
if (!o) { return; }
if (!obj) { return; } if (!obj) { return; }
struct Object *coin; struct Object *coin;
s8 count; s8 count;
@ -888,6 +898,7 @@ s8 current_mario_room_check(s16 room) {
* Triggers dialog when Mario is facing an object and controls it while in the dialog. * Triggers dialog when Mario is facing an object and controls it while in the dialog.
*/ */
s16 trigger_obj_dialog_when_facing(struct MarioState* m, s32 *inDialog, s16 dialogID, f32 dist, s32 actionArg, u8 (*inContinueDialogFunction)(void)) { s16 trigger_obj_dialog_when_facing(struct MarioState* m, s32 *inDialog, s16 dialogID, f32 dist, s32 actionArg, u8 (*inContinueDialogFunction)(void)) {
if (!o) { return 0; }
if (!m || !inDialog) { return 0; } if (!m || !inDialog) { return 0; }
s16 dialogueResponse; s16 dialogueResponse;
@ -917,9 +928,8 @@ s16 trigger_obj_dialog_when_facing(struct MarioState* m, s32 *inDialog, s16 dial
*Checks if a floor is one that should cause an object to "die". *Checks if a floor is one that should cause an object to "die".
*/ */
void obj_check_floor_death(s16 collisionFlags, struct Surface *floor) { void obj_check_floor_death(s16 collisionFlags, struct Surface *floor) {
if (floor == NULL) { if (!o) { return; }
return; if (floor == NULL) { return; }
}
if ((collisionFlags & OBJ_COL_FLAG_GROUNDED) == OBJ_COL_FLAG_GROUNDED) { if ((collisionFlags & OBJ_COL_FLAG_GROUNDED) == OBJ_COL_FLAG_GROUNDED) {
switch (floor->type) { switch (floor->type) {
@ -941,6 +951,7 @@ void obj_check_floor_death(s16 collisionFlags, struct Surface *floor) {
* audio, and eventually despawning it. Returns TRUE when the obj is dead. * audio, and eventually despawning it. Returns TRUE when the obj is dead.
*/ */
s8 obj_lava_death(void) { s8 obj_lava_death(void) {
if (!o) { return 0; }
struct Object *deathSmoke; struct Object *deathSmoke;
if (o->oTimer >= 31) { if (o->oTimer >= 31) {

View file

@ -83,6 +83,7 @@ void wiggler_jumped_on_attack_handler(void);
void huge_goomba_weakly_attacked(void); void huge_goomba_weakly_attacked(void);
s32 obj_is_rendering_enabled(void) { s32 obj_is_rendering_enabled(void) {
if (!o) { return 0; }
if (o->header.gfx.node.flags & GRAPH_RENDER_ACTIVE) { if (o->header.gfx.node.flags & GRAPH_RENDER_ACTIVE) {
return TRUE; return TRUE;
} else { } else {
@ -91,6 +92,7 @@ s32 obj_is_rendering_enabled(void) {
} }
s16 obj_get_pitch_from_vel(void) { s16 obj_get_pitch_from_vel(void) {
if (!o) { return 0; }
return -atan2s(o->oForwardVel, o->oVelY); return -atan2s(o->oForwardVel, o->oVelY);
} }
@ -113,11 +115,13 @@ static s32 obj_update_race_proposition_dialog(struct MarioState* m, s16 dialogID
} }
void obj_set_dist_from_home(f32 distFromHome) { void obj_set_dist_from_home(f32 distFromHome) {
if (!o) { return; }
o->oPosX = o->oHomeX + distFromHome * coss(o->oMoveAngleYaw); o->oPosX = o->oHomeX + distFromHome * coss(o->oMoveAngleYaw);
o->oPosZ = o->oHomeZ + distFromHome * sins(o->oMoveAngleYaw); o->oPosZ = o->oHomeZ + distFromHome * sins(o->oMoveAngleYaw);
} }
s32 obj_is_near_to_and_facing_mario(struct MarioState* m, f32 maxDist, s16 maxAngleDiff) { s32 obj_is_near_to_and_facing_mario(struct MarioState* m, f32 maxDist, s16 maxAngleDiff) {
if (!o) { return 0; }
struct Object* player = m->marioObj; struct Object* player = m->marioObj;
s32 distanceToPlayer = dist_between_objects(o, player); s32 distanceToPlayer = dist_between_objects(o, player);
s32 angleToPlayer = obj_angle_to_object(o, player); s32 angleToPlayer = obj_angle_to_object(o, player);
@ -131,6 +135,7 @@ s32 obj_is_near_to_and_facing_mario(struct MarioState* m, f32 maxDist, s16 maxAn
//! Although having no return value, this function //! Although having no return value, this function
//! must be u32 to match other functions on -O2. //! must be u32 to match other functions on -O2.
static BAD_RETURN(u32) obj_perform_position_op(s32 op) { static BAD_RETURN(u32) obj_perform_position_op(s32 op) {
if (!o) { return; }
switch (op) { switch (op) {
case POS_OP_SAVE_POSITION: case POS_OP_SAVE_POSITION:
sObjSavedPosX = o->oPosX; sObjSavedPosX = o->oPosX;
@ -153,6 +158,7 @@ static BAD_RETURN(u32) obj_perform_position_op(s32 op) {
} }
void platform_on_track_update_pos_or_spawn_ball(s32 ballIndex, f32 x, f32 y, f32 z) { void platform_on_track_update_pos_or_spawn_ball(s32 ballIndex, f32 x, f32 y, f32 z) {
if (!o) { return; }
struct Object *trackBall; struct Object *trackBall;
struct Waypoint *initialPrevWaypoint; struct Waypoint *initialPrevWaypoint;
struct Waypoint *nextWaypoint; struct Waypoint *nextWaypoint;
@ -250,6 +256,7 @@ void platform_on_track_update_pos_or_spawn_ball(s32 ballIndex, f32 x, f32 y, f32
} }
void cur_obj_spin_all_dimensions(f32 arg0, f32 arg1) { void cur_obj_spin_all_dimensions(f32 arg0, f32 arg1) {
if (!o) { return; }
f32 val24; f32 val24;
f32 val20; f32 val20;
f32 val1C; f32 val1C;
@ -305,6 +312,7 @@ void cur_obj_spin_all_dimensions(f32 arg0, f32 arg1) {
} }
void obj_rotate_yaw_and_bounce_off_walls(s16 targetYaw, s16 turnAmount) { void obj_rotate_yaw_and_bounce_off_walls(s16 targetYaw, s16 turnAmount) {
if (!o) { return; }
if (o->oMoveFlags & OBJ_MOVE_HIT_WALL) { if (o->oMoveFlags & OBJ_MOVE_HIT_WALL) {
targetYaw = cur_obj_reflect_move_angle_off_wall(); targetYaw = cur_obj_reflect_move_angle_off_wall();
} }
@ -312,10 +320,12 @@ void obj_rotate_yaw_and_bounce_off_walls(s16 targetYaw, s16 turnAmount) {
} }
s16 obj_get_pitch_to_home(f32 latDistToHome) { s16 obj_get_pitch_to_home(f32 latDistToHome) {
if (!o) { return 0; }
return atan2s(latDistToHome, o->oPosY - o->oHomeY); return atan2s(latDistToHome, o->oPosY - o->oHomeY);
} }
void obj_compute_vel_from_move_pitch(f32 speed) { void obj_compute_vel_from_move_pitch(f32 speed) {
if (!o) { return; }
o->oForwardVel = speed * coss(o->oMoveAnglePitch); o->oForwardVel = speed * coss(o->oMoveAnglePitch);
o->oVelY = speed * -sins(o->oMoveAnglePitch); o->oVelY = speed * -sins(o->oMoveAnglePitch);
} }
@ -368,6 +378,7 @@ s32 cur_obj_set_anim_if_at_end(s32 arg0) {
} }
s32 cur_obj_play_sound_at_anim_range(s8 arg0, s8 arg1, u32 sound) { s32 cur_obj_play_sound_at_anim_range(s8 arg0, s8 arg1, u32 sound) {
if (!o) { return 0; }
s32 val04; s32 val04;
if ((val04 = o->header.gfx.animInfo.animAccel / 0x10000) <= 0) { if ((val04 = o->header.gfx.animInfo.animAccel / 0x10000) <= 0) {
@ -383,6 +394,7 @@ s32 cur_obj_play_sound_at_anim_range(s8 arg0, s8 arg1, u32 sound) {
} }
s16 obj_turn_pitch_toward_mario(struct MarioState* m, f32 targetOffsetY, s16 turnAmount) { s16 obj_turn_pitch_toward_mario(struct MarioState* m, f32 targetOffsetY, s16 turnAmount) {
if (!o) { return 0; }
if (!m) { return 0; } if (!m) { return 0; }
s16 targetPitch; s16 targetPitch;
@ -394,6 +406,7 @@ s16 obj_turn_pitch_toward_mario(struct MarioState* m, f32 targetOffsetY, s16 tur
} }
s32 approach_f32_ptr(f32 *px, f32 target, f32 delta) { s32 approach_f32_ptr(f32 *px, f32 target, f32 delta) {
if (!px) { return FALSE; }
if (*px > target) { if (*px > target) {
delta = -delta; delta = -delta;
} }
@ -408,14 +421,17 @@ s32 approach_f32_ptr(f32 *px, f32 target, f32 delta) {
} }
s32 obj_forward_vel_approach(f32 target, f32 delta) { s32 obj_forward_vel_approach(f32 target, f32 delta) {
if (!o) { return 0; }
return approach_f32_ptr(&o->oForwardVel, target, delta); return approach_f32_ptr(&o->oForwardVel, target, delta);
} }
s32 obj_y_vel_approach(f32 target, f32 delta) { s32 obj_y_vel_approach(f32 target, f32 delta) {
if (!o) { return 0; }
return approach_f32_ptr(&o->oVelY, target, delta); return approach_f32_ptr(&o->oVelY, target, delta);
} }
s32 obj_move_pitch_approach(s16 target, s16 delta) { s32 obj_move_pitch_approach(s16 target, s16 delta) {
if (!o) { return 0; }
o->oMoveAnglePitch = approach_s16_symmetric(o->oMoveAnglePitch, target, delta); o->oMoveAnglePitch = approach_s16_symmetric(o->oMoveAnglePitch, target, delta);
if ((s16) o->oMoveAnglePitch == target) { if ((s16) o->oMoveAnglePitch == target) {
@ -426,6 +442,7 @@ s32 obj_move_pitch_approach(s16 target, s16 delta) {
} }
s32 obj_face_pitch_approach(s16 targetPitch, s16 deltaPitch) { s32 obj_face_pitch_approach(s16 targetPitch, s16 deltaPitch) {
if (!o) { return 0; }
o->oFaceAnglePitch = approach_s16_symmetric(o->oFaceAnglePitch, targetPitch, deltaPitch); o->oFaceAnglePitch = approach_s16_symmetric(o->oFaceAnglePitch, targetPitch, deltaPitch);
if ((s16) o->oFaceAnglePitch == targetPitch) { if ((s16) o->oFaceAnglePitch == targetPitch) {
@ -436,6 +453,7 @@ s32 obj_face_pitch_approach(s16 targetPitch, s16 deltaPitch) {
} }
s32 obj_face_yaw_approach(s16 targetYaw, s16 deltaYaw) { s32 obj_face_yaw_approach(s16 targetYaw, s16 deltaYaw) {
if (!o) { return 0; }
o->oFaceAngleYaw = approach_s16_symmetric(o->oFaceAngleYaw, targetYaw, deltaYaw); o->oFaceAngleYaw = approach_s16_symmetric(o->oFaceAngleYaw, targetYaw, deltaYaw);
if ((s16) o->oFaceAngleYaw == targetYaw) { if ((s16) o->oFaceAngleYaw == targetYaw) {
@ -446,6 +464,7 @@ s32 obj_face_yaw_approach(s16 targetYaw, s16 deltaYaw) {
} }
s32 obj_face_roll_approach(s16 targetRoll, s16 deltaRoll) { s32 obj_face_roll_approach(s16 targetRoll, s16 deltaRoll) {
if (!o) { return 0; }
o->oFaceAngleRoll = approach_s16_symmetric(o->oFaceAngleRoll, targetRoll, deltaRoll); o->oFaceAngleRoll = approach_s16_symmetric(o->oFaceAngleRoll, targetRoll, deltaRoll);
if ((s16) o->oFaceAngleRoll == targetRoll) { if ((s16) o->oFaceAngleRoll == targetRoll) {
@ -471,6 +490,7 @@ s32 obj_smooth_turn(s16 *angleVel, s32 *angle, s16 targetAngle, f32 targetSpeedP
} }
void obj_roll_to_match_yaw_turn(s16 targetYaw, s16 maxRoll, s16 rollSpeed) { void obj_roll_to_match_yaw_turn(s16 targetYaw, s16 maxRoll, s16 rollSpeed) {
if (!o) { return; }
s16 targetRoll = o->oMoveAngleYaw - targetYaw; s16 targetRoll = o->oMoveAngleYaw - targetYaw;
clamp_s16(&targetRoll, -maxRoll, maxRoll); clamp_s16(&targetRoll, -maxRoll, maxRoll);
obj_face_roll_approach(targetRoll, rollSpeed); obj_face_roll_approach(targetRoll, rollSpeed);
@ -481,10 +501,12 @@ s16 random_linear_offset(s16 base, s16 range) {
} }
s16 random_mod_offset(s16 base, s16 step, s16 mod) { s16 random_mod_offset(s16 base, s16 step, s16 mod) {
if (!mod) { return 0; }
return base + step * (random_u16() % mod); return base + step * (random_u16() % mod);
} }
s16 obj_random_fixed_turn(s16 delta) { s16 obj_random_fixed_turn(s16 delta) {
if (!o) { return 0; }
return o->oMoveAngleYaw + (s16) random_sign() * delta; return o->oMoveAngleYaw + (s16) random_sign() * delta;
} }
@ -496,6 +518,7 @@ s16 obj_random_fixed_turn(s16 delta) {
* Return -1 once it's reached endScale. * Return -1 once it's reached endScale.
*/ */
s32 obj_grow_then_shrink(f32 *scaleVel, f32 shootFireScale, f32 endScale) { s32 obj_grow_then_shrink(f32 *scaleVel, f32 shootFireScale, f32 endScale) {
if (!o) { return 0; }
if (o->oTimer < 2) { if (o->oTimer < 2) {
o->header.gfx.scale[0] += *scaleVel; o->header.gfx.scale[0] += *scaleVel;
@ -542,6 +565,7 @@ s32 oscillate_toward(s32 *value, f32 *vel, s32 target, f32 velCloseToZero, f32 a
void obj_update_blinking(s32 *blinkTimer, s16 baseCycleLength, s16 cycleLengthRange, void obj_update_blinking(s32 *blinkTimer, s16 baseCycleLength, s16 cycleLengthRange,
s16 blinkLength) { s16 blinkLength) {
if (!o) { return; }
if (*blinkTimer != 0) { if (*blinkTimer != 0) {
*blinkTimer -= 1; *blinkTimer -= 1;
} else { } else {
@ -556,6 +580,7 @@ void obj_update_blinking(s32 *blinkTimer, s16 baseCycleLength, s16 cycleLengthRa
} }
s32 obj_resolve_object_collisions(s32 *targetYaw) { s32 obj_resolve_object_collisions(s32 *targetYaw) {
if (!o) { return 0; }
struct Object *otherObject; struct Object *otherObject;
f32 dx; f32 dx;
f32 dz; f32 dz;
@ -602,6 +627,7 @@ s32 obj_resolve_object_collisions(s32 *targetYaw) {
} }
s32 obj_bounce_off_walls_edges_objects(s32 *targetYaw) { s32 obj_bounce_off_walls_edges_objects(s32 *targetYaw) {
if (!o) { return 0; }
if (o->oMoveFlags & OBJ_MOVE_HIT_WALL) { if (o->oMoveFlags & OBJ_MOVE_HIT_WALL) {
*targetYaw = cur_obj_reflect_move_angle_off_wall(); *targetYaw = cur_obj_reflect_move_angle_off_wall();
} else if (o->oMoveFlags & OBJ_MOVE_HIT_EDGE) { } else if (o->oMoveFlags & OBJ_MOVE_HIT_EDGE) {
@ -624,6 +650,7 @@ s32 obj_resolve_collisions_and_turn(s16 targetYaw, s16 turnSpeed) {
} }
void obj_die_if_health_non_positive(void) { void obj_die_if_health_non_positive(void) {
if (!o) { return; }
if (o->oHealth <= 0) { if (o->oHealth <= 0) {
if (o->oDeathSound == 0) { if (o->oDeathSound == 0) {
spawn_mist_particles_with_sound(SOUND_OBJ_DEFAULT_DEATH); spawn_mist_particles_with_sound(SOUND_OBJ_DEFAULT_DEATH);
@ -651,11 +678,13 @@ void obj_die_if_health_non_positive(void) {
} }
void obj_unused_die(void) { void obj_unused_die(void) {
if (!o) { return; }
o->oHealth = 0; o->oHealth = 0;
obj_die_if_health_non_positive(); obj_die_if_health_non_positive();
} }
void obj_set_knockback_action(s32 attackType) { void obj_set_knockback_action(s32 attackType) {
if (!o) { return; }
switch (attackType) { switch (attackType) {
case ATTACK_KICK_OR_TRIP: case ATTACK_KICK_OR_TRIP:
case ATTACK_FAST_ATTACK: case ATTACK_FAST_ATTACK:
@ -680,11 +709,13 @@ void obj_set_knockback_action(s32 attackType) {
} }
void obj_set_squished_action(void) { void obj_set_squished_action(void) {
if (!o) { return; }
cur_obj_play_sound_2(SOUND_OBJ_STOMPED); cur_obj_play_sound_2(SOUND_OBJ_STOMPED);
o->oAction = OBJ_ACT_SQUISHED; o->oAction = OBJ_ACT_SQUISHED;
} }
s32 obj_die_if_above_lava_and_health_non_positive(void) { s32 obj_die_if_above_lava_and_health_non_positive(void) {
if (!o) { return 0; }
if (o->oMoveFlags & OBJ_MOVE_UNDERWATER_ON_GROUND) { if (o->oMoveFlags & OBJ_MOVE_UNDERWATER_ON_GROUND) {
if (o->oGravity + o->oBuoyancy > 0.0f if (o->oGravity + o->oBuoyancy > 0.0f
|| find_water_level(o->oPosX, o->oPosZ) - o->oPosY < 150.0f) { || find_water_level(o->oPosX, o->oPosZ) - o->oPosY < 150.0f) {
@ -707,6 +738,7 @@ s32 obj_die_if_above_lava_and_health_non_positive(void) {
s32 obj_handle_attacks(struct ObjectHitbox *hitbox, s32 attackedMarioAction, s32 obj_handle_attacks(struct ObjectHitbox *hitbox, s32 attackedMarioAction,
u8 *attackHandlers) { u8 *attackHandlers) {
if (!o) { return 0; }
s32 attackType; s32 attackType;
obj_set_hitbox(o, hitbox); obj_set_hitbox(o, hitbox);
@ -771,6 +803,7 @@ s32 obj_handle_attacks(struct ObjectHitbox *hitbox, s32 attackedMarioAction,
} }
void obj_act_knockback(UNUSED f32 baseScale) { void obj_act_knockback(UNUSED f32 baseScale) {
if (!o) { return; }
cur_obj_update_floor_and_walls(); cur_obj_update_floor_and_walls();
if (o->header.gfx.animInfo.curAnim != NULL) { if (o->header.gfx.animInfo.curAnim != NULL) {
@ -788,6 +821,7 @@ void obj_act_knockback(UNUSED f32 baseScale) {
} }
void obj_act_squished(f32 baseScale) { void obj_act_squished(f32 baseScale) {
if (!o) { return; }
f32 targetScaleY = baseScale * 0.3f; f32 targetScaleY = baseScale * 0.3f;
cur_obj_update_floor_and_walls(); cur_obj_update_floor_and_walls();
@ -809,6 +843,7 @@ void obj_act_squished(f32 baseScale) {
} }
s32 obj_update_standard_actions(f32 scale) { s32 obj_update_standard_actions(f32 scale) {
if (!o) { return 0; }
if (o->oAction < 100) { if (o->oAction < 100) {
return TRUE; return TRUE;
} else { } else {
@ -830,6 +865,7 @@ s32 obj_update_standard_actions(f32 scale) {
} }
s32 obj_check_attacks(struct ObjectHitbox *hitbox, s32 attackedMarioAction) { s32 obj_check_attacks(struct ObjectHitbox *hitbox, s32 attackedMarioAction) {
if (!o) { return 0; }
s32 attackType; s32 attackType;
obj_set_hitbox(o, hitbox); obj_set_hitbox(o, hitbox);
@ -856,6 +892,7 @@ s32 obj_check_attacks(struct ObjectHitbox *hitbox, s32 attackedMarioAction) {
} }
s32 obj_move_for_one_second(s32 endAction) { s32 obj_move_for_one_second(s32 endAction) {
if (!o) { return 0; }
cur_obj_update_floor_and_walls(); cur_obj_update_floor_and_walls();
cur_obj_extend_animation_if_at_end(); cur_obj_extend_animation_if_at_end();
@ -887,6 +924,7 @@ s32 obj_move_for_one_second(s32 endAction) {
* with partial updates. * with partial updates.
*/ */
void treat_far_home_as_mario(f32 threshold, s32* distanceToPlayer, s32* angleToPlayer) { void treat_far_home_as_mario(f32 threshold, s32* distanceToPlayer, s32* angleToPlayer) {
if (!o) { return; }
f32 dx = o->oHomeX - o->oPosX; f32 dx = o->oHomeX - o->oPosX;
f32 dy = o->oHomeY - o->oPosY; f32 dy = o->oHomeY - o->oPosY;
f32 dz = o->oHomeZ - o->oPosZ; f32 dz = o->oHomeZ - o->oPosZ;

View file

@ -215,7 +215,7 @@ Gfx *geo_switch_area(s32 callContext, struct GraphNode *node) {
struct MarioState* m = &gMarioStates[i]; struct MarioState* m = &gMarioStates[i];
if (!is_player_active(m)) { continue; } if (!is_player_active(m)) { continue; }
struct Object* door = m->interactObj; struct Object* door = m ? m->interactObj : NULL;
if (door == NULL) { continue; } if (door == NULL) { continue; }
if (door->oInteractType != INTERACT_DOOR) { continue; } if (door->oInteractType != INTERACT_DOOR) { continue; }
if (door->oAction == 0) { continue; } if (door->oAction == 0) { continue; }
@ -360,6 +360,7 @@ f32 dist_between_object_and_point(struct Object *obj, f32 pointX, f32 pointY, f3
} }
void cur_obj_forward_vel_approach_upward(f32 target, f32 increment) { void cur_obj_forward_vel_approach_upward(f32 target, f32 increment) {
if (!o) { return; }
if (o->oForwardVel >= target) { if (o->oForwardVel >= target) {
o->oForwardVel = target; o->oForwardVel = target;
} else { } else {
@ -429,6 +430,7 @@ s16 approach_s16_symmetric(s16 value, s16 target, s16 increment) {
} }
s32 cur_obj_rotate_yaw_toward(s16 target, s16 increment) { s32 cur_obj_rotate_yaw_toward(s16 target, s16 increment) {
if (!o) { return 0; }
s16 startYaw; s16 startYaw;
startYaw = (s16) o->oMoveAngleYaw; startYaw = (s16) o->oMoveAngleYaw;
@ -456,6 +458,7 @@ s16 obj_angle_to_object(struct Object *obj1, struct Object *obj2) {
s16 obj_pitch_to_object(struct Object* obj, struct Object* target) { s16 obj_pitch_to_object(struct Object* obj, struct Object* target) {
if (obj == NULL) { return 0; } if (obj == NULL) { return 0; }
if (!target) { return 0; }
f32 a, b, c, d; f32 a, b, c, d;
a = target->oPosX - obj->oPosX; a = target->oPosX - obj->oPosX;
c = target->oPosZ - obj->oPosZ; c = target->oPosZ - obj->oPosZ;
@ -480,7 +483,7 @@ s16 obj_angle_to_point(struct Object *obj, f32 pointX, f32 pointZ) {
} }
s16 obj_turn_toward_object(struct Object *obj, struct Object *target, s16 angleIndex, s16 turnAmount) { s16 obj_turn_toward_object(struct Object *obj, struct Object *target, s16 angleIndex, s16 turnAmount) {
if (obj == NULL || target == NULL) { return 0; } if (obj == NULL || target == NULL || !o) { return 0; }
f32 a, b, c, d; f32 a, b, c, d;
UNUSED s32 unused; UNUSED s32 unused;
s16 targetAngle = 0; s16 targetAngle = 0;
@ -751,6 +754,7 @@ struct Object *spawn_object_relative_with_scale(s16 behaviorParam, s16 relativeP
} }
void cur_obj_move_using_vel(void) { void cur_obj_move_using_vel(void) {
if (!o) { return; }
o->oPosX += o->oVelX; o->oPosX += o->oVelX;
o->oPosY += o->oVelY; o->oPosY += o->oVelY;
o->oPosZ += o->oVelZ; o->oPosZ += o->oVelZ;
@ -792,6 +796,7 @@ void obj_set_gfx_pos_from_pos(struct Object *obj) {
} }
void obj_init_animation(struct Object *obj, s32 animIndex) { void obj_init_animation(struct Object *obj, s32 animIndex) {
if (!o || !obj) { return; }
struct AnimationTable *animations = o->oAnimations; struct AnimationTable *animations = o->oAnimations;
if (animations && (u32)animIndex < animations->count) { if (animations && (u32)animIndex < animations->count) {
geo_obj_init_animation(&obj->header.gfx, animations->anims[animIndex]); geo_obj_init_animation(&obj->header.gfx, animations->anims[animIndex]);
@ -869,12 +874,14 @@ void obj_scale(struct Object *obj, f32 scale) {
} }
void cur_obj_scale(f32 scale) { void cur_obj_scale(f32 scale) {
if (!o) { return; }
o->header.gfx.scale[0] = scale; o->header.gfx.scale[0] = scale;
o->header.gfx.scale[1] = scale; o->header.gfx.scale[1] = scale;
o->header.gfx.scale[2] = scale; o->header.gfx.scale[2] = scale;
} }
void cur_obj_init_animation(s32 animIndex) { void cur_obj_init_animation(s32 animIndex) {
if (!o) { return; }
struct AnimationTable *animations = o->oAnimations; struct AnimationTable *animations = o->oAnimations;
if (animations && (u32)animIndex < animations->count) { if (animations && (u32)animIndex < animations->count) {
geo_obj_init_animation(&o->header.gfx, animations->anims[animIndex]); geo_obj_init_animation(&o->header.gfx, animations->anims[animIndex]);
@ -882,6 +889,7 @@ void cur_obj_init_animation(s32 animIndex) {
} }
void cur_obj_init_animation_with_sound(s32 animIndex) { void cur_obj_init_animation_with_sound(s32 animIndex) {
if (!o) { return; }
struct AnimationTable *animations = o->oAnimations; struct AnimationTable *animations = o->oAnimations;
if (animations && (u32)animIndex < animations->count) { if (animations && (u32)animIndex < animations->count) {
geo_obj_init_animation(&o->header.gfx, animations->anims[animIndex]); geo_obj_init_animation(&o->header.gfx, animations->anims[animIndex]);
@ -890,6 +898,7 @@ void cur_obj_init_animation_with_sound(s32 animIndex) {
} }
void obj_init_animation_with_accel_and_sound(struct Object *obj, s32 animIndex, f32 accel) { void obj_init_animation_with_accel_and_sound(struct Object *obj, s32 animIndex, f32 accel) {
if (!o) { return; }
if (obj != NULL) { if (obj != NULL) {
struct AnimationTable *animations = o->oAnimations; struct AnimationTable *animations = o->oAnimations;
if (animations && (u32)animIndex < animations->count) { if (animations && (u32)animIndex < animations->count) {
@ -901,6 +910,7 @@ void obj_init_animation_with_accel_and_sound(struct Object *obj, s32 animIndex,
} }
void cur_obj_init_animation_with_accel_and_sound(s32 animIndex, f32 accel) { void cur_obj_init_animation_with_accel_and_sound(s32 animIndex, f32 accel) {
if (!o) { return; }
struct AnimationTable *animations = o->oAnimations; struct AnimationTable *animations = o->oAnimations;
if (animations && (u32)animIndex < animations->count) { if (animations && (u32)animIndex < animations->count) {
s32 animAccel = (s32)(accel * 65536.0f); s32 animAccel = (s32)(accel * 65536.0f);
@ -924,6 +934,7 @@ void cur_obj_enable_rendering_and_become_tangible(struct Object *obj) {
} }
void cur_obj_enable_rendering(void) { void cur_obj_enable_rendering(void) {
if (!o) { return; }
o->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE; o->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE;
} }
@ -934,18 +945,22 @@ void cur_obj_disable_rendering_and_become_intangible(struct Object *obj) {
} }
void cur_obj_disable_rendering(void) { void cur_obj_disable_rendering(void) {
if (!o) { return; }
o->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE; o->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
} }
void cur_obj_unhide(void) { void cur_obj_unhide(void) {
if (!o) { return; }
o->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE; o->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE;
} }
void cur_obj_hide(void) { void cur_obj_hide(void) {
if (!o) { return; }
o->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE; o->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE;
} }
void cur_obj_set_pos_relative(struct Object *other, f32 dleft, f32 dy, f32 dforward) { void cur_obj_set_pos_relative(struct Object *other, f32 dleft, f32 dy, f32 dforward) {
if (!o) { return; }
if (other == NULL) { return; } if (other == NULL) { return; }
f32 facingZ = coss(other->oMoveAngleYaw); f32 facingZ = coss(other->oMoveAngleYaw);
f32 facingX = sins(other->oMoveAngleYaw); f32 facingX = sins(other->oMoveAngleYaw);
@ -961,6 +976,7 @@ void cur_obj_set_pos_relative(struct Object *other, f32 dleft, f32 dy, f32 dforw
} }
void cur_obj_set_pos_relative_to_parent(f32 dleft, f32 dy, f32 dforward) { void cur_obj_set_pos_relative_to_parent(f32 dleft, f32 dy, f32 dforward) {
if (!o) { return; }
cur_obj_set_pos_relative(o->parentObj, dleft, dy, dforward); cur_obj_set_pos_relative(o->parentObj, dleft, dy, dforward);
} }
@ -969,6 +985,7 @@ void cur_obj_enable_rendering_2(void) {
} }
void cur_obj_unused_init_on_floor(void) { void cur_obj_unused_init_on_floor(void) {
if (!o) { return; }
cur_obj_enable_rendering(); cur_obj_enable_rendering();
o->oPosY = find_floor_height(o->oPosX, o->oPosY, o->oPosZ); o->oPosY = find_floor_height(o->oPosX, o->oPosY, o->oPosZ);
@ -1207,17 +1224,21 @@ struct Object *cur_obj_find_nearby_held_actor(const BehaviorScript *behavior, f3
} }
void cur_obj_reset_timer_and_subaction(void) { void cur_obj_reset_timer_and_subaction(void) {
if (!o) { return; }
o->oTimer = 0; o->oTimer = 0;
o->oSubAction = 0; o->oSubAction = 0;
} }
void cur_obj_change_action(s32 action) { void cur_obj_change_action(s32 action) {
if (!o) { return; }
o->oAction = action; o->oAction = action;
o->oPrevAction = action; o->oPrevAction = action;
cur_obj_reset_timer_and_subaction(); cur_obj_reset_timer_and_subaction();
} }
void cur_obj_set_vel_from_mario_vel(struct MarioState* m, f32 f12, f32 f14) { void cur_obj_set_vel_from_mario_vel(struct MarioState* m, f32 f12, f32 f14) {
if (!o) { return; }
if (!m) { return; }
f32 sp4 = m->forwardVel; f32 sp4 = m->forwardVel;
f32 sp0 = f12 * f14; f32 sp0 = f12 * f14;
@ -1229,12 +1250,14 @@ void cur_obj_set_vel_from_mario_vel(struct MarioState* m, f32 f12, f32 f14) {
} }
BAD_RETURN(s16) cur_obj_reverse_animation(void) { BAD_RETURN(s16) cur_obj_reverse_animation(void) {
if (!o) { return; }
if (o->header.gfx.animInfo.animFrame >= 0) { if (o->header.gfx.animInfo.animFrame >= 0) {
o->header.gfx.animInfo.animFrame--; o->header.gfx.animInfo.animFrame--;
} }
} }
BAD_RETURN(s32) cur_obj_extend_animation_if_at_end(void) { BAD_RETURN(s32) cur_obj_extend_animation_if_at_end(void) {
if (!o) { return; }
s32 sp4 = o->header.gfx.animInfo.animFrame; s32 sp4 = o->header.gfx.animInfo.animFrame;
s32 sp0 = o->header.gfx.animInfo.curAnim ? o->header.gfx.animInfo.curAnim->loopEnd - 2 : 0; s32 sp0 = o->header.gfx.animInfo.curAnim ? o->header.gfx.animInfo.curAnim->loopEnd - 2 : 0;
@ -1242,6 +1265,7 @@ BAD_RETURN(s32) cur_obj_extend_animation_if_at_end(void) {
} }
s32 cur_obj_check_if_near_animation_end(void) { s32 cur_obj_check_if_near_animation_end(void) {
if (!o) { return 0; }
u32 animFlags = o->header.gfx.animInfo.curAnim ? (s32) o->header.gfx.animInfo.curAnim->flags : 0; u32 animFlags = o->header.gfx.animInfo.curAnim ? (s32) o->header.gfx.animInfo.curAnim->flags : 0;
s32 animFrame = o->header.gfx.animInfo.animFrame; s32 animFrame = o->header.gfx.animInfo.animFrame;
s32 nearLoopEnd = o->header.gfx.animInfo.curAnim ? o->header.gfx.animInfo.curAnim->loopEnd - 2 : 0; s32 nearLoopEnd = o->header.gfx.animInfo.curAnim ? o->header.gfx.animInfo.curAnim->loopEnd - 2 : 0;
@ -1259,6 +1283,7 @@ s32 cur_obj_check_if_near_animation_end(void) {
} }
s32 cur_obj_check_if_at_animation_end(void) { s32 cur_obj_check_if_at_animation_end(void) {
if (!o) { return 0; }
s32 animFrame = o->header.gfx.animInfo.animFrame; s32 animFrame = o->header.gfx.animInfo.animFrame;
s32 lastFrame = o->header.gfx.animInfo.curAnim ? o->header.gfx.animInfo.curAnim->loopEnd - 1 : 0; s32 lastFrame = o->header.gfx.animInfo.curAnim ? o->header.gfx.animInfo.curAnim->loopEnd - 1 : 0;
@ -1270,6 +1295,7 @@ s32 cur_obj_check_if_at_animation_end(void) {
} }
s32 cur_obj_check_anim_frame(s32 frame) { s32 cur_obj_check_anim_frame(s32 frame) {
if (!o) { return 0; }
s32 animFrame = o->header.gfx.animInfo.animFrame; s32 animFrame = o->header.gfx.animInfo.animFrame;
if (animFrame == frame) { if (animFrame == frame) {
@ -1280,6 +1306,7 @@ s32 cur_obj_check_anim_frame(s32 frame) {
} }
s32 cur_obj_check_anim_frame_in_range(s32 startFrame, s32 rangeLength) { s32 cur_obj_check_anim_frame_in_range(s32 startFrame, s32 rangeLength) {
if (!o) { return 0; }
s32 animFrame = o->header.gfx.animInfo.animFrame; s32 animFrame = o->header.gfx.animInfo.animFrame;
if (animFrame >= startFrame && animFrame < startFrame + rangeLength) { if (animFrame >= startFrame && animFrame < startFrame + rangeLength) {
@ -1290,6 +1317,7 @@ s32 cur_obj_check_anim_frame_in_range(s32 startFrame, s32 rangeLength) {
} }
s32 cur_obj_check_frame_prior_current_frame(s16 *a0) { s32 cur_obj_check_frame_prior_current_frame(s16 *a0) {
if (!o) { return 0; }
s16 sp6 = o->header.gfx.animInfo.animFrame; s16 sp6 = o->header.gfx.animInfo.animFrame;
while (*a0 != -1) { while (*a0 != -1) {
@ -1304,6 +1332,7 @@ s32 cur_obj_check_frame_prior_current_frame(s16 *a0) {
} }
s32 mario_is_in_air_action(struct MarioState* m) { s32 mario_is_in_air_action(struct MarioState* m) {
if (!m) { return 0; }
if (m->action & ACT_FLAG_AIR) { if (m->action & ACT_FLAG_AIR) {
return TRUE; return TRUE;
} else { } else {
@ -1312,6 +1341,7 @@ s32 mario_is_in_air_action(struct MarioState* m) {
} }
s32 mario_is_dive_sliding(struct MarioState* m) { s32 mario_is_dive_sliding(struct MarioState* m) {
if (!m) { return 0; }
if (m->action == ACT_DIVE_SLIDE) { if (m->action == ACT_DIVE_SLIDE) {
return TRUE; return TRUE;
} else { } else {
@ -1320,11 +1350,13 @@ s32 mario_is_dive_sliding(struct MarioState* m) {
} }
void cur_obj_set_y_vel_and_animation(f32 sp18, s32 sp1C) { void cur_obj_set_y_vel_and_animation(f32 sp18, s32 sp1C) {
if (!o) { return; }
o->oVelY = sp18; o->oVelY = sp18;
cur_obj_init_animation_with_sound(sp1C); cur_obj_init_animation_with_sound(sp1C);
} }
void cur_obj_unrender_and_reset_state(s32 sp18, s32 sp1C) { void cur_obj_unrender_and_reset_state(s32 sp18, s32 sp1C) {
if (!o) { return; }
cur_obj_become_intangible(); cur_obj_become_intangible();
cur_obj_disable_rendering(); cur_obj_disable_rendering();
@ -1336,6 +1368,7 @@ void cur_obj_unrender_and_reset_state(s32 sp18, s32 sp1C) {
} }
void cur_obj_move_after_thrown_or_dropped(f32 forwardVel, f32 velY) { void cur_obj_move_after_thrown_or_dropped(f32 forwardVel, f32 velY) {
if (!o) { return; }
o->oMoveFlags = 0; o->oMoveFlags = 0;
o->oFloorHeight = find_floor_height(o->oPosX, o->oPosY + 160.0f, o->oPosZ); o->oFloorHeight = find_floor_height(o->oPosX, o->oPosY + 160.0f, o->oPosZ);
@ -1356,6 +1389,7 @@ void cur_obj_move_after_thrown_or_dropped(f32 forwardVel, f32 velY) {
} }
void cur_obj_get_thrown_or_placed(f32 forwardVel, f32 velY, s32 thrownAction) { void cur_obj_get_thrown_or_placed(f32 forwardVel, f32 velY, s32 thrownAction) {
if (!o) { return; }
if (o->behavior == segmented_to_virtual(smlua_override_behavior(bhvBowser))) { if (o->behavior == segmented_to_virtual(smlua_override_behavior(bhvBowser))) {
// Interestingly, when bowser is thrown, he is offset slightly to // Interestingly, when bowser is thrown, he is offset slightly to
// Mario's right // Mario's right
@ -1382,6 +1416,7 @@ void cur_obj_get_thrown_or_placed(f32 forwardVel, f32 velY, s32 thrownAction) {
} }
void cur_obj_get_dropped(void) { void cur_obj_get_dropped(void) {
if (!o) { return; }
cur_obj_become_tangible(); cur_obj_become_tangible();
cur_obj_enable_rendering(); cur_obj_enable_rendering();
@ -1410,6 +1445,7 @@ void mario_set_flag(s32 flag) {
} }
s32 cur_obj_clear_interact_status_flag(s32 flag) { s32 cur_obj_clear_interact_status_flag(s32 flag) {
if (!o) { return 0; }
if (o->oInteractStatus & flag) { if (o->oInteractStatus & flag) {
o->oInteractStatus &= flag ^ ~(0); o->oInteractStatus &= flag ^ ~(0);
return TRUE; return TRUE;
@ -1437,25 +1473,30 @@ void cur_obj_disable(void) {
} }
void cur_obj_become_intangible(void) { void cur_obj_become_intangible(void) {
if (!o) { return; }
// When the timer is negative, the object is intangible and the timer // When the timer is negative, the object is intangible and the timer
// doesn't count down // doesn't count down
o->oIntangibleTimer = -1; o->oIntangibleTimer = -1;
} }
void cur_obj_become_tangible(void) { void cur_obj_become_tangible(void) {
if (!o) { return; }
o->oIntangibleTimer = 0; o->oIntangibleTimer = 0;
} }
void obj_become_tangible(struct Object *obj) { void obj_become_tangible(struct Object *obj) {
if (!obj) { return; }
obj->oIntangibleTimer = 0; obj->oIntangibleTimer = 0;
} }
void cur_obj_update_floor_height(void) { void cur_obj_update_floor_height(void) {
if (!o) { return; }
struct Surface *floor; struct Surface *floor;
o->oFloorHeight = find_floor(o->oPosX, o->oPosY, o->oPosZ, &floor); o->oFloorHeight = find_floor(o->oPosX, o->oPosY, o->oPosZ, &floor);
} }
struct Surface *cur_obj_update_floor_height_and_get_floor(void) { struct Surface *cur_obj_update_floor_height_and_get_floor(void) {
if (!o) { return NULL; }
struct Surface *floor; struct Surface *floor;
o->oFloorHeight = find_floor(o->oPosX, o->oPosY, o->oPosZ, &floor); o->oFloorHeight = find_floor(o->oPosX, o->oPosY, o->oPosZ, &floor);
return floor; return floor;
@ -1483,11 +1524,13 @@ void apply_drag_to_value(f32 *value, f32 dragStrength) {
} }
void cur_obj_apply_drag_xz(f32 dragStrength) { void cur_obj_apply_drag_xz(f32 dragStrength) {
if (!o) { return; }
apply_drag_to_value(&o->oVelX, dragStrength); apply_drag_to_value(&o->oVelX, dragStrength);
apply_drag_to_value(&o->oVelZ, dragStrength); apply_drag_to_value(&o->oVelZ, dragStrength);
} }
s32 cur_obj_move_xz(f32 steepSlopeNormalY, s32 careAboutEdgesAndSteepSlopes) { s32 cur_obj_move_xz(f32 steepSlopeNormalY, s32 careAboutEdgesAndSteepSlopes) {
if (!o) { return 0; }
struct Surface *intendedFloor = NULL; struct Surface *intendedFloor = NULL;
f32 intendedX = o->oPosX + o->oVelX; f32 intendedX = o->oPosX + o->oVelX;
@ -1547,6 +1590,7 @@ s32 cur_obj_move_xz(f32 steepSlopeNormalY, s32 careAboutEdgesAndSteepSlopes) {
} }
void cur_obj_move_update_underwater_flags(void) { void cur_obj_move_update_underwater_flags(void) {
if (!o) { return; }
f32 decelY = (f32)(sqrtf(o->oVelY * o->oVelY) * (o->oDragStrength * 7.0f)) / 100.0L; f32 decelY = (f32)(sqrtf(o->oVelY * o->oVelY) * (o->oDragStrength * 7.0f)) / 100.0L;
if (o->oVelY > 0) { if (o->oVelY > 0) {
@ -1564,6 +1608,7 @@ void cur_obj_move_update_underwater_flags(void) {
} }
void cur_obj_move_update_ground_air_flags(UNUSED f32 gravity, f32 bounciness) { void cur_obj_move_update_ground_air_flags(UNUSED f32 gravity, f32 bounciness) {
if (!o) { return; }
o->oMoveFlags &= ~OBJ_MOVE_BOUNCE; o->oMoveFlags &= ~OBJ_MOVE_BOUNCE;
if (o->oPosY < o->oFloorHeight) { if (o->oPosY < o->oFloorHeight) {
@ -1599,6 +1644,7 @@ void cur_obj_move_update_ground_air_flags(UNUSED f32 gravity, f32 bounciness) {
} }
f32 cur_obj_move_y_and_get_water_level(f32 gravity, f32 buoyancy) { f32 cur_obj_move_y_and_get_water_level(f32 gravity, f32 buoyancy) {
if (!o) { return 0; }
f32 waterLevel; f32 waterLevel;
o->oVelY += gravity + buoyancy; o->oVelY += gravity + buoyancy;
@ -1617,6 +1663,7 @@ f32 cur_obj_move_y_and_get_water_level(f32 gravity, f32 buoyancy) {
} }
void cur_obj_move_y(f32 gravity, f32 bounciness, f32 buoyancy) { void cur_obj_move_y(f32 gravity, f32 bounciness, f32 buoyancy) {
if (!o) { return; }
f32 waterLevel; f32 waterLevel;
o->oMoveFlags &= ~OBJ_MOVE_LEFT_GROUND; o->oMoveFlags &= ~OBJ_MOVE_LEFT_GROUND;
@ -1670,6 +1717,7 @@ static void stub_obj_helpers_1(void) {
} }
void cur_obj_unused_resolve_wall_collisions(f32 offsetY, f32 radius) { void cur_obj_unused_resolve_wall_collisions(f32 offsetY, f32 radius) {
if (!o) { return; }
if (radius > 0.1L) { if (radius > 0.1L) {
f32_find_wall_collision(&o->oPosX, &o->oPosY, &o->oPosZ, offsetY, radius); f32_find_wall_collision(&o->oPosX, &o->oPosY, &o->oPosZ, offsetY, radius);
} }
@ -1690,6 +1738,7 @@ s16 abs_angle_diff(s16 x0, s16 x1) {
} }
void cur_obj_move_xz_using_fvel_and_yaw(void) { void cur_obj_move_xz_using_fvel_and_yaw(void) {
if (!o) { return; }
o->oVelX = o->oForwardVel * sins(o->oMoveAngleYaw); o->oVelX = o->oForwardVel * sins(o->oMoveAngleYaw);
o->oVelZ = o->oForwardVel * coss(o->oMoveAngleYaw); o->oVelZ = o->oForwardVel * coss(o->oMoveAngleYaw);
@ -1698,6 +1747,7 @@ void cur_obj_move_xz_using_fvel_and_yaw(void) {
} }
void cur_obj_move_y_with_terminal_vel(void) { void cur_obj_move_y_with_terminal_vel(void) {
if (!o) { return; }
if (o->oVelY < -70.0f) { if (o->oVelY < -70.0f) {
o->oVelY = -70.0f; o->oVelY = -70.0f;
} }
@ -1706,6 +1756,7 @@ void cur_obj_move_y_with_terminal_vel(void) {
} }
void cur_obj_compute_vel_xz(void) { void cur_obj_compute_vel_xz(void) {
if (!o) { return; }
o->oVelX = o->oForwardVel * sins(o->oMoveAngleYaw); o->oVelX = o->oForwardVel * sins(o->oMoveAngleYaw);
o->oVelZ = o->oForwardVel * coss(o->oMoveAngleYaw); o->oVelZ = o->oForwardVel * coss(o->oMoveAngleYaw);
} }
@ -1740,14 +1791,17 @@ s32 obj_check_if_collided_with_object(struct Object *obj1, struct Object *obj2)
} }
void cur_obj_set_behavior(const BehaviorScript *behavior) { void cur_obj_set_behavior(const BehaviorScript *behavior) {
if (!o) { return; }
o->behavior = segmented_to_virtual(behavior); o->behavior = segmented_to_virtual(behavior);
} }
void obj_set_behavior(struct Object *obj, const BehaviorScript *behavior) { void obj_set_behavior(struct Object *obj, const BehaviorScript *behavior) {
if (!obj) { return; }
obj->behavior = segmented_to_virtual(behavior); obj->behavior = segmented_to_virtual(behavior);
} }
s32 cur_obj_has_behavior(const BehaviorScript *behavior) { s32 cur_obj_has_behavior(const BehaviorScript *behavior) {
if (!o) { return 0; }
behavior = smlua_override_behavior(behavior); behavior = smlua_override_behavior(behavior);
if (o->behavior == segmented_to_virtual(behavior)) { if (o->behavior == segmented_to_virtual(behavior)) {
return TRUE; return TRUE;
@ -1767,6 +1821,7 @@ s32 obj_has_behavior(struct Object *obj, const BehaviorScript *behavior) {
} }
f32 cur_obj_lateral_dist_from_obj_to_home(struct Object *obj) { f32 cur_obj_lateral_dist_from_obj_to_home(struct Object *obj) {
if (!o) { return 0; }
f32 dist; f32 dist;
f32 dx = o->oHomeX - obj->oPosX; f32 dx = o->oHomeX - obj->oPosX;
f32 dz = o->oHomeZ - obj->oPosZ; f32 dz = o->oHomeZ - obj->oPosZ;
@ -1776,6 +1831,7 @@ f32 cur_obj_lateral_dist_from_obj_to_home(struct Object *obj) {
} }
f32 cur_obj_lateral_dist_from_mario_to_home(void) { f32 cur_obj_lateral_dist_from_mario_to_home(void) {
if (!o) { return 0; }
struct Object* player = nearest_player_to_object(o); struct Object* player = nearest_player_to_object(o);
if (!player) { return 10000; } if (!player) { return 10000; }
f32 dist; f32 dist;
@ -1787,6 +1843,7 @@ f32 cur_obj_lateral_dist_from_mario_to_home(void) {
} }
f32 cur_obj_lateral_dist_to_home(void) { f32 cur_obj_lateral_dist_to_home(void) {
if (!o) { return 0; }
f32 dist; f32 dist;
f32 dx = o->oHomeX - o->oPosX; f32 dx = o->oHomeX - o->oPosX;
f32 dz = o->oHomeZ - o->oPosZ; f32 dz = o->oHomeZ - o->oPosZ;
@ -1796,6 +1853,7 @@ f32 cur_obj_lateral_dist_to_home(void) {
} }
s32 cur_obj_outside_home_square(f32 halfLength) { s32 cur_obj_outside_home_square(f32 halfLength) {
if (!o) { return 0; }
if (o->oHomeX - halfLength > o->oPosX) { if (o->oHomeX - halfLength > o->oPosX) {
return TRUE; return TRUE;
} }
@ -1816,6 +1874,7 @@ s32 cur_obj_outside_home_square(f32 halfLength) {
} }
s32 cur_obj_outside_home_rectangle(f32 minX, f32 maxX, f32 minZ, f32 maxZ) { s32 cur_obj_outside_home_rectangle(f32 minX, f32 maxX, f32 minZ, f32 maxZ) {
if (!o) { return 0; }
if (o->oHomeX + minX > o->oPosX) { if (o->oHomeX + minX > o->oPosX) {
return TRUE; return TRUE;
} }
@ -1836,6 +1895,7 @@ s32 cur_obj_outside_home_rectangle(f32 minX, f32 maxX, f32 minZ, f32 maxZ) {
} }
void cur_obj_set_pos_to_home(void) { void cur_obj_set_pos_to_home(void) {
if (!o) { return; }
o->oPosX = o->oHomeX; o->oPosX = o->oHomeX;
o->oPosY = o->oHomeY; o->oPosY = o->oHomeY;
o->oPosZ = o->oHomeZ; o->oPosZ = o->oHomeZ;
@ -1843,6 +1903,7 @@ void cur_obj_set_pos_to_home(void) {
} }
void cur_obj_set_pos_to_home_and_stop(void) { void cur_obj_set_pos_to_home_and_stop(void) {
if (!o) { return; }
cur_obj_set_pos_to_home(); cur_obj_set_pos_to_home();
o->oForwardVel = 0; o->oForwardVel = 0;
@ -1850,6 +1911,7 @@ void cur_obj_set_pos_to_home_and_stop(void) {
} }
void cur_obj_shake_y(f32 amount) { void cur_obj_shake_y(f32 amount) {
if (!o) { return; }
//! Technically could cause a bit of drift, but not much //! Technically could cause a bit of drift, but not much
if (o->oTimer % 2 == 0) { if (o->oTimer % 2 == 0) {
o->oPosY += amount; o->oPosY += amount;
@ -1864,6 +1926,7 @@ void cur_obj_start_cam_event(UNUSED struct Object *obj, s32 cameraEvent) {
} }
void set_mario_interact_hoot_if_in_range(UNUSED s32 sp0, UNUSED s32 sp4, f32 sp8) { void set_mario_interact_hoot_if_in_range(UNUSED s32 sp0, UNUSED s32 sp4, f32 sp8) {
if (!o) { return; }
if (o->oDistanceToMario < sp8) { if (o->oDistanceToMario < sp8) {
gMarioObject->oInteractStatus = INT_STATUS_HOOT_GRABBED_BY_MARIO; gMarioObject->oInteractStatus = INT_STATUS_HOOT_GRABBED_BY_MARIO;
} }
@ -1880,6 +1943,7 @@ void obj_set_cylboard(struct Object *obj) {
} }
void cur_obj_set_billboard_if_vanilla_cam(void) { void cur_obj_set_billboard_if_vanilla_cam(void) {
if (!o) { return; }
if (configEnableCamera) { if (configEnableCamera) {
o->header.gfx.node.flags &= ~GRAPH_RENDER_BILLBOARD; o->header.gfx.node.flags &= ~GRAPH_RENDER_BILLBOARD;
o->header.gfx.node.flags |= GRAPH_RENDER_CYLBOARD; o->header.gfx.node.flags |= GRAPH_RENDER_CYLBOARD;
@ -1904,11 +1968,13 @@ void obj_set_hurtbox_radius_and_height(struct Object *o, f32 radius, f32 height)
} }
void cur_obj_set_hitbox_radius_and_height(f32 radius, f32 height) { void cur_obj_set_hitbox_radius_and_height(f32 radius, f32 height) {
if (!o) { return; }
o->hitboxRadius = radius; o->hitboxRadius = radius;
o->hitboxHeight = height; o->hitboxHeight = height;
} }
void cur_obj_set_hurtbox_radius_and_height(f32 radius, f32 height) { void cur_obj_set_hurtbox_radius_and_height(f32 radius, f32 height) {
if (!o) { return; }
o->hurtboxRadius = radius; o->hurtboxRadius = radius;
o->hurtboxHeight = height; o->hurtboxHeight = height;
} }
@ -1952,11 +2018,14 @@ void obj_spawn_loot_yellow_coins(struct Object *obj, s32 numCoins, f32 sp28) {
void cur_obj_spawn_loot_coin_at_mario_pos(struct MarioState* m) { void cur_obj_spawn_loot_coin_at_mario_pos(struct MarioState* m) {
struct Object *coin; struct Object *coin;
if (o->oNumLootCoins <= 0) { if (!m) { return; }
if (o && o->oNumLootCoins <= 0) {
return; return;
} }
if (o) {
o->oNumLootCoins--; o->oNumLootCoins--;
}
coin = spawn_object(o, MODEL_YELLOW_COIN, bhvSingleCoinGetsSpawned); coin = spawn_object(o, MODEL_YELLOW_COIN, bhvSingleCoinGetsSpawned);
if (coin == NULL) { return; } if (coin == NULL) { return; }
@ -1966,6 +2035,7 @@ void cur_obj_spawn_loot_coin_at_mario_pos(struct MarioState* m) {
} }
f32 cur_obj_abs_y_dist_to_home(void) { f32 cur_obj_abs_y_dist_to_home(void) {
if (!o) { return 0; }
f32 dist = o->oHomeY - o->oPosY; f32 dist = o->oHomeY - o->oPosY;
if (dist < 0) { if (dist < 0) {
@ -1976,6 +2046,7 @@ f32 cur_obj_abs_y_dist_to_home(void) {
} }
s32 cur_obj_advance_looping_anim(void) { s32 cur_obj_advance_looping_anim(void) {
if (!o) { return 0; }
s32 animFrame = o->header.gfx.animInfo.animFrame; s32 animFrame = o->header.gfx.animInfo.animFrame;
s32 loopEnd = o->header.gfx.animInfo.curAnim->loopEnd; s32 loopEnd = o->header.gfx.animInfo.curAnim->loopEnd;
s32 result; s32 result;
@ -1994,6 +2065,7 @@ s32 cur_obj_advance_looping_anim(void) {
} }
s32 cur_obj_detect_steep_floor(s16 steepAngleDegrees) { s32 cur_obj_detect_steep_floor(s16 steepAngleDegrees) {
if (!o) { return 0; }
struct Surface *intendedFloor; struct Surface *intendedFloor;
f32 intendedX, intendedFloorHeight, intendedZ; f32 intendedX, intendedFloorHeight, intendedZ;
f32 deltaFloorHeight; f32 deltaFloorHeight;
@ -2021,6 +2093,7 @@ s32 cur_obj_detect_steep_floor(s16 steepAngleDegrees) {
} }
s32 cur_obj_resolve_wall_collisions(void) { s32 cur_obj_resolve_wall_collisions(void) {
if (!o) { return 0; }
s32 numCollisions; s32 numCollisions;
struct Surface *wall; struct Surface *wall;
struct WallCollisionData collisionData; struct WallCollisionData collisionData;
@ -2055,6 +2128,7 @@ s32 cur_obj_resolve_wall_collisions(void) {
} }
void cur_obj_update_floor(void) { void cur_obj_update_floor(void) {
if (!o) { return; }
struct Surface *floor = cur_obj_update_floor_height_and_get_floor(); struct Surface *floor = cur_obj_update_floor_height_and_get_floor();
o->oFloor = floor; o->oFloor = floor;
@ -2078,6 +2152,7 @@ void cur_obj_update_floor(void) {
} }
void cur_obj_update_floor_and_resolve_wall_collisions(s16 steepSlopeDegrees) { void cur_obj_update_floor_and_resolve_wall_collisions(s16 steepSlopeDegrees) {
if (!o) { return; }
#ifdef VERSION_JP #ifdef VERSION_JP
o->oMoveFlags &= ~OBJ_MOVE_ABOVE_LAVA; o->oMoveFlags &= ~OBJ_MOVE_ABOVE_LAVA;
#else #else
@ -2114,6 +2189,7 @@ void cur_obj_update_floor_and_walls(void) {
} }
void cur_obj_move_standard(s16 steepSlopeAngleDegrees) { void cur_obj_move_standard(s16 steepSlopeAngleDegrees) {
if (!o) { return; }
f32 gravity = o->oGravity; f32 gravity = o->oGravity;
f32 bounciness = o->oBounciness; f32 bounciness = o->oBounciness;
f32 buoyancy = o->oBuoyancy; f32 buoyancy = o->oBuoyancy;
@ -2154,6 +2230,7 @@ void cur_obj_move_standard(s16 steepSlopeAngleDegrees) {
} }
s32 cur_obj_within_12k_bounds(void) { s32 cur_obj_within_12k_bounds(void) {
if (!o) { return 0; }
if (o->oPosX < -12000.0f || 12000.0f < o->oPosX) { if (o->oPosX < -12000.0f || 12000.0f < o->oPosX) {
return FALSE; return FALSE;
} }
@ -2170,6 +2247,7 @@ s32 cur_obj_within_12k_bounds(void) {
} }
void cur_obj_move_using_vel_and_gravity(void) { void cur_obj_move_using_vel_and_gravity(void) {
if (!o) { return; }
//if (cur_obj_within_12k_bounds()) { //if (cur_obj_within_12k_bounds()) {
o->oPosX += o->oVelX; o->oPosX += o->oVelX;
o->oPosZ += o->oVelZ; o->oPosZ += o->oVelZ;
@ -2185,6 +2263,7 @@ void cur_obj_move_using_fvel_and_gravity(void) {
void obj_set_pos_relative(struct Object *obj, struct Object *other, f32 dleft, f32 dy, void obj_set_pos_relative(struct Object *obj, struct Object *other, f32 dleft, f32 dy,
f32 dforward) { f32 dforward) {
if (!obj || !other) { return; }
f32 facingZ = coss(other->oMoveAngleYaw); f32 facingZ = coss(other->oMoveAngleYaw);
f32 facingX = sins(other->oMoveAngleYaw); f32 facingX = sins(other->oMoveAngleYaw);
@ -2199,6 +2278,7 @@ void obj_set_pos_relative(struct Object *obj, struct Object *other, f32 dleft, f
} }
s16 cur_obj_angle_to_home(void) { s16 cur_obj_angle_to_home(void) {
if (!o) { return 0; }
s16 angle; s16 angle;
f32 dx = o->oHomeX - o->oPosX; f32 dx = o->oHomeX - o->oPosX;
f32 dz = o->oHomeZ - o->oPosZ; f32 dz = o->oHomeZ - o->oPosZ;
@ -2208,6 +2288,7 @@ s16 cur_obj_angle_to_home(void) {
} }
void obj_set_gfx_pos_at_obj_pos(struct Object *obj1, struct Object *obj2) { void obj_set_gfx_pos_at_obj_pos(struct Object *obj1, struct Object *obj2) {
if (!obj1 || !obj2) { return; }
obj1->header.gfx.pos[0] = obj2->oPosX; obj1->header.gfx.pos[0] = obj2->oPosX;
obj1->header.gfx.pos[1] = obj2->oPosY + obj2->oGraphYOffset; obj1->header.gfx.pos[1] = obj2->oPosY + obj2->oGraphYOffset;
obj1->header.gfx.pos[2] = obj2->oPosZ; obj1->header.gfx.pos[2] = obj2->oPosZ;
@ -2296,24 +2377,28 @@ void obj_create_transform_from_self(struct Object *obj) {
} }
void cur_obj_rotate_move_angle_using_vel(void) { void cur_obj_rotate_move_angle_using_vel(void) {
if (!o) { return; }
o->oMoveAnglePitch += o->oAngleVelPitch; o->oMoveAnglePitch += o->oAngleVelPitch;
o->oMoveAngleYaw += o->oAngleVelYaw; o->oMoveAngleYaw += o->oAngleVelYaw;
o->oMoveAngleRoll += o->oAngleVelRoll; o->oMoveAngleRoll += o->oAngleVelRoll;
} }
void cur_obj_rotate_face_angle_using_vel(void) { void cur_obj_rotate_face_angle_using_vel(void) {
if (!o) { return; }
o->oFaceAnglePitch += o->oAngleVelPitch; o->oFaceAnglePitch += o->oAngleVelPitch;
o->oFaceAngleYaw += o->oAngleVelYaw; o->oFaceAngleYaw += o->oAngleVelYaw;
o->oFaceAngleRoll += o->oAngleVelRoll; o->oFaceAngleRoll += o->oAngleVelRoll;
} }
void cur_obj_set_face_angle_to_move_angle(void) { void cur_obj_set_face_angle_to_move_angle(void) {
if (!o) { return; }
o->oFaceAnglePitch = o->oMoveAnglePitch; o->oFaceAnglePitch = o->oMoveAnglePitch;
o->oFaceAngleYaw = o->oMoveAngleYaw; o->oFaceAngleYaw = o->oMoveAngleYaw;
o->oFaceAngleRoll = o->oMoveAngleRoll; o->oFaceAngleRoll = o->oMoveAngleRoll;
} }
s32 cur_obj_follow_path(UNUSED s32 unusedArg) { s32 cur_obj_follow_path(UNUSED s32 unusedArg) {
if (!o) { return 0; }
struct Waypoint *startWaypoint; struct Waypoint *startWaypoint;
struct Waypoint *lastWaypoint; struct Waypoint *lastWaypoint;
struct Waypoint *targetWaypoint; struct Waypoint *targetWaypoint;
@ -2378,6 +2463,7 @@ s32 cur_obj_follow_path(UNUSED s32 unusedArg) {
} }
void chain_segment_init(struct ChainSegment *segment) { void chain_segment_init(struct ChainSegment *segment) {
if (!o) { return; }
if (segment == NULL) { return; } if (segment == NULL) { return; }
segment->posX = 0.0f; segment->posX = 0.0f;
segment->posY = 0.0f; segment->posY = 0.0f;
@ -2422,6 +2508,7 @@ void obj_build_vel_from_transform(struct Object *a0) {
} }
void cur_obj_set_pos_via_transform(void) { void cur_obj_set_pos_via_transform(void) {
if (!o) { return; }
obj_build_transform_from_pos_and_angle(o, O_PARENT_RELATIVE_POS_INDEX, O_MOVE_ANGLE_INDEX); obj_build_transform_from_pos_and_angle(o, O_PARENT_RELATIVE_POS_INDEX, O_MOVE_ANGLE_INDEX);
obj_build_vel_from_transform(o); obj_build_vel_from_transform(o);
o->oPosX += o->oVelX; o->oPosX += o->oVelX;
@ -2430,6 +2517,7 @@ void cur_obj_set_pos_via_transform(void) {
} }
s16 cur_obj_reflect_move_angle_off_wall(void) { s16 cur_obj_reflect_move_angle_off_wall(void) {
if (!o) { return 0; }
s16 angle = o->oWallAngle - ((s16) o->oMoveAngleYaw - (s16) o->oWallAngle) + 0x8000; s16 angle = o->oWallAngle - ((s16) o->oMoveAngleYaw - (s16) o->oWallAngle) + 0x8000;
return angle; return angle;
} }
@ -2517,6 +2605,7 @@ s32 absi(s32 x) {
} }
s32 cur_obj_wait_then_blink(s32 timeUntilBlinking, s32 numBlinks) { s32 cur_obj_wait_then_blink(s32 timeUntilBlinking, s32 numBlinks) {
if (!o) { return 0; }
s32 done = FALSE; s32 done = FALSE;
s32 timeBlinking; s32 timeBlinking;
@ -2558,6 +2647,7 @@ void spawn_mist_particles_with_sound(u32 sp18) {
} }
void cur_obj_push_mario_away(f32 radius) { void cur_obj_push_mario_away(f32 radius) {
if (!o) { return; }
for (s32 i = 0; i < MAX_PLAYERS; i++) { for (s32 i = 0; i < MAX_PLAYERS; i++) {
struct Object* player = gMarioStates[i].marioObj; struct Object* player = gMarioStates[i].marioObj;
if (!player) { continue; } if (!player) { continue; }
@ -2575,6 +2665,7 @@ void cur_obj_push_mario_away(f32 radius) {
} }
void cur_obj_push_mario_away_from_cylinder(f32 radius, f32 extentY) { void cur_obj_push_mario_away_from_cylinder(f32 radius, f32 extentY) {
if (!o) { return; }
for (s32 i = 0; i < MAX_PLAYERS; i++) { for (s32 i = 0; i < MAX_PLAYERS; i++) {
struct Object* player = gMarioStates[i].marioObj; struct Object* player = gMarioStates[i].marioObj;
if (!player) { continue; } if (!player) { continue; }
@ -2600,6 +2691,7 @@ void cur_obj_push_mario_away_from_cylinder(f32 radius, f32 extentY) {
} }
void bhv_dust_smoke_loop(void) { void bhv_dust_smoke_loop(void) {
if (!o) { return; }
o->oPosX += o->oVelX; o->oPosX += o->oVelX;
o->oPosY += o->oVelY; o->oPosY += o->oVelY;
o->oPosZ += o->oVelZ; o->oPosZ += o->oVelZ;
@ -2615,6 +2707,7 @@ static void stub_obj_helpers_2(void) {
} }
s32 cur_obj_set_direction_table(s8 *a0) { s32 cur_obj_set_direction_table(s8 *a0) {
if (!o) { return 0; }
o->oToxBoxMovementPattern = a0; o->oToxBoxMovementPattern = a0;
o->oToxBoxMovementStep = 0; o->oToxBoxMovementStep = 0;
@ -2622,6 +2715,7 @@ s32 cur_obj_set_direction_table(s8 *a0) {
} }
s32 cur_obj_progress_direction_table(void) { s32 cur_obj_progress_direction_table(void) {
if (!o) { return 0; }
s8 spF; s8 spF;
s8 *sp8 = o->oToxBoxMovementPattern; s8 *sp8 = o->oToxBoxMovementPattern;
s32 sp4 = o->oToxBoxMovementStep + 1; s32 sp4 = o->oToxBoxMovementStep + 1;
@ -2642,6 +2736,7 @@ void stub_obj_helpers_3(UNUSED s32 sp0, UNUSED s32 sp4) {
} }
void cur_obj_scale_over_time(s32 a0, s32 a1, f32 sp10, f32 sp14) { void cur_obj_scale_over_time(s32 a0, s32 a1, f32 sp10, f32 sp14) {
if (!o) { return; }
f32 sp4 = sp14 - sp10; f32 sp4 = sp14 - sp10;
f32 sp0 = (f32) o->oTimer / a1; f32 sp0 = (f32) o->oTimer / a1;
@ -2659,6 +2754,7 @@ void cur_obj_scale_over_time(s32 a0, s32 a1, f32 sp10, f32 sp14) {
} }
void cur_obj_set_pos_to_home_with_debug(void) { void cur_obj_set_pos_to_home_with_debug(void) {
if (!o) { return; }
o->oPosX = o->oHomeX + gDebugInfo[5][0]; o->oPosX = o->oHomeX + gDebugInfo[5][0];
o->oPosY = o->oHomeY + gDebugInfo[5][1]; o->oPosY = o->oHomeY + gDebugInfo[5][1];
o->oPosZ = o->oHomeZ + gDebugInfo[5][2]; o->oPosZ = o->oHomeZ + gDebugInfo[5][2];
@ -2687,6 +2783,7 @@ s32 cur_obj_is_any_player_on_platform(void) {
} }
s32 cur_obj_shake_y_until(s32 cycles, s32 amount) { s32 cur_obj_shake_y_until(s32 cycles, s32 amount) {
if (!o) { return 0; }
if (o->oTimer % 2 != 0) { if (o->oTimer % 2 != 0) {
o->oPosY -= amount; o->oPosY -= amount;
} else { } else {
@ -2701,6 +2798,7 @@ s32 cur_obj_shake_y_until(s32 cycles, s32 amount) {
} }
s32 cur_obj_move_up_and_down(s32 a0) { s32 cur_obj_move_up_and_down(s32 a0) {
if (!o) { return 0; }
if (a0 >= 4 || a0 < 0) { if (a0 >= 4 || a0 < 0) {
return TRUE; return TRUE;
} }
@ -2710,6 +2808,7 @@ s32 cur_obj_move_up_and_down(s32 a0) {
} }
void cur_obj_call_action_function(void (*actionFunctions[])(void), uint32_t actionFunctionsLength) { void cur_obj_call_action_function(void (*actionFunctions[])(void), uint32_t actionFunctionsLength) {
if (!o) { return; }
if (!actionFunctions) { return; } if (!actionFunctions) { return; }
if ((uint32_t)o->oAction >= actionFunctionsLength) { return; } if ((uint32_t)o->oAction >= actionFunctionsLength) { return; }
void (*actionFunction)(void) = actionFunctions[o->oAction]; void (*actionFunction)(void) = actionFunctions[o->oAction];
@ -2718,6 +2817,7 @@ void cur_obj_call_action_function(void (*actionFunctions[])(void), uint32_t acti
} }
struct Object *spawn_star_with_no_lvl_exit(s32 sp20, s32 sp24) { struct Object *spawn_star_with_no_lvl_exit(s32 sp20, s32 sp24) {
if (!o) { return NULL; }
struct Object *sp1C = spawn_object(o, MODEL_STAR, bhvSpawnedStarNoLevelExit); struct Object *sp1C = spawn_object(o, MODEL_STAR, bhvSpawnedStarNoLevelExit);
if (sp1C == NULL) { return NULL; } if (sp1C == NULL) { return NULL; }
sp1C->oSparkleSpawnUnk1B0 = sp24; sp1C->oSparkleSpawnUnk1B0 = sp24;
@ -2738,6 +2838,7 @@ s32 bit_shift_left(s32 a0) {
} }
s32 cur_obj_mario_far_away(void) { s32 cur_obj_mario_far_away(void) {
if (!o) { return 0; }
for (s32 i = 0; i < MAX_PLAYERS; i++) { for (s32 i = 0; i < MAX_PLAYERS; i++) {
if (!is_player_active(&gMarioStates[i])) { continue; } if (!is_player_active(&gMarioStates[i])) { continue; }
struct Object* player = gMarioStates[i].marioObj; struct Object* player = gMarioStates[i].marioObj;
@ -2784,6 +2885,7 @@ static void stub_obj_helpers_5(void) {
} }
void bhv_init_room(void) { void bhv_init_room(void) {
if (!o) { return; }
struct Surface *floor; struct Surface *floor;
f32 floorHeight; f32 floorHeight;
@ -2809,6 +2911,7 @@ void bhv_init_room(void) {
} }
void cur_obj_enable_rendering_if_mario_in_room(void) { void cur_obj_enable_rendering_if_mario_in_room(void) {
if (!o) { return; }
if (o->oRoom == -1) { return; } if (o->oRoom == -1) { return; }
if (gMarioCurrentRoom == 0) { return; } if (gMarioCurrentRoom == 0) { return; }
@ -2842,6 +2945,7 @@ void cur_obj_enable_rendering_if_mario_in_room(void) {
} }
s32 cur_obj_set_hitbox_and_die_if_attacked(struct ObjectHitbox *hitbox, s32 deathSound, s32 noLootCoins) { s32 cur_obj_set_hitbox_and_die_if_attacked(struct ObjectHitbox *hitbox, s32 deathSound, s32 noLootCoins) {
if (!o) { return 0; }
s32 interacted = FALSE; s32 interacted = FALSE;
obj_set_hitbox(o, hitbox); obj_set_hitbox(o, hitbox);
@ -2867,6 +2971,7 @@ s32 cur_obj_set_hitbox_and_die_if_attacked(struct ObjectHitbox *hitbox, s32 deat
void obj_explode_and_spawn_coins(f32 sp18, s32 sp1C) { void obj_explode_and_spawn_coins(f32 sp18, s32 sp1C) {
if (!o) { return; }
spawn_mist_particles_variable(0, 0, sp18); spawn_mist_particles_variable(0, 0, sp18);
spawn_triangle_break_particles(30, 138, 3.0f, 4); spawn_triangle_break_particles(30, 138, 3.0f, 4);
obj_mark_for_deletion(o); obj_mark_for_deletion(o);
@ -2883,12 +2988,14 @@ void obj_set_collision_data(struct Object *obj, const void *segAddr) {
} }
void cur_obj_if_hit_wall_bounce_away(void) { void cur_obj_if_hit_wall_bounce_away(void) {
if (!o) { return; }
if (o->oMoveFlags & OBJ_MOVE_HIT_WALL) { if (o->oMoveFlags & OBJ_MOVE_HIT_WALL) {
o->oMoveAngleYaw = o->oWallAngle; o->oMoveAngleYaw = o->oWallAngle;
} }
} }
s32 cur_obj_hide_if_mario_far_away_y(f32 distY) { s32 cur_obj_hide_if_mario_far_away_y(f32 distY) {
if (!o) { return 0; }
if (!gMarioStates[0].marioObj) { return FALSE; } if (!gMarioStates[0].marioObj) { return FALSE; }
if (absf(o->oPosY - gMarioStates[0].marioObj->oPosY) < distY * draw_distance_scalar()) { if (absf(o->oPosY - gMarioStates[0].marioObj->oPosY) < distY * draw_distance_scalar()) {
cur_obj_unhide(); cur_obj_unhide();
@ -2922,6 +3029,7 @@ s32 geo_offset_klepto_debug(s32 callContext, struct GraphNode *a1, UNUSED s32 sp
} }
s32 obj_is_hidden(struct Object *obj) { s32 obj_is_hidden(struct Object *obj) {
if (!obj) { return 0; }
if (obj->header.gfx.node.flags & GRAPH_RENDER_INVISIBLE) { if (obj->header.gfx.node.flags & GRAPH_RENDER_INVISIBLE) {
return TRUE; return TRUE;
} else { } else {
@ -2960,6 +3068,7 @@ void clear_time_stop_flags(s32 flags) {
} }
s32 cur_obj_can_mario_activate_textbox(struct MarioState* m, f32 radius, f32 height, UNUSED s32 unused) { s32 cur_obj_can_mario_activate_textbox(struct MarioState* m, f32 radius, f32 height, UNUSED s32 unused) {
if (!o) { return 0; }
if (!m->visibleToEnemies) { return FALSE; } if (!m->visibleToEnemies) { return FALSE; }
if (o->oDistanceToMario < 1500.0f) { if (o->oDistanceToMario < 1500.0f) {
f32 latDistToMario = lateral_dist_between_objects(o, m->marioObj); f32 latDistToMario = lateral_dist_between_objects(o, m->marioObj);
@ -2981,6 +3090,7 @@ s32 cur_obj_can_mario_activate_textbox_2(struct MarioState* m, f32 radius, f32 h
} }
void cur_obj_end_dialog(struct MarioState* m, s32 dialogFlags, s32 dialogResult) { void cur_obj_end_dialog(struct MarioState* m, s32 dialogFlags, s32 dialogResult) {
if (!o) { return; }
if (m->playerIndex != 0) { return; } if (m->playerIndex != 0) { return; }
o->oDialogResponse = dialogResult; o->oDialogResponse = dialogResult;
@ -2992,6 +3102,7 @@ void cur_obj_end_dialog(struct MarioState* m, s32 dialogFlags, s32 dialogResult)
} }
s32 cur_obj_update_dialog(struct MarioState* m, s32 actionArg, s32 dialogFlags, s32 dialogID, UNUSED s32 unused, u8 (*inContinueDialogFunction)(void)) { s32 cur_obj_update_dialog(struct MarioState* m, s32 actionArg, s32 dialogFlags, s32 dialogID, UNUSED s32 unused, u8 (*inContinueDialogFunction)(void)) {
if (!o) { return 0; }
s32 dialogResponse = 0; s32 dialogResponse = 0;
UNUSED s32 doneTurning = TRUE; UNUSED s32 doneTurning = TRUE;
@ -3071,6 +3182,7 @@ s32 cur_obj_update_dialog(struct MarioState* m, s32 actionArg, s32 dialogFlags,
} }
s32 cur_obj_update_dialog_with_cutscene(struct MarioState* m, s32 actionArg, s32 dialogFlags, s32 cutsceneTable, s32 dialogID, u8 (*inContinueDialogFunction)(void)) { s32 cur_obj_update_dialog_with_cutscene(struct MarioState* m, s32 actionArg, s32 dialogFlags, s32 cutsceneTable, s32 dialogID, u8 (*inContinueDialogFunction)(void)) {
if (!o) { return 0; }
s32 dialogResponse = 0; s32 dialogResponse = 0;
s32 doneTurning = TRUE; s32 doneTurning = TRUE;
@ -3152,6 +3264,7 @@ s32 cur_obj_update_dialog_with_cutscene(struct MarioState* m, s32 actionArg, s32
} }
s32 cur_obj_has_model(u16 modelID) { s32 cur_obj_has_model(u16 modelID) {
if (!o) { return 0; }
if (modelID >= MAX_LOADED_GRAPH_NODES) { return FALSE; } if (modelID >= MAX_LOADED_GRAPH_NODES) { return FALSE; }
if (o->header.gfx.sharedChild == gLoadedGraphNodes[modelID]) { if (o->header.gfx.sharedChild == gLoadedGraphNodes[modelID]) {
return TRUE; return TRUE;
@ -3163,6 +3276,7 @@ s32 cur_obj_has_model(u16 modelID) {
} }
void cur_obj_align_gfx_with_floor(void) { void cur_obj_align_gfx_with_floor(void) {
if (!o) { return; }
struct Surface *floor; struct Surface *floor;
Vec3f floorNormal; Vec3f floorNormal;
Vec3f position; Vec3f position;
@ -3195,6 +3309,7 @@ s32 mario_is_within_rectangle(s16 minX, s16 maxX, s16 minZ, s16 maxZ) {
} }
void cur_obj_shake_screen(s32 shake) { void cur_obj_shake_screen(s32 shake) {
if (!o) { return; }
set_camera_shake_from_point(shake, o->oPosX, o->oPosY, o->oPosZ); set_camera_shake_from_point(shake, o->oPosX, o->oPosY, o->oPosZ);
} }
@ -3219,6 +3334,7 @@ s32 obj_attack_collided_from_other_object(struct Object *obj) {
} }
s32 cur_obj_was_attacked_or_ground_pounded(void) { s32 cur_obj_was_attacked_or_ground_pounded(void) {
if (!o) { return 0; }
s32 attacked = FALSE; s32 attacked = FALSE;
if ((o->oInteractStatus & INT_STATUS_INTERACTED) if ((o->oInteractStatus & INT_STATUS_INTERACTED)
@ -3241,6 +3357,7 @@ void obj_copy_behavior_params(struct Object *dst, struct Object *src) {
} }
void cur_obj_init_animation_and_anim_frame(s32 animIndex, s32 animFrame) { void cur_obj_init_animation_and_anim_frame(s32 animIndex, s32 animFrame) {
if (!o) { return; }
cur_obj_init_animation_with_sound(animIndex); cur_obj_init_animation_with_sound(animIndex);
o->header.gfx.animInfo.animFrame = animFrame; o->header.gfx.animInfo.animFrame = animFrame;
} }
@ -3256,6 +3373,7 @@ void cur_obj_init_animation_and_extend_if_at_end(s32 animIndex) {
} }
s32 cur_obj_check_grabbed_mario(void) { s32 cur_obj_check_grabbed_mario(void) {
if (!o) { return 0; }
if (o->oInteractStatus & INT_STATUS_GRABBED_MARIO) { if (o->oInteractStatus & INT_STATUS_GRABBED_MARIO) {
o->oKingBobombUnk88 = 1; o->oKingBobombUnk88 = 1;
cur_obj_become_intangible(); cur_obj_become_intangible();
@ -3293,15 +3411,20 @@ void cur_obj_unused_play_footstep_sound(s32 animFrame1, s32 animFrame2, s32 soun
void enable_time_stop_including_mario(void) { void enable_time_stop_including_mario(void) {
gTimeStopState |= TIME_STOP_ENABLED | TIME_STOP_MARIO_AND_DOORS; gTimeStopState |= TIME_STOP_ENABLED | TIME_STOP_MARIO_AND_DOORS;
if (o) {
o->activeFlags |= ACTIVE_FLAG_INITIATED_TIME_STOP; o->activeFlags |= ACTIVE_FLAG_INITIATED_TIME_STOP;
}
} }
void disable_time_stop_including_mario(void) { void disable_time_stop_including_mario(void) {
gTimeStopState &= ~(TIME_STOP_ENABLED | TIME_STOP_MARIO_AND_DOORS); gTimeStopState &= ~(TIME_STOP_ENABLED | TIME_STOP_MARIO_AND_DOORS);
if (o) {
o->activeFlags &= ~ACTIVE_FLAG_INITIATED_TIME_STOP; o->activeFlags &= ~ACTIVE_FLAG_INITIATED_TIME_STOP;
}
} }
s32 cur_obj_check_interacted(void) { s32 cur_obj_check_interacted(void) {
if (!o) { return 0; }
if (o->oInteractStatus & INT_STATUS_INTERACTED) { if (o->oInteractStatus & INT_STATUS_INTERACTED) {
o->oInteractStatus = 0; o->oInteractStatus = 0;
return TRUE; return TRUE;
@ -3311,7 +3434,7 @@ s32 cur_obj_check_interacted(void) {
} }
void cur_obj_spawn_loot_blue_coin(void) { void cur_obj_spawn_loot_blue_coin(void) {
if (o->oNumLootCoins >= 5) { if (o && o->oNumLootCoins >= 5) {
spawn_object(o, MODEL_BLUE_COIN, bhvMrIBlueCoin); spawn_object(o, MODEL_BLUE_COIN, bhvMrIBlueCoin);
o->oNumLootCoins -= 5; o->oNumLootCoins -= 5;
} }
@ -3319,6 +3442,7 @@ void cur_obj_spawn_loot_blue_coin(void) {
#ifndef VERSION_JP #ifndef VERSION_JP
void cur_obj_spawn_star_at_y_offset(f32 targetX, f32 targetY, f32 targetZ, f32 offsetY) { void cur_obj_spawn_star_at_y_offset(f32 targetX, f32 targetY, f32 targetZ, f32 offsetY) {
if (!o) { return; }
f32 objectPosY = o->oPosY; f32 objectPosY = o->oPosY;
o->oPosY += offsetY + gDebugInfo[5][0]; o->oPosY += offsetY + gDebugInfo[5][0];
spawn_default_star(targetX, targetY, targetZ); spawn_default_star(targetX, targetY, targetZ);
@ -3327,6 +3451,7 @@ void cur_obj_spawn_star_at_y_offset(f32 targetX, f32 targetY, f32 targetZ, f32 o
#endif #endif
void cur_obj_set_home_once(void) { void cur_obj_set_home_once(void) {
if (!o) { return; }
if (o->setHome) { return; } if (o->setHome) { return; }
o->setHome = TRUE; o->setHome = TRUE;
o->oHomeX = o->oPosX; o->oHomeX = o->oPosX;

View file

@ -160,7 +160,7 @@ void queue_rumble_data_object(struct Object* object, s16 a0, s16 a1) {
} }
void queue_rumble_data_mario(struct MarioState* m, s16 a0, s16 a1) { void queue_rumble_data_mario(struct MarioState* m, s16 a0, s16 a1) {
if (m->playerIndex != 0) { return; } if (!m || m->playerIndex != 0) { return; }
queue_rumble_data(a0, a1); queue_rumble_data(a0, a1);
} }
@ -189,7 +189,7 @@ u8 is_rumble_finished_and_queue_empty(void) {
} }
void reset_rumble_timers(struct MarioState* m) { void reset_rumble_timers(struct MarioState* m) {
if (m->playerIndex != 0) { return; } if (!m || m->playerIndex != 0) { return; }
if (gCurrDemoInput != NULL) { if (gCurrDemoInput != NULL) {
return; return;
@ -207,7 +207,7 @@ void reset_rumble_timers(struct MarioState* m) {
} }
void reset_rumble_timers_2(struct MarioState* m, s32 a0) { void reset_rumble_timers_2(struct MarioState* m, s32 a0) {
if (m->playerIndex != 0) { return; } if (!m || m->playerIndex != 0) { return; }
if (gCurrDemoInput != NULL) { if (gCurrDemoInput != NULL) {
return; return;

View file

@ -22,6 +22,11 @@
#define MENU_DATA_MAGIC 0x4849 #define MENU_DATA_MAGIC 0x4849
#define SAVE_FILE_MAGIC 0x4441 #define SAVE_FILE_MAGIC 0x4441
#define INVALID_FILE_INDEX(_fi) ((u32)_fi >= NUM_SAVE_FILES)
#define INVALID_SRC_SLOT(_ss) ((u32)_ss >= 2)
#define INVALID_LEVEL_NUM(_ln) ((u32)_ln >= LEVEL_COUNT)
#define INVALID_COURSE_INDEX(_ci) ((u32)_ci >= COURSE_STAGES_COUNT)
STATIC_ASSERT(sizeof(struct SaveBuffer) == EEPROM_SIZE, "eeprom buffer size must match"); STATIC_ASSERT(sizeof(struct SaveBuffer) == EEPROM_SIZE, "eeprom buffer size must match");
extern struct SaveBuffer gSaveBuffer; extern struct SaveBuffer gSaveBuffer;
@ -57,10 +62,9 @@ s8 get_level_course_num(s16 levelNum) {
return (info ? info->courseNum : COURSE_NONE); return (info ? info->courseNum : COURSE_NONE);
} }
if (levelNum < 0 || levelNum >= LEVEL_COUNT) { if (INVALID_LEVEL_NUM(levelNum)) {
return COURSE_NONE; return COURSE_NONE;
} }
return gLevelToCourseNumTable[levelNum]; return gLevelToCourseNumTable[levelNum];
} }
@ -155,6 +159,8 @@ static s32 write_eeprom_data(void *buffer, s32 size, const uintptr_t baseofs) {
*/ */
static inline s32 write_eeprom_savefile(const u32 file, const u32 slot, const u32 num) { static inline s32 write_eeprom_savefile(const u32 file, const u32 slot, const u32 num) {
if (INVALID_FILE_INDEX(file)) { return 0; }
if (INVALID_SRC_SLOT(slot)) { return 0; }
// calculate the EEPROM address using the file number and slot // calculate the EEPROM address using the file number and slot
const uintptr_t ofs = (u8*)&gSaveBuffer.files[file][slot] - (u8*)&gSaveBuffer; const uintptr_t ofs = (u8*)&gSaveBuffer.files[file][slot] - (u8*)&gSaveBuffer;
@ -170,6 +176,7 @@ static inline s32 write_eeprom_savefile(const u32 file, const u32 slot, const u3
} }
static inline s32 write_eeprom_menudata(const u32 slot, const u32 num) { static inline s32 write_eeprom_menudata(const u32 slot, const u32 num) {
if (INVALID_SRC_SLOT(slot)) { return 0; }
// calculate the EEPROM address using the slot // calculate the EEPROM address using the slot
const uintptr_t ofs = (u8*)&gSaveBuffer.menuData[slot] - (u8*)&gSaveBuffer; const uintptr_t ofs = (u8*)&gSaveBuffer.menuData[slot] - (u8*)&gSaveBuffer;
@ -226,7 +233,9 @@ static void add_save_block_signature(void *buffer, s32 size, u16 magic) {
* Copy main menu data from one backup slot to the other slot. * Copy main menu data from one backup slot to the other slot.
*/ */
UNUSED static void restore_main_menu_data(s32 srcSlot) { UNUSED static void restore_main_menu_data(s32 srcSlot) {
if (INVALID_SRC_SLOT(srcSlot)) { return; }
s32 destSlot = srcSlot ^ 1; s32 destSlot = srcSlot ^ 1;
if (INVALID_SRC_SLOT(destSlot)) { return; }
// Compute checksum on source data // Compute checksum on source data
add_save_block_signature(&gSaveBuffer.menuData[srcSlot], sizeof(gSaveBuffer.menuData[srcSlot]), MENU_DATA_MAGIC); add_save_block_signature(&gSaveBuffer.menuData[srcSlot], sizeof(gSaveBuffer.menuData[srcSlot]), MENU_DATA_MAGIC);
@ -266,10 +275,12 @@ UNUSED static void wipe_main_menu_data(void) {
} }
static s32 get_coin_score_age(s32 fileIndex, s32 courseIndex) { static s32 get_coin_score_age(s32 fileIndex, s32 courseIndex) {
if (INVALID_FILE_INDEX(fileIndex)) { return 0; }
return (gSaveBuffer.menuData[0].coinScoreAges[fileIndex] >> (2 * courseIndex)) & 0x3; return (gSaveBuffer.menuData[0].coinScoreAges[fileIndex] >> (2 * courseIndex)) & 0x3;
} }
static void set_coin_score_age(s32 fileIndex, s32 courseIndex, s32 age) { static void set_coin_score_age(s32 fileIndex, s32 courseIndex, s32 age) {
if (INVALID_FILE_INDEX(fileIndex)) { return; }
s32 mask = 0x3 << (2 * courseIndex); s32 mask = 0x3 << (2 * courseIndex);
gSaveBuffer.menuData[0].coinScoreAges[fileIndex] &= ~mask; gSaveBuffer.menuData[0].coinScoreAges[fileIndex] &= ~mask;
@ -280,6 +291,7 @@ static void set_coin_score_age(s32 fileIndex, s32 courseIndex, s32 age) {
* Mark a coin score for a save file as the newest out of all save files. * Mark a coin score for a save file as the newest out of all save files.
*/ */
static void touch_coin_score_age(s32 fileIndex, s32 courseIndex) { static void touch_coin_score_age(s32 fileIndex, s32 courseIndex) {
if (INVALID_FILE_INDEX(fileIndex)) { return; }
s32 i; s32 i;
u32 age; u32 age;
u32 currentAge = get_coin_score_age(fileIndex, courseIndex); u32 currentAge = get_coin_score_age(fileIndex, courseIndex);
@ -301,6 +313,7 @@ static void touch_coin_score_age(s32 fileIndex, s32 courseIndex) {
* Mark all coin scores for a save file as new. * Mark all coin scores for a save file as new.
*/ */
static void touch_high_score_ages(s32 fileIndex) { static void touch_high_score_ages(s32 fileIndex) {
if (INVALID_FILE_INDEX(fileIndex)) { return; }
s32 i; s32 i;
for (i = 0; i < 15; i++) { for (i = 0; i < 15; i++) {
@ -312,7 +325,10 @@ static void touch_high_score_ages(s32 fileIndex) {
* Copy save file data from one backup slot to the other slot. * Copy save file data from one backup slot to the other slot.
*/ */
UNUSED static void restore_save_file_data(s32 fileIndex, s32 srcSlot) { UNUSED static void restore_save_file_data(s32 fileIndex, s32 srcSlot) {
if (INVALID_FILE_INDEX(fileIndex)) { return; }
if (INVALID_SRC_SLOT(srcSlot)) { return; }
s32 destSlot = srcSlot ^ 1; s32 destSlot = srcSlot ^ 1;
if (INVALID_SRC_SLOT(destSlot)) { return; }
// Compute checksum on source data // Compute checksum on source data
add_save_block_signature(&gSaveBuffer.files[fileIndex][srcSlot], add_save_block_signature(&gSaveBuffer.files[fileIndex][srcSlot],
@ -355,6 +371,7 @@ static void save_file_bswap(struct SaveBuffer *buf) {
} }
void save_file_do_save(s32 fileIndex, s8 forceSave) { void save_file_do_save(s32 fileIndex, s8 forceSave) {
if (INVALID_FILE_INDEX(fileIndex)) { return; }
if (gNetworkType != NT_SERVER) { if (gNetworkType != NT_SERVER) {
if (gNetworkType == NT_CLIENT) { network_send_save_file(fileIndex); return; } if (gNetworkType == NT_CLIENT) { network_send_save_file(fileIndex); return; }
else if (gNetworkType == NT_NONE && !forceSave) { return; } else if (gNetworkType == NT_NONE && !forceSave) { return; }
@ -381,8 +398,7 @@ void save_file_do_save(s32 fileIndex, s8 forceSave) {
} }
void save_file_erase(s32 fileIndex) { void save_file_erase(s32 fileIndex) {
if (fileIndex < 0 || fileIndex >= NUM_SAVE_FILES) if (INVALID_FILE_INDEX(fileIndex)) { return; }
return;
touch_high_score_ages(fileIndex); touch_high_score_ages(fileIndex);
bzero(&gSaveBuffer.files[fileIndex][0], sizeof(gSaveBuffer.files[fileIndex][0])); bzero(&gSaveBuffer.files[fileIndex][0], sizeof(gSaveBuffer.files[fileIndex][0]));
@ -404,6 +420,7 @@ void save_file_reload(u8 load_all) {
} }
void save_file_erase_current_backup_save(void) { void save_file_erase_current_backup_save(void) {
if (INVALID_FILE_INDEX(gCurrSaveFileNum-1)) { return; }
if (network_is_server()) { if (network_is_server()) {
bzero(&gSaveBuffer.files[gCurrSaveFileNum-1][1], sizeof(gSaveBuffer.files[gCurrSaveFileNum-1][1])); bzero(&gSaveBuffer.files[gCurrSaveFileNum-1][1], sizeof(gSaveBuffer.files[gCurrSaveFileNum-1][1]));
@ -415,8 +432,8 @@ void save_file_erase_current_backup_save(void) {
//! Needs to be s32 to match on -O2, despite no return value. //! Needs to be s32 to match on -O2, despite no return value.
BAD_RETURN(s32) save_file_copy(s32 srcFileIndex, s32 destFileIndex) { BAD_RETURN(s32) save_file_copy(s32 srcFileIndex, s32 destFileIndex) {
if (srcFileIndex < 0 || srcFileIndex >= NUM_SAVE_FILES || destFileIndex < 0 || destFileIndex >= NUM_SAVE_FILES) if (INVALID_FILE_INDEX(srcFileIndex)) { return; }
return; if (INVALID_FILE_INDEX(destFileIndex)) { return; }
touch_high_score_ages(destFileIndex); touch_high_score_ages(destFileIndex);
bcopy(&gSaveBuffer.files[srcFileIndex][0], &gSaveBuffer.files[destFileIndex][0], bcopy(&gSaveBuffer.files[srcFileIndex][0], &gSaveBuffer.files[destFileIndex][0],
@ -486,6 +503,8 @@ void save_file_collect_star_or_key(s16 coinScore, s16 starIndex, u8 fromNetwork)
s32 fileIndex = gCurrSaveFileNum - 1; s32 fileIndex = gCurrSaveFileNum - 1;
s32 courseIndex = gCurrCourseNum - 1; s32 courseIndex = gCurrCourseNum - 1;
if (INVALID_FILE_INDEX(fileIndex)) { return; }
if (INVALID_SRC_SLOT(gSaveFileUsingBackupSlot)) { return; }
s32 starFlag = 1 << starIndex; s32 starFlag = 1 << starIndex;
UNUSED s32 flags = save_file_get_flags(); UNUSED s32 flags = save_file_get_flags();
@ -497,7 +516,7 @@ void save_file_collect_star_or_key(s16 coinScore, s16 starIndex, u8 fromNetwork)
gGotFileCoinHiScore = FALSE; gGotFileCoinHiScore = FALSE;
} }
if (courseIndex >= 0 && courseIndex < COURSE_STAGES_COUNT && !fromNetwork) { if (!INVALID_COURSE_INDEX(courseIndex) && !fromNetwork) {
//! Compares the coin score as a 16 bit value, but only writes the 8 bit //! Compares the coin score as a 16 bit value, but only writes the 8 bit
// truncation. This can allow a high score to decrease. // truncation. This can allow a high score to decrease.
@ -539,6 +558,7 @@ void save_file_collect_star_or_key(s16 coinScore, s16 starIndex, u8 fromNetwork)
} }
s32 save_file_exists(s32 fileIndex) { s32 save_file_exists(s32 fileIndex) {
if (INVALID_FILE_INDEX(fileIndex)) { return 0; }
return (gSaveBuffer.files[fileIndex][0].flags & SAVE_FLAG_FILE_EXISTS) != 0; return (gSaveBuffer.files[fileIndex][0].flags & SAVE_FLAG_FILE_EXISTS) != 0;
} }
@ -569,6 +589,7 @@ u32 save_file_get_max_coin_score(s32 courseIndex) {
} }
s32 save_file_get_course_star_count(s32 fileIndex, s32 courseIndex) { s32 save_file_get_course_star_count(s32 fileIndex, s32 courseIndex) {
if (INVALID_FILE_INDEX(fileIndex)) { return 0; }
s32 i; s32 i;
s32 count = 0; s32 count = 0;
u8 flag = 1; u8 flag = 1;
@ -583,8 +604,12 @@ s32 save_file_get_course_star_count(s32 fileIndex, s32 courseIndex) {
} }
s32 save_file_get_total_star_count(s32 fileIndex, s32 minCourse, s32 maxCourse) { s32 save_file_get_total_star_count(s32 fileIndex, s32 minCourse, s32 maxCourse) {
if (INVALID_FILE_INDEX(fileIndex)) { return 02; }
s32 count = 0; s32 count = 0;
if (minCourse < -1) { minCourse = -1; }
if (maxCourse >= COURSE_STAGES_COUNT) { maxCourse = COURSE_STAGES_COUNT; }
// Get standard course star count. // Get standard course star count.
for (; minCourse <= maxCourse; minCourse++) { for (; minCourse <= maxCourse; minCourse++) {
count += save_file_get_course_star_count(fileIndex, minCourse); count += save_file_get_course_star_count(fileIndex, minCourse);
@ -595,6 +620,8 @@ s32 save_file_get_total_star_count(s32 fileIndex, s32 minCourse, s32 maxCourse)
} }
void save_file_set_flags(u32 flags) { void save_file_set_flags(u32 flags) {
if (INVALID_FILE_INDEX(gCurrSaveFileNum - 1)) { return; }
if (INVALID_SRC_SLOT(gSaveFileUsingBackupSlot)) { return; }
// prevent saving any flag that would make the player hatless on level transition // prevent saving any flag that would make the player hatless on level transition
flags &= ~(SAVE_FLAG_CAP_ON_GROUND | SAVE_FLAG_CAP_ON_KLEPTO | SAVE_FLAG_CAP_ON_MR_BLIZZARD | SAVE_FLAG_CAP_ON_UKIKI); flags &= ~(SAVE_FLAG_CAP_ON_GROUND | SAVE_FLAG_CAP_ON_KLEPTO | SAVE_FLAG_CAP_ON_MR_BLIZZARD | SAVE_FLAG_CAP_ON_UKIKI);
if (flags == 0) { return; } if (flags == 0) { return; }
@ -605,12 +632,16 @@ void save_file_set_flags(u32 flags) {
} }
void save_file_clear_flags(u32 flags) { void save_file_clear_flags(u32 flags) {
if (INVALID_FILE_INDEX(gCurrSaveFileNum - 1)) { return; }
if (INVALID_SRC_SLOT(gSaveFileUsingBackupSlot)) { return; }
gSaveBuffer.files[gCurrSaveFileNum - 1][gSaveFileUsingBackupSlot].flags &= ~flags; gSaveBuffer.files[gCurrSaveFileNum - 1][gSaveFileUsingBackupSlot].flags &= ~flags;
gSaveBuffer.files[gCurrSaveFileNum - 1][gSaveFileUsingBackupSlot].flags |= SAVE_FLAG_FILE_EXISTS; gSaveBuffer.files[gCurrSaveFileNum - 1][gSaveFileUsingBackupSlot].flags |= SAVE_FLAG_FILE_EXISTS;
gSaveFileModified = TRUE; gSaveFileModified = TRUE;
} }
u32 save_file_get_flags(void) { u32 save_file_get_flags(void) {
if (INVALID_FILE_INDEX(gCurrSaveFileNum - 1)) { return 0; }
if (INVALID_SRC_SLOT(gSaveFileUsingBackupSlot)) { return 0; }
if (gCurrCreditsEntry != NULL || gCurrDemoInput != NULL) { if (gCurrCreditsEntry != NULL || gCurrDemoInput != NULL) {
return 0; return 0;
} }
@ -622,11 +653,13 @@ u32 save_file_get_flags(void) {
* If course is -1, return the bitset of obtained castle secret stars. * If course is -1, return the bitset of obtained castle secret stars.
*/ */
u32 save_file_get_star_flags(s32 fileIndex, s32 courseIndex) { u32 save_file_get_star_flags(s32 fileIndex, s32 courseIndex) {
u32 starFlags; if (INVALID_FILE_INDEX(fileIndex)) { return 0; }
if (INVALID_SRC_SLOT(gSaveFileUsingBackupSlot)) { return 0; }
u32 starFlags = 0;
if (courseIndex == -1) { if (courseIndex == -1) {
starFlags = SAVE_FLAG_TO_STAR_FLAG(gSaveBuffer.files[fileIndex][gSaveFileUsingBackupSlot].flags); starFlags = SAVE_FLAG_TO_STAR_FLAG(gSaveBuffer.files[fileIndex][gSaveFileUsingBackupSlot].flags);
} else { } else if (!INVALID_COURSE_INDEX(courseIndex)) {
starFlags = gSaveBuffer.files[fileIndex][gSaveFileUsingBackupSlot].courseStars[courseIndex] & 0x7F; starFlags = gSaveBuffer.files[fileIndex][gSaveFileUsingBackupSlot].courseStars[courseIndex] & 0x7F;
} }
@ -638,10 +671,12 @@ u32 save_file_get_star_flags(s32 fileIndex, s32 courseIndex) {
* If course is -1, add to the bitset of obtained castle secret stars. * If course is -1, add to the bitset of obtained castle secret stars.
*/ */
void save_file_set_star_flags(s32 fileIndex, s32 courseIndex, u32 starFlags) { void save_file_set_star_flags(s32 fileIndex, s32 courseIndex, u32 starFlags) {
if (INVALID_FILE_INDEX(fileIndex)) { return; }
if (INVALID_SRC_SLOT(gSaveFileUsingBackupSlot)) { return; }
if (courseIndex == -1) { if (courseIndex == -1) {
gSaveBuffer.files[fileIndex][gSaveFileUsingBackupSlot].flags |= STAR_FLAG_TO_SAVE_FLAG(starFlags); gSaveBuffer.files[fileIndex][gSaveFileUsingBackupSlot].flags |= STAR_FLAG_TO_SAVE_FLAG(starFlags);
network_send_save_set_flag(fileIndex, courseIndex, 0, (STAR_FLAG_TO_SAVE_FLAG(starFlags) | SAVE_FLAG_FILE_EXISTS)); network_send_save_set_flag(fileIndex, courseIndex, 0, (STAR_FLAG_TO_SAVE_FLAG(starFlags) | SAVE_FLAG_FILE_EXISTS));
} else { } else if (!INVALID_COURSE_INDEX(courseIndex)) {
gSaveBuffer.files[fileIndex][gSaveFileUsingBackupSlot].courseStars[courseIndex] |= starFlags; gSaveBuffer.files[fileIndex][gSaveFileUsingBackupSlot].courseStars[courseIndex] |= starFlags;
network_send_save_set_flag(fileIndex, courseIndex, starFlags, SAVE_FLAG_FILE_EXISTS); network_send_save_set_flag(fileIndex, courseIndex, starFlags, SAVE_FLAG_FILE_EXISTS);
} }
@ -651,6 +686,9 @@ void save_file_set_star_flags(s32 fileIndex, s32 courseIndex, u32 starFlags) {
} }
s32 save_file_get_course_coin_score(s32 fileIndex, s32 courseIndex) { s32 save_file_get_course_coin_score(s32 fileIndex, s32 courseIndex) {
if (INVALID_FILE_INDEX(fileIndex)) { return 0; }
if (INVALID_SRC_SLOT(gSaveFileUsingBackupSlot)) { return 0; }
if (INVALID_COURSE_INDEX(courseIndex)) { return 0; }
return gSaveBuffer.files[fileIndex][gSaveFileUsingBackupSlot].courseCoinScores[courseIndex]; return gSaveBuffer.files[fileIndex][gSaveFileUsingBackupSlot].courseCoinScores[courseIndex];
} }
@ -658,6 +696,9 @@ s32 save_file_get_course_coin_score(s32 fileIndex, s32 courseIndex) {
* Return TRUE if the cannon is unlocked in the current course. * Return TRUE if the cannon is unlocked in the current course.
*/ */
s32 save_file_is_cannon_unlocked(void) { s32 save_file_is_cannon_unlocked(void) {
if (INVALID_FILE_INDEX(gCurrSaveFileNum - 1)) { return 0; }
if (INVALID_SRC_SLOT(gSaveFileUsingBackupSlot)) { return 0; }
if (INVALID_COURSE_INDEX(gCurrCourseNum)) { return 0; }
return (gSaveBuffer.files[gCurrSaveFileNum - 1][gSaveFileUsingBackupSlot].courseStars[gCurrCourseNum] & 0x80) != 0; return (gSaveBuffer.files[gCurrSaveFileNum - 1][gSaveFileUsingBackupSlot].courseStars[gCurrCourseNum] & 0x80) != 0;
} }
@ -665,6 +706,9 @@ s32 save_file_is_cannon_unlocked(void) {
* Sets the cannon status to unlocked in the current course. * Sets the cannon status to unlocked in the current course.
*/ */
void save_file_set_cannon_unlocked(void) { void save_file_set_cannon_unlocked(void) {
if (INVALID_FILE_INDEX(gCurrSaveFileNum - 1)) { return; }
if (INVALID_SRC_SLOT(gSaveFileUsingBackupSlot)) { return; }
if (INVALID_COURSE_INDEX(gCurrCourseNum)) { return; }
gSaveBuffer.files[gCurrSaveFileNum - 1][gSaveFileUsingBackupSlot].courseStars[gCurrCourseNum] |= 0x80; gSaveBuffer.files[gCurrSaveFileNum - 1][gSaveFileUsingBackupSlot].courseStars[gCurrCourseNum] |= 0x80;
gSaveBuffer.files[gCurrSaveFileNum - 1][gSaveFileUsingBackupSlot].flags |= SAVE_FLAG_FILE_EXISTS; gSaveBuffer.files[gCurrSaveFileNum - 1][gSaveFileUsingBackupSlot].flags |= SAVE_FLAG_FILE_EXISTS;
gSaveFileModified = TRUE; gSaveFileModified = TRUE;
@ -672,6 +716,8 @@ void save_file_set_cannon_unlocked(void) {
} }
void save_file_set_cap_pos(s16 x, s16 y, s16 z) { void save_file_set_cap_pos(s16 x, s16 y, s16 z) {
if (INVALID_FILE_INDEX(gCurrSaveFileNum - 1)) { return; }
if (INVALID_SRC_SLOT(gSaveFileUsingBackupSlot)) { return; }
struct SaveFile *saveFile = &gSaveBuffer.files[gCurrSaveFileNum - 1][gSaveFileUsingBackupSlot]; struct SaveFile *saveFile = &gSaveBuffer.files[gCurrSaveFileNum - 1][gSaveFileUsingBackupSlot];
saveFile->capLevel = gCurrLevelNum; saveFile->capLevel = gCurrLevelNum;
@ -681,6 +727,8 @@ void save_file_set_cap_pos(s16 x, s16 y, s16 z) {
} }
s32 save_file_get_cap_pos(Vec3s capPos) { s32 save_file_get_cap_pos(Vec3s capPos) {
if (INVALID_FILE_INDEX(gCurrSaveFileNum - 1)) { return 0; }
if (INVALID_SRC_SLOT(gSaveFileUsingBackupSlot)) { return 0; }
struct SaveFile *saveFile = &gSaveBuffer.files[gCurrSaveFileNum - 1][gSaveFileUsingBackupSlot]; struct SaveFile *saveFile = &gSaveBuffer.files[gCurrSaveFileNum - 1][gSaveFileUsingBackupSlot];
s32 flags = save_file_get_flags(); s32 flags = save_file_get_flags();
@ -705,6 +753,8 @@ u16 save_file_get_sound_mode(void) {
} }
void save_file_move_cap_to_default_location(void) { void save_file_move_cap_to_default_location(void) {
if (INVALID_FILE_INDEX(gCurrSaveFileNum - 1)) { return; }
if (INVALID_SRC_SLOT(gSaveFileUsingBackupSlot)) { return; }
if (save_file_get_flags() & SAVE_FLAG_CAP_ON_GROUND || gMarioStates[0].cap == SAVE_FLAG_CAP_ON_GROUND) { if (save_file_get_flags() & SAVE_FLAG_CAP_ON_GROUND || gMarioStates[0].cap == SAVE_FLAG_CAP_ON_GROUND) {
switch (gSaveBuffer.files[gCurrSaveFileNum - 1][gSaveFileUsingBackupSlot].capLevel) { switch (gSaveBuffer.files[gCurrSaveFileNum - 1][gSaveFileUsingBackupSlot].capLevel) {
case LEVEL_SSL: case LEVEL_SSL:

View file

@ -241,7 +241,7 @@ void draw_skybox_tile_grid(Gfx **dlist, s8 background, s8 player, s8 colorIndex)
if (tileIndex < 0) { tileIndex = 0; } if (tileIndex < 0) { tileIndex = 0; }
if (tileIndex > 79) { tileIndex = 79; } if (tileIndex > 79) { tileIndex = 79; }
Texture* texture = NULL; Texture* texture = NULL;
if (background >= 10) { if (background < 0 || background >= 10) {
texture = gCustomSkyboxPtrList[tileIndex]; texture = gCustomSkyboxPtrList[tileIndex];
} else { } else {
texture = (Texture*)(*(SkyboxTexture *) segmented_to_virtual(sSkyboxTextures[background]))[tileIndex]; texture = (Texture*)(*(SkyboxTexture *) segmented_to_virtual(sSkyboxTextures[background]))[tileIndex];

View file

@ -16,6 +16,7 @@
* objects. (King Bobomb, Bowser, King Whomp) * objects. (King Bobomb, Bowser, King Whomp)
*/ */
void exec_anim_sound_state(struct SoundState *soundStates, u16 maxSoundStates) { void exec_anim_sound_state(struct SoundState *soundStates, u16 maxSoundStates) {
if (!gCurrentObject) { return; }
s32 stateIdx = gCurrentObject->oSoundStateID; s32 stateIdx = gCurrentObject->oSoundStateID;
if (stateIdx >= maxSoundStates) { return; } if (stateIdx >= maxSoundStates) { return; }
@ -62,12 +63,14 @@ void create_sound_spawner(s32 soundMagic) {
* separate left/right leg functions that went unused. * separate left/right leg functions that went unused.
*/ */
void cur_obj_play_sound_1(s32 soundMagic) { void cur_obj_play_sound_1(s32 soundMagic) {
if (!gCurrentObject) { return; }
if (gCurrentObject->header.gfx.node.flags & GRAPH_RENDER_ACTIVE) { if (gCurrentObject->header.gfx.node.flags & GRAPH_RENDER_ACTIVE) {
play_sound(soundMagic, gCurrentObject->header.gfx.cameraToObject); play_sound(soundMagic, gCurrentObject->header.gfx.cameraToObject);
} }
} }
void cur_obj_play_sound_2(s32 soundMagic) { void cur_obj_play_sound_2(s32 soundMagic) {
if (!gCurrentObject) { return; }
if (gCurrentObject->header.gfx.node.flags & GRAPH_RENDER_ACTIVE) { if (gCurrentObject->header.gfx.node.flags & GRAPH_RENDER_ACTIVE) {
play_sound(soundMagic, gCurrentObject->header.gfx.cameraToObject); play_sound(soundMagic, gCurrentObject->header.gfx.cameraToObject);

View file

@ -352,16 +352,19 @@ u32 allocate_mario_action(u32 actFlags) {
/// ///
f32 get_hand_foot_pos_x(struct MarioState* m, u8 index) { f32 get_hand_foot_pos_x(struct MarioState* m, u8 index) {
if (!m) { return 0; }
if (index >= 4) { index = 0; } if (index >= 4) { index = 0; }
return m->marioBodyState->handFootPos[index][0]; return m->marioBodyState->handFootPos[index][0];
} }
f32 get_hand_foot_pos_y(struct MarioState* m, u8 index) { f32 get_hand_foot_pos_y(struct MarioState* m, u8 index) {
if (!m) { return 0; }
if (index >= 4) { index = 0; } if (index >= 4) { index = 0; }
return m->marioBodyState->handFootPos[index][1]; return m->marioBodyState->handFootPos[index][1];
} }
f32 get_hand_foot_pos_z(struct MarioState* m, u8 index) { f32 get_hand_foot_pos_z(struct MarioState* m, u8 index) {
if (!m) { return 0; }
if (index >= 4) { index = 0; } if (index >= 4) { index = 0; }
return m->marioBodyState->handFootPos[index][2]; return m->marioBodyState->handFootPos[index][2];
} }

View file

@ -87,11 +87,13 @@ struct Object* spawn_non_sync_object(enum BehaviorId behaviorId, enum ModelExten
} }
s32 obj_has_behavior_id(struct Object *o, enum BehaviorId behaviorId) { s32 obj_has_behavior_id(struct Object *o, enum BehaviorId behaviorId) {
if (!o) { return 0; }
const BehaviorScript *behavior = get_behavior_from_id(behaviorId); const BehaviorScript *behavior = get_behavior_from_id(behaviorId);
return o->behavior == smlua_override_behavior(behavior); return o->behavior == smlua_override_behavior(behavior);
} }
s32 obj_has_model_extended(struct Object *o, enum ModelExtendedId modelId) { s32 obj_has_model_extended(struct Object *o, enum ModelExtendedId modelId) {
if (!o) { return 0; }
u16 slot = smlua_model_util_load(modelId); u16 slot = smlua_model_util_load(modelId);
if (slot >= MAX_LOADED_GRAPH_NODES) { return false; } if (slot >= MAX_LOADED_GRAPH_NODES) { return false; }
struct GraphNode *model = gLoadedGraphNodes[slot]; struct GraphNode *model = gLoadedGraphNodes[slot];
@ -99,6 +101,7 @@ s32 obj_has_model_extended(struct Object *o, enum ModelExtendedId modelId) {
} }
void obj_set_model_extended(struct Object *o, enum ModelExtendedId modelId) { void obj_set_model_extended(struct Object *o, enum ModelExtendedId modelId) {
if (!o) { return; }
obj_set_model(o, smlua_model_util_load(modelId)); obj_set_model(o, smlua_model_util_load(modelId));
} }
@ -138,6 +141,7 @@ struct Object *obj_get_first_with_behavior_id(enum BehaviorId behaviorId) {
} }
struct Object *obj_get_first_with_behavior_id_and_field_s32(enum BehaviorId behaviorId, s32 fieldIndex, s32 value) { struct Object *obj_get_first_with_behavior_id_and_field_s32(enum BehaviorId behaviorId, s32 fieldIndex, s32 value) {
if (fieldIndex < 0 || fieldIndex >= 0x50) { return NULL; }
const BehaviorScript* behavior = get_behavior_from_id(behaviorId); const BehaviorScript* behavior = get_behavior_from_id(behaviorId);
u32 sanityDepth = 0; u32 sanityDepth = 0;
behavior = smlua_override_behavior(behavior); behavior = smlua_override_behavior(behavior);
@ -154,6 +158,7 @@ struct Object *obj_get_first_with_behavior_id_and_field_s32(enum BehaviorId beha
} }
struct Object *obj_get_first_with_behavior_id_and_field_f32(enum BehaviorId behaviorId, s32 fieldIndex, f32 value) { struct Object *obj_get_first_with_behavior_id_and_field_f32(enum BehaviorId behaviorId, s32 fieldIndex, f32 value) {
if (fieldIndex < 0 || fieldIndex >= 0x50) { return NULL; }
const BehaviorScript* behavior = get_behavior_from_id(behaviorId); const BehaviorScript* behavior = get_behavior_from_id(behaviorId);
behavior = smlua_override_behavior(behavior); behavior = smlua_override_behavior(behavior);
if (behavior) { if (behavior) {
@ -227,6 +232,7 @@ struct Object *obj_get_next_with_same_behavior_id(struct Object *o) {
} }
struct Object *obj_get_next_with_same_behavior_id_and_field_s32(struct Object *o, s32 fieldIndex, s32 value) { struct Object *obj_get_next_with_same_behavior_id_and_field_s32(struct Object *o, s32 fieldIndex, s32 value) {
if (fieldIndex < 0 || fieldIndex >= 0x50) { return NULL; }
if (o) { if (o) {
for (struct Object *obj = obj_get_next(o); obj != NULL; obj = obj_get_next(obj)) { for (struct Object *obj = obj_get_next(o); obj != NULL; obj = obj_get_next(obj)) {
if (obj->behavior == o->behavior && obj->activeFlags != ACTIVE_FLAG_DEACTIVATED && obj->OBJECT_FIELD_S32(fieldIndex) == value) { if (obj->behavior == o->behavior && obj->activeFlags != ACTIVE_FLAG_DEACTIVATED && obj->OBJECT_FIELD_S32(fieldIndex) == value) {
@ -238,6 +244,7 @@ struct Object *obj_get_next_with_same_behavior_id_and_field_s32(struct Object *o
} }
struct Object *obj_get_next_with_same_behavior_id_and_field_f32(struct Object *o, s32 fieldIndex, f32 value) { struct Object *obj_get_next_with_same_behavior_id_and_field_f32(struct Object *o, s32 fieldIndex, f32 value) {
if (fieldIndex < 0 || fieldIndex >= 0x50) { return NULL; }
if (o) { if (o) {
for (struct Object *obj = obj_get_next(o); obj != NULL; obj = obj_get_next(obj)) { for (struct Object *obj = obj_get_next(o); obj != NULL; obj = obj_get_next(obj)) {
if (obj->behavior == o->behavior && obj->activeFlags != ACTIVE_FLAG_DEACTIVATED && obj->OBJECT_FIELD_F32(fieldIndex) == value) { if (obj->behavior == o->behavior && obj->activeFlags != ACTIVE_FLAG_DEACTIVATED && obj->OBJECT_FIELD_F32(fieldIndex) == value) {
@ -401,6 +408,7 @@ void obj_move_xyz(struct Object *o, f32 dx, f32 dy, f32 dz) {
void set_whirlpools(f32 x, f32 y, f32 z, s16 strength, s16 area, s32 index) { void set_whirlpools(f32 x, f32 y, f32 z, s16 strength, s16 area, s32 index) {
static struct Whirlpool whirlpool; static struct Whirlpool whirlpool;
if (index < 0 || index >= 2) { return; }
gAreas[area].whirlpools[index] = &whirlpool; gAreas[area].whirlpools[index] = &whirlpool;
gAreas[area].whirlpools[index]->pos[0] = x; gAreas[area].whirlpools[index]->pos[0] = x;
@ -411,6 +419,7 @@ void set_whirlpools(f32 x, f32 y, f32 z, s16 strength, s16 area, s32 index) {
#ifdef DEVELOPMENT #ifdef DEVELOPMENT
void obj_randomize(struct Object* o) { void obj_randomize(struct Object* o) {
if (!o) { return; }
for (int i = 0; i < 80; i++) { for (int i = 0; i < 80; i++) {
if (rand() % 10 < 5) { if (rand() % 10 < 5) {
o->rawData.asU32[i] = rand() % 10; o->rawData.asU32[i] = rand() % 10;