diff --git a/src/code_80057C60.c b/src/code_80057C60.c index ee82cd511..cab096140 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -561,10 +561,10 @@ void render_object_p1(void) { CourseManager_DrawBombKarts(PLAYER_ONE); //render_bomb_karts_wrap(PLAYER_ONE); if (gGamestate == ENDING) { - func_80055F48(PLAYER_ONE); - func_80056160(PLAYER_ONE); - func_8005217C(PLAYER_ONE); - func_80054BE8(PLAYER_ONE); + //func_80055F48(PLAYER_ONE); + //func_80056160(PLAYER_ONE); + //func_8005217C(PLAYER_ONE); + //func_80054BE8(PLAYER_ONE); return; } if (!gDemoMode) { @@ -1424,9 +1424,9 @@ void func_8005A070(void) { if (gIsGamePaused == false) { func_8005C728(); if (gGamestate == ENDING) { - func_80086604(); - func_80086D80(); - update_cheep_cheep(1); + //func_80086604(); + //func_80086D80(); + //update_cheep_cheep(1); func_80077640(); } else if (gGamestate == CREDITS_SEQUENCE) { func_80059820(PLAYER_ONE); diff --git a/src/engine/World.h b/src/engine/World.h index 3b48284e8..a90ff7441 100644 --- a/src/engine/World.h +++ b/src/engine/World.h @@ -22,6 +22,53 @@ extern "C" { #include "engine/Engine.h" }; +struct FVector { + float x, y, z; + + FVector& operator=(const FVector& other) { + x = other.x; + y = other.y; + z = other.z; + return *this; + } +}; + +/** + * For selecting a section of a course path + * Usage: IPathSpan(point1, point2) --> IPathSpan(40, 65) + */ +struct IPathSpan { + int Start, End; + + // Default Constructor + IPathSpan() : Start(0), End(0) {} + + // Parameterized Constructor + IPathSpan(int InStart, int InEnd) + : Start(InStart), End(InEnd) {} + + // Copy Assignment Operator + IPathSpan& operator=(const IPathSpan& Other) { + if (this != &Other) { // Avoid self-assignment + Start = Other.Start; + End = Other.End; + } + return *this; + } + + // Equality Operator + bool operator==(const IPathSpan& Other) const { + return Start == Other.Start && End == Other.End; + } + + // Inequality Operator + bool operator!=(const IPathSpan& Other) const { + return !(*this == Other); + } +}; + + + class OObject; class Cup; // <-- Forward declaration class Course; diff --git a/src/engine/courses/BansheeBoardwalk.cpp b/src/engine/courses/BansheeBoardwalk.cpp index 9983ac0b7..80549ac90 100644 --- a/src/engine/courses/BansheeBoardwalk.cpp +++ b/src/engine/courses/BansheeBoardwalk.cpp @@ -7,6 +7,7 @@ #include "World.h" #include "engine/actors/AFinishline.h" #include "engine/objects/BombKart.h" +#include "engine/objects/CheepCheep.h" #include "assets/banshee_boardwalk_data.h" #include "assets/boo_frames.h" @@ -150,6 +151,9 @@ void BansheeBoardwalk::SpawnActors() { gWorldInstance.AddActor(new AFinishline()); spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_banshee_boardwalk_item_box_spawns)); + + + gWorldInstance.AddObject(new OCheepCheep(FVector(xOrientation * -1650.0, -200.0f, -1650.0f), OCheepCheep::CheepType::RACE, IPathSpan(160, 170))); } void BansheeBoardwalk::SpawnVehicles() { @@ -199,7 +203,7 @@ void BansheeBoardwalk::UpdateCourseObjects() { update_bat(); } wrapper_update_boos(); - update_cheep_cheep(0); + //update_cheep_cheep(0); } } @@ -207,7 +211,7 @@ void BansheeBoardwalk::RenderCourseObjects(s32 cameraId) { if (gGamestate != CREDITS_SEQUENCE) { render_object_trash_bin(cameraId); render_object_bat(cameraId); - func_8005217C(cameraId); + //func_8005217C(cameraId); // render cheep cheep render_object_boos(cameraId); } } diff --git a/src/engine/courses/PodiumCeremony.cpp b/src/engine/courses/PodiumCeremony.cpp index e05b54e51..6f04bd291 100644 --- a/src/engine/courses/PodiumCeremony.cpp +++ b/src/engine/courses/PodiumCeremony.cpp @@ -8,6 +8,9 @@ #include "engine/objects/BombKart.h" #include "assets/royal_raceway_data.h" #include "assets/ceremony_data.h" +#include "engine/objects/Trophy.h" +#include "engine/objects/Podium.h" +#include "engine/objects/CheepCheep.h" extern "C" { #include "main.h" @@ -30,6 +33,7 @@ extern "C" { #include "collision.h" #include "memory.h" #include "courses/staff_ghost_data.h" + #include "podium_ceremony_actors.h" extern const char *royal_raceway_dls[]; } @@ -160,6 +164,43 @@ void PodiumCeremony::SpawnActors() { spawn_foliage((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_royal_raceway_tree_spawn)); spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_royal_raceway_item_box_spawns)); spawn_piranha_plants((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_royal_raceway_piranha_plant_spawn)); + + gWorldInstance.AddObject(new OCheepCheep(FVector((f32)0xf37e, (f32)0x0013, (f32)0xfe22), OCheepCheep::CheepType::PODIUM_CEREMONY, IPathSpan(0, 0))); + gWorldInstance.AddObject(new OPodium(FVector((f32)0xf37e, (f32)0x0013, (f32)0xfe22))); + + FVector pos = {0,0,0}; + pos.y = 90.0f; + OTrophy::TrophyType type = OTrophy::TrophyType::BRONZE; + switch(D_802874D8.unk1D) { + case 0: // Bronze + if (gCCSelection == CC_150) { + OTrophy::TrophyType::BRONZE_150; + } else { + OTrophy::TrophyType::BRONZE; + } + break; + case 1: // Silver + pos.x -= 3.0; + pos.z += 15.0; + + if (gCCSelection == CC_150) { + OTrophy::TrophyType::SILVER_150; + } else { + OTrophy::TrophyType::SILVER; + } + break; + case 2: // Gold + pos.x -= 2.0; + pos.z -= 15.0; + if (gCCSelection == CC_150) { + OTrophy::TrophyType::GOLD_150; + } else { + OTrophy::TrophyType::GOLD; + } + break; + } + + gWorldInstance.AddObject(new OTrophy(pos, type, OTrophy::Behaviour::PODIUM_CEREMONY)); } void PodiumCeremony::SpawnVehicles() { diff --git a/src/engine/courses/TestCourse.cpp b/src/engine/courses/TestCourse.cpp index 2750c727f..465f97012 100644 --- a/src/engine/courses/TestCourse.cpp +++ b/src/engine/courses/TestCourse.cpp @@ -14,6 +14,7 @@ #include "engine/actors/ACloud.h" #include "engine/vehicles/Train.h" #include "engine/objects/Trophy.h" +#include "engine/objects/CheepCheep.h" extern "C" { #include "main.h" @@ -189,14 +190,14 @@ void TestCourse::SpawnActors() { rrxing->crossingTrigger = crossing1; Vec3f pos = {0, 80, 0}; - //gWorldInstance.AddActor(new ACloud(pos)); + // gWorldInstance.AddActor(new ACloud(pos)); // gWorldInstance.AddActor(new OSeagull(0, pos)); // gWorldInstance.AddActor(new OSeagull(1, pos)); // gWorldInstance.AddActor(new OSeagull(2, pos)); // gWorldInstance.AddActor(new OSeagull(3, pos)); - - gWorldInstance.AddObject(new OTrophy(FVector(0,0,0), OTrophy::TrophyType::GOLD, OTrophy::Behaviour::GO_FISH)); + gWorldInstance.AddObject(new OCheepCheep(FVector(0, 40, 0), OCheepCheep::CheepType::RACE, IPathSpan(0, 10))); + //gWorldInstance.AddObject(new OTrophy(FVector(0,0,0), OTrophy::TrophyType::GOLD, OTrophy::Behaviour::GO_FISH)); } // Likely sets minimap boundaries diff --git a/src/engine/objects/CheepCheep.cpp b/src/engine/objects/CheepCheep.cpp new file mode 100644 index 000000000..e81ba7c24 --- /dev/null +++ b/src/engine/objects/CheepCheep.cpp @@ -0,0 +1,244 @@ +#include "CheepCheep.h" + +#include "assets/banshee_boardwalk_data.h" +#include "assets/common_data.h" + +extern "C" { +#include "math_util.h" +#include "math_util_2.h" +#include "render_objects.h" +#include "update_objects.h" +#include "code_800029B0.h" +#include "code_80086E70.h" +#include "waypoints.h" +#include "code_80057C60.h" +#include "some_data.h" +extern Vec3s D_800E634C[]; +extern Lights1 D_800E45C0[]; +} + +OCheepCheep::OCheepCheep(const FVector& pos, CheepType type, IPathSpan span) { + _type = type; + _spawnPos = pos; + _span = span; +} + +void OCheepCheep::Tick() { // update_cheep_cheep + s32 objectIndex; + switch (_type) { + case CheepType::RACE: + UNUSED s32 pad; + + OCheepCheep::func_8007BD04(0); + objectIndex = indexObjectList2[0]; + OCheepCheep::func_8007BBBC(objectIndex); + object_calculate_new_pos_offset(objectIndex); + break; + case CheepType::PODIUM_CEREMONY: + objectIndex = indexObjectList2[0]; + if (D_801658BC == 1) { + D_801658BC = 0; + init_object(objectIndex, 0); + } + if (gObjectList[objectIndex].state != 0) { + OCheepCheep::func_8007BEC8(objectIndex); + OCheepCheep::func_8007BFB0(objectIndex); + } + break; + } +} + +void OCheepCheep::Draw(s32 cameraId) { // func_8005217C + Lights1* D_800E45C0l = (Lights1*) (D_800E45C0); + Object* object; + s32 temp_a3; + + temp_a3 = indexObjectList2[0]; + object = &gObjectList[temp_a3]; + if (object->state >= 2) { + if (is_obj_flag_status_active(temp_a3, 0x10) != 0) { + rsp_set_matrix_transformation(object->pos, object->direction_angle, object->sizeScaling); + func_800520C0(temp_a3); + + gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007828); + gSPLight(gDisplayListHead++, &D_800E45C0l[0].l[0], LIGHT_1); + gSPLight(gDisplayListHead++, &D_800E45C0l[0].a, LIGHT_2); + gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_banshee_boardwalk_dl_7B38); + gSPLight(gDisplayListHead++, &D_800E45C0l[1].l[0], LIGHT_1); + gSPLight(gDisplayListHead++, &D_800E45C0l[1].a, LIGHT_2); + gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_banshee_boardwalk_dl_7978); + gSPLight(gDisplayListHead++, &D_800E45C0l[2].l[0], LIGHT_1); + gSPLight(gDisplayListHead++, &D_800E45C0l[2].a, LIGHT_2); + gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_banshee_boardwalk_dl_78C0); + gSPLight(gDisplayListHead++, &D_800E45C0l[3].l[0], LIGHT_1); + gSPLight(gDisplayListHead++, &D_800E45C0l[3].a, LIGHT_2); + gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_banshee_boardwalk_dl_7650); + } + } +} + +void OCheepCheep::func_8007BBBC(s32 objectIndex) { + f32 var_f14; + Object* object; + + object = &gObjectList[objectIndex]; + switch (object->state) { + case 1: + func_800735BC(objectIndex, (Gfx*)d_course_banshee_boardwalk_dl_cheep_cheep, 2.0f); + set_object_flag(objectIndex, 0x00000010); + object->unk_0D5 = 0; + break; + case 2: + if (gIsMirrorMode != 0) { + func_80087E08(objectIndex, 18.0f, 0.7f, 25.0f, (s16) -0x00005800, 0x0000012C); + } else { + func_80087E08(objectIndex, 18.0f, 0.7f, 25.0f, (s16) 0x00005800, 0x0000012C); + } + if (object->velocity[2] < 0.0f) { + var_f14 = -object->velocity[2]; + } else { + var_f14 = object->velocity[2]; + } + object->direction_angle[0] = func_80041658(object->velocity[1], var_f14); + set_and_run_timer_object(objectIndex, 0x00000046); + break; + case 3: + func_80072428(objectIndex); + break; + case 0: + break; + } +} + +void OCheepCheep::func_8007BD04(s32 playerId) { + s32 objectIndex; + + objectIndex = indexObjectList2[0]; + if (gObjectList[objectIndex].state == 0) { + if (((s32) gNearestWaypointByPlayerId[playerId] >= _span.Start) && + ((s32) gNearestWaypointByPlayerId[playerId] <= _span.End)) { + set_obj_origin_pos(objectIndex, xOrientation * _spawnPos.x, _spawnPos.y, _spawnPos.z); + init_object(objectIndex, 1); + } + } +} + +void OCheepCheep::init_var_cheep_cheep(s32 objectIndex) { + Object* object; + + object = &gObjectList[objectIndex]; + object->unk_0D5 = 1; + object->status = 0; + object->model = (Gfx*)d_course_banshee_boardwalk_dl_cheep_cheep; + object->sizeScaling = 0.2f; + object_next_state(objectIndex); + set_obj_origin_pos(objectIndex, D_800E634C[0][0], D_800E634C[0][1] + 55.0, D_800E634C[0][2]); + set_obj_origin_offset(objectIndex, 0.0f, 30.0f, 0.0f); + set_obj_direction_angle(objectIndex, 0U, 0x3800U, 0U); +} + +void OCheepCheep::func_8007BEC8(s32 objectIndex) { + Object* object; + + object = &gObjectList[objectIndex]; + switch (object->state) { + case 1: + OCheepCheep::init_var_cheep_cheep(objectIndex); + break; + case 2: + if (set_and_run_timer_object(objectIndex, 0x0000003C) != 0) { + set_object_flag(objectIndex, 0x00000010); + func_80086E70(objectIndex); + } + break; + case 3: + if (object->unk_0AE == 0) { + object_next_state(objectIndex); + } + break; + case 4: + if (set_and_run_timer_object(objectIndex, 0x0000000A) != 0) { + func_8008701C(objectIndex, 2); + } + break; + case 5: + if (object->unk_0AE == 0) { + func_80072428(objectIndex); + } + break; + case 0: + default: + break; + } +} + +void OCheepCheep::func_8007BFB0(s32 objectIndex) { + Object* object; + + object = &gObjectList[objectIndex]; + switch (object->unk_0AE) { + case 0: + break; + case 1: + object->velocity[1] = -0.2f; + if ((f64) object->offset[1] <= 0.0) { + object->offset[1] = 0.0f; + object->velocity[1] = 0.0f; + func_80086F60(objectIndex); + } + break; + case 2: + if (func_800871AC(objectIndex, 0x00000014) != 0) { + object->unk_084[7] = 0x0040; + } + break; + case 3: + object->sizeScaling = (f32) ((f64) object->sizeScaling - 0.0015); + if ((s32) object->direction_angle[0] >= 0xA01) { + object->unk_084[7] -= 4; + } + if (u16_step_up_towards(object->direction_angle, 0x0C00U, (u16) object->unk_084[7]) != 0) { + func_80086FD4(objectIndex); + } + break; + case 4: + object->sizeScaling = (f32) ((f64) object->sizeScaling - 0.0015); + object->unk_034 = 0.001f; + func_80086FD4(objectIndex); + object->unk_084[7] = 0; + break; + case 5: + if (object->unk_034 <= 0.004) { + object->unk_034 += 0.0002; + } + object->sizeScaling += object->unk_034; + s16_step_up_towards(&object->unk_084[7], 0x0100, 0x0010); + object->direction_angle[0] -= object->unk_084[7]; + if (func_80087060(objectIndex, 0x00000035) != 0) { + func_80086FD4(objectIndex); + } + break; + case 6: + if (func_80087060(objectIndex, 0x0000000F) != 0) { + func_80086FD4(objectIndex); + D_801658CE = 1; + } + break; + case 7: + object->sizeScaling = (f32) ((f64) object->sizeScaling - 0.05); + if ((f64) object->sizeScaling <= 0.01) { + clear_object_flag(objectIndex, 0x00000010); + object->sizeScaling = 0.000001f; + func_80086FD4(objectIndex); + } + break; + case 8: + func_80086F60(objectIndex); + break; + } + if (object->unk_0AE < 0xA) { + func_80074344(objectIndex, &object->sizeScaling, 0.2f, 0.21f, 0.001f, 0, -1); + } + object_add_velocity_offset_y(objectIndex); + object_calculate_new_pos_offset(objectIndex); +} diff --git a/src/engine/objects/CheepCheep.h b/src/engine/objects/CheepCheep.h new file mode 100644 index 000000000..32e9a5aeb --- /dev/null +++ b/src/engine/objects/CheepCheep.h @@ -0,0 +1,48 @@ +#pragma once + +#include +#include +#include "Object.h" + +#include "World.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "common_structs.h" +#include "objects.h" +#include "course_offsets.h" +#include "some_data.h" +} + + +class OCheepCheep : public OObject { +public: + enum CheepType { + RACE, + PODIUM_CEREMONY + }; + + enum Behaviour : uint16_t { + }; + +public: + + explicit OCheepCheep(const FVector& pos, CheepType type, IPathSpan span); + + virtual void Tick() override; + virtual void Draw(s32 cameraId) override; + void func_8007BBBC(s32 objectIndex); + void func_8007BD04(s32 playerId); + void init_var_cheep_cheep(s32 objectIndex); + void func_8007BEC8(s32 objectIndex); + void func_8007BFB0(s32 objectIndex); + +private: + + s32 _idx; + CheepType _type; + FVector _spawnPos; + IPathSpan _span; + +}; diff --git a/src/engine/objects/Mole.cpp b/src/engine/objects/Mole.cpp index 9ef7f40ef..78b186e77 100644 --- a/src/engine/objects/Mole.cpp +++ b/src/engine/objects/Mole.cpp @@ -72,7 +72,7 @@ void OMole::Tick() { } } -void OMole::Draw(Camera* camera) { +void OMole::Draw(s32 cameraId) { } diff --git a/src/engine/objects/Mole.h b/src/engine/objects/Mole.h index d5d605fa5..7ff95c58c 100644 --- a/src/engine/objects/Mole.h +++ b/src/engine/objects/Mole.h @@ -2,7 +2,7 @@ #include #include -#include "GameObject.h" +#include "Object.h" extern "C" { #include "macros.h" @@ -16,7 +16,7 @@ extern "C" { } -class OMole : public GameObject { +class OMole : public OObject { public: enum Behaviour : uint16_t { }; @@ -25,7 +25,7 @@ public: explicit OMole(Vec3f pos); virtual void Tick() override; - virtual void Draw(Camera*) override; + virtual void Draw(s32 cameraId) override; void func_80054E10(s32 objectIndex); void func_80054EB8(); diff --git a/src/engine/objects/Podium.cpp b/src/engine/objects/Podium.cpp new file mode 100644 index 000000000..426a65b60 --- /dev/null +++ b/src/engine/objects/Podium.cpp @@ -0,0 +1,140 @@ +#include "Podium.h" +#include "assets/ceremony_data.h" + +extern "C" { +#include "main.h" +#include "defines.h" +#include "update_objects.h" +#include "render_objects.h" +#include "code_80057C60.h" +#include "podium_ceremony_actors.h" +#include "math_util.h" +#include "math_util_2.h" +#include "assets/common_data.h" +#include "some_data.h" +#include "code_80091440.h" +#include "code_80086E70.h" +#include "code_80086E70.h" +extern Vec3s D_800E634C[]; +} + +// Might be Cheep Cheep related? +// Vec3s D_800E634C[] = { +// { 0xf37e, 0x0013, 0xfe22 }, +// { 0xf37b, 0x0013, 0xfe31 }, +// { 0xf380, 0x0013, 0xfe14 }, +// }; + +OPodium::OPodium(const FVector& pos) { + + for (size_t i = 0; i < NUM_PODIUMS; i++) { + s32 objectIndex = indexObjectList1[i]; + init_object(objectIndex, 0); + set_obj_origin_pos(objectIndex, pos.x - 1.5, pos.y, pos.z); + } +} + +void OPodium::Tick() { // func_80086604 + s32 objectIndex; + // if ((D_8016347C != 0) && (D_802874D8.unk1D < 3)) { + // if (D_801658C6 == 0) { + // for (size_t i = 0; i < 3; i++) { + // objectIndex = indexObjectList1[i]; + // init_object(objectIndex, 0); + // } + // D_801658C6 = 1; + // } + // } + for (size_t i = 0; i != NUM_PODIUMS; i++) { + objectIndex = indexObjectList1[i]; + if (gObjectList[objectIndex].state != 0) { + OPodium::func_80086528(objectIndex, i); + OPodium::func_80086424(objectIndex); + } + } +} + +void OPodium::Draw(s32 cameraId) { // func_80055F48 + for (size_t i = 0; i < NUM_PODIUMS; i++) { + Object* object; + + object = &gObjectList[i]; + if (object->state >= 2) { + func_80043220(object->pos, object->direction_angle, object->sizeScaling, object->model); + rsp_set_matrix_transformation(object->pos, object->direction_angle, object->sizeScaling); + gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D0077A0); + gSPDisplayList(gDisplayListHead++, object->model); + } + } +} + +void OPodium::func_8008629C(s32 objectIndex, s32 arg1) { + switch (arg1) { /* irregular */ + case 0: + gObjectList[objectIndex].model = (Gfx*)podium_dl3; + gObjectList[objectIndex].unk_04C = 0x00000038; + break; + case 1: + gObjectList[objectIndex].model = (Gfx*)podium2_dl3; + gObjectList[objectIndex].unk_04C = 0x0000002B; + break; + case 2: + gObjectList[objectIndex].model = (Gfx*)podium3_dl3; + gObjectList[objectIndex].unk_04C = 0x0000001E; + break; + default: + break; + } + gObjectList[objectIndex].sizeScaling = 1.0f; + //set_obj_origin_pos(objectIndex, D_800E634C[0][0] - 1.5, D_800E634C[0][1], D_800E634C[0][2]); + set_obj_origin_offset(objectIndex, 0.0f, -10.0f, 0.0f); + set_obj_direction_angle(objectIndex, 0U, 0xF8E4U, 0U); + gObjectList[objectIndex].unk_048 = 0; + object_next_state(objectIndex); +} + +void OPodium::func_80086424(s32 objectIndex) { + switch (gObjectList[objectIndex].unk_0AE) { + case 0: + break; + case 1: + gObjectList[objectIndex].velocity[1] = 0.75f; + func_80086FD4(objectIndex); + break; + case 2: + if (gObjectList[objectIndex].offset[1] >= -2.0) { + gObjectList[objectIndex].velocity[1] -= 0.1; + } + object_add_velocity_offset_y(objectIndex); + if (gObjectList[objectIndex].offset[1] >= 0.0) { + gObjectList[objectIndex].offset[1] = 0.0f; + gObjectList[objectIndex].velocity[1] = 0.0f; + func_80086F60(objectIndex); + } + break; + } + object_calculate_new_pos_offset(objectIndex); +} + +void OPodium::func_80086528(s32 objectIndex, s32 arg1) { + switch (gObjectList[objectIndex].state) { /* irregular */ + case 1: + func_8008629C(objectIndex, arg1); + break; + case 2: + if (set_and_run_timer_object(objectIndex, gObjectList[objectIndex].unk_04C) != 0) { + func_80091440(arg1); + func_80086E70(objectIndex); + object_next_state(objectIndex); + } + break; + case 0: + break; + case 3: + if (gObjectList[objectIndex].unk_0AE == 0) { + gObjectList[objectIndex].unk_048 = 1; + object_next_state(objectIndex); + } + break; + } +} diff --git a/src/engine/objects/Podium.h b/src/engine/objects/Podium.h new file mode 100644 index 000000000..2b3a1033a --- /dev/null +++ b/src/engine/objects/Podium.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include + +#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 "course_offsets.h" +#include "some_data.h" +} + + +class OPodium : public OObject { +public: + enum Behaviour : uint16_t { + }; + +public: + + explicit OPodium(const FVector& pos); + + virtual void Tick() override; + virtual void Draw(s32 cameraId) override; + void func_8008629C(s32 objectIndex, s32 arg1); + void func_80086424(s32 objectIndex); + void func_80086528(s32 objectIndex, s32 arg1); + +private: + + s32 _idx; +}; diff --git a/src/engine/objects/Seagull.cpp b/src/engine/objects/Seagull.cpp index 4b36bbf31..b641ab5b4 100644 --- a/src/engine/objects/Seagull.cpp +++ b/src/engine/objects/Seagull.cpp @@ -2,7 +2,6 @@ #include #include "Seagull.h" #include "engine/Actor.h" -#include "ObjectReimpl.h" #include #include "port/Game.h" @@ -135,7 +134,7 @@ void OSeagull::func_8008275C(s32 objectIndex) { switch (gObjectList[objectIndex].unk_0DD) { case 1: func_8008B78C(objectIndex); - ObjectImpl::CalculateNewPosOffset(this); + object_calculate_new_pos_offset(objectIndex); break; case 2: func_8008B78C(objectIndex); @@ -145,7 +144,7 @@ void OSeagull::func_8008275C(s32 objectIndex) { Offset[0] *= 2.0; Offset[1] *= 2.5; Offset[2] *= 2.0; - ObjectImpl::CalculateNewPosOffset(this); + object_calculate_new_pos_offset(objectIndex); gObjectList[objectIndex].direction_angle[1] = get_angle_between_two_vectors(gObjectList[objectIndex].unk_01C, gObjectList[objectIndex].pos); break; diff --git a/src/engine/objects/Trophy.cpp b/src/engine/objects/Trophy.cpp index 464a2277c..5ac54f5ec 100644 --- a/src/engine/objects/Trophy.cpp +++ b/src/engine/objects/Trophy.cpp @@ -226,7 +226,6 @@ void OTrophy::Draw(s32 cameraId) { func_80057A50(40, 0, (char*) "Trophies Collected: ", (s16) numTrophies); break; } - } } diff --git a/src/engine/objects/Trophy.h b/src/engine/objects/Trophy.h index d73e04929..d413faf12 100644 --- a/src/engine/objects/Trophy.h +++ b/src/engine/objects/Trophy.h @@ -3,6 +3,7 @@ #include #include #include "Object.h" +#include "World.h" extern "C" { #include "macros.h" @@ -15,18 +16,6 @@ extern "C" { #include "some_data.h" } -//! @todo move this like World.h or something -struct FVector { - float x, y, z; - - FVector& operator=(const FVector& other) { - x = other.x; - y = other.y; - z = other.z; - return *this; - } -}; - class OTrophy : public OObject { public: enum TrophyType { diff --git a/src/engine/particles/ParticleEmitter.cpp b/src/engine/particles/ParticleEmitter.cpp new file mode 100644 index 000000000..5154abf56 --- /dev/null +++ b/src/engine/particles/ParticleEmitter.cpp @@ -0,0 +1,13 @@ +#include + +#include "ParticleEmitter.h" + + + +ParticleEmitter::ParticleEmitter() {} + + // Virtual functions to be overridden by derived classes +void ParticleEmitter::Tick() { } +void ParticleEmitter::Draw(s32 cameraId) { } + +bool ParticleEmitter::IsMod() { return false; } diff --git a/src/engine/particles/ParticleEmitter.h b/src/engine/particles/ParticleEmitter.h new file mode 100644 index 000000000..1a71164d1 --- /dev/null +++ b/src/engine/particles/ParticleEmitter.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +extern "C" { +#include "macros.h" +#include "main.h" +#include "camera.h" +#include "common_structs.h" + + +class ParticleEmitter { +public: + virtual ~ParticleEmitter() = default; // Virtual destructor for proper cleanup in derived classes + + explicit ParticleEmitter(); + + virtual void Tick(); + virtual void Draw(s32 cameraId); + virtual bool IsMod(); +}; + +} \ No newline at end of file diff --git a/src/engine/particles/StarEmitter.cpp b/src/engine/particles/StarEmitter.cpp new file mode 100644 index 000000000..b717f177d --- /dev/null +++ b/src/engine/particles/StarEmitter.cpp @@ -0,0 +1,31 @@ + + +#include "StarEmitter.h" + +extern "C" { +#include "render_objects.h" +#include "common_data.h" +#include "code_80057C60.h" +} + +void StarEmitter::Tick() { + +} + +void StarEmitter::Draw(s32 cameraId) { // func_80054BE8 + s32 var_s0; + s32 temp_a0; + Camera* camera; + + camera = &camera1[cameraId]; + gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007AE0); + load_texture_block_ia8_nomirror(D_8018D488, 0x00000020, 0x00000020); + func_8004B35C(0x000000FF, 0x000000FF, 0, 0x000000FF); + D_80183E80[0] = 0; + for (var_s0 = 0; var_s0 < gObjectParticle3_SIZE; var_s0++) { + temp_a0 = gObjectParticle3[var_s0]; + if ((temp_a0 != -1) && (gObjectList[temp_a0].state >= 2)) { + func_80054AFC(temp_a0, camera->pos); + } + } +} diff --git a/src/engine/particles/StarEmitter.h b/src/engine/particles/StarEmitter.h new file mode 100644 index 000000000..20841598c --- /dev/null +++ b/src/engine/particles/StarEmitter.h @@ -0,0 +1,42 @@ +#pragma once + +#include +#include +#include "ParticleEmitter.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "vehicles.h" +#include "waypoints.h" +#include "common_structs.h" +#include "objects.h" +#include "course_offsets.h" +#include "some_data.h" +} + +/** + * Used in the podium ceremony when the trophy appears + */ +class StarEmitter : public ParticleEmitter { +public: + enum Behaviour : uint16_t { + }; + +public: + f32 Diameter = 0.0f; // Waddle in a circle around the spawn point at this diameter. + uint16_t MirrorModeAngleOffset; + + explicit StarEmitter(Vec3f pos); + + virtual void Tick() override; + virtual void Draw(s32 cameraId) override; + void func_80086700(s32 objectIndex); + void func_80086940(s32 objectIndex); + void func_80086C14(s32 objectIndex); + void func_80086C6C(s32 objectIndex); + +private: + + s32 _idx; +}; diff --git a/src/render_objects.c b/src/render_objects.c index a56e91c0d..8c9a8d0e3 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -3411,35 +3411,6 @@ void func_800520C0(s32 arg0) { } } -void func_8005217C(UNUSED s32 arg0) { - Lights1* D_800E45C0l = LOAD_ASSET(D_800E45C0); - Object* object; - s32 temp_a3; - - temp_a3 = indexObjectList2[0]; - object = &gObjectList[temp_a3]; - if (object->state >= 2) { - if (is_obj_flag_status_active(temp_a3, 0x00000010) != 0) { - rsp_set_matrix_transformation(object->pos, object->direction_angle, object->sizeScaling); - func_800520C0(temp_a3); - - gSPDisplayList(gDisplayListHead++, D_0D007828); - gSPLight(gDisplayListHead++, &D_800E45C0l[0].l[0], LIGHT_1); - gSPLight(gDisplayListHead++, &D_800E45C0l[0].a, LIGHT_2); - gSPDisplayList(gDisplayListHead++, d_course_banshee_boardwalk_dl_7B38); - gSPLight(gDisplayListHead++, &D_800E45C0l[1].l[0], LIGHT_1); - gSPLight(gDisplayListHead++, &D_800E45C0l[1].a, LIGHT_2); - gSPDisplayList(gDisplayListHead++, d_course_banshee_boardwalk_dl_7978); - gSPLight(gDisplayListHead++, &D_800E45C0l[2].l[0], LIGHT_1); - gSPLight(gDisplayListHead++, &D_800E45C0l[2].a, LIGHT_2); - gSPDisplayList(gDisplayListHead++, d_course_banshee_boardwalk_dl_78C0); - gSPLight(gDisplayListHead++, &D_800E45C0l[3].l[0], LIGHT_1); - gSPLight(gDisplayListHead++, &D_800E45C0l[3].a, LIGHT_2); - gSPDisplayList(gDisplayListHead++, d_course_banshee_boardwalk_dl_7650); - } - } -} - void func_800523B8(s32 objectIndex, s32 arg1, u32 arg2) { UNUSED s32 pad[2]; Object* object; @@ -3997,25 +3968,6 @@ void func_80054AFC(s32 objectIndex, Vec3f arg1) { gSPDisplayList(gDisplayListHead++, common_rectangle_display); } -void func_80054BE8(s32 cameraId) { - s32 var_s0; - s32 temp_a0; - Camera* camera; - - camera = &camera1[cameraId]; - gSPDisplayList(gDisplayListHead++, D_0D007AE0); - load_texture_block_ia8_nomirror(D_8018D488, 0x00000020, 0x00000020); - func_8004B35C(0x000000FF, 0x000000FF, 0, 0x000000FF); - D_80183E80[0] = 0; - for (var_s0 = 0; var_s0 < gObjectParticle3_SIZE; var_s0++) { - temp_a0 = gObjectParticle3[var_s0]; - if ((temp_a0 != -1) && (gObjectList[temp_a0].state >= 2)) { - func_80054AFC(temp_a0, camera->pos); - } - } -} - - void func_80055164(s32 objectIndex) { if (gObjectList[objectIndex].state >= 2) { gSPDisplayList(gDisplayListHead++, D_0D0077A0); @@ -4271,45 +4223,6 @@ void func_80055EF4(s32 objectIndex, UNUSED s32 arg1) { } } -void func_80055F48(s32 arg0) { - s32 someIndex; - - for (someIndex = 0; someIndex < 3; someIndex++) { - func_80055EF4(indexObjectList1[someIndex], arg0); - } -} - -void func_80055FA0(s32 objectIndex, UNUSED s32 arg1) { - Mat4 someMatrix1; - Mat4 someMatrix2; - Object* object; - - object = &gObjectList[objectIndex]; - if (object->state >= 2) { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[0]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[0]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - mtxf_set_matrix_transformation(someMatrix1, object->pos, object->direction_angle, object->sizeScaling); - //convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], someMatrix1); - //gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), - // G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW); - - AddHudMatrix(someMatrix1, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW); - - gSPDisplayList(gDisplayListHead++, D_0D0077A0); - gSPDisplayList(gDisplayListHead++, object->model); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[0]), - G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - mtxf_identity(someMatrix2); - render_set_position(someMatrix2, 0); - } -} - -void func_80056160(s32 arg0) { - func_80055FA0(indexObjectList1[3], arg0); -} - void render_object_neon(s32 cameraId) { Camera* camera; s32 var_s2; diff --git a/src/render_objects.h b/src/render_objects.h index b77d7ce18..8559ce6ca 100644 --- a/src/render_objects.h +++ b/src/render_objects.h @@ -330,7 +330,6 @@ void func_80051F9C(void); void func_80052044(void); void func_80052080(void); void func_800520C0(s32); -void func_8005217C(s32); void func_800523B8(s32, s32, u32); void render_object_boos(s32); void render_object_bat(s32); @@ -361,7 +360,6 @@ void render_object_bowser_flame(s32); void func_8005477C(s32, u8, Vec3f); void render_object_smoke_particles(s32); void func_80054AFC(s32, Vec3f); -void func_80054BE8(s32); void func_80054D00(s32, s32); void func_80054E10(s32); void func_80054EB8(s32); @@ -430,6 +428,7 @@ void func_80057B14(s32, s32, char*, u32); void func_80057B80(s32, s32, char*, u32); void func_80057BEC(s32, s32, char*, u32); +extern Lights1 D_800E45C0[]; extern Lights1 D_800E4668; extern f32 D_801637C4; diff --git a/src/update_objects.c b/src/update_objects.c index e441e2392..fe25980cd 100644 --- a/src/update_objects.c +++ b/src/update_objects.c @@ -2289,6 +2289,18 @@ void func_80077428(s32 arg0) { func_80086E70(arg0); } + + + + + + + + + + + + void func_80077450(s32 objectIndex) { UNUSED s16 stackPadding0; s16 sp3C; @@ -2357,6 +2369,20 @@ void func_80077640(void) { } } + + + + + + + + + + + + + + void init_object_leaf_particle(s32 objectIndex, Vec3f arg1, s32 num) { UNUSED s32 stackPadding1; UNUSED u16 stackPadding0; @@ -4496,206 +4522,27 @@ void func_8007BB9C(s32 arg0) { func_8007B34C(arg0); } -void func_8007BBBC(s32 objectIndex) { - f32 var_f14; - Object* object; - object = &gObjectList[objectIndex]; - switch (object->state) { /* irregular */ - case 1: - func_800735BC(objectIndex, d_course_banshee_boardwalk_dl_cheep_cheep, 2.0f); - set_object_flag(objectIndex, 0x00000010); - object->unk_0D5 = 0; - break; - case 2: - if (gIsMirrorMode != 0) { - func_80087E08(objectIndex, 18.0f, 0.7f, 25.0f, (s16) -0x00005800, 0x0000012C); - } else { - func_80087E08(objectIndex, 18.0f, 0.7f, 25.0f, (s16) 0x00005800, 0x0000012C); - } - if (object->velocity[2] < 0.0f) { - var_f14 = -object->velocity[2]; - } else { - var_f14 = object->velocity[2]; - } - object->direction_angle[0] = func_80041658(object->velocity[1], var_f14); - set_and_run_timer_object(objectIndex, 0x00000046); - break; - case 3: - func_80072428(objectIndex); - break; - case 0: - break; - } -} -void func_8007BD04(s32 playerId) { - s32 objectIndex; - objectIndex = indexObjectList2[0]; - if (gObjectList[objectIndex].state == 0) { - if (((s32) gNearestWaypointByPlayerId[playerId] >= 0xA0) && - ((s32) gNearestWaypointByPlayerId[playerId] < 0xAB)) { - set_obj_origin_pos(objectIndex, xOrientation * -1650.0, -200.0f, -1650.0f); - init_object(objectIndex, 1); - } - } -} -void update_cheep_cheep_race(void) { - UNUSED s32 pad; - s32 objectIndex; - func_8007BD04(0); - objectIndex = indexObjectList2[0]; - func_8007BBBC(objectIndex); - object_calculate_new_pos_offset(objectIndex); -} -void init_var_cheep_cheep(s32 objectIndex) { - Object* object; - object = &gObjectList[objectIndex]; - object->unk_0D5 = 1; - object->status = 0; - object->model = d_course_banshee_boardwalk_dl_cheep_cheep; - object->sizeScaling = 0.2f; - object_next_state(objectIndex); - set_obj_origin_pos(objectIndex, D_800E634C[0][0], D_800E634C[0][1] + 55.0, D_800E634C[0][2]); - set_obj_origin_offset(objectIndex, 0.0f, 30.0f, 0.0f); - set_obj_direction_angle(objectIndex, 0U, 0x3800U, 0U); -} -void func_8007BEC8(s32 objectIndex) { - Object* object; - object = &gObjectList[objectIndex]; - switch (object->state) { - case 1: - init_var_cheep_cheep(objectIndex); - break; - case 2: - if (set_and_run_timer_object(objectIndex, 0x0000003C) != 0) { - set_object_flag(objectIndex, 0x00000010); - func_80086E70(objectIndex); - } - break; - case 3: - if (object->unk_0AE == 0) { - object_next_state(objectIndex); - } - break; - case 4: - if (set_and_run_timer_object(objectIndex, 0x0000000A) != 0) { - func_8008701C(objectIndex, 2); - } - break; - case 5: - if (object->unk_0AE == 0) { - func_80072428(objectIndex); - } - break; - case 0: - default: - break; - } -} -void func_8007BFB0(s32 objectIndex) { - Object* object; - object = &gObjectList[objectIndex]; - switch (object->unk_0AE) { - case 0: - break; - case 1: - object->velocity[1] = -0.2f; - if ((f64) object->offset[1] <= 0.0) { - object->offset[1] = 0.0f; - object->velocity[1] = 0.0f; - func_80086F60(objectIndex); - } - break; - case 2: - if (func_800871AC(objectIndex, 0x00000014) != 0) { - object->unk_084[7] = 0x0040; - } - break; - case 3: - object->sizeScaling = (f32) ((f64) object->sizeScaling - 0.0015); - if ((s32) object->direction_angle[0] >= 0xA01) { - object->unk_084[7] -= 4; - } - if (u16_step_up_towards(object->direction_angle, 0x0C00U, (u16) object->unk_084[7]) != 0) { - func_80086FD4(objectIndex); - } - break; - case 4: - object->sizeScaling = (f32) ((f64) object->sizeScaling - 0.0015); - object->unk_034 = 0.001f; - func_80086FD4(objectIndex); - object->unk_084[7] = 0; - break; - case 5: - if (object->unk_034 <= 0.004) { - object->unk_034 += 0.0002; - } - object->sizeScaling += object->unk_034; - s16_step_up_towards(&object->unk_084[7], 0x0100, 0x0010); - object->direction_angle[0] -= object->unk_084[7]; - if (func_80087060(objectIndex, 0x00000035) != 0) { - func_80086FD4(objectIndex); - } - break; - case 6: - if (func_80087060(objectIndex, 0x0000000F) != 0) { - func_80086FD4(objectIndex); - D_801658CE = 1; - } - break; - case 7: - object->sizeScaling = (f32) ((f64) object->sizeScaling - 0.05); - if ((f64) object->sizeScaling <= 0.01) { - clear_object_flag(objectIndex, 0x00000010); - object->sizeScaling = 0.000001f; - func_80086FD4(objectIndex); - } - break; - case 8: - func_80086F60(objectIndex); - break; - } - if (object->unk_0AE < 0xA) { - func_80074344(objectIndex, &object->sizeScaling, 0.2f, 0.21f, 0.001f, 0, -1); - } - object_add_velocity_offset_y(objectIndex); - object_calculate_new_pos_offset(objectIndex); -} -void update_cheep_cheep_ending(void) { - s32 objectIndex; - objectIndex = indexObjectList2[0]; - if (D_801658BC == 1) { - D_801658BC = 0; - init_object(objectIndex, 0); - } - if (gObjectList[objectIndex].state != 0) { - func_8007BEC8(objectIndex); - func_8007BFB0(objectIndex); - } -} -void update_cheep_cheep(s32 arg0) { - switch (arg0) { - case 0: - update_cheep_cheep_race(); - break; - case 1: - update_cheep_cheep_ending(); - break; - } -} + + + + + + + void wrapper_update_boos(void) { update_boos(); @@ -6366,254 +6213,3 @@ void update_neon(void) { } } } - -void func_8008629C(s32 objectIndex, s32 arg1) { - switch (arg1) { /* irregular */ - case 0: - gObjectList[objectIndex].model = podium_dl3; - gObjectList[objectIndex].unk_04C = 0x00000038; - break; - case 1: - gObjectList[objectIndex].model = podium2_dl3; - gObjectList[objectIndex].unk_04C = 0x0000002B; - break; - case 2: - gObjectList[objectIndex].model = podium3_dl3; - gObjectList[objectIndex].unk_04C = 0x0000001E; - break; - default: - break; - } - gObjectList[objectIndex].sizeScaling = 1.0f; - set_obj_origin_pos(objectIndex, D_800E634C[0][0] - 1.5, D_800E634C[0][1], D_800E634C[0][2]); - set_obj_origin_offset(objectIndex, 0.0f, -10.0f, 0.0f); - set_obj_direction_angle(objectIndex, 0U, 0xF8E4U, 0U); - gObjectList[objectIndex].unk_048 = 0; - object_next_state(objectIndex); -} - -void func_80086424(s32 objectIndex) { - switch (gObjectList[objectIndex].unk_0AE) { - case 0: - break; - case 1: - gObjectList[objectIndex].velocity[1] = 0.75f; - func_80086FD4(objectIndex); - break; - case 2: - if (gObjectList[objectIndex].offset[1] >= -2.0) { - gObjectList[objectIndex].velocity[1] -= 0.1; - } - object_add_velocity_offset_y(objectIndex); - if (gObjectList[objectIndex].offset[1] >= 0.0) { - gObjectList[objectIndex].offset[1] = 0.0f; - gObjectList[objectIndex].velocity[1] = 0.0f; - func_80086F60(objectIndex); - } - break; - } - object_calculate_new_pos_offset(objectIndex); -} - -void func_80086528(s32 objectIndex, s32 arg1) { - switch (gObjectList[objectIndex].state) { /* irregular */ - case 1: - func_8008629C(objectIndex, arg1); - break; - case 2: - if (set_and_run_timer_object(objectIndex, gObjectList[objectIndex].unk_04C) != 0) { - func_80091440(arg1); - func_80086E70(objectIndex); - object_next_state(objectIndex); - } - break; - case 0: - break; - case 3: - if (gObjectList[objectIndex].unk_0AE == 0) { - gObjectList[objectIndex].unk_048 = 1; - object_next_state(objectIndex); - } - break; - } -} - -void func_80086604(void) { - s32 objectIndex; - s32 var_s1; - - if ((D_8016347C != 0) && (D_802874D8.unk1D < 3)) { - if (D_801658C6 == 0) { - for (var_s1 = 0; var_s1 < 3; var_s1++) { - objectIndex = indexObjectList1[var_s1]; - init_object(objectIndex, 0); - } - D_801658C6 = 1; - } - } - for (var_s1 = 0; var_s1 != 3; var_s1++) { - objectIndex = indexObjectList1[var_s1]; - if (gObjectList[objectIndex].state != 0) { - func_80086528(objectIndex, var_s1); - func_80086424(objectIndex); - } - } -} - -void func_80086700(s32 objectIndex) { - if (gCCSelection < CC_150) { - switch (D_802874D8.unk1D) { /* switch 1; irregular */ - case 0: /* switch 1 */ - gObjectList[objectIndex].model = gold_trophy_dl10; - break; - case 1: /* switch 1 */ - gObjectList[objectIndex].model = gold_trophy_dl12; - break; - case 2: /* switch 1 */ - gObjectList[objectIndex].model = gold_trophy_dl14; - break; - default: /* switch 1 */ - break; - } - } else { - switch (D_802874D8.unk1D) { /* irregular */ - case 0: - gObjectList[objectIndex].model = gold_trophy_dl11; - break; - case 1: - gObjectList[objectIndex].model = gold_trophy_dl13; - break; - case 2: - gObjectList[objectIndex].model = gold_trophy_dl15; - break; - default: - break; - } - } - gObjectList[objectIndex].sizeScaling = 0.005f; - set_obj_origin_pos(objectIndex, gObjectList[indexObjectList2[0]].pos[0], - gObjectList[indexObjectList2[0]].pos[1] + 16.0, gObjectList[indexObjectList2[0]].pos[2]); - set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); - set_obj_direction_angle(objectIndex, 0U, 0U, 0U); - gObjectList[objectIndex].unk_084[1] = 0x0200; - object_next_state(objectIndex); - func_80086E70(objectIndex); -} - -void func_80086940(s32 objectIndex) { - Object* object; - - object = &gObjectList[objectIndex]; - switch (object->unk_0AE) { - case 0: - break; - case 1: - func_80086FD4(objectIndex); - break; - case 2: - f32_step_towards(&object->sizeScaling, 0.025f, 0.001f); - func_80087C48(objectIndex, 6.0f, 0.1f, 0x000000C8); - if ((f64) object->velocity[1] <= 0.0) { - func_8008701C(objectIndex, 3); - } - break; - case 3: - func_800871AC(objectIndex, 0x00000064); - break; - case 4: - D_801658D6 = 1; - object->velocity[1] = -0.4f; - func_80086FD4(objectIndex); - object->origin_pos[1] = 90.0f; - object->offset[1] = 60.0f; - switch (D_802874D8.unk1D) { /* switch 1; irregular */ - case 1: /* switch 1 */ - object->origin_pos[0] -= 3.0; - object->origin_pos[2] += 15.0; - break; - case 2: /* switch 1 */ - object->origin_pos[0] -= 2.0; - object->origin_pos[2] -= 15.0; - break; - } - break; - case 5: - if ((f64) object->offset[1] <= 8.0) { - f32_step_towards(&object->velocity[1], -0.1f, -0.01f); - } - object_add_velocity_offset_y(objectIndex); - if ((f64) object->offset[1] <= 0.0) { - func_80086FD4(objectIndex); - } - break; - case 6: - if (func_800871AC(objectIndex, 0x00000041) != 0) { - D_801658F4 = 1; - } - break; - case 7: - if (func_800871AC(objectIndex, 0x00000064) != 0) { - func_8009265C(); - func_80086F60(objectIndex); - } - break; - } - if (D_801658D6 != 0) { - object->direction_angle[0] += 0x400; - object->direction_angle[1] = 0xE800; - object->direction_angle[2] = 0xDA00; - } else { - object->direction_angle[0] += 0x400; - object->direction_angle[1] -= 0x200; - } - object_calculate_new_pos_offset(objectIndex); -} - -void func_80086C14(s32 objectIndex) { - switch (gObjectList[objectIndex].state) { /* irregular */ - case 1: - func_80086700(objectIndex); - break; - case 0: - case 2: - break; - } -} - -void func_80086C6C(s32 objectIndex) { - Vec3f sp24; - - sp24[0] = (gObjectList[objectIndex].pos[0] - 5.0f) + random_int(0x000AU); - sp24[2] = (gObjectList[objectIndex].pos[2] - 5.0f) + random_int(0x000AU); - if (D_801658F4 != 0) { - sp24[1] = gObjectList[objectIndex].pos[1] + 14.0; - } else { - sp24[1] = gObjectList[objectIndex].pos[1] - 2.0; - } - func_800773D8(sp24, (s32) D_801658F4); -} - -void func_80086D80(void) { - s32 temp_s2; - s32 var_s0; - - if ((D_801658CE != 0) && (D_801658DC == 0)) { - temp_s2 = indexObjectList1[3]; - init_object(temp_s2, 0); - D_801658DC = 1; - } - temp_s2 = indexObjectList1[3]; - if (gObjectList[temp_s2].state != 0) { - func_80086C14(temp_s2); - func_80086940(temp_s2); - if (D_801658F4 != 0) { - if (D_8016559C == 0) { - func_80086C6C(temp_s2); - } - } else { - for (var_s0 = 0; var_s0 < 2; var_s0++) { - func_80086C6C(temp_s2); - } - } - } -}