diff options
| author | MegaMech <inkstudios1@hotmail.com> | 2024-12-28 20:30:18 -0700 |
|---|---|---|
| committer | MegaMech <inkstudios1@hotmail.com> | 2024-12-28 20:30:18 -0700 |
| commit | 9c4b35206a2c697acc7345e91587c52a09240eb9 (patch) | |
| tree | 2f067808a40bc464e10b90ca69411e2220393de5 /src/engine | |
| parent | 830922541296d049cd5c0689c1f610586f56bc75 (diff) | |
Fix podium ceremony. Wip particle emitters
Diffstat (limited to 'src/engine')
| -rw-r--r-- | src/engine/World.cpp | 16 | ||||
| -rw-r--r-- | src/engine/World.h | 4 | ||||
| -rw-r--r-- | src/engine/courses/PodiumCeremony.cpp | 8 | ||||
| -rw-r--r-- | src/engine/objects/CheepCheep.cpp | 1 | ||||
| -rw-r--r-- | src/engine/objects/Object.h | 4 | ||||
| -rw-r--r-- | src/engine/objects/Podium.cpp | 30 | ||||
| -rw-r--r-- | src/engine/objects/Podium.h | 1 | ||||
| -rw-r--r-- | src/engine/objects/Trophy.cpp | 92 | ||||
| -rw-r--r-- | src/engine/objects/Trophy.h | 3 | ||||
| -rw-r--r-- | src/engine/particles/StarEmitter.cpp | 152 | ||||
| -rw-r--r-- | src/engine/particles/StarEmitter.h | 11 |
11 files changed, 279 insertions, 43 deletions
diff --git a/src/engine/World.cpp b/src/engine/World.cpp index b14c45219..5cd85213b 100644 --- a/src/engine/World.cpp +++ b/src/engine/World.cpp @@ -254,6 +254,10 @@ void World::TickObjects60fps() { } } +ParticleEmitter* World::AddEmitter(ParticleEmitter* emitter) { + Emitters.push_back(emitter); + return Emitters.back(); +} void World::DrawObjects(s32 cameraId) { for (const auto& object : Objects) { @@ -261,6 +265,18 @@ void World::DrawObjects(s32 cameraId) { } } +void World::TickParticles() { + for (const auto& emitter : Emitters) { + emitter->Tick(); + } +} + +void World::DrawParticles(s32 cameraId) { + for (const auto& emitter : Emitters) { + emitter->Draw(cameraId); + } +} + Object* World::GetObjectByIndex(size_t index) { //if (index < this->Objects.size()) { // Assuming GameActor::a is accessible, use reinterpret_cast if needed diff --git a/src/engine/World.h b/src/engine/World.h index 403a708c2..3fa687e76 100644 --- a/src/engine/World.h +++ b/src/engine/World.h @@ -164,6 +164,10 @@ public: void DrawObjects(s32 cameraId); Object *GetObjectByIndex(size_t); + void TickParticles(); + void DrawParticles(s32 cameraId); + ParticleEmitter* AddEmitter(ParticleEmitter* emitter); + void AddCup(Cup*); void SetCup(Cup* cup); const char* GetCupName(); diff --git a/src/engine/courses/PodiumCeremony.cpp b/src/engine/courses/PodiumCeremony.cpp index 6f04bd291..5c4bbe7fb 100644 --- a/src/engine/courses/PodiumCeremony.cpp +++ b/src/engine/courses/PodiumCeremony.cpp @@ -165,11 +165,11 @@ void PodiumCeremony::SpawnActors() { 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))); + gWorldInstance.AddObject(new OCheepCheep(FVector((f32)-3202, (f32)19, (f32)-478), OCheepCheep::CheepType::PODIUM_CEREMONY, IPathSpan(0, 0))); + gWorldInstance.AddObject(new OPodium(FVector((f32)-3202, (f32)19, (f32)-478))); - FVector pos = {0,0,0}; - pos.y = 90.0f; + FVector pos = {0, 90.0f, 0}; + OTrophy::TrophyType type = OTrophy::TrophyType::BRONZE; switch(D_802874D8.unk1D) { case 0: // Bronze diff --git a/src/engine/objects/CheepCheep.cpp b/src/engine/objects/CheepCheep.cpp index e81ba7c24..10cdf6602 100644 --- a/src/engine/objects/CheepCheep.cpp +++ b/src/engine/objects/CheepCheep.cpp @@ -52,7 +52,6 @@ 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) { diff --git a/src/engine/objects/Object.h b/src/engine/objects/Object.h index c41cfae6d..af2df81b5 100644 --- a/src/engine/objects/Object.h +++ b/src/engine/objects/Object.h @@ -11,14 +11,16 @@ class OObject { public: uint8_t uuid[16]; Object o; + bool PendingDestroy = false; virtual ~OObject() = default; explicit OObject(); virtual void Tick(); + virtual void Tick60fps(); virtual void Draw(s32 cameraId); virtual void Collision(); virtual void Expire(); - virtual void Destroy(); + virtual void Destroy(); // Mark object for deletion at the start of the next frame }; diff --git a/src/engine/objects/Podium.cpp b/src/engine/objects/Podium.cpp index 426a65b60..1922c98a5 100644 --- a/src/engine/objects/Podium.cpp +++ b/src/engine/objects/Podium.cpp @@ -27,24 +27,26 @@ extern Vec3s D_800E634C[]; OPodium::OPodium(const FVector& pos) { + _pos = 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); + //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; - // } - // } + 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) { @@ -58,9 +60,9 @@ void OPodium::Draw(s32 cameraId) { // func_80055F48 for (size_t i = 0; i < NUM_PODIUMS; i++) { Object* object; - object = &gObjectList[i]; + object = &gObjectList[indexObjectList1[i]]; if (object->state >= 2) { - func_80043220(object->pos, object->direction_angle, object->sizeScaling, object->model); + //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); @@ -86,7 +88,7 @@ void OPodium::func_8008629C(s32 objectIndex, s32 arg1) { 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_pos(objectIndex, _pos.x - 1.5, _pos.y, _pos.z); set_obj_origin_offset(objectIndex, 0.0f, -10.0f, 0.0f); set_obj_direction_angle(objectIndex, 0U, 0xF8E4U, 0U); gObjectList[objectIndex].unk_048 = 0; diff --git a/src/engine/objects/Podium.h b/src/engine/objects/Podium.h index 2b3a1033a..ea79d7232 100644 --- a/src/engine/objects/Podium.h +++ b/src/engine/objects/Podium.h @@ -35,4 +35,5 @@ public: private: s32 _idx; + FVector _pos; }; diff --git a/src/engine/objects/Trophy.cpp b/src/engine/objects/Trophy.cpp index 5ac54f5ec..c14cc23ca 100644 --- a/src/engine/objects/Trophy.cpp +++ b/src/engine/objects/Trophy.cpp @@ -24,7 +24,18 @@ OTrophy::OTrophy(const FVector& pos, TrophyType trophy, Behaviour bhv) { _spawnPos.y += 16.0f; // Adjust the height so the trophy sits on the surface when positioned to 0,0,0 _bhv = bhv; - init_object(objectIndex, 0); + if (bhv == OTrophy::Behaviour::PODIUM_CEREMONY) { + _toggleVisibility = &D_801658CE; + } else { + int8_t toggle = 1; + _toggleVisibility = &toggle; + _isMod = true; + } + + // This allows spawning for mods + if (*_toggleVisibility == true) { + init_object(objectIndex, 0); + } switch (trophy) { case TrophyType::GOLD: @@ -47,13 +58,6 @@ OTrophy::OTrophy(const FVector& pos, TrophyType trophy, Behaviour bhv) { break; } - if (OTrophy::Behaviour::PODIUM_CEREMONY) { - _toggleVisibility = &D_801658CE; - } else { - int8_t toggle = 1; - _toggleVisibility = &toggle; - } - // Set defaults for modded behaviours if (_bhv != OTrophy::Behaviour::PODIUM_CEREMONY) { gObjectList[objectIndex].sizeScaling = 0.025f; @@ -81,15 +85,15 @@ void OTrophy::Tick() { // func_80086D80 s32 objectIndex = indexObjectList1[3]; s32 var_s0; - // if ((D_801658CE != 0) && (D_801658DC == 0)) { - // temp_s2 = indexObjectList1[3]; - // init_object(temp_s2, 0); - // D_801658DC = 1; - // } + // Fallback for podium ceremony where the trophy is not spawned until it is needed + if ((*_toggleVisibility == true) && (D_801658DC == 0) && (_isMod == false)) { + init_object(objectIndex, 0); + D_801658DC = 1; + } switch(_bhv) { case OTrophy::Behaviour::PODIUM_CEREMONY: - if (gObjectList[objectIndex].state != 0) { + if (gObjectList[objectIndex].state != 0 && (*_toggleVisibility == true)) { OTrophy::func_80086C14(objectIndex); OTrophy::func_80086940(objectIndex); if (D_801658F4 != 0) { @@ -197,8 +201,7 @@ void OTrophy::Draw(s32 cameraId) { Mat4 someMatrix1; Mat4 someMatrix2; Object* object; - - if (_toggleVisibility) { + if (*_toggleVisibility == true) { object = &gObjectList[listIndex]; if (object->state >= 2) { gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[0]), @@ -332,3 +335,60 @@ void OTrophy::func_80086C6C(s32 objectIndex) { } func_800773D8(sp24, (s32) D_801658F4); } + +void OTrophy::func_800773D8(f32* arg0, s32 arg1) { + s32 objectIndex = add_unused_obj_index(gObjectParticle3, &gNextFreeObjectParticle3, gObjectParticle3_SIZE); + if (objectIndex != NULL_OBJECT_ID) { + func_80077138(objectIndex, arg0, arg1); + } +} + +void OTrophy::func_80077138(s32 objectIndex, Vec3f arg1, s32 arg2) { + s8 temp_v0_3; + Vec3s sp30; + + init_object(objectIndex, arg2); + gObjectList[objectIndex].unk_0D5 = 0x0C; + gObjectList[objectIndex].sizeScaling = 0.05f; + set_obj_origin_pos(objectIndex, arg1[0], arg1[1], arg1[2]); + set_obj_orientation(objectIndex, 0U, 0U, 0U); + set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); + switch (arg2) { + case 0: + gObjectList[objectIndex].velocity[1] = -1.0f; + gObjectList[objectIndex].unk_034 = (f32) ((random_int(0x004BU) * 0.01) + 0.25); + gObjectList[objectIndex].direction_angle[1] = random_int(0x0040U) << 0xA; + func_8008751C(objectIndex); + gObjectList[objectIndex].unk_084[5] = 0x001E; + break; + case 1: + gObjectList[objectIndex].velocity[1] = 1.5f; + gObjectList[objectIndex].unk_034 = (f32) ((random_int(0x0064U) * 0.01) + 0.5); + gObjectList[objectIndex].direction_angle[1] = random_int(0x0040U) << 0xA; + func_8008751C(objectIndex); + gObjectList[objectIndex].unk_084[5] = 0x0032; + break; + } + temp_v0_3 = random_int(0x000CU); + if (temp_v0_3 < 9) { + func_8005C674(temp_v0_3, &sp30[2], &sp30[1], sp30); + gObjectList[objectIndex].unk_048 = 0; + gObjectList[objectIndex].unk_084[0] = sp30[2]; + gObjectList[objectIndex].unk_084[1] = sp30[1]; + gObjectList[objectIndex].unk_084[2] = sp30[0]; + } else { + temp_v0_3 = random_int(3U); + func_8005C6B4(temp_v0_3, &sp30[2], &sp30[1], sp30); + gObjectList[objectIndex].unk_084[0] = sp30[2]; + gObjectList[objectIndex].unk_084[1] = sp30[1]; + gObjectList[objectIndex].unk_084[2] = sp30[0]; + gObjectList[objectIndex].unk_084[4] = temp_v0_3; + gObjectList[objectIndex].unk_048 = 1; + } + gObjectList[objectIndex].primAlpha = 0x00FF; + gObjectList[objectIndex].unk_084[3] = random_int(0x0800U) + 0x400; + if ((gObjectList[objectIndex].direction_angle[1] < 0x3000) || + (gObjectList[objectIndex].direction_angle[1] >= 0xB001)) { + gObjectList[objectIndex].unk_084[3] = -gObjectList[objectIndex].unk_084[3]; + } +}
\ No newline at end of file diff --git a/src/engine/objects/Trophy.h b/src/engine/objects/Trophy.h index d413faf12..a227ef5b9 100644 --- a/src/engine/objects/Trophy.h +++ b/src/engine/objects/Trophy.h @@ -43,6 +43,8 @@ public: void func_80086940(s32 objectIndex); void func_80086C14(s32 objectIndex); void func_80086C6C(s32 objectIndex); + void func_800773D8(f32* arg0, s32 arg1); + void func_80077138(s32 objectIndex, Vec3f arg1, s32 arg2); private: @@ -52,4 +54,5 @@ private: Behaviour _bhv; int8_t *_toggleVisibility; Vec3f _oldPos; + bool _isMod = false; }; diff --git a/src/engine/particles/StarEmitter.cpp b/src/engine/particles/StarEmitter.cpp index b717f177d..14745d39a 100644 --- a/src/engine/particles/StarEmitter.cpp +++ b/src/engine/particles/StarEmitter.cpp @@ -6,10 +6,89 @@ extern "C" { #include "render_objects.h" #include "common_data.h" #include "code_80057C60.h" +#include "update_objects.h" +#include "code_80086E70.h" +#include "math_util.h" +#include "math_util_2.h" } -void StarEmitter::Tick() { +StarEmitter::StarEmitter(FVector pos) { + s32 objectIndex = add_unused_obj_index(gObjectParticle3, &gNextFreeObjectParticle3, gObjectParticle3_SIZE); + s8 temp_v0_3; + Vec3s sp30; + if (objectIndex == NULL_OBJECT_ID) { + return; + //func_80077138(objectIndex, arg0, arg1); + } + + D_801658F4 = 1; + + init_object(objectIndex, D_801658F4); + gObjectList[objectIndex].unk_0D5 = 0x0C; + gObjectList[objectIndex].sizeScaling = 0.05f; + set_obj_origin_pos(objectIndex, pos.x, pos.y, pos.z); + set_obj_orientation(objectIndex, 0U, 0U, 0U); + set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); + switch (D_801658F4) { + case 0: + gObjectList[objectIndex].velocity[1] = -1.0f; + gObjectList[objectIndex].unk_034 = (f32) ((random_int(0x004BU) * 0.01) + 0.25); + gObjectList[objectIndex].direction_angle[1] = random_int(0x0040U) << 0xA; + func_8008751C(objectIndex); + gObjectList[objectIndex].unk_084[5] = 0x001E; + break; + case 1: + gObjectList[objectIndex].velocity[1] = 1.5f; + gObjectList[objectIndex].unk_034 = (f32) ((random_int(0x0064U) * 0.01) + 0.5); + gObjectList[objectIndex].direction_angle[1] = random_int(0x0040U) << 0xA; + func_8008751C(objectIndex); + gObjectList[objectIndex].unk_084[5] = 0x0032; + break; + } + temp_v0_3 = random_int(0x000CU); + if (temp_v0_3 < 9) { + func_8005C674(temp_v0_3, &sp30[2], &sp30[1], sp30); + gObjectList[objectIndex].unk_048 = 0; + gObjectList[objectIndex].unk_084[0] = sp30[2]; + gObjectList[objectIndex].unk_084[1] = sp30[1]; + gObjectList[objectIndex].unk_084[2] = sp30[0]; + } else { + temp_v0_3 = random_int(3U); + func_8005C6B4(temp_v0_3, &sp30[2], &sp30[1], sp30); + gObjectList[objectIndex].unk_084[0] = sp30[2]; + gObjectList[objectIndex].unk_084[1] = sp30[1]; + gObjectList[objectIndex].unk_084[2] = sp30[0]; + gObjectList[objectIndex].unk_084[4] = temp_v0_3; + gObjectList[objectIndex].unk_048 = 1; + } + gObjectList[objectIndex].primAlpha = 0x00FF; + gObjectList[objectIndex].unk_084[3] = random_int(0x0800U) + 0x400; + if ((gObjectList[objectIndex].direction_angle[1] < 0x3000) || + (gObjectList[objectIndex].direction_angle[1] >= 0xB001)) { + gObjectList[objectIndex].unk_084[3] = -gObjectList[objectIndex].unk_084[3]; + } +} + +void StarEmitter::Tick() { // func_80077640 + s32 someIndex; + s32 objectIndex; + Object* object; + + for (someIndex = 0; someIndex < gObjectParticle3_SIZE; someIndex++) { + objectIndex = gObjectParticle3[someIndex]; + if (objectIndex != DELETED_OBJECT_ID) { + object = &gObjectList[objectIndex]; + printf("Tick Star %d\n", object->state); + if (object->state != 0) { + StarEmitter::func_80077450(objectIndex); + StarEmitter::func_80077584(objectIndex); + if (object->state == 0) { + delete_object_wrapper(&gObjectParticle3[someIndex]); + } + } + } + } } void StarEmitter::Draw(s32 cameraId) { // func_80054BE8 @@ -22,10 +101,79 @@ void StarEmitter::Draw(s32 cameraId) { // func_80054BE8 load_texture_block_ia8_nomirror(D_8018D488, 0x00000020, 0x00000020); func_8004B35C(0x000000FF, 0x000000FF, 0, 0x000000FF); D_80183E80[0] = 0; + printf("Draw Star\n"); 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); + StarEmitter::func_80054AFC(temp_a0, camera->pos); } } } + +void StarEmitter::func_80054AFC(s32 objectIndex, Vec3f arg1) { + printf("Drawing Star!\n"); + D_80183E80[0] = func_800418E8(gObjectList[objectIndex].pos[2], gObjectList[objectIndex].pos[1], arg1); + D_80183E80[1] = func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], arg1); + D_80183E80[2] = (u16) gObjectList[objectIndex].orientation[2]; + func_8004B138((s32) gObjectList[objectIndex].unk_084[0], (s32) gObjectList[objectIndex].unk_084[1], + (s32) gObjectList[objectIndex].unk_084[2], (s32) gObjectList[objectIndex].primAlpha); + rsp_set_matrix_transformation(gObjectList[objectIndex].pos, (u16*) D_80183E80, + gObjectList[objectIndex].sizeScaling); + gSPVertex(gDisplayListHead++, (uintptr_t)D_0D005AE0, 4, 0); + gSPDisplayList(gDisplayListHead++, (Gfx*)common_rectangle_display); +} + +void StarEmitter::func_80077428(s32 objectIndex) { + object_next_state(objectIndex); + func_80086E70(objectIndex); +} + +void StarEmitter::func_80077584(s32 objectIndex) { + Object* object; + + object = &gObjectList[objectIndex]; + if ((object->unk_0AE != 0) && (object->unk_0AE == 1) && ((u8) object->unk_0D8 != 0)) { + if (object->velocity[1] >= -0.5) { + object->velocity[1] -= 0.15; + } else { + object->velocity[2] = 0.0f; + object->velocity[0] = 0.0f; + } + } + object->orientation[2] += object->unk_084[3]; + object_add_velocity_offset_xyz(objectIndex); + object_calculate_new_pos_offset(objectIndex); +} + +void StarEmitter::func_80077450(s32 objectIndex) { + UNUSED s16 stackPadding0; + s16 sp3C; + s16 sp3A; + s16 sp38; + + switch (gObjectList[objectIndex].state) { + case 0: + break; + case 1: + StarEmitter::func_80077428(objectIndex); + break; + case 2: + f32_step_up_towards(&gObjectList[objectIndex].sizeScaling, 0.1f, 0.01f); + if ((gObjectList[objectIndex].pos[1] <= gObjectList[objectIndex].unk_084[5]) && + (func_80073B00(objectIndex, &gObjectList[objectIndex].primAlpha, 0x000000FF, 0, 0x00000010, 0, 0) != + 0)) { + func_80086F60(objectIndex); + func_80072428(objectIndex); + } + break; + } + if (gObjectList[objectIndex].unk_048 != 0) { + printf("SOME THING\n"); + + gObjectList[objectIndex].unk_084[4] = (s16) ((s32) (gObjectList[objectIndex].unk_084[4] + 1) % 3); + func_8005C6B4(gObjectList[objectIndex].unk_084[4], &sp3C, &sp3A, &sp38); + gObjectList[objectIndex].unk_084[0] = sp3C; + gObjectList[objectIndex].unk_084[1] = sp3A; + gObjectList[objectIndex].unk_084[2] = sp38; + } +}
\ No newline at end of file diff --git a/src/engine/particles/StarEmitter.h b/src/engine/particles/StarEmitter.h index 20841598c..285c959f4 100644 --- a/src/engine/particles/StarEmitter.h +++ b/src/engine/particles/StarEmitter.h @@ -3,6 +3,7 @@ #include <libultraship.h> #include <vector> #include "ParticleEmitter.h" +#include "World.h" extern "C" { #include "macros.h" @@ -27,14 +28,14 @@ public: f32 Diameter = 0.0f; // Waddle in a circle around the spawn point at this diameter. uint16_t MirrorModeAngleOffset; - explicit StarEmitter(Vec3f pos); + explicit StarEmitter(FVector 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); + void func_80077428(s32 objectIndex); + void func_80077584(s32 objectIndex); + void func_80077450(s32 objectIndex); + void func_80054AFC(s32 objectIndex, Vec3f arg1); private: |
