From 830922541296d049cd5c0689c1f610586f56bc75 Mon Sep 17 00:00:00 2001 From: MegaMech Date: Sat, 28 Dec 2024 00:25:41 -0700 Subject: Reimpl Lakitu --- src/engine/objects/Lakitu.cpp | 856 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 856 insertions(+) create mode 100644 src/engine/objects/Lakitu.cpp (limited to 'src/engine/objects/Lakitu.cpp') diff --git a/src/engine/objects/Lakitu.cpp b/src/engine/objects/Lakitu.cpp new file mode 100644 index 000000000..1c8547bc8 --- /dev/null +++ b/src/engine/objects/Lakitu.cpp @@ -0,0 +1,856 @@ +#include +#include +#include "Lakitu.h" +#include + +#include "port/Game.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "actors.h" +#include "math_util.h" +#include "sounds.h" +#include "update_objects.h" +#include "render_player.h" +#include "external.h" +#include "bomb_kart.h" +#include "collision.h" +#include "code_80086E70.h" +#include "render_objects.h" +#include "code_80057C60.h" +#include "defines.h" +#include "code_80005FD0.h" +#include "math_util_2.h" +#include "collision.h" +#include "assets/bowsers_castle_data.h" +#include "ceremony_and_credits.h" +#include "objects.h" +#include "update_objects.h" +#include "render_objects.h" +#include "course_offsets.h" +#include "data/some_data.h" +#include "race_logic.h" +#include "effects.h" +#include "memory.h" +extern s8 gPlayerCount; +} + +OLakitu::OLakitu(s32 playerId, LakituType type) { + _playerId = playerId; + + init_object(gIndexLakituList[playerId], (s32)type); +} + +void OLakitu::Activate(LakituType type) { + init_object(gIndexLakituList[_playerId], (s32)type); +} + +void OLakitu::Tick() { + OLakitu::func_8007AA44(_playerId); +} + +void OLakitu::Tick60fps() { // update_object_lakitu + s32 playerId = _playerId; + s32 objectIndex = gIndexLakituList[playerId]; + + switch (gObjectList[objectIndex].unk_0D8) { + case 0: + break; + case 1: + OLakitu::update_object_lakitu_starter(objectIndex, playerId); + func_8008BFFC(objectIndex); + break; + case 2: + OLakitu::update_object_lakitu_checkered_flag(objectIndex, playerId); + func_8008BFFC(objectIndex); + break; + case 3: + OLakitu::update_object_lakitu_fishing(objectIndex, playerId); + break; + case 4: + OLakitu::update_object_lakitu_second_lap(objectIndex, playerId); + func_8008BFFC(objectIndex); + break; + case 5: + OLakitu::update_object_lakitu_final_lap(objectIndex, playerId); + func_8008BFFC(objectIndex); + break; + case 6: + OLakitu::update_object_lakitu_reverse(objectIndex, playerId); + func_8008BFFC(objectIndex); + break; + case 7: + OLakitu::update_object_lakitu_fishing2(objectIndex, playerId); + break; + } +} + +void OLakitu::Draw(s32 cameraId) { + UNUSED s32 stackPadding; + Camera* camera; + f32 var_f0; + f32 var_f2; + s32 objectIndex; + Object* object; + + objectIndex = gIndexLakituList[cameraId]; + camera = &camera1[cameraId]; + if (is_obj_flag_status_active(objectIndex, 0x00000010) != 0) { + object = &gObjectList[objectIndex]; + object->orientation[0] = 0; + object->orientation[1] = func_800418AC(object->pos[0], object->pos[2], camera->pos); + object->orientation[2] = 0x8000; + if (func_80072354(objectIndex, 2) != 0) { + draw_2d_texture_at(object->pos, object->orientation, object->sizeScaling, (u8*) object->activeTLUT, + (u8*)object->activeTexture, object->vertex, (s32) object->textureWidth, + (s32) object->textureHeight, (s32) object->textureWidth, + (s32) object->textureHeight / 2); + } else { + func_800485C4(object->pos, object->orientation, object->sizeScaling, (s32) object->primAlpha, + (u8*) object->activeTLUT, (u8*)object->activeTexture, object->vertex, (s32) object->textureWidth, + (s32) object->textureHeight, (s32) object->textureWidth, (s32) object->textureHeight / 2); + } + if (gScreenModeSelection == SCREEN_MODE_1P) { + var_f0 = object->pos[0] - camera->pos[0]; + var_f2 = object->pos[2] - camera->pos[2]; + if (var_f0 < 0.0f) { + var_f0 = -var_f0; + } + if (var_f2 < 0.0f) { + var_f2 = -var_f2; + } + if ((var_f0 + var_f2) <= 200.0) { + func_8004A630(&D_8018C0B0[cameraId], object->pos, 0.35f); + } + } + } +} + +void OLakitu::func_80079114(s32 objectIndex, s32 playerId, s32 arg2) { + s32 a; + if (gObjectList[objectIndex].state >= 2) { + if ((u8) gObjectList[objectIndex].unk_0D8 == 1) { + if (playerId == 0) { + func_80074894(objectIndex, gLakituTexturePtr); + return; + } + a = gIndexLakituList[0]; + gObjectList[objectIndex].activeTLUT = gObjectList[a].activeTLUT; + gObjectList[objectIndex].activeTexture = gObjectList[a].activeTexture; + if (0) {} + return; + } + switch (arg2) { + case 0: + func_800748F4(objectIndex, gLakituTexturePtr); + break; + case 1: + func_800748C4(objectIndex, gLakituTexturePtr); + break; + case 2: + func_80074894(objectIndex, gLakituTexturePtr); + break; + } + } +} + +void OLakitu::func_800791F0(s32 objectIndex, s32 playerId) { + Player* player = &gPlayerOne[playerId]; + + if ((gObjectList[objectIndex].unk_0D8 != 3) && (gObjectList[objectIndex].unk_0D8 != 7)) { + func_800722CC(objectIndex, 1); + if (CourseManager_GetProps()->LakituTowType == LakituTowType::ICE) { + player->unk_0CA &= 0xFFEF; + } + } + + if (CourseManager_GetProps()->LakituTowType == LakituTowType::ICE) { + func_800722CC(objectIndex, 0x00000010); + player->unk_0CA &= 0xFFDF; + } + func_800C9018(playerId, SOUND_ARG_LOAD(0x01, 0x00, 0xFA, 0x28)); +} + +static const char* sLakituTextures[] = { + gTextureLakituNoLights1, gTextureLakituNoLights2, gTextureLakituNoLights3, gTextureLakituNoLights4, + gTextureLakituNoLights5, gTextureLakituNoLights6, gTextureLakituNoLights7, gTextureLakituNoLights8, + gTextureLakituRedLights01, gTextureLakituRedLights02, gTextureLakituRedLights03, gTextureLakituRedLights04, + gTextureLakituRedLights05, gTextureLakituRedLights06, gTextureLakituRedLights07, gTextureLakituRedLights08, + gTextureLakituRedLights09, gTextureLakituRedLights10, gTextureLakituRedLights11, gTextureLakituRedLights12, + gTextureLakituRedLights13, gTextureLakituRedLights14, gTextureLakituRedLights15, gTextureLakituRedLights16, + gTextureLakituBlueLight1, gTextureLakituBlueLight2, gTextureLakituBlueLight3, gTextureLakituBlueLight4, + gTextureLakituBlueLight5, gTextureLakituBlueLight6, gTextureLakituBlueLight7, gTextureLakituBlueLight8, +}; + +void OLakitu::init_obj_lakitu_starter_and_checkered_flag(s32 objectIndex, s32 playerId) { + if (playerId == 0) { + D_801656F0 = 0; + D_8018D168 = 0; + } + + // u8 *tlut = (u8 *) LOAD_ASSET_RAW(common_tlut_lakitu_countdown); + // u8 *lights = (u8 *) LOAD_ASSET_RAW(gTextureLakituNoLights1); + + init_texture_object( + objectIndex, + (u8*) load_lakitu_tlut_x64(common_tlut_lakitu_countdown, ARRAY_COUNT(common_tlut_lakitu_countdown)), + sLakituTextures, 56, (u16) 72); + Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_lakitu); + gObjectList[objectIndex].vertex = vtx; + gObjectList[objectIndex].sizeScaling = 0.15f; + clear_object_flag(objectIndex, 0x00000010); + object_next_state(objectIndex); + gObjectList[objectIndex].unk_048 = D_8018D180; +} + +void OLakitu::update_object_lakitu_starter(s32 objectIndex, s32 arg1) { + UNUSED s32 pad; + switch (gObjectList[objectIndex].state) { + case 0: + break; + case 1: + OLakitu::init_obj_lakitu_starter_and_checkered_flag(objectIndex, arg1); + break; + case 2: + set_and_run_timer_object(objectIndex, gObjectList[objectIndex].unk_048); + if ((gObjectList[objectIndex].timer == 0x00000055) && (gPlayerCount == 3) && (arg1 == 0)) { + D_8018D168 = 1; + } + break; + case 3: + set_object_flag(objectIndex, 0x00000010); + func_80086F10(objectIndex, 1, &D_800E67B8); // set a spline + object_next_state(objectIndex); + break; + case 4: + if ((set_and_run_timer_object(objectIndex, 0x0000001E) != false) && (gPlayerCount != 3) && (arg1 == 0)) { + D_8018D168 = 1; + } + break; + case 5: + set_and_run_timer_object(objectIndex, 0x0000001E); + break; + case 6: + func_80072E54(objectIndex, 1, 7, 1, 2, 0); + break; + case 7: + if (set_and_run_timer_object(objectIndex, 0x00000014) != 0) { + gObjectList[objectIndex].tlutList += 0x200; + if (arg1 == 0) { + play_sound2(SOUND_ACTION_COUNTDOWN_LIGHT); + } + } + break; + case 8: + func_80072E54(objectIndex, 8, 0x0000000F, 1, 6, 0); + break; + case 9: + if ((set_and_run_timer_object(objectIndex, 8) != 0) && (arg1 == 0)) { + play_sound2(SOUND_ACTION_COUNTDOWN_LIGHT); + } + break; + case 10: + if ((func_80072E54(objectIndex, 0x00000010, 0x00000017, 1, 6, 0) != 0) && (arg1 == 0)) { + D_801656F0 = 1; + } + break; + case 11: + if (set_and_run_timer_object(objectIndex, 8) != 0) { + gObjectList[objectIndex].tlutList += 0x200; + if (arg1 == 0) { + play_sound2(SOUND_ACTION_GREEN_LIGHT); + } + } + break; + case 12: + func_80072E54(objectIndex, 0x00000018, 0x0000001B, 1, 6, 0); + break; + case 13: + if (arg1 == 0) { + OLakitu::func_800729EC(objectIndex); + D_8018D160 = 1; + break; + } + object_next_state(objectIndex); + break; + case 14: + set_and_run_timer_object(objectIndex, 0x00000078); + break; + case 15: + func_80072428(objectIndex); + break; + } +} + +void OLakitu::func_800729EC(s32 objectIndex) { + u32 temp_v1 = 1; + s32 i; + + start_race(); + object_next_state(objectIndex); + D_8018D2BC = 1; + D_8018D2A4 = 1; + + if (GetCourse() != GetYoshiValley()) { + for (i = 0; i < gPlayerCount; i++) { + playerHUD[i].unk_81 = temp_v1; + } + } + func_8005AB20(); +} + +static const char* sLakituCheckeredList[] = { + gTextureLakituCheckeredFlag01, gTextureLakituCheckeredFlag02, gTextureLakituCheckeredFlag03, + gTextureLakituCheckeredFlag04, gTextureLakituCheckeredFlag05, gTextureLakituCheckeredFlag06, + gTextureLakituCheckeredFlag07, gTextureLakituCheckeredFlag08, gTextureLakituCheckeredFlag09, + gTextureLakituCheckeredFlag10, gTextureLakituCheckeredFlag11, gTextureLakituCheckeredFlag12, + gTextureLakituCheckeredFlag13, gTextureLakituCheckeredFlag14, gTextureLakituCheckeredFlag15, + gTextureLakituCheckeredFlag16, gTextureLakituCheckeredFlag17, gTextureLakituCheckeredFlag18, + gTextureLakituCheckeredFlag19, gTextureLakituCheckeredFlag20, gTextureLakituCheckeredFlag21, + gTextureLakituCheckeredFlag22, gTextureLakituCheckeredFlag23, gTextureLakituCheckeredFlag24, + gTextureLakituCheckeredFlag25, gTextureLakituCheckeredFlag26, gTextureLakituCheckeredFlag27, + gTextureLakituCheckeredFlag28, gTextureLakituCheckeredFlag29, gTextureLakituCheckeredFlag30, + gTextureLakituCheckeredFlag31, gTextureLakituCheckeredFlag32 +}; + +void OLakitu::init_obj_lakitu_checkered_flag(s32 objectIndex, s32 playerIndex) { + Object* object; + + OLakitu::func_800791F0(objectIndex, playerIndex); + + u8* tex = (u8*) LOAD_ASSET_RAW(common_tlut_lakitu_checkered_flag); + Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_also_lakitu); + + init_texture_object(objectIndex, (u8*) tex, sLakituCheckeredList, 0x48U, (u16) 0x00000038); + object = &gObjectList[objectIndex]; + object->activeTexture = *gObjectList[objectIndex].textureList; + object->vertex = vtx; + object->pos[2] = 5000.0f; + object->pos[1] = 5000.0f; + object->pos[0] = 5000.0f; + object->sizeScaling = 0.15f; + func_80086F10(objectIndex, 2, &D_800E6834); + clear_object_flag(objectIndex, 0x00000010); + object_next_state(objectIndex); +} + +void OLakitu::update_object_lakitu_checkered_flag(s32 objectIndex, s32 playerIndex) { + switch (gObjectList[objectIndex].state) { + case 0: + break; + case 1: + OLakitu::init_obj_lakitu_checkered_flag(objectIndex, playerIndex); + break; + case 2: + set_object_flag(objectIndex, 0x00000010); + object_next_state(objectIndex); + break; + case 3: + func_80072E54(objectIndex, 0, 0x0000001F, 1, 2, -1); + break; + case 4: + func_80072428(objectIndex); + break; + } +} + +void OLakitu::func_800797AC(s32 playerId) { + s32 objectIndex; + Player* player; + + objectIndex = gIndexLakituList[playerId]; + player = &gPlayerOne[playerId]; + //if ((GetCourse() == GetSherbetLand()) && (player->unk_0CA & 1)) { + if ((CourseManager_GetProps()->LakituTowType == LakituTowType::ICE) && (player->unk_0CA & 1)) { + init_object(objectIndex, 7); + player->unk_0CA |= 0x10; + } else { + init_object(objectIndex, 3); + } + func_800722A4(objectIndex, 1); +} + +void OLakitu::func_80079860(s32 playerId) { + s32 objectIndex; + Player* player; + + objectIndex = gIndexLakituList[playerId]; + player = &gPlayerOne[playerId]; + if ((func_80072354(objectIndex, 1) != 0) && + (((func_802ABDF4(player->collision.meshIndexZX) != 0) && (player->collision.surfaceDistance[2] <= 3.0f)) || + (player->unk_0CA & 1) || ((player->surfaceType == OUT_OF_BOUNDS) && !(player->effects & 8)))) { + func_80090778(player); + OLakitu::func_800797AC(playerId); + } +} + +void OLakitu::func_8007993C(s32 objectIndex, Player* player) { + if (player->unk_0CA & 4) { + func_800722A4(objectIndex, 2); + gObjectList[objectIndex].primAlpha = player->unk_0C6; + return; + } + func_800722CC(objectIndex, 2); +} + +static const char* sLakituFishingTextures[] = { gTextureLakituFishing1, gTextureLakituFishing2, gTextureLakituFishing3, + gTextureLakituFishing4 }; + +void OLakitu::init_obj_lakitu_red_flag_fishing(s32 objectIndex, s32 arg1) { + + u8* tlut = (u8*) LOAD_ASSET_RAW(common_tlut_lakitu_fishing); + Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(D_0D005F30); + + OLakitu::func_800791F0(objectIndex, arg1); + init_texture_object(objectIndex, tlut, sLakituFishingTextures, 0x38U, (u16) 0x00000048); + gObjectList[objectIndex].vertex = vtx; + gObjectList[objectIndex].sizeScaling = 0.15f; + func_80086E70(objectIndex); + clear_object_flag(objectIndex, 0x00000010); + func_80073720(objectIndex); + object_next_state(objectIndex); + func_800C8F80((u8) arg1, 0x0100FA28); +} + +void OLakitu::func_80079A5C(s32 objectIndex, UNUSED Player* player) { + switch (gObjectList[objectIndex].unk_0AE) { + case 0: + break; + case 1: + gObjectList[objectIndex].origin_pos[2] = 0.0f; + gObjectList[objectIndex].origin_pos[1] = 0.0f; + gObjectList[objectIndex].origin_pos[0] = 0.0f; + gObjectList[objectIndex].offset[2] = 0.0f; + gObjectList[objectIndex].offset[0] = 0.0f; + gObjectList[objectIndex].offset[1] = 80.0f; + func_80086FD4(objectIndex); + break; + case 2: + if (f32_step_down_towards(&gObjectList[objectIndex].offset[1], 5.0f, 1.0f) != 0) { + func_80086F60(objectIndex); + } + break; + case 3: + if (f32_step_up_towards(&gObjectList[objectIndex].offset[1], 100.0f, 1.0f) != 0) { + func_80086F60(objectIndex); + } + break; + } +} + +void OLakitu::update_object_lakitu_fishing(s32 objectIndex, s32 playerId) { + Player* player = &gPlayerOne[playerId]; + + switch (gObjectList[objectIndex].state) { /* switch 1; irregular */ + case 0: /* switch 1 */ + break; + case 1: /* switch 1 */ + OLakitu::init_obj_lakitu_red_flag_fishing(objectIndex, playerId); + break; + case 2: /* switch 1 */ + set_object_flag(objectIndex, 0x00000010); + func_800736E0(objectIndex); + object_next_state(objectIndex); + break; + case 3: /* switch 1 */ + func_800730BC(objectIndex, 0, 3, 1, 2, -1); + break; + } + switch (gObjectList[objectIndex].unk_0D6) { + case 0: + break; + case 1: + if (func_80086FA4(objectIndex) != 0) { + func_80073654(objectIndex); + } + break; + case 2: + func_80090868(player); + func_80073654(objectIndex); + break; + case 3: + if (!(player->unk_0CA & 2)) { + func_80086EAC(objectIndex, 0, 3); + func_80073654(objectIndex); + } + break; + case 4: + if (func_80086FA4(objectIndex) != 0) { + func_80073654(objectIndex); + } + break; + case 5: + func_800722CC(objectIndex, 1); + func_800C9018((u8) playerId, SOUND_ARG_LOAD(0x01, 0x00, 0xFA, 0x28)); + func_80072428(objectIndex); + func_80073720(objectIndex); + break; + } + if (gObjectList[objectIndex].state >= 2) { + OLakitu::func_8007993C(objectIndex, player); + } + OLakitu::func_80079A5C(objectIndex, player); +} + +void OLakitu::update_object_lakitu_fishing2(s32 objectIndex, s32 playerId) { + Player* player = &gPlayerOne[playerId]; + + switch (gObjectList[objectIndex].state) { /* switch 1; irregular */ + case 0: /* switch 1 */ + break; + case 1: /* switch 1 */ + OLakitu::init_obj_lakitu_red_flag_fishing(objectIndex, playerId); + break; + case 2: /* switch 1 */ + set_object_flag(objectIndex, 0x00000010); + func_800736E0(objectIndex); + player->unk_0CA |= 0x80; + object_next_state(objectIndex); + break; + case 3: /* switch 1 */ + func_800730BC(objectIndex, 0, 3, 1, 2, -1); + break; + } + switch (gObjectList[objectIndex].unk_0D6) { + case 1: + if (func_80086FA4(objectIndex) != 0) { + func_800C9060((u8) playerId, 0x1900A055U); + func_80073654(objectIndex); + } + break; + case 2: + func_80090868(player); + func_800722A4(objectIndex, 4); + func_80073654(objectIndex); + break; + case 3: + if ((player->surfaceType == ICE) && !(player->unk_0CA & 1) && + ((f64) player->collision.surfaceDistance[2] <= 30.0)) { + func_800722A4(objectIndex, 8); + } + if (!(player->unk_0CA & 2)) { + func_80086EAC(objectIndex, 0, 3); + func_80073654(objectIndex); + } + break; + case 4: + func_8007375C(objectIndex, 0x0000001E); + break; + case 5: + player->unk_0CA &= 0xFF7F; + func_800722A4(objectIndex, 0x00000010); + func_800722A4(objectIndex, 0x00000020); + func_800722CC(objectIndex, 4); + func_800722CC(objectIndex, 8); + func_80073654(objectIndex); + func_800C9060((u8) playerId, 0x1900A056U); + break; + case 6: + if (func_8007375C(objectIndex, 0x000000A0) != 0) { + func_800722CC(objectIndex, 0x00000010); + player->unk_0CA &= 0xFFEF; + player->unk_0CA |= 0x20; + } + break; + case 7: + func_8007375C(objectIndex, 0x0000003C); + break; + case 8: + func_80073720(objectIndex); + func_80072428(objectIndex); + player->unk_0CA &= 0xFFDF; + func_800722CC(objectIndex, 1); + func_800C9018((u8) playerId, SOUND_ARG_LOAD(0x01, 0x00, 0xFA, 0x28)); + break; + } + + if (gObjectList[objectIndex].state >= 2) { + OLakitu::func_8007993C(objectIndex, player); + } + OLakitu::func_80079A5C(objectIndex, player); +} + +static const char* sLakituSecondLapTextures[] = { + gTextureLakituSecondLap01, gTextureLakituSecondLap02, gTextureLakituSecondLap03, gTextureLakituSecondLap04, + gTextureLakituSecondLap05, gTextureLakituSecondLap06, gTextureLakituSecondLap07, gTextureLakituSecondLap08, + gTextureLakituSecondLap09, gTextureLakituSecondLap10, gTextureLakituSecondLap11, gTextureLakituSecondLap12, + gTextureLakituSecondLap13, gTextureLakituSecondLap14, gTextureLakituSecondLap15, gTextureLakituSecondLap16 +}; + +void OLakitu::func_8007A060(s32 objectIndex, s32 playerIndex) { + Object* object; + + OLakitu::func_800791F0(objectIndex, playerIndex); + + u8* tlut = (u8*) LOAD_ASSET_RAW(common_tlut_lakitu_second_lap); + Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_also_lakitu); + + init_texture_object(objectIndex, tlut, sLakituSecondLapTextures, 0x48U, (u16) 0x00000038); + object = &gObjectList[objectIndex]; + object->activeTexture = *gObjectList[objectIndex].textureList; + object->vertex = vtx; + object->pos[2] = 5000.0f; + object->pos[1] = 5000.0f; + object->pos[0] = 5000.0f; + object->sizeScaling = 0.15f; + clear_object_flag(objectIndex, 0x00000010); + func_80086F10(objectIndex, 5, &D_800E694C); + object_next_state(objectIndex); +} + +void OLakitu::update_object_lakitu_second_lap(s32 objectIndex, s32 playerIndex) { + switch (gObjectList[objectIndex].state) { + case 0: + break; + case 1: + OLakitu::func_8007A060(objectIndex, playerIndex); + break; + case 2: + set_object_flag(objectIndex, 0x00000010); + object_next_state(objectIndex); + break; + case 3: + set_and_run_timer_object(objectIndex, 0x00000014); + break; + case 4: + func_80072E54(objectIndex, 0, 0x0000000F, 1, 2, 1); + break; + case 5: + set_and_run_timer_object(objectIndex, 0x0000003C); + break; + case 6: + func_80072F88(objectIndex, 0x0000000F, 0, 1, 2, 1); + break; + case 7: + if (gObjectList[objectIndex].unk_0AE == 0) { + func_80072428(objectIndex); + } + break; + } +} + +static const char* sLakituFinalLapTextures[] = { + gTextureLakituFinalLap01, gTextureLakituFinalLap02, gTextureLakituFinalLap03, gTextureLakituFinalLap04, + gTextureLakituFinalLap05, gTextureLakituFinalLap06, gTextureLakituFinalLap07, gTextureLakituFinalLap08, + gTextureLakituFinalLap09, gTextureLakituFinalLap10, gTextureLakituFinalLap11, gTextureLakituFinalLap12, + gTextureLakituFinalLap13, gTextureLakituFinalLap14, gTextureLakituFinalLap15, gTextureLakituFinalLap16, +}; + +void OLakitu::func_8007A228(s32 objectIndex, s32 playerIndex) { + Object* object; + + OLakitu::func_800791F0(objectIndex, playerIndex); + + u8* tlut = (u8*) LOAD_ASSET_RAW(common_tlut_lakitu_final_lap); + Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_also_lakitu); + + init_texture_object(objectIndex, tlut, sLakituFinalLapTextures, 0x48U, (u16) 0x00000038); + object = &gObjectList[objectIndex]; + object->activeTexture = *gObjectList[objectIndex].textureList; + object->vertex = vtx; + object->pos[2] = 5000.0f; + object->pos[1] = 5000.0f; + object->pos[0] = 5000.0f; + object->sizeScaling = 0.15f; + clear_object_flag(objectIndex, 0x00000010); + func_80086F10(objectIndex, 5, &D_800E694C); + object_next_state(objectIndex); +} + +void OLakitu::update_object_lakitu_final_lap(s32 objectIndex, s32 playerIndex) { + switch (gObjectList[objectIndex].state) { + case 0: + break; + case 1: + OLakitu::func_8007A228(objectIndex, playerIndex); + break; + case 2: + set_object_flag(objectIndex, 0x00000010); + object_next_state(objectIndex); + break; + case 3: + set_and_run_timer_object(objectIndex, 0x00000014); + break; + case 4: + func_80072E54(objectIndex, 0, 0x0000000F, 1, 2, 1); + break; + case 5: + set_and_run_timer_object(objectIndex, 0x0000003C); + break; + case 6: + func_80072F88(objectIndex, 0x0000000F, 0, 1, 2, 1); + break; + case 7: + if (gObjectList[objectIndex].unk_0AE == 0) { + func_80072428(objectIndex); + } + break; + } +} + +static const char* sLakituReverseTextures[] = { + gTextureLakituReverse01, gTextureLakituReverse02, gTextureLakituReverse03, gTextureLakituReverse04, + gTextureLakituReverse05, gTextureLakituReverse06, gTextureLakituReverse07, gTextureLakituReverse08, + gTextureLakituReverse09, gTextureLakituReverse10, gTextureLakituReverse11, gTextureLakituReverse12, + gTextureLakituReverse13, gTextureLakituReverse14, gTextureLakituReverse15, gTextureLakituReverse16 +}; + +void OLakitu::func_8007A3F0(s32 objectIndex, s32 arg1) { + f32 var = 5000.0f; + OLakitu::func_800791F0(objectIndex, arg1); + + u8* tlut = (u8*) LOAD_ASSET_RAW(common_tlut_lakitu_reverse); + Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_also_lakitu); + + init_texture_object(objectIndex, tlut, sLakituReverseTextures, 72, (u16) 56); + gObjectList[objectIndex].activeTexture = *gObjectList[objectIndex].textureList; + gObjectList[objectIndex].vertex = vtx; + gObjectList[objectIndex].pos[2] = var; + gObjectList[objectIndex].pos[1] = var; + gObjectList[objectIndex].pos[0] = var; + gObjectList[objectIndex].sizeScaling = 0.15f; + clear_object_flag(objectIndex, 0x00000010); + func_80086F10(objectIndex, 6, &D_800E69B0); + gObjectList[objectIndex].unk_0D6 = 0; + object_next_state(objectIndex); + func_800C8F80((u8) arg1, 0x0100FA28); +} + +void OLakitu::update_object_lakitu_reverse(s32 objectIndex, s32 playerId) { + Player* sp2C = &gPlayerOne[playerId]; + + switch (gObjectList[objectIndex].state) { + case 0: + break; + case 1: + OLakitu::func_8007A3F0(objectIndex, playerId); + break; + case 2: + set_object_flag(objectIndex, 0x00000010); + gObjectList[objectIndex].unk_0D6 = 1; + object_next_state(objectIndex); + break; + case 3: + func_800730BC(objectIndex, 0, 0x0000000F, 1, 2, -1); + break; + case 4: + func_80072428(objectIndex); + break; + } + switch (gObjectList[objectIndex].unk_0D6) { + case 1: + if ((gObjectList[objectIndex].state >= 3) && (!(sp2C->effects & 0x400000))) { + func_80086F10(objectIndex, 6, &D_800E69F4); + gObjectList[objectIndex].unk_0D6 = 2; + gObjectList[objectIndex].unk_04C = 0x00000050; + func_800C9018((u8) playerId, SOUND_ARG_LOAD(0x01, 0x00, 0xFA, 0x28)); + return; + } + return; + case 2: + gObjectList[objectIndex].unk_04C--; + if (gObjectList[objectIndex].unk_04C == 0) { + object_next_state(objectIndex); + gObjectList[objectIndex].unk_0D6 = 0; + } + break; + } +} + +void OLakitu::func_8007A66C(s32 objectIndex) { + Player* player = &gPlayers[_playerId]; + Camera* camera = &cameras[_playerId]; + u16 rot = 0x8000 - camera->rot[1]; + + gObjectList[objectIndex].pos[0] = + (player->pos[0] + + (coss(rot) * (gObjectList[objectIndex].origin_pos[0] + gObjectList[objectIndex].offset[0]))) - + (sins(rot) * (gObjectList[objectIndex].origin_pos[2] + gObjectList[objectIndex].offset[2])); + gObjectList[objectIndex].pos[1] = + player->unk_074 + gObjectList[objectIndex].origin_pos[1] + gObjectList[objectIndex].offset[1]; + gObjectList[objectIndex].pos[2] = + (player->pos[2] + + (sins(rot) * (gObjectList[objectIndex].origin_pos[0] + gObjectList[objectIndex].offset[0]))) + + (coss(rot) * (gObjectList[objectIndex].origin_pos[2] + gObjectList[objectIndex].offset[2])); +} + +void OLakitu::func_8007A778(s32 objectIndex) { + Player* player = &gPlayers[_playerId]; + Camera* camera = &cameras[_playerId]; + u16 rot = 0x8000 - camera->rot[1]; + + gObjectList[objectIndex].pos[0] = + (player->pos[0] + + (coss(rot) * (gObjectList[objectIndex].origin_pos[0] + gObjectList[objectIndex].offset[0]))) - + (sins(rot) * (gObjectList[objectIndex].origin_pos[2] + gObjectList[objectIndex].offset[2])); + gObjectList[objectIndex].pos[1] = + player->pos[1] + gObjectList[objectIndex].origin_pos[1] + gObjectList[objectIndex].offset[1]; + gObjectList[objectIndex].pos[2] = + (player->pos[2] + + (sins(rot) * (gObjectList[objectIndex].origin_pos[0] + gObjectList[objectIndex].offset[0]))) + + (coss(rot) * (gObjectList[objectIndex].origin_pos[2] + gObjectList[objectIndex].offset[2])); +} + +void OLakitu::func_8007A88C(s32 playerId) { + s32 objectIndex; + Player* player; + + objectIndex = gIndexLakituList[playerId]; + player = &gPlayerOne[playerId]; + + if ((gObjectList[objectIndex].state == 0) && (player->effects & 0x400000)) { + //func_800790E4(playerId); + init_object(gIndexLakituList[playerId], 6); + } +} + +void OLakitu::func_8007A910(s32 arg0) { + if (D_801657B4 == 0) { + OLakitu::func_8007A88C(arg0); + } + func_80079860(arg0); +} + +// animate lakitu? +void OLakitu::func_8007AA44(s32 playerId) { + s32 objectIndex; + + OLakitu::func_8007A910(playerId); + objectIndex = gIndexLakituList[playerId]; + gLakituTexturePtr = (const char**)&gLakituTextureBuffer[playerId]; + switch (gObjectList[objectIndex].unk_0D8) { + case 1: + OLakitu::func_80079114(objectIndex, playerId, 2); + OLakitu::func_8007A66C(objectIndex); + break; + case 2: + OLakitu::func_80079114(objectIndex, playerId, 0); + OLakitu::func_8007A66C(objectIndex); + break; + case 3: + OLakitu::func_80079114(objectIndex, playerId, 0); + OLakitu::func_8007A778(objectIndex); + break; + case 4: + OLakitu::func_80079114(objectIndex, playerId, 0); + OLakitu::func_8007A66C(objectIndex); + break; + case 5: + OLakitu::func_80079114(objectIndex, playerId, 0); + OLakitu::func_8007A66C(objectIndex); + break; + case 6: + OLakitu::func_80079114(objectIndex, playerId, 0); + OLakitu::func_8007A66C(objectIndex); + break; + case 7: + OLakitu::func_80079114(objectIndex, playerId, 0); + OLakitu::func_8007A778(objectIndex); + break; + case 0: + default: + break; + } +} + -- cgit v1.2.3