mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2026-05-31 13:11:07 +00:00
More behavior changes/fixes
This commit is contained in:
parent
9f91ce3c0f
commit
ccf94a6cd7
5 changed files with 65 additions and 29 deletions
|
|
@ -25,7 +25,7 @@ static u8 boo_ignore_update(void) {
|
|||
|
||||
struct SyncObject* boo_sync_object_init(void) {
|
||||
// There's lots of different boos, all of the sync objects are initialized via this function
|
||||
// all of them use distance based syncing which works fine for boos
|
||||
// all of them use distance based syncing which works fine enough
|
||||
struct SyncObject *so = sync_object_init(o, 4000.0f);
|
||||
if (so == NULL) { return NULL; }
|
||||
so->ignore_if_true = boo_ignore_update;
|
||||
|
|
@ -43,6 +43,7 @@ struct SyncObject* boo_sync_object_init(void) {
|
|||
sync_object_init_field(o, o->oInteractType);
|
||||
sync_object_init_field(o, o->oOpacity);
|
||||
sync_object_init_field(o, o->oRoom);
|
||||
sync_object_init_field(o, o->globalPlayerIndex);
|
||||
return so;
|
||||
}
|
||||
|
||||
|
|
@ -350,17 +351,12 @@ static s32 boo_get_attack_status(void) {
|
|||
if (o->oInteractStatus & INT_STATUS_INTERACTED) {
|
||||
if ((o->oInteractStatus & INT_STATUS_WAS_ATTACKED) && !obj_has_attack_type(ATTACK_FROM_ABOVE)) {
|
||||
cur_obj_become_intangible();
|
||||
|
||||
o->oInteractStatus = 0;
|
||||
|
||||
cur_obj_play_sound_2(SOUND_OBJ_BOO_LAUGH_SHORT);
|
||||
|
||||
attackStatus = BOO_ATTACKED;
|
||||
} else {
|
||||
cur_obj_play_sound_2(SOUND_OBJ_BOO_BOUNCE_TOP);
|
||||
|
||||
o->oInteractStatus = 0;
|
||||
|
||||
attackStatus = BOO_BOUNCED_ON;
|
||||
}
|
||||
}
|
||||
|
|
@ -469,7 +465,17 @@ static void boo_act_1(void) {
|
|||
}
|
||||
|
||||
if (attackStatus == BOO_ATTACKED) {
|
||||
o->oAction = 3;
|
||||
if (o->oBehParams2ndByte == 0) {
|
||||
// for go on a ghost hunt, assign global player index to nearest player for dialog
|
||||
struct MarioState *marioState = nearest_mario_state_to_object(o);
|
||||
if (marioState && marioState->playerIndex == 0) { // only let local player assign global player index for himself
|
||||
o->globalPlayerIndex = network_global_index_from_local(marioState->playerIndex);
|
||||
}
|
||||
o->oAction = 3;
|
||||
network_send_object(o); // force send object
|
||||
} else {
|
||||
o->oAction = 3;
|
||||
}
|
||||
}
|
||||
|
||||
if (attackStatus == BOO_ATTACKED) {
|
||||
|
|
@ -507,13 +513,22 @@ static void boo_act_4(void) {
|
|||
dialogID = gBehaviorValues.dialogs.GhostHuntDialog;
|
||||
}
|
||||
|
||||
struct MarioState* marioState = nearest_mario_state_to_object(o);
|
||||
if (marioState) {
|
||||
if (marioState->playerIndex != 0 || cur_obj_update_dialog(&gMarioStates[0], 2, 2, dialogID, 0, boo_act_4_continue_dialog)) {
|
||||
if (o->globalPlayerIndex >= MAX_PLAYERS) o->globalPlayerIndex = 0;
|
||||
struct MarioState *marioState = &gMarioStates[network_local_index_from_global(o->globalPlayerIndex)];
|
||||
if (!is_player_active(marioState) || !marioState->visibleToEnemies) {
|
||||
// use player with the smallest global index instead
|
||||
struct NetworkPlayer *np = get_network_player_smallest_global();
|
||||
marioState = &gMarioStates[np->localIndex];
|
||||
o->globalPlayerIndex = np->globalIndex;
|
||||
network_send_object(o);
|
||||
}
|
||||
|
||||
if (is_player_active(marioState)) {
|
||||
if (marioState->playerIndex != 0 || cur_obj_update_dialog(marioState, 2, 2, dialogID, 0, boo_act_4_continue_dialog)) {
|
||||
create_sound_spawner(SOUND_OBJ_DYING_ENEMY1);
|
||||
obj_mark_for_deletion(o);
|
||||
|
||||
if (dialogID == (s32) gBehaviorValues.dialogs.GhostHuntAfterDialog) { // If the Big Boo should spawn, play the jingle
|
||||
if (dialogID == (s32)gBehaviorValues.dialogs.GhostHuntAfterDialog) { // If the Big Boo should spawn, play the jingle
|
||||
play_puzzle_jingle();
|
||||
}
|
||||
}
|
||||
|
|
@ -533,7 +548,7 @@ void bhv_boo_loop(void) {
|
|||
// only sync when Boo isn't in a death state
|
||||
if (o->oAction < 3 || o->oAction == 5) {
|
||||
if (!sync_object_is_initialized(o->oSyncID)) {
|
||||
struct SyncObject* so = boo_sync_object_init();
|
||||
struct SyncObject *so = boo_sync_object_init();
|
||||
if (so) { so->syncDeathEvent = FALSE; }
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -167,9 +167,12 @@ UNUSED static u8 eyerok_boss_act_show_intro_text_continue_dialog(void) {
|
|||
static void eyerok_boss_act_show_intro_text(void) {
|
||||
if (o->globalPlayerIndex >= MAX_PLAYERS) o->globalPlayerIndex = 0;
|
||||
struct MarioState *marioState = &gMarioStates[network_local_index_from_global(o->globalPlayerIndex)];
|
||||
if (!is_player_active(marioState)) {
|
||||
if (!is_player_active(marioState) || !marioState->visibleToEnemies) {
|
||||
// use player with the smallest global index instead
|
||||
marioState = &gMarioStates[get_network_player_smallest_global()->localIndex];
|
||||
struct NetworkPlayer *np = get_network_player_smallest_global();
|
||||
marioState = &gMarioStates[np->localIndex];
|
||||
o->globalPlayerIndex = np->globalIndex;
|
||||
network_send_object(o);
|
||||
}
|
||||
if (should_start_or_continue_dialog(marioState, o) && cur_obj_update_dialog_with_cutscene(marioState, 2, 0, CUTSCENE_DIALOG, gBehaviorValues.dialogs.EyerokIntroDialog, eyerok_boss_act_show_intro_text_continue_dialog)) {
|
||||
o->oAction = EYEROK_BOSS_ACT_FIGHT;
|
||||
|
|
@ -234,9 +237,12 @@ u8 eyerok_boss_act_die_continue_dialog(void) { return o->oAction == EYEROK_BOSS_
|
|||
static void eyerok_boss_act_die(void) {
|
||||
if (o->globalPlayerIndex >= MAX_PLAYERS) o->globalPlayerIndex = 0;
|
||||
struct MarioState *marioState = &gMarioStates[network_local_index_from_global(o->globalPlayerIndex)];
|
||||
if (!is_player_active(marioState)) {
|
||||
if (!is_player_active(marioState) || !marioState->visibleToEnemies) {
|
||||
// use player with the smallest global index instead
|
||||
marioState = &gMarioStates[get_network_player_smallest_global()->localIndex];
|
||||
struct NetworkPlayer *np = get_network_player_smallest_global();
|
||||
marioState = &gMarioStates[np->localIndex];
|
||||
o->globalPlayerIndex = np->globalIndex;
|
||||
network_send_object(o);
|
||||
}
|
||||
if (o->oTimer == 60) {
|
||||
if (should_start_or_continue_dialog(marioState, o) && cur_obj_update_dialog_with_cutscene(marioState, 2, 0, CUTSCENE_DIALOG, gBehaviorValues.dialogs.EyerokDefeatedDialog, eyerok_boss_act_die_continue_dialog)) {
|
||||
|
|
|
|||
|
|
@ -65,9 +65,12 @@ void king_bobomb_act_0(void) {
|
|||
} else {
|
||||
if (o->globalPlayerIndex >= MAX_PLAYERS) o->globalPlayerIndex = 0;
|
||||
struct MarioState *marioState = &gMarioStates[network_local_index_from_global(o->globalPlayerIndex)];
|
||||
if (!is_player_active(marioState)) {
|
||||
if (!is_player_active(marioState) || !marioState->visibleToEnemies) {
|
||||
// use player with the smallest global index instead
|
||||
marioState = &gMarioStates[get_network_player_smallest_global()->localIndex];
|
||||
struct NetworkPlayer *np = get_network_player_smallest_global();
|
||||
marioState = &gMarioStates[np->localIndex];
|
||||
o->globalPlayerIndex = np->globalIndex;
|
||||
network_send_object(o);
|
||||
}
|
||||
if (marioState && should_start_or_continue_dialog(marioState, o) && cur_obj_update_dialog_with_cutscene(marioState, 2, 1, CUTSCENE_DIALOG, gBehaviorValues.dialogs.KingBobombIntroDialog, king_bobomb_act_0_continue_dialog)) {
|
||||
o->oAction = 2;
|
||||
|
|
@ -243,7 +246,7 @@ void king_bobomb_act_7(void) {
|
|||
marioState = &gMarioStates[get_network_player_smallest_global()->localIndex];
|
||||
}
|
||||
// update dialog if we are within king bobomb's area
|
||||
bool canUpdateDialog = (marioState->pos[1] >= o->oPosY - 100.0f);
|
||||
bool canUpdateDialog = (marioState->pos[1] >= o->oPosY - 100.0f && marioState->visibleToEnemies);
|
||||
if (!canUpdateDialog) {
|
||||
// iterate through players via global index until we find someone who can
|
||||
for (int i = 0; i < MAX_PLAYERS; i++) {
|
||||
|
|
@ -252,7 +255,7 @@ void king_bobomb_act_7(void) {
|
|||
marioState = &gMarioStates[np->localIndex];
|
||||
|
||||
if (!is_player_active(marioState)) continue;
|
||||
canUpdateDialog = (marioState->pos[1] >= o->oPosY - 100.0f);
|
||||
canUpdateDialog = (marioState->pos[1] >= o->oPosY - 100.0f && marioState->visibleToEnemies);
|
||||
if (!canUpdateDialog) continue;
|
||||
break;
|
||||
}
|
||||
|
|
@ -376,9 +379,12 @@ void king_bobomb_act_5(void) { // bobomb returns home
|
|||
case 4:
|
||||
if (o->globalPlayerIndex >= MAX_PLAYERS) o->globalPlayerIndex = 0;
|
||||
marioState = &gMarioStates[network_local_index_from_global(o->globalPlayerIndex)];
|
||||
if (!is_player_active(marioState)) {
|
||||
if (!is_player_active(marioState) || !marioState->visibleToEnemies) {
|
||||
// use player with the smallest global index instead
|
||||
marioState = &gMarioStates[get_network_player_smallest_global()->localIndex];
|
||||
struct NetworkPlayer *np = get_network_player_smallest_global();
|
||||
marioState = &gMarioStates[np->localIndex];
|
||||
o->globalPlayerIndex = np->globalIndex;
|
||||
network_send_object(o);
|
||||
}
|
||||
if (marioState && should_start_or_continue_dialog(marioState, o) && cur_obj_update_dialog_with_cutscene(marioState, 2, 1, CUTSCENE_DIALOG, gBehaviorValues.dialogs.KingBobombCheatDialog, king_bobomb_act_5_continue_dialog)) {
|
||||
o->oAction = 2;
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ static void racing_penguin_act_show_init_text(void) {
|
|||
if (!is_player_active(marioState) || !marioState->visibleToEnemies) {
|
||||
// use player with the smallest global index instead
|
||||
struct NetworkPlayer *np = get_network_player_smallest_global();
|
||||
marioState = &gMarioStates[get_network_player_smallest_global()->localIndex];
|
||||
marioState = &gMarioStates[np->localIndex];
|
||||
o->globalPlayerIndex = np->globalIndex;
|
||||
|
||||
// double check that we are actually active and visible this time
|
||||
|
|
|
|||
|
|
@ -17,9 +17,12 @@ static void bhv_snowmans_bottom_override_ownership(u8 *shouldOverride, u8 *shoul
|
|||
*shouldOverride = TRUE;
|
||||
if (o->globalPlayerIndex >= MAX_PLAYERS) o->globalPlayerIndex = 0;
|
||||
struct MarioState *marioState = &gMarioStates[network_local_index_from_global(o->globalPlayerIndex)];
|
||||
if (!is_player_active(marioState)) {
|
||||
if (!is_player_active(marioState) || !marioState->visibleToEnemies) {
|
||||
// use player with the smallest global index instead
|
||||
marioState = &gMarioStates[get_network_player_smallest_global()->localIndex];
|
||||
struct NetworkPlayer *np = get_network_player_smallest_global();
|
||||
marioState = &gMarioStates[np->localIndex];
|
||||
o->globalPlayerIndex = np->globalIndex;
|
||||
network_send_object(o);
|
||||
}
|
||||
*shouldOwn = marioState->playerIndex == 0;
|
||||
}
|
||||
|
|
@ -77,9 +80,12 @@ void adjust_rolling_face_pitch(f32 f12) {
|
|||
void snowmans_bottom_act_1(void) {
|
||||
if (o->globalPlayerIndex >= MAX_PLAYERS) o->globalPlayerIndex = 0;
|
||||
struct MarioState *marioState = &gMarioStates[network_local_index_from_global(o->globalPlayerIndex)];
|
||||
if (!is_player_active(marioState)) {
|
||||
if (!is_player_active(marioState) || !marioState->visibleToEnemies) {
|
||||
// use player with the smallest global index instead
|
||||
marioState = &gMarioStates[get_network_player_smallest_global()->localIndex];
|
||||
struct NetworkPlayer *np = get_network_player_smallest_global();
|
||||
marioState = &gMarioStates[np->localIndex];
|
||||
o->globalPlayerIndex = np->globalIndex;
|
||||
network_send_object(o);
|
||||
}
|
||||
struct Object *player = marioState->visibleToEnemies ? marioState->marioObj : NULL;
|
||||
s32 angleToPlayer = player ? obj_angle_to_object(o, player) : 0;
|
||||
|
|
@ -161,9 +167,12 @@ static void bhv_snowmans_bottom_handle_dialog() {
|
|||
} else {
|
||||
if (o->globalPlayerIndex >= MAX_PLAYERS) o->globalPlayerIndex = 0;
|
||||
struct MarioState *marioState = &gMarioStates[network_local_index_from_global(o->globalPlayerIndex)];
|
||||
if (!is_player_active(marioState)) {
|
||||
if (!is_player_active(marioState) || !marioState->visibleToEnemies) {
|
||||
// use player with the smallest global index instead
|
||||
marioState = &gMarioStates[get_network_player_smallest_global()->localIndex];
|
||||
struct NetworkPlayer *np = get_network_player_smallest_global();
|
||||
marioState = &gMarioStates[np->localIndex];
|
||||
o->globalPlayerIndex = np->globalIndex;
|
||||
network_send_object(o);
|
||||
}
|
||||
if (marioState->playerIndex == 0 && should_start_or_continue_dialog(marioState, o) && (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 400) == 1) && set_mario_npc_dialog(marioState, 1, bhv_snowmans_bottom_loop_continue_dialog) && cutscene_object_with_dialog(CUTSCENE_DIALOG, o, gBehaviorValues.dialogs.SnowmanHeadBodyDialog)) {
|
||||
o->oForwardVel = 10.0f;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue