diff --git a/src/engine/courses/LuigiRaceway.cpp b/src/engine/courses/LuigiRaceway.cpp index 7740ebf49..6020b72d1 100644 --- a/src/engine/courses/LuigiRaceway.cpp +++ b/src/engine/courses/LuigiRaceway.cpp @@ -7,6 +7,7 @@ #include "World.h" #include "engine/objects/BombKart.h" #include "assets/luigi_raceway_data.h" +#include "engine/objects/HotAirBalloon.h" #include "engine/actors/AFinishline.h" extern "C" { @@ -168,6 +169,12 @@ void LuigiRaceway::SpawnActors() { gWorldInstance.AddActor(new AFinishline()); spawn_foliage((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_luigi_raceway_tree_spawn)); spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_luigi_raceway_item_box_spawns)); + + if (gGamestate == CREDITS_SEQUENCE) { + gWorldInstance.AddObject(new OHotAirBalloon(FVector(-1250.0f, 0.0f, 1110.0f))); + } else { // Normal gameplay + gWorldInstance.AddObject(new OHotAirBalloon(FVector(-176.0, 0.0f, -2323.0f))); + } } void LuigiRaceway::SpawnVehicles() { @@ -202,8 +209,7 @@ void LuigiRaceway::InitCourseObjects() { if (gModeSelection == GRAND_PRIX) { func_80070714(); } - D_80165898 = 0; - init_object(indexObjectList1[0], 0); + for (i = 0; i < D_80165738; i++) { find_unused_obj_index(&gObjectParticle3[i]); init_object(gObjectParticle3[i], 0); @@ -212,15 +218,9 @@ void LuigiRaceway::InitCourseObjects() { } void LuigiRaceway::UpdateCourseObjects() { - if (D_80165898 != 0) { - update_hot_air_balloon(); - } } void LuigiRaceway::RenderCourseObjects(s32 cameraId) { - if (D_80165898 != 0) { - render_object_hot_air_balloon(cameraId); - } } void LuigiRaceway::SomeSounds() { diff --git a/src/engine/courses/TestCourse.cpp b/src/engine/courses/TestCourse.cpp index 3f95dc56b..40b03059e 100644 --- a/src/engine/courses/TestCourse.cpp +++ b/src/engine/courses/TestCourse.cpp @@ -20,6 +20,7 @@ #include "engine/objects/TrashBin.h" #include "engine/objects/Hedgehog.h" #include "engine/objects/Flagpole.h" +#include "engine/objects/HotAirBalloon.h" #include "engine/particles/StarEmitter.h" extern "C" { @@ -210,6 +211,7 @@ void TestCourse::SpawnActors() { //gWorldInstance.AddEmitter(new StarEmitter(FVector(0,50,0))); //gWorldInstance.AddObject(new OHedgehog(FVector(0, 0, 0), FVector2D(0, -200), 9)); //gWorldInstance.AddObject(new OFlagpole(FVector(0, 0, -200), 0x400)); + gWorldInstance.AddObject(new OHotAirBalloon(FVector(0.0, 20.0f, -200.0f))); } // Likely sets minimap boundaries diff --git a/src/engine/objects/HotAirBalloon.cpp b/src/engine/objects/HotAirBalloon.cpp new file mode 100644 index 000000000..234eef6d9 --- /dev/null +++ b/src/engine/objects/HotAirBalloon.cpp @@ -0,0 +1,174 @@ +#include "HotAirBalloon.h" +#include "World.h" +#include "port/Game.h" + +extern "C" { +#include "render_objects.h" +#include "update_objects.h" +#include "assets/luigi_raceway_data.h" +#include "assets/common_data.h" +#include "math_util.h" +#include "math_util_2.h" +#include "code_80086E70.h" +#include "code_80057C60.h" +#include "actors.h" +} + +OHotAirBalloon::OHotAirBalloon(const FVector& pos) { + _pos = pos; + + D_80165898 = 0; + + // Spawn balloon on second lap. + if (GetCourse() == GetLuigiRaceway()) { + _visible = (bool*)&D_80165898; + } else { // Spawn balloon on race start + bool mod = true; + _visible = &mod; + } + + init_object(indexObjectList1[0], 0); +} + +void OHotAirBalloon::Tick() { + s32 objectIndex = indexObjectList1[0]; + + if (*_visible) { + if (gObjectList[objectIndex].state != 0) { + OHotAirBalloon::func_80085768(objectIndex); + OHotAirBalloon::func_80085534(objectIndex); + object_calculate_new_pos_offset(objectIndex); + if (gObjectList[objectIndex].state >= 2) { + gActorHotAirBalloonItemBox->pos[0] = gObjectList[objectIndex].pos[0]; + gActorHotAirBalloonItemBox->pos[1] = gObjectList[objectIndex].pos[1] - 10.0; + gActorHotAirBalloonItemBox->pos[2] = gObjectList[objectIndex].pos[2]; + } + } + } +} + +void OHotAirBalloon::Draw(s32 cameraId) { + s32 objectIndex; + objectIndex = indexObjectList1[0]; + if (*_visible) { + if (gGamestate != CREDITS_SEQUENCE) { + func_8008A1D0(objectIndex, cameraId, 0x000005DC, 0x00000BB8); + if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { + OHotAirBalloon::func_80055CCC(objectIndex, cameraId); + } + } else { + clear_object_flag(objectIndex, 0x00100000); + OHotAirBalloon::func_80055CCC(objectIndex, cameraId); + } + } +} + +void OHotAirBalloon::func_80055CCC(s32 objectIndex, s32 cameraId) { + UNUSED s32 pad; + f32 test; + Camera* camera; + + camera = &camera1[cameraId]; + if (gObjectList[objectIndex].state >= 2) { + func_8008A454(objectIndex, cameraId, 0x0000012C); + test = gObjectList[objectIndex].pos[1] - gObjectList[objectIndex].surfaceHeight; + func_8004A6EC(objectIndex, (20.0 / test) + 0.5); + if (is_obj_index_flag_status_inactive(objectIndex, 0x00100000) != 0) { + func_80043328(gObjectList[objectIndex].pos, (u16*) gObjectList[objectIndex].direction_angle, + gObjectList[objectIndex].sizeScaling, (Gfx*)d_course_luigi_raceway_dl_F960); + gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_luigi_raceway_dl_F650); + } else { + D_80183E80[0] = (s16) gObjectList[objectIndex].direction_angle[0]; + D_80183E80[1] = + (s16) (func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos) + + 0x8000); + D_80183E80[2] = (u16) gObjectList[objectIndex].direction_angle[2]; + func_80043328(gObjectList[objectIndex].pos, D_80183E80, gObjectList[objectIndex].sizeScaling, + (Gfx*)d_course_luigi_raceway_dl_FBE0); + gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_luigi_raceway_dl_FA20); + if (gPlayerCountSelection1 == 1) { + gObjectList[objectIndex].direction_angle[1] = 0; + } + } + } +} + +void OHotAirBalloon::init_hot_air_balloon(s32 objectIndex) { + gObjectList[objectIndex].sizeScaling = 1.0f; + gObjectList[objectIndex].model = (Gfx*)d_course_luigi_raceway_dl_F960; + if (gGamestate != CREDITS_SEQUENCE) { + set_obj_origin_pos(objectIndex, xOrientation * _pos.x, _pos.y, _pos.z); + set_obj_origin_offset(objectIndex, 0.0f, 300.0f, 0.0f); + } else { + set_obj_origin_pos(objectIndex, xOrientation * _pos.x, _pos.y, _pos.z); + set_obj_origin_offset(objectIndex, 0.0f, 300.0f, 0.0f); + } + func_8008B844(objectIndex); + func_800886F4(objectIndex); + func_80086EF0(objectIndex); + gObjectList[objectIndex].velocity[1] = -2.0f; + init_actor_hot_air_balloon_item_box(0.0f, 0.0f, 0.0f); + object_next_state(objectIndex); +} + +void OHotAirBalloon::func_80085534(s32 objectIndex) { + switch (gObjectList[objectIndex].unk_0AE) { + case 1: + if (gObjectList[objectIndex].offset[1] <= 18.0) { + func_80086FD4(objectIndex); + } + break; + case 2: + f32_step_towards(&gObjectList[objectIndex].velocity[1], 0.0f, 0.05f); + if (gObjectList[objectIndex].velocity[1] == 0.0) { + func_80086FD4(objectIndex); + } + break; + case 3: + func_800871AC(objectIndex, 1); + break; + case 4: + f32_step_towards(&gObjectList[objectIndex].velocity[1], 1.0f, 0.05f); + if (gObjectList[objectIndex].velocity[1] == 1.0) { + func_80086FD4(objectIndex); + } + break; + case 5: + func_800871AC(objectIndex, 90); + break; + case 6: + f32_step_towards(&gObjectList[objectIndex].velocity[1], 0.0f, 0.05f); + if (gObjectList[objectIndex].velocity[1] == 0.0) { + func_80086FD4(objectIndex); + } + break; + case 7: + f32_step_towards(&gObjectList[objectIndex].velocity[1], -1.0f, 0.05f); + if (gObjectList[objectIndex].velocity[1] == -1.0) { + func_80086FD4(objectIndex); + } + break; + case 8: + func_800871AC(objectIndex, 90); + break; + case 9: + f32_step_towards(&gObjectList[objectIndex].velocity[1], 0.0f, 0.05f); + if (func_80087060(objectIndex, 90) != 0) { + func_8008701C(objectIndex, 3); + } + break; + } + object_add_velocity_offset_y(objectIndex); + gObjectList[objectIndex].direction_angle[1] += 0x100; +} + +void OHotAirBalloon::func_80085768(s32 objectIndex) { + switch (gObjectList[objectIndex].state) { /* irregular */ + case 1: + OHotAirBalloon::init_hot_air_balloon(objectIndex); + break; + case 0: + case 2: + break; + } +} diff --git a/src/engine/objects/HotAirBalloon.h b/src/engine/objects/HotAirBalloon.h new file mode 100644 index 000000000..301e111c4 --- /dev/null +++ b/src/engine/objects/HotAirBalloon.h @@ -0,0 +1,34 @@ +#pragma once + +#include +#include +#include "Object.h" + +#include "World.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "vehicles.h" +#include "waypoints.h" +#include "common_structs.h" +#include "objects.h" +#include "camera.h" +#include "some_data.h" +} + +class OHotAirBalloon : public OObject { +public: + explicit OHotAirBalloon(const FVector& pos); + + virtual void Tick() override; + virtual void Draw(s32 cameraId) override; + void func_80055CCC(s32 objectIndex, s32 cameraId); + void init_hot_air_balloon(s32 objectIndex); + void func_80085534(s32 objectIndex); + void func_80085768(s32 objectIndex); + +private: + FVector _pos; + bool *_visible; +}; diff --git a/src/render_objects.c b/src/render_objects.c index 35a1ec775..0571da4ce 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -3931,50 +3931,6 @@ void render_object_chain_chomps(s32 cameraId) { } } -void func_80055CCC(s32 objectIndex, s32 cameraId) { - UNUSED s32 pad; - f32 test; - Camera* camera; - - camera = &camera1[cameraId]; - if (gObjectList[objectIndex].state >= 2) { - func_8008A454(objectIndex, cameraId, 0x0000012C); - test = gObjectList[objectIndex].pos[1] - gObjectList[objectIndex].surfaceHeight; - func_8004A6EC(objectIndex, (20.0 / test) + 0.5); - if (is_obj_index_flag_status_inactive(objectIndex, 0x00100000) != 0) { - func_80043328(gObjectList[objectIndex].pos, (u16*) gObjectList[objectIndex].direction_angle, - gObjectList[objectIndex].sizeScaling, d_course_luigi_raceway_dl_F960); - gSPDisplayList(gDisplayListHead++, d_course_luigi_raceway_dl_F650); - } else { - D_80183E80[0] = (s16) gObjectList[objectIndex].direction_angle[0]; - D_80183E80[1] = - (s16) (func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos) + - 0x8000); - D_80183E80[2] = (u16) gObjectList[objectIndex].direction_angle[2]; - func_80043328(gObjectList[objectIndex].pos, D_80183E80, gObjectList[objectIndex].sizeScaling, - d_course_luigi_raceway_dl_FBE0); - gSPDisplayList(gDisplayListHead++, d_course_luigi_raceway_dl_FA20); - if (gPlayerCountSelection1 == 1) { - gObjectList[objectIndex].direction_angle[1] = 0; - } - } - } -} - -void render_object_hot_air_balloon(s32 arg0) { - s32 objectIndex; - objectIndex = indexObjectList1[0]; - if (gGamestate != 9) { - func_8008A1D0(objectIndex, arg0, 0x000005DC, 0x00000BB8); - if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { - func_80055CCC(objectIndex, arg0); - } - } else { - clear_object_flag(objectIndex, 0x00100000); - func_80055CCC(objectIndex, arg0); - } -} - void func_80055EF4(s32 objectIndex, UNUSED s32 arg1) { Object* object; diff --git a/src/render_objects.h b/src/render_objects.h index ed14fb684..6474e8db2 100644 --- a/src/render_objects.h +++ b/src/render_objects.h @@ -370,8 +370,6 @@ void func_800557B4(s32, u32, u32); void render_object_train_penguins(s32); void func_80055AB8(s32, s32); void render_object_chain_chomps(s32); -void func_80055CCC(s32, s32); -void render_object_hot_air_balloon(s32); void func_80055EF4(s32, s32); void func_80055F48(s32); diff --git a/src/update_objects.c b/src/update_objects.c index 80edaaf19..e806d43d2 100644 --- a/src/update_objects.c +++ b/src/update_objects.c @@ -4434,102 +4434,6 @@ void func_800842C8(void) { } } -void init_hot_air_balloon(s32 objectIndex) { - gObjectList[objectIndex].sizeScaling = 1.0f; - gObjectList[objectIndex].model = d_course_luigi_raceway_dl_F960; - if (gGamestate != 9) { - set_obj_origin_pos(objectIndex, xOrientation * -176.0, 0.0f, -2323.0f); - set_obj_origin_offset(objectIndex, 0.0f, 300.0f, 0.0f); - } else { - set_obj_origin_pos(objectIndex, xOrientation * -1250.0, 0.0f, 1110.0f); - set_obj_origin_offset(objectIndex, 0.0f, 300.0f, 0.0f); - } - func_8008B844(objectIndex); - func_800886F4(objectIndex); - func_80086EF0(objectIndex); - gObjectList[objectIndex].velocity[1] = -2.0f; - init_actor_hot_air_balloon_item_box(0.0f, 0.0f, 0.0f); - object_next_state(objectIndex); -} - -void func_80085534(s32 objectIndex) { - switch (gObjectList[objectIndex].unk_0AE) { - case 1: - if (gObjectList[objectIndex].offset[1] <= 18.0) { - func_80086FD4(objectIndex); - } - break; - case 2: - f32_step_towards(&gObjectList[objectIndex].velocity[1], 0.0f, 0.05f); - if (gObjectList[objectIndex].velocity[1] == 0.0) { - func_80086FD4(objectIndex); - } - break; - case 3: - func_800871AC(objectIndex, 1); - break; - case 4: - f32_step_towards(&gObjectList[objectIndex].velocity[1], 1.0f, 0.05f); - if (gObjectList[objectIndex].velocity[1] == 1.0) { - func_80086FD4(objectIndex); - } - break; - case 5: - func_800871AC(objectIndex, 0x0000005A); - break; - case 6: - f32_step_towards(&gObjectList[objectIndex].velocity[1], 0.0f, 0.05f); - if (gObjectList[objectIndex].velocity[1] == 0.0) { - func_80086FD4(objectIndex); - } - break; - case 7: - f32_step_towards(&gObjectList[objectIndex].velocity[1], -1.0f, 0.05f); - if (gObjectList[objectIndex].velocity[1] == -1.0) { - func_80086FD4(objectIndex); - } - break; - case 8: - func_800871AC(objectIndex, 0x0000005A); - break; - case 9: - f32_step_towards(&gObjectList[objectIndex].velocity[1], 0.0f, 0.05f); - if (func_80087060(objectIndex, 0x0000005A) != 0) { - func_8008701C(objectIndex, 3); - } - break; - } - object_add_velocity_offset_y(objectIndex); - gObjectList[objectIndex].direction_angle[1] += 0x100; -} - -void func_80085768(s32 objectIndex) { - switch (gObjectList[objectIndex].state) { /* irregular */ - case 1: - init_hot_air_balloon(objectIndex); - break; - case 0: - case 2: - break; - } -} - -void update_hot_air_balloon(void) { - s32 objectIndex; - - objectIndex = indexObjectList1[0]; - if (gObjectList[objectIndex].state != 0) { - func_80085768(objectIndex); - func_80085534(objectIndex); - object_calculate_new_pos_offset(objectIndex); - if (gObjectList[objectIndex].state >= 2) { - gActorHotAirBalloonItemBox->pos[0] = gObjectList[objectIndex].pos[0]; - gActorHotAirBalloonItemBox->pos[1] = gObjectList[objectIndex].pos[1] - 10.0; - gActorHotAirBalloonItemBox->pos[2] = gObjectList[objectIndex].pos[2]; - } - } -} - void func_80085878(s32 objectIndex, s32 arg1) { TrackWaypoint* temp_v0; Object* object;