diff options
| author | MegaMech <MegaMech@users.noreply.github.com> | 2024-12-31 09:50:21 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-31 09:50:21 -0700 |
| commit | 1101dcafb08a1f17b06306ff44a9d869ffeb7862 (patch) | |
| tree | e63c623057b555fedd3d017b5d6c34d12de31098 /src/engine/objects/Trophy.cpp | |
| parent | 7e6aba50a2a2fa80db153ad154f5ae77cc344650 (diff) | |
| parent | 7ee714e4e93609a5dbf1dc648df0ce504e3d7284 (diff) | |
Merge pull request #133 from MegaMech/next
Fix loadtile, Impl more OObjects
Diffstat (limited to 'src/engine/objects/Trophy.cpp')
| -rw-r--r-- | src/engine/objects/Trophy.cpp | 394 |
1 files changed, 394 insertions, 0 deletions
diff --git a/src/engine/objects/Trophy.cpp b/src/engine/objects/Trophy.cpp new file mode 100644 index 000000000..c14cc23ca --- /dev/null +++ b/src/engine/objects/Trophy.cpp @@ -0,0 +1,394 @@ +#include "Trophy.h" +#include "assets/common_data.h" +#include "assets/data_segment2.h" +extern "C" { +#include "main.h" +#include "defines.h" +#include "update_objects.h" +#include "code_80057C60.h" +#include "assets/ceremony_data.h" +#include "podium_ceremony_actors.h" +#include "math_util.h" +#include "math_util_2.h" +#include "data/some_data.h" +#include "engine/Matrix.h" +#include "render_objects.h" +#include "code_80086E70.h" +#include "code_80091750.h" +} + +OTrophy::OTrophy(const FVector& pos, TrophyType trophy, Behaviour bhv) { + s32 objectIndex = indexObjectList1[3]; + _trophy = trophy; + _spawnPos = pos; + _spawnPos.y += 16.0f; // Adjust the height so the trophy sits on the surface when positioned to 0,0,0 + _bhv = bhv; + + 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: + gObjectList[objectIndex].model = (Gfx*)gold_trophy_dl10; + break; + case TrophyType::SILVER: + gObjectList[objectIndex].model = (Gfx*)gold_trophy_dl12; + break; + case TrophyType::BRONZE: + gObjectList[objectIndex].model = (Gfx*)gold_trophy_dl14; + break; + case TrophyType::GOLD_150: + gObjectList[objectIndex].model = (Gfx*)gold_trophy_dl11; + break; + case TrophyType::SILVER_150: + gObjectList[objectIndex].model = (Gfx*)gold_trophy_dl13; + break; + case TrophyType::BRONZE_150: + gObjectList[objectIndex].model = (Gfx*)gold_trophy_dl15; + break; + } + + // Set defaults for modded behaviours + if (_bhv != OTrophy::Behaviour::PODIUM_CEREMONY) { + gObjectList[objectIndex].sizeScaling = 0.025f; + gObjectList[objectIndex].unk_084[1] = 0x0200; + object_next_state(objectIndex); + func_80086E70(objectIndex); + } + + switch(_bhv) { + case OTrophy::Behaviour::GO_FISH: + gObjectList[objectIndex].sizeScaling = 0.010f; + break; + } + + Object *object = &gObjectList[objectIndex]; + object->origin_pos[0] = _spawnPos.x; + object->origin_pos[1] = _spawnPos.y; + object->origin_pos[2] = _spawnPos.z; + object->pos[0] = _spawnPos.x; + object->pos[1] = _spawnPos.y; + object->pos[2] = _spawnPos.z; +} + +void OTrophy::Tick() { // func_80086D80 + s32 objectIndex = indexObjectList1[3]; + s32 var_s0; + + // 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 && (*_toggleVisibility == true)) { + OTrophy::func_80086C14(objectIndex); + OTrophy::func_80086940(objectIndex); + if (D_801658F4 != 0) { + if (D_8016559C == 0) { + OTrophy::func_80086C6C(objectIndex); + } + } else { + for (var_s0 = 0; var_s0 < 2; var_s0++) { + OTrophy::func_80086C6C(objectIndex); + } + } + } + break; + + case OTrophy::Behaviour::STATIONARY: + if (gObjectList[objectIndex].state != 0) { + gObjectList[objectIndex].sizeScaling = 0.025f; + set_obj_origin_pos(objectIndex, _spawnPos.x, + _spawnPos.y + 16.0, _spawnPos.z); + 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); + OTrophy::func_80086940(objectIndex); + } + break; + case OTrophy::Behaviour::ROTATE: + if (gObjectList[objectIndex].state != 0) { + + gObjectList[objectIndex].direction_angle[0] += 0x400; + gObjectList[objectIndex].direction_angle[1] -= 0x200; + } + break; + case OTrophy::Behaviour::ROTATE2: + if (gObjectList[objectIndex].state != 0) { + + gObjectList[objectIndex].direction_angle[0] += 0x400; + gObjectList[objectIndex].direction_angle[1] = 0xE800; + gObjectList[objectIndex].direction_angle[2] = 0xDA00; + } + break; + case OTrophy::Behaviour::GO_FISH: + if (gObjectList[objectIndex].state != 0) { + + // Get the player's yaw + Player *player = &gPlayers[0]; + float yaw = (player->rotation[1] + 0x4000) * (M_PI / 32768.0f); // Convert degrees to radians + + // Calculate forward direction based on yaw (same as before) + float lookAtX = player->pos[0] + cos(yaw); + float lookAtZ = player->pos[2] + sin(yaw); + + float forwardX = lookAtX - player->pos[0]; + float forwardY = 0; // Optional: Ignore height changes + float forwardZ = lookAtZ - player->pos[2]; + + // Normalize the forward vector + float length = sqrtf(forwardX * forwardX + forwardZ * forwardZ); + if (length != 0) { + forwardX /= length; + forwardZ /= length; + } + + float distance = 30.0f; + + // Calculate the object's position in front of the player (same as before) + gObjectList[objectIndex].pos[0] = player->pos[0] + forwardX * distance; + gObjectList[objectIndex].pos[1] = player->pos[1] + 8.0f; // Optional height offset + gObjectList[objectIndex].pos[2] = player->pos[2] + forwardZ * distance; + + // Apply more sensitive random movement based on player velocity to simulate floating behavior + float velocityFactor = 0.1f; // Increased factor for more sensitivity + gObjectList[objectIndex].pos[0] += player->velocity[0] * velocityFactor; + gObjectList[objectIndex].pos[1] += player->velocity[1] * velocityFactor; // Optional: Add vertical movement + gObjectList[objectIndex].pos[2] += player->velocity[2] * velocityFactor; + + // Increase oscillation for more dynamic movement (sine wave effect) + float oscillationSpeed = 4.0f; // Increased speed for quicker oscillations + float oscillationAmplitude = 0.4f; // Increased amplitude for more noticeable movement + gObjectList[objectIndex].pos[1] += oscillationAmplitude * sinf(oscillationSpeed * gGlobalTimer); // Vertical oscillation based on time + + // Now use smooth interpolation (lerp) to gradually move the trophy towards its target position + float lerpFactor = 0.25f; // Increased to make the trophy follow the player more quickly + + gObjectList[objectIndex].pos[0] = _oldPos[0] + lerpFactor * (gObjectList[objectIndex].pos[0] - _oldPos[0]); + gObjectList[objectIndex].pos[1] = _oldPos[1] + lerpFactor * (gObjectList[objectIndex].pos[1] - _oldPos[1]); + gObjectList[objectIndex].pos[2] = _oldPos[2] + lerpFactor * (gObjectList[objectIndex].pos[2] - _oldPos[2]); + + // Save the current position for the next frame + _oldPos[0] = gObjectList[objectIndex].pos[0]; + _oldPos[1] = gObjectList[objectIndex].pos[1]; + _oldPos[2] = gObjectList[objectIndex].pos[2]; + + + gObjectList[objectIndex].direction_angle[0] += 0x400; + gObjectList[objectIndex].direction_angle[1] -= 0x200; + } + break; + } +} + +void OTrophy::Draw(s32 cameraId) { + s32 listIndex = indexObjectList1[3]; + Mat4 someMatrix1; + Mat4 someMatrix2; + Object* object; + if (*_toggleVisibility == true) { + object = &gObjectList[listIndex]; + 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++, (Gfx*)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); + } + + switch (_bhv) { + case GO_FISH: + size_t numTrophies = 0; + func_80057A50(40, 0, (char*) "Trophies Collected: ", (s16) numTrophies); + break; + } + } +} + +void OTrophy::func_80086700(s32 objectIndex) { + 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 OTrophy::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) { + // case 1: + // object->origin_pos[0] -= 3.0; + // object->origin_pos[2] += 15.0; + // break; + // case 2: + // 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 OTrophy::func_80086C14(s32 objectIndex) { + switch (gObjectList[objectIndex].state) { /* irregular */ + case 1: + OTrophy::func_80086700(objectIndex); + break; + case 0: + case 2: + break; + } +} + +void OTrophy::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 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 |
