diff --git a/src/code_800029B0.c b/src/code_800029B0.c index a75691622..88453dcaa 100644 --- a/src/code_800029B0.c +++ b/src/code_800029B0.c @@ -323,8 +323,8 @@ void credits_spawn_actors(void) { gNextFreeMemoryAddress += 0x9000; destroy_all_actors(); CM_CleanWorld(); - CM_CreditsSpawnActors(); + CM_BeginPlay(); gNumPermanentActors = gNumActors; } diff --git a/src/ending/ceremony_and_credits.c b/src/ending/ceremony_and_credits.c index 5b964e0d6..fd8b2405c 100644 --- a/src/ending/ceremony_and_credits.c +++ b/src/ending/ceremony_and_credits.c @@ -22,7 +22,8 @@ #include "code_80057C60.h" #include "defines.h" -#include "src/port/Engine.h" +#include "port/Engine.h" +#include "port/Game.h" f32 D_802856B0 = 98.0f; f32 D_802856B4 = 12.0f; @@ -996,8 +997,11 @@ void func_80284154(CinematicCamera* camera) { void func_80284184(CinematicCamera* camera) { f32 trophy; - trophy = ((gObjectList[indexObjectList1[3]].pos[1] - camera->lookAt[1]) * 0.9f) + camera->lookAt[1]; - f32_lerp(&camera->pos[1], trophy, 0.5); + + if (gTrophyIndex != NULL) { + trophy = ((gObjectList[gTrophyIndex].pos[1] - camera->lookAt[1]) * 0.9f) + camera->lookAt[1]; + f32_lerp(&camera->pos[1], trophy, 0.5); + } } void func_802841E8(CinematicCamera* camera) { diff --git a/src/engine/TrainCrossing.cpp b/src/engine/TrainCrossing.cpp index 2d4442a30..8dce6984b 100644 --- a/src/engine/TrainCrossing.cpp +++ b/src/engine/TrainCrossing.cpp @@ -10,11 +10,12 @@ extern "C" { #include "main.h" #include "vehicles.h" #include "code_80005FD0.h" +#include "code_80057C60.h" #include "common_structs.h" } TrainCrossing::TrainCrossing(Vec3f position, u32 waypointMin, u32 waypointMax, f32 approachRadius, f32 exitRadius) { - Position[0] = position[0]; + Position[0] = position[0] * xOrientation; Position[1] = position[1]; Position[2] = position[2]; ApproachRadius = approachRadius; diff --git a/src/engine/World.cpp b/src/engine/World.cpp index d67a2577c..a63c22b10 100644 --- a/src/engine/World.cpp +++ b/src/engine/World.cpp @@ -195,6 +195,13 @@ void World::DrawParticles(s32 cameraId) { } } +// Sets OObjects or AActors static member variables back to default values +void World::Reset() { + for (const auto& object : Objects) { + object->Reset(); + } +} + 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 3ba6e0437..9490293b7 100644 --- a/src/engine/World.h +++ b/src/engine/World.h @@ -65,6 +65,7 @@ public: void TickParticles(); void DrawParticles(s32 cameraId); ParticleEmitter* AddEmitter(ParticleEmitter* emitter); + void Reset(void); // Sets OObjects or AActors static member variables back to default values void AddCup(Cup*); void SetCup(Cup* cup); diff --git a/src/engine/actors/AFinishline.cpp b/src/engine/actors/AFinishline.cpp index cc920f2bb..77dd37ede 100644 --- a/src/engine/actors/AFinishline.cpp +++ b/src/engine/actors/AFinishline.cpp @@ -1,5 +1,6 @@ #include #include +#include "CoreMath.h" #include "AFinishline.h" #include "engine/Actor.h" @@ -16,23 +17,24 @@ extern f32 gKartHopInitialVelocityTable[]; extern f32 gKartGravityTable[]; } -AFinishline::AFinishline(Vec3f pos) { - if (pos != nullptr) { // Allow user to set their own values - Pos[0] = pos[0]; - Pos[1] = pos[1] - 15; - Pos[2] = pos[2]; - } else { // Default to first waypoint position - Pos[0] = D_80164490->posX; - Pos[1] = (f32) (D_80164490->posY - 15); - Pos[2] = D_80164490->posZ; +AFinishline::AFinishline(std::optional pos) { + + if (pos.has_value()) { + // Set spawn point to the provided position + Pos[0] = D_8015F8D0[0] = pos.value().x; + Pos[1] = D_8015F8D0[1] = pos.value().y - 15; + Pos[2] = D_8015F8D0[2] = pos.value().z; + } else { + // Set spawn point to the tracks first path point. + Pos[0] = D_8015F8D0[0] = D_80164490->posX; + Pos[1] = D_8015F8D0[1] = (f32) (D_80164490->posY - 15); + Pos[2] = D_8015F8D0[2] = D_80164490->posZ; } Rot[0] = 0; Rot[1] = 0; Rot[2] = 0; - - Flags = -0x8000 | 0x4000; BoundingBoxSize = 0.0f; @@ -40,8 +42,6 @@ AFinishline::AFinishline(Vec3f pos) { void AFinishline::Tick() {} -extern Gfx cloud_mesh[]; - void AFinishline::Draw(Camera *camera) { Mat4 mtx; s16 temp = Pos[2]; diff --git a/src/engine/actors/AFinishline.h b/src/engine/actors/AFinishline.h index ea27f3b61..61b561a5e 100644 --- a/src/engine/actors/AFinishline.h +++ b/src/engine/actors/AFinishline.h @@ -1,6 +1,7 @@ #pragma once #include +#include "CoreMath.h" #include "engine/Actor.h" extern "C" { @@ -16,7 +17,7 @@ public: * Default behaviour places the finishline at the first waypoint. * @arg pos, optional. Sets a custom position */ - AFinishline(Vec3f pos = nullptr); + AFinishline(std::optional pos); virtual ~AFinishline() override = default; diff --git a/src/engine/courses/BansheeBoardwalk.cpp b/src/engine/courses/BansheeBoardwalk.cpp index 4ff92d107..5ebaf2bc1 100644 --- a/src/engine/courses/BansheeBoardwalk.cpp +++ b/src/engine/courses/BansheeBoardwalk.cpp @@ -150,8 +150,6 @@ void BansheeBoardwalk::LoadTextures() { } void BansheeBoardwalk::BeginPlay() { - gWorldInstance.AddActor(new AFinishline()); - spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_banshee_boardwalk_item_box_spawns)); diff --git a/src/engine/courses/BowsersCastle.cpp b/src/engine/courses/BowsersCastle.cpp index 6f4ecccc5..cac1dde92 100644 --- a/src/engine/courses/BowsersCastle.cpp +++ b/src/engine/courses/BowsersCastle.cpp @@ -149,8 +149,6 @@ void BowsersCastle::LoadTextures() { } void BowsersCastle::BeginPlay() { - gWorldInstance.AddActor(new AFinishline()); - spawn_foliage((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_bowsers_castle_tree_spawn)); spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_bowsers_castle_item_box_spawns)); diff --git a/src/engine/courses/ChocoMountain.cpp b/src/engine/courses/ChocoMountain.cpp index 4406159e9..632f31981 100644 --- a/src/engine/courses/ChocoMountain.cpp +++ b/src/engine/courses/ChocoMountain.cpp @@ -164,7 +164,6 @@ void ChocoMountain::LoadTextures() { } void ChocoMountain::BeginPlay() { - gWorldInstance.AddActor(new AFinishline()); spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_choco_mountain_item_box_spawns)); spawn_falling_rocks((struct ActorSpawnData*)LOAD_ASSET_RAW((const char*)d_course_choco_mountain_falling_rock_spawns)); diff --git a/src/engine/courses/Course.cpp b/src/engine/courses/Course.cpp index 3b2ac641d..3e5c0b2ab 100644 --- a/src/engine/courses/Course.cpp +++ b/src/engine/courses/Course.cpp @@ -225,11 +225,6 @@ void Course::Waypoints(Player* player, int8_t playerId) { } } -void Course::SpawnVehicles() { -} -void Course::UpdateVehicles() { -} - void Course::Render(struct UnkStruct_800DC5EC* arg0) { } void Course::RenderCredits() { diff --git a/src/engine/courses/Course.h b/src/engine/courses/Course.h index d4f637073..889012a12 100644 --- a/src/engine/courses/Course.h +++ b/src/engine/courses/Course.h @@ -78,6 +78,8 @@ public: const char* gfx = nullptr; size_t gfxSize = 0; const course_texture* textures = nullptr; + bool bSpawnFinishline = true; + std::optional FinishlineSpawnPoint; virtual ~Course() = default; @@ -107,8 +109,6 @@ public: virtual void SetStaffGhost(); virtual void Render(struct UnkStruct_800DC5EC*); virtual void RenderCredits(); - virtual void SpawnVehicles(); - virtual void UpdateVehicles(); virtual void Waypoints(Player* player, int8_t playerId); virtual void Collision(); virtual void ScrollingTextures(); diff --git a/src/engine/courses/DKJungle.cpp b/src/engine/courses/DKJungle.cpp index a49a029c3..bb9c951bc 100644 --- a/src/engine/courses/DKJungle.cpp +++ b/src/engine/courses/DKJungle.cpp @@ -151,29 +151,29 @@ void DKJungle::LoadTextures() { } void DKJungle::BeginPlay() { - gWorldInstance.AddActor(new AFinishline()); - spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_dks_jungle_parkway_item_box_spawns)); + init_kiwano_fruit(); func_80298D10(); + if (gGamestate != CREDITS_SEQUENCE) { + generate_ferry_waypoints(); - generate_ferry_waypoints(); + // The original game only ran vehicle logic every second frame. + // Thus the speed gets divided by two to set speed to match properly + gWorldInstance.AddActor(new ABoat((0.6666666f)/4, 0)); - // The original game only ran vehicle logic every second frame. - // Thus the speed gets divided by two to set speed to match properly - gWorldInstance.AddActor(new ABoat((0.6666666f)/4, 0)); + if (gModeSelection == VERSUS) { + Vec3f pos = {0, 0, 0}; - if (gModeSelection == VERSUS) { - Vec3f pos = {0, 0, 0}; - - gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][50], 50, 3, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][100], 100, 1, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][150], 150, 3, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][190], 190, 1, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][250], 250, 3, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][50], 50, 3, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][100], 100, 1, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][150], 150, 3, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][190], 190, 1, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][250], 250, 3, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f)); + } } } diff --git a/src/engine/courses/FrappeSnowland.cpp b/src/engine/courses/FrappeSnowland.cpp index 61527d685..7383946d1 100644 --- a/src/engine/courses/FrappeSnowland.cpp +++ b/src/engine/courses/FrappeSnowland.cpp @@ -128,8 +128,6 @@ void FrappeSnowland::LoadTextures() { } void FrappeSnowland::BeginPlay() { - gWorldInstance.AddActor(new AFinishline()); - spawn_foliage((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_frappe_snowland_tree_spawns)); spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_frappe_snowland_item_box_spawns)); diff --git a/src/engine/courses/KalimariDesert.cpp b/src/engine/courses/KalimariDesert.cpp index e783d4e0f..133a38e08 100644 --- a/src/engine/courses/KalimariDesert.cpp +++ b/src/engine/courses/KalimariDesert.cpp @@ -141,75 +141,77 @@ void KalimariDesert::BeginPlay() { Vec3f velocity = { 0.0f, 0.0f, 0.0f }; Vec3s rotation = { 0, 0, 0 }; - gWorldInstance.AddActor(new AFinishline()); - spawn_foliage((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_kalimari_desert_cactus_spawn)); spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_kalimari_desert_item_box_spawns)); - Vec3f crossingPos = {-2500, 2, 2355}; - Vec3f crossingPos2 = {-1639, 2, 68}; - uintptr_t* crossing1 = (uintptr_t*) gWorldInstance.AddCrossing(crossingPos, 306, 310, 900.0f, 650.0f); - uintptr_t* crossing2 = (uintptr_t*) gWorldInstance.AddCrossing(crossingPos2, 176, 182, 900.0f, 650.0f); + if (gGamestate != CREDITS_SEQUENCE) { - vec3f_set(position, -1680.0f, 2.0f, 35.0f); - position[0] *= gCourseDirection; - rrxing = (struct RailroadCrossing*) GET_ACTOR(add_actor_to_empty_slot(position, rotation, velocity, - ACTOR_RAILROAD_CROSSING)); - rrxing->crossingTrigger = crossing2; - vec3f_set(position, -1600.0f, 2.0f, 35.0f); - position[0] *= gCourseDirection; - rrxing = (struct RailroadCrossing*) GET_ACTOR(add_actor_to_empty_slot(position, rotation, velocity, - ACTOR_RAILROAD_CROSSING)); - rrxing->crossingTrigger = crossing2; - vec3s_set(rotation, 0, -0x2000, 0); - vec3f_set(position, -2459.0f, 2.0f, 2263.0f); - position[0] *= gCourseDirection; - rrxing = (struct RailroadCrossing*) GET_ACTOR(add_actor_to_empty_slot(position, rotation, velocity, - ACTOR_RAILROAD_CROSSING)); - rrxing->crossingTrigger = crossing1; - vec3f_set(position, -2467.0f, 2.0f, 2375.0f); - position[0] *= gCourseDirection; - rrxing = (struct RailroadCrossing*) GET_ACTOR(add_actor_to_empty_slot(position, rotation, velocity, - ACTOR_RAILROAD_CROSSING)); - rrxing->crossingTrigger = crossing1; + Vec3f crossingPos = {-2500, 2, 2355}; + Vec3f crossingPos2 = {-1639, 2, 68}; + uintptr_t* crossing1 = (uintptr_t*) gWorldInstance.AddCrossing(crossingPos, 306, 310, 900.0f, 650.0f); + uintptr_t* crossing2 = (uintptr_t*) gWorldInstance.AddCrossing(crossingPos2, 176, 182, 900.0f, 650.0f); + + vec3f_set(position, -1680.0f, 2.0f, 35.0f); + position[0] *= gCourseDirection; + rrxing = (struct RailroadCrossing*) GET_ACTOR(add_actor_to_empty_slot(position, rotation, velocity, + ACTOR_RAILROAD_CROSSING)); + rrxing->crossingTrigger = crossing2; + vec3f_set(position, -1600.0f, 2.0f, 35.0f); + position[0] *= gCourseDirection; + rrxing = (struct RailroadCrossing*) GET_ACTOR(add_actor_to_empty_slot(position, rotation, velocity, + ACTOR_RAILROAD_CROSSING)); + rrxing->crossingTrigger = crossing2; + + // Original game forgot to put gCourseDirection to face the crossing the right direction in extra mode + vec3s_set(rotation, 0, -0x2000 * gCourseDirection, 0); + vec3f_set(position, -2459.0f, 2.0f, 2263.0f); + position[0] *= gCourseDirection; + rrxing = (struct RailroadCrossing*) GET_ACTOR(add_actor_to_empty_slot(position, rotation, velocity, + ACTOR_RAILROAD_CROSSING)); + rrxing->crossingTrigger = crossing1; + vec3f_set(position, -2467.0f, 2.0f, 2375.0f); + position[0] *= gCourseDirection; + rrxing = (struct RailroadCrossing*) GET_ACTOR(add_actor_to_empty_slot(position, rotation, velocity, + ACTOR_RAILROAD_CROSSING)); + rrxing->crossingTrigger = crossing1; + generate_train_waypoints(); - generate_train_waypoints(); + s32 centerWaypoint = 160; - s32 centerWaypoint = 160; + // Spawn two trains + for (size_t i = 0; i < _numTrains; ++i) { + uint32_t waypoint = CalculateWaypointDistribution(i, _numTrains, gVehicle2DWaypointLength, centerWaypoint); - // Spawn two trains - for (size_t i = 0; i < _numTrains; ++i) { - uint32_t waypoint = CalculateWaypointDistribution(i, _numTrains, gVehicle2DWaypointLength, centerWaypoint); + if (CVarGetInteger("gMultiplayerNoFeatureCuts", 0) == false) { + // Multiplayer modes have no tender and no carriages + if (gActiveScreenMode != SCREEN_MODE_1P) { + _tender = ATrain::TenderStatus::NO_TENDER; + _numCarriages = 0; + } - if (CVarGetInteger("gMultiplayerNoFeatureCuts", 0) == false) { - // Multiplayer modes have no tender and no carriages - if (gActiveScreenMode != SCREEN_MODE_1P) { - _tender = ATrain::TenderStatus::NO_TENDER; - _numCarriages = 0; + // 2 player versus mode has a tender and a carriage + if ((gModeSelection == VERSUS) && (gPlayerCountSelection1 == 2)) { + _tender = ATrain::TenderStatus::HAS_TENDER; + _numCarriages = 1; + } } - // 2 player versus mode has a tender and a carriage - if ((gModeSelection == VERSUS) && (gPlayerCountSelection1 == 2)) { - _tender = ATrain::TenderStatus::HAS_TENDER; - _numCarriages = 1; - } + gWorldInstance.AddActor(new ATrain(_tender, _numCarriages, 2.5f, waypoint)); } - gWorldInstance.AddActor(new ATrain(_tender, _numCarriages, 2.5f, waypoint)); - } + if (gModeSelection == VERSUS) { + Vec3f pos = {0, 0, 0}; - if (gModeSelection == VERSUS) { - Vec3f pos = {0, 0, 0}; - - gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][50], 50, 3, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][138], 138, 1, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][280], 280, 3, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][404], 404, 1, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][510], 510, 3, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][50], 50, 3, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][138], 138, 1, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][280], 280, 3, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][404], 404, 1, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][510], 510, 3, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f)); + } } } diff --git a/src/engine/courses/KoopaTroopaBeach.cpp b/src/engine/courses/KoopaTroopaBeach.cpp index 4e017912e..3fd22598a 100644 --- a/src/engine/courses/KoopaTroopaBeach.cpp +++ b/src/engine/courses/KoopaTroopaBeach.cpp @@ -140,8 +140,6 @@ void KoopaTroopaBeach::LoadTextures() { } void KoopaTroopaBeach::BeginPlay() { - gWorldInstance.AddActor(new AFinishline()); - init_actor_hot_air_balloon_item_box(328.0f * gCourseDirection, 70.0f, 2541.0f); spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_koopa_troopa_beach_item_box_spawns)); spawn_palm_trees((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_koopa_troopa_beach_tree_spawn)); @@ -161,21 +159,15 @@ void KoopaTroopaBeach::BeginPlay() { if (gGamestate == CREDITS_SEQUENCE) { for (size_t i = 0; i < NUM_SEAGULLS; i++) { - //gWorldInstance.AddObject(new OSeagull(FVector(-360.0f, 60.0f, -1300.0f))); - Vec3f pos = {-360.0f, 60.0f, -1300.0f}; - gWorldInstance.AddObject(new OSeagull(pos)); + gWorldInstance.AddObject(new OSeagull(FVector(-360.0f, 60.0f, -1300.0f))); } } else { // Normal gameplay for (size_t i = 0; i < 4; i++) { - Vec3f pos = {-985.0f, 15.0f, 1200.0f}; - gWorldInstance.AddObject(new OSeagull(pos)); - //gWorldInstance.AddObject(new OSeagull(FVector(-985.0f, 15.0f, 1200.0f))); + gWorldInstance.AddObject(new OSeagull(FVector(-985.0f, 15.0f, 1200.0f))); } for (size_t i = 0; i < 6; i++) { - //gWorldInstance.AddObject(new OSeagull(FVector(328.0f, 20.0f, 2541.0f))); - Vec3f pos2 = {328.0f, 20.0f, 2541.0f}; - gWorldInstance.AddObject(new OSeagull(pos2)); + gWorldInstance.AddObject(new OSeagull(FVector(328.0f, 20.0f, 2541.0f))); } } diff --git a/src/engine/courses/LuigiRaceway.cpp b/src/engine/courses/LuigiRaceway.cpp index a821ec2d9..555af3212 100644 --- a/src/engine/courses/LuigiRaceway.cpp +++ b/src/engine/courses/LuigiRaceway.cpp @@ -165,7 +165,6 @@ void LuigiRaceway::LoadTextures() { } void LuigiRaceway::BeginPlay() { - 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)); diff --git a/src/engine/courses/MarioRaceway.cpp b/src/engine/courses/MarioRaceway.cpp index a2cc96525..e3b9bba21 100644 --- a/src/engine/courses/MarioRaceway.cpp +++ b/src/engine/courses/MarioRaceway.cpp @@ -180,8 +180,6 @@ void MarioRaceway::BeginPlay() { Vec3f velocity = { 0.0f, 0.0f, 0.0f }; Vec3s rotation = { 0, 0, 0 }; - gWorldInstance.AddActor(new AFinishline()); - spawn_foliage((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_mario_raceway_tree_spawns)); spawn_piranha_plants((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_mario_raceway_piranha_plant_spawns)); spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_mario_raceway_item_box_spawns)); @@ -204,10 +202,6 @@ void MarioRaceway::BeginPlay() { } } -void MarioRaceway::SpawnVehicles() { - -} - // Likely sets minimap boundaries void MarioRaceway::MinimapSettings() { D_8018D220 = reinterpret_cast(dma_textures(gTextureExhaust5, 0x443, 0x1000)); diff --git a/src/engine/courses/MarioRaceway.h b/src/engine/courses/MarioRaceway.h index 9714fd0f5..a91226dbe 100644 --- a/src/engine/courses/MarioRaceway.h +++ b/src/engine/courses/MarioRaceway.h @@ -27,7 +27,6 @@ public: virtual void Load() override; virtual void LoadTextures() override; virtual void BeginPlay() override; - virtual void SpawnVehicles() override; virtual void MinimapSettings() override; virtual void InitCourseObjects() override; virtual void SomeSounds() override; diff --git a/src/engine/courses/MooMooFarm.cpp b/src/engine/courses/MooMooFarm.cpp index 5adaeb2a6..cf83a920d 100644 --- a/src/engine/courses/MooMooFarm.cpp +++ b/src/engine/courses/MooMooFarm.cpp @@ -8,6 +8,7 @@ #include "engine/actors/AFinishline.h" #include "engine/objects/BombKart.h" #include "assets/moo_moo_farm_data.h" +#include "engine/objects/MoleGroup.h" #include "engine/objects/Mole.h" extern "C" { @@ -159,14 +160,156 @@ void MooMooFarm::LoadTextures() { dma_textures(gTextureCow05Right, 0x00000400U, 0x00000800U); } -void MooMooFarm::BeginPlay() { - gWorldInstance.AddActor(new AFinishline()); +// These are full arrays that are not used in the original game +static std::vector sMoleSpawns1 = { + { FVector(771, 20, -2022) }, + { FVector(807, 15, -2063) }, + { FVector(847, 18, -2040) }, + { FVector(913, 14, -2054) }, + { FVector(939, 21, -1997) }, + { FVector(941, 17, -2024) }, + { FVector(994, 17, -1994) }, + { FVector(863, 22, -2010) }, +}; +static std::vector sMoleSpawns2 = { + { FVector(1500, 2, 1140) }, + { FVector(1510, 15, 1050) }, + { FVector(1609, 21, 935) }, + { FVector(1289, 3, 1269) }, + { FVector(1468, 22, 1046) }, + { FVector(1380, 12, 1154) }, + { FVector(1297, 19, 1170) }, + { FVector(1589, 11, 1004) }, + { FVector(1414, 3, 1185) }, + { FVector(1405, 4, 1254) }, + { FVector(1463, 8, 1118) }, +}; + +static std::vector sMoleSpawns3 = { + { FVector(701, 2, 1279) }, + { FVector(811, 8, 1278) }, + { FVector(791, 16, 1229) }, + { FVector(876, 15, 1266) }, + { FVector(984, 23, 1248) }, + { FVector(891, 20, 1242) }, + { FVector(920, 15, 1304) }, + { FVector(823, 6, 1327) }, + { FVector(717, 8, 1239) }, + { FVector(695, 19, 1176) }, + { FVector(628, 8, 1191) }, + { FVector(724, 4, 1339) }, +}; + +void MooMooFarm::BeginPlay() { if (gPlayerCountSelection1 != 4) { spawn_foliage((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_moo_moo_farm_tree_spawn)); } spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_moo_moo_farm_item_box_spawns)); + for (size_t i = 0; i < gObjectParticle2_SIZE; i++) { + find_unused_obj_index(&gObjectParticle2[i]); + } + + if (gGamestate != CREDITS_SEQUENCE) { + switch(gCCSelection) { + case CC_50: { + std::vector moleSpawns1_50 = { { FVector(771, 20, -2022) }, + { FVector(807, 15, -2063) }, + { FVector(847, 18, -2040) }, + { FVector(913, 14, -2054) } }; + + gWorldInstance.AddObject(new OMoleGroup(moleSpawns1_50)); + + std::vector moleSpawns2_50 = { { FVector(1500, 2, 1140) }, { FVector(1510, 15, 1050) }, + { FVector(1609, 21, 935) }, { FVector(1289, 3, 1269) }, + { FVector(1468, 22, 1046) }, { FVector(1380, 12, 1154) } }; + + gWorldInstance.AddObject(new OMoleGroup(moleSpawns2_50)); + + std::vector moleSpawns3_50 = { { FVector(701, 2, 1279) }, { FVector(811, 8, 1278) }, + { FVector(791, 16, 1229) }, { FVector(876, 15, 1266) }, + { FVector(984, 23, 1248) }, { FVector(891, 20, 1242) } }; + + gWorldInstance.AddObject(new OMoleGroup(moleSpawns3_50)); + break; + } + case CC_100: { + std::vector moleSpawns1_100 = { { FVector(771, 20, -2022) }, + { FVector(807, 15, -2063) }, + { FVector(847, 18, -2040) }, + { FVector(913, 14, -2054) }, + { FVector(939, 21, -1997) } }; + + gWorldInstance.AddObject(new OMoleGroup(moleSpawns1_100)); + + std::vector moleSpawns2_100 = { { FVector(1500, 2, 1140) }, { FVector(1510, 15, 1050) }, + { FVector(1609, 21, 935) }, { FVector(1289, 3, 1269) }, + { FVector(1468, 22, 1046) }, { FVector(1380, 12, 1154) }, + { FVector(1297, 19, 1170) }, { FVector(1589, 11, 1004) } }; + + gWorldInstance.AddObject(new OMoleGroup(moleSpawns2_100)); + + std::vector moleSpawns3_100 = { { FVector(701, 2, 1279) }, { FVector(811, 8, 1278) }, + { FVector(791, 16, 1229) }, { FVector(876, 15, 1266) }, + { FVector(984, 23, 1248) }, { FVector(891, 20, 1242) }, + { FVector(920, 15, 1304) }, { FVector(823, 6, 1327) } }; + + gWorldInstance.AddObject(new OMoleGroup(moleSpawns3_100)); + break; + } + case CC_150: { + std::vector moleSpawns1_150 = { { FVector(771, 20, -2022) }, + { FVector(807, 15, -2063) }, + { FVector(847, 18, -2040) }, + { FVector(913, 14, -2054) }, + { FVector(939, 21, -1997) } }; + + gWorldInstance.AddObject(new OMoleGroup(moleSpawns1_150)); + + std::vector moleSpawns2_150 = { { FVector(1500, 2, 1140) }, { FVector(1510, 15, 1050) }, + { FVector(1609, 21, 935) }, { FVector(1289, 3, 1269) }, + { FVector(1468, 22, 1046) }, { FVector(1380, 12, 1154) }, + { FVector(1297, 19, 1170) }, { FVector(1589, 11, 1004) } }; + + gWorldInstance.AddObject(new OMoleGroup(moleSpawns2_150)); + + std::vector moleSpawns3_150 = { { FVector(701, 2, 1279) }, { FVector(811, 8, 1278) }, + { FVector(791, 16, 1229) }, { FVector(876, 15, 1266) }, + { FVector(984, 23, 1248) }, { FVector(891, 20, 1242) }, + { FVector(920, 15, 1304) }, { FVector(823, 6, 1327) }, + { FVector(717, 8, 1239) }, { FVector(695, 19, 1176) } }; + + gWorldInstance.AddObject(new OMoleGroup(moleSpawns3_150)); + break; + } + case CC_EXTRA: { + std::vector moleSpawns1_extra = { { FVector(771, 20, -2022) }, + { FVector(807, 15, -2063) }, + { FVector(847, 18, -2040) }, + { FVector(913, 14, -2054) }, + { FVector(939, 21, -1997) } }; + + gWorldInstance.AddObject(new OMoleGroup(moleSpawns1_extra)); + + std::vector moleSpawns2_extra = { { FVector(1500, 2, 1140) }, { FVector(1510, 15, 1050) }, + { FVector(1609, 21, 935) }, { FVector(1289, 3, 1269) }, + { FVector(1468, 22, 1046) }, { FVector(1380, 12, 1154) }, + { FVector(1297, 19, 1170) }, { FVector(1589, 11, 1004) } }; + + gWorldInstance.AddObject(new OMoleGroup(moleSpawns2_extra)); + + std::vector moleSpawns3_extra = { { FVector(701, 2, 1279) }, { FVector(811, 8, 1278) }, + { FVector(791, 16, 1229) }, { FVector(876, 15, 1266) }, + { FVector(984, 23, 1248) }, { FVector(891, 20, 1242) }, + { FVector(920, 15, 1304) }, { FVector(823, 6, 1327) } }; + + gWorldInstance.AddObject(new OMoleGroup(moleSpawns3_extra)); + break; + } + } + } + if (gModeSelection == VERSUS) { Vec3f pos = {0, 0, 0}; @@ -189,89 +332,6 @@ void MooMooFarm::MinimapSettings() { D_8018D2E8 = 36; } -void MooMooFarm::InitCourseObjects() { - size_t objectId; - size_t i; - if (gGamestate != CREDITS_SEQUENCE) { - if ((gPlayerCount == 1) || ((gPlayerCount == 2) && (gModeSelection == VERSUS))) { - switch (gCCSelection) { /* switch 2; irregular */ - case CC_50: /* switch 2 */ - D_8018D1C8 = 4; - D_8018D1D0 = 6; - D_8018D1D8 = 6; - break; - case CC_100: /* switch 2 */ - D_8018D1C8 = 5; - D_8018D1D0 = 8; - D_8018D1D8 = 8; - break; - case CC_150: /* switch 2 */ - D_8018D1C8 = 5; - D_8018D1D0 = 8; - D_8018D1D8 = 10; - break; - case CC_EXTRA: /* switch 2 */ - D_8018D1C8 = 5; - D_8018D1D0 = 8; - D_8018D1D8 = 8; - break; - } - } else { - D_8018D1C8 = 4; - D_8018D1D0 = 6; - D_8018D1D8 = 6; - } - - Vec3f pos = {0, 22, 0}; - for (size_t i = 0; i < NUM_GROUP1_MOLES; i++) { - D_8018D198[i] = 0; - gWorldInstance.AddObject(new OMole(pos)); - - } - - // for (i = 0; i < NUM_GROUP1_MOLES; i++) { - // D_8018D198[i] = 0; - // find_unused_obj_index(&indexObjectList1[i]); - // } - // for (i = 0; i < NUM_GROUP2_MOLES; i++) { - // D_8018D1A8[i] = 0; - // find_unused_obj_index(&indexObjectList1[i]); - // } - // for (i = 0; i < NUM_GROUP3_MOLES; i++) { - // D_8018D1B8[i] = 0; - // find_unused_obj_index(&indexObjectList1[i]); - // } - // for (i = 0; i < NUM_TOTAL_MOLES; i++) { - // find_unused_obj_index(&gObjectParticle1[i]); - // objectId = gObjectParticle1[i]; - // init_object(objectId, 0); - // gObjectList[objectId].pos[0] = gMoleSpawns.asVec3sList[i][0] * xOrientation; - // gObjectList[objectId].pos[2] = gMoleSpawns.asVec3sList[i][2]; - // func_800887C0(objectId); - // gObjectList[objectId].sizeScaling = 0.7f; - // } - - - for (i = 0; i < gObjectParticle2_SIZE; i++) { - find_unused_obj_index(&gObjectParticle2[i]); - } - } -} - -void MooMooFarm::UpdateCourseObjects() { - if (gGamestate != CREDITS_SEQUENCE) { - //update_moles(); - } -} - -void MooMooFarm::RenderCourseObjects(s32 cameraId) { - if (gGamestate != CREDITS_SEQUENCE) { - //render_object_moles(cameraId); - } -} - -void MooMooFarm::SomeSounds() {} - void MooMooFarm::WhatDoesThisDo(Player* player, int8_t playerId) { if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x145) && ((s16) gNearestWaypointByPlayerId[playerId] < 0x18B)) { diff --git a/src/engine/courses/MooMooFarm.h b/src/engine/courses/MooMooFarm.h index 0293b1b04..8b8b1b811 100644 --- a/src/engine/courses/MooMooFarm.h +++ b/src/engine/courses/MooMooFarm.h @@ -31,10 +31,6 @@ public: virtual void LoadTextures() override; virtual void BeginPlay() override; virtual void MinimapSettings() override; - virtual void InitCourseObjects() override; - virtual void UpdateCourseObjects() override; - virtual void RenderCourseObjects(s32 cameraId) override; - virtual void SomeSounds() override; virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; virtual void MinimapFinishlinePosition() override; diff --git a/src/engine/courses/PodiumCeremony.cpp b/src/engine/courses/PodiumCeremony.cpp index 736a3ed9f..637dbc5d3 100644 --- a/src/engine/courses/PodiumCeremony.cpp +++ b/src/engine/courses/PodiumCeremony.cpp @@ -11,6 +11,7 @@ #include "engine/objects/Trophy.h" #include "engine/objects/Podium.h" #include "engine/objects/CheepCheep.h" +#include "engine/particles/StarEmitter.h" extern "C" { #include "main.h" @@ -186,7 +187,7 @@ void PodiumCeremony::BeginPlay() { break; } - gWorldInstance.AddObject(new OTrophy(pos, type, OTrophy::Behaviour::PODIUM_CEREMONY)); + OTrophy* trophy = reinterpret_cast(gWorldInstance.AddObject(new OTrophy(pos, type, OTrophy::Behaviour::PODIUM_CEREMONY))); Vec3f kart = {0, 0, 0}; gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[3][3], 3, 5, 1.25f)); diff --git a/src/engine/courses/RainbowRoad.cpp b/src/engine/courses/RainbowRoad.cpp index b878eebfb..11ca643b8 100644 --- a/src/engine/courses/RainbowRoad.cpp +++ b/src/engine/courses/RainbowRoad.cpp @@ -134,8 +134,6 @@ void RainbowRoad::LoadTextures() { } void RainbowRoad::BeginPlay() { - gWorldInstance.AddActor(new AFinishline()); - spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_rainbow_road_item_box_spawns)); if (gGamestate != CREDITS_SEQUENCE) { diff --git a/src/engine/courses/RoyalRaceway.cpp b/src/engine/courses/RoyalRaceway.cpp index de1ab164b..7ff7579ff 100644 --- a/src/engine/courses/RoyalRaceway.cpp +++ b/src/engine/courses/RoyalRaceway.cpp @@ -171,8 +171,6 @@ void RoyalRaceway::LoadTextures() { } void RoyalRaceway::BeginPlay() { - gWorldInstance.AddActor(new AFinishline()); - 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)); diff --git a/src/engine/courses/SherbetLand.cpp b/src/engine/courses/SherbetLand.cpp index 7e77ecdbb..a452d2c03 100644 --- a/src/engine/courses/SherbetLand.cpp +++ b/src/engine/courses/SherbetLand.cpp @@ -130,22 +130,13 @@ void SherbetLand::LoadTextures() { } void SherbetLand::BeginPlay() { - gWorldInstance.AddActor(new AFinishline()); - spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_sherbet_land_item_box_spawns)); - - -// Originally, multiplayer did not spawn the big penguin -// if (gPlayerCountSelection1 == 1) { + // Multiplayer does not spawn the big penguin +// if (gPlayerCountSelection1 == 1) { Vec3f pos = {-383.0f, 2.0f, -690.0f}; gWorldInstance.AddObject(new OPenguin(pos, 0, OPenguin::PenguinType::EMPEROR, OPenguin::Behaviour::STRUT)); -// } - - //! @bug Skip spawning penguins due to animation crash for now - if (gGamestate == CREDITS_SEQUENCE) { - return; - } +// } Vec3f pos2 = {-2960.0f, -80.0f, 1521.0f}; auto penguin = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos2, 0x150, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE))); @@ -199,15 +190,17 @@ void SherbetLand::BeginPlay() { auto penguin14 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos11, 0x9000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE6))); penguin14->MirrorModeAngleOffset = -0x4000; - if (gModeSelection == VERSUS) { - Vec3f kart = {0, 0, 0}; - gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][50], 50, 3, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][100], 100, 1, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][150], 150, 3, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][200], 200, 1, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][250], 250, 3, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][0], 0, 0, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][0], 0, 0, 0.8333333f)); + if (gGamestate != CREDITS_SEQUENCE) { + if (gModeSelection == VERSUS) { + Vec3f kart = {0, 0, 0}; + gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][50], 50, 3, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][100], 100, 1, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][150], 150, 3, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][200], 200, 1, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][250], 250, 3, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][0], 0, 0, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][0], 0, 0, 0.8333333f)); + } } } diff --git a/src/engine/courses/TestCourse.cpp b/src/engine/courses/TestCourse.cpp index 30a925d80..aaf3143c3 100644 --- a/src/engine/courses/TestCourse.cpp +++ b/src/engine/courses/TestCourse.cpp @@ -25,7 +25,6 @@ #include "engine/objects/HotAirBalloon.h" #include "engine/objects/Crab.h" #include "engine/objects/Boos.h" -#include "engine/particles/StarEmitter.h" extern "C" { #include "main.h" @@ -151,91 +150,6 @@ void TestCourse::LoadTextures() { dma_textures(gTexturePiranhaPlant9, 0x000003E8U, 0x00000800U); } -void TestCourse::BeginPlay() { - struct ActorSpawnData itemboxes[] = { - { 200, 1500, 200 , 0}, - { 350, 2500, 300 , 1}, - { 400, 2000, 350 , 2}, - { 40, 0, -800, 0}, - { -40, 0, -800, 0}, - { 0, 0, -800, 0}, - { 999, 6, 482, 0}, - { 1064, 8, 275, {0}}, - { 1028, 5, -39 , {0}}, - { 320, 0, 1020, {0}}, - { 293, 0, 950, {0}}, - {{ -32768, 0, 0 }, {0}}, - }; - - struct ActorSpawnData rocks[] = { - {{ 200, 1500, 200 }, {0}}, - {{ 350, 2500, 300 }, {1}}, - {{ 400, 2000, 350 }, {2}}, - {{ -32768, 0, 0 }, {0}}, - }; - - gWorldInstance.AddActor(new AFinishline()); - - spawn_all_item_boxes(itemboxes); - spawn_falling_rocks(rocks); - - Vec3f test = {-100, 0, -150}; - Vec3s rot = {0, 0, 0}; - Vec3f vel = {0, 0, 0}; - - add_actor_to_empty_slot(test, rot, vel, ACTOR_TREE_MARIO_RACEWAY); - - struct RailroadCrossing* rrxing; - Vec3f position; - Vec3f velocity = { 0.0f, 0.0f, 0.0f }; - Vec3s rotation = { 0, 0, 0 }; - vec3f_set(position, 50.0f, 2.0f, 50.0f); - - Vec3f crossingPos = {0, 2, 0}; - uintptr_t* crossing1 = (uintptr_t*) gWorldInstance.AddCrossing(crossingPos, 0, 2, 900.0f, 650.0f); - - position[0] *= gCourseDirection; - rrxing = (struct RailroadCrossing*) GET_ACTOR(add_actor_to_empty_slot(position, rotation, velocity, - ACTOR_RAILROAD_CROSSING)); - rrxing->crossingTrigger = crossing1; - - Vec3f pos = {0, 80, 0}; - // 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 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)); - //gWorldInstance.AddObject(new OSnowman(FVector(0, 0, 0))); - //gWorldInstance.AddObject(new OTrashBin(FVector(0.0f, 0.0f, 0.0f), FRotation(0, 90, 0), 1.0f, OTrashBin::Behaviour::MUNCHING)); - -//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))); - - //gWorldInstance.AddObject(new OCrab(FVector2D(0, 0), FVector2D(0, -200))); -// gWorldInstance.AddActor(new ABowserStatue(FVector(-200, 0, 0), ABowserStatue::Behaviour::CRUSH)); - -// gWorldInstance.AddObject(new OBoos(10, IPathSpan(0, 5), IPathSpan(18, 23), IPathSpan(25, 50))); - -} - -// Likely sets minimap boundaries -void TestCourse::MinimapSettings() { - D_8018D220 = reinterpret_cast(dma_textures(gTextureExhaust5, 0x443, 0x1000)); - D_8018D2A0 = 0.022f; - D_8018D2E0 = 6; - D_8018D2E8 = 28; - D_8018D2C0[0] = 260; - D_8018D2D8[0] = 170; - D_80165718 = 0; - D_80165720 = 5; - D_80165728 = -240; -} - Path2D test_course_path2D[] = { { 0, 0}, { 0, -100}, @@ -294,22 +208,98 @@ Path2D test_course_path2D[] = { { -32768, -32768 } // Terminator }; -void TestCourse::SpawnVehicles() { +void TestCourse::BeginPlay() { + struct ActorSpawnData itemboxes[] = { + { 200, 1500, 200 , 0}, + { 350, 2500, 300 , 1}, + { 400, 2000, 350 , 2}, + { 40, 0, -800, 0}, + { -40, 0, -800, 0}, + { 0, 0, -800, 0}, + { 999, 6, 482, 0}, + { 1064, 8, 275, {0}}, + { 1028, 5, -39 , {0}}, + { 320, 0, 1020, {0}}, + { 293, 0, 950, {0}}, + {{ -32768, 0, 0 }, {0}}, + }; + + struct ActorSpawnData rocks[] = { + {{ 200, 1500, 200 }, {0}}, + {{ 350, 2500, 300 }, {1}}, + {{ 400, 2000, 350 }, {2}}, + {{ -32768, 0, 0 }, {0}}, + }; + + spawn_all_item_boxes(itemboxes); + spawn_falling_rocks(rocks); + + Vec3f test = {-100, 0, -150}; + Vec3s rot = {0, 0, 0}; + Vec3f vel = {0, 0, 0}; + + add_actor_to_empty_slot(test, rot, vel, ACTOR_TREE_MARIO_RACEWAY); + + struct RailroadCrossing* rrxing; + Vec3f position; + Vec3f velocity = { 0.0f, 0.0f, 0.0f }; + Vec3s rotation = { 0, 0, 0 }; + vec3f_set(position, 50.0f, 2.0f, 50.0f); + + Vec3f crossingPos = {0, 2, 0}; + uintptr_t* crossing1 = (uintptr_t*) gWorldInstance.AddCrossing(crossingPos, 0, 2, 900.0f, 650.0f); + + position[0] *= gCourseDirection; + rrxing = (struct RailroadCrossing*) GET_ACTOR(add_actor_to_empty_slot(position, rotation, velocity, + ACTOR_RAILROAD_CROSSING)); + rrxing->crossingTrigger = crossing1; + + Vec3f pos = {0, 80, 0}; + // 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 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)); + //gWorldInstance.AddObject(new OSnowman(FVector(0, 0, 0))); + //gWorldInstance.AddObject(new OTrashBin(FVector(0.0f, 0.0f, 0.0f), FRotation(0, 90, 0), 1.0f, OTrashBin::Behaviour::MUNCHING)); + + //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))); + + //gWorldInstance.AddObject(new OCrab(FVector2D(0, 0), FVector2D(0, -200))); +// gWorldInstance.AddActor(new ABowserStatue(FVector(-200, 0, 0), ABowserStatue::Behaviour::CRUSH)); + +// gWorldInstance.AddObject(new OBoos(10, IPathSpan(0, 5), IPathSpan(18, 23), IPathSpan(25, 50))); + gVehicle2DWaypoint = test_course_path2D; gVehicle2DWaypointLength = 53; D_80162EB0 = spawn_actor_on_surface(test_course_path2D[0].x, 2000.0f, test_course_path2D[0].z); - + //gWorldInstance.AddTrain(ATrain::TenderStatus::HAS_TENDER, 5, 2.5f, 0); //gWorldInstance.AddTrain(ATrain::TenderStatus::HAS_TENDER, 5, 2.5f, 8); - Vec3f pos = {0, 0, 0}; + Vec3f pos2 = {0, 0, 0}; + + gWorldInstance.AddObject(new OBombKart(pos2, &D_80164550[0][25], 25, 4, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(pos2, &D_80164550[0][45], 45, 4, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][25], 25, 4, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][45], 45, 4, 0.8333333f)); } -void TestCourse::UpdateVehicles() { - update_vehicle_trains(); +// Likely sets minimap boundaries +void TestCourse::MinimapSettings() { + D_8018D220 = reinterpret_cast(dma_textures(gTextureExhaust5, 0x443, 0x1000)); + D_8018D2A0 = 0.022f; + D_8018D2E0 = 6; + D_8018D2E8 = 28; + D_8018D2C0[0] = 260; + D_8018D2D8[0] = 170; + D_80165718 = 0; + D_80165720 = 5; + D_80165728 = -240; } void TestCourse::InitCourseObjects() {} diff --git a/src/engine/courses/TestCourse.h b/src/engine/courses/TestCourse.h index 2ba8a9f49..3421304e2 100644 --- a/src/engine/courses/TestCourse.h +++ b/src/engine/courses/TestCourse.h @@ -36,8 +36,6 @@ public: virtual void Render(struct UnkStruct_800DC5EC*) override; virtual void RenderCredits() override; virtual void Collision() override; - virtual void SpawnVehicles() override; - virtual void UpdateVehicles() override; virtual void Destroy() override; virtual bool IsMod() override; }; diff --git a/src/engine/courses/ToadsTurnpike.cpp b/src/engine/courses/ToadsTurnpike.cpp index f6aa3f738..a9507acad 100644 --- a/src/engine/courses/ToadsTurnpike.cpp +++ b/src/engine/courses/ToadsTurnpike.cpp @@ -118,6 +118,14 @@ ToadsTurnpike::ToadsTurnpike() { Props.Clouds = gToadsTurnpikeRainbowRoadStars; Props.CloudList = gToadsTurnpikeRainbowRoadStars; + + FVector finish; + finish.x = (gIsMirrorMode != 0) ? 100 + 138.0f : 100 - 138.0f; + finish.y = (f32) (0 - 15); + finish.z = 16; + + this->FinishlineSpawnPoint = finish; + Props.MinimapFinishlineX = 0; Props.MinimapFinishlineY = 0; @@ -149,58 +157,53 @@ void ToadsTurnpike::LoadTextures() { } void ToadsTurnpike::BeginPlay() { - Vec3f pos; - pos[0] = (gIsMirrorMode != 0) ? D_80164490->posX + 138.0f : D_80164490->posX - 138.0f; - pos[1] = (f32) (D_80164490->posY - 15); - pos[2] = D_80164490->posZ; - - gWorldInstance.AddActor(new AFinishline(pos)); - spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_toads_turnpike_item_box_spawns)); - uint32_t waypoint; - f32 a = ((gCCSelection * 90.0) / 216.0f) + 4.583333333333333; - f32 b = ((gCCSelection * 90.0) / 216.0f) + 2.9166666666666665; - a /= 2; // Normally vehicle logic is only ran every 2 frames. This slows the vehicles down to match. - b /= 2; + if (gGamestate != CREDITS_SEQUENCE) { + uint32_t waypoint; + f32 a = ((gCCSelection * 90.0) / 216.0f) + 4.583333333333333; + f32 b = ((gCCSelection * 90.0) / 216.0f) + 2.9166666666666665; + a /= 2; // Normally vehicle logic is only ran every 2 frames. This slows the vehicles down to match. + b /= 2; - // Other game modes spawn seven of each vehicle - if (gModeSelection == TIME_TRIALS) { - _numTrucks = 8; - _numBuses = 8; - _numTankerTrucks = 8; - _numCars = 8; - } - - for (size_t i = 0; i < _numTrucks; i++) { - waypoint = CalculateWaypointDistribution(i, _numTrucks, gWaypointCountByPathIndex[0], 0); - gWorldInstance.AddActor(new ATruck(a, b, &D_80164550[0][0], waypoint)); - } + // Other game modes spawn seven of each vehicle + if (gModeSelection == TIME_TRIALS) { + _numTrucks = 8; + _numBuses = 8; + _numTankerTrucks = 8; + _numCars = 8; + } - for (size_t i = 0; i < _numBuses; i++) { - waypoint = CalculateWaypointDistribution(i, _numBuses, gWaypointCountByPathIndex[0], 75); - gWorldInstance.AddActor(new ABus(a, b, &D_80164550[0][0], waypoint)); - } + for (size_t i = 0; i < _numTrucks; i++) { + waypoint = CalculateWaypointDistribution(i, _numTrucks, gWaypointCountByPathIndex[0], 0); + gWorldInstance.AddActor(new ATruck(a, b, &D_80164550[0][0], waypoint)); + } - for (size_t i = 0; i < _numTankerTrucks; i++) { - waypoint = CalculateWaypointDistribution(i, _numTankerTrucks, gWaypointCountByPathIndex[0], 50); - gWorldInstance.AddActor(new ATankerTruck(a, b, &D_80164550[0][0], waypoint)); - } + for (size_t i = 0; i < _numBuses; i++) { + waypoint = CalculateWaypointDistribution(i, _numBuses, gWaypointCountByPathIndex[0], 75); + gWorldInstance.AddActor(new ABus(a, b, &D_80164550[0][0], waypoint)); + } - for (size_t i = 0; i < _numCars; i++) { - waypoint = CalculateWaypointDistribution(i, _numCars, gWaypointCountByPathIndex[0], 25); - gWorldInstance.AddActor(new ACar(a, b, &D_80164550[0][0], waypoint)); - } + for (size_t i = 0; i < _numTankerTrucks; i++) { + waypoint = CalculateWaypointDistribution(i, _numTankerTrucks, gWaypointCountByPathIndex[0], 50); + gWorldInstance.AddActor(new ATankerTruck(a, b, &D_80164550[0][0], waypoint)); + } - if (gModeSelection == VERSUS) { - Vec3f pos = {0, 0, 0}; - gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][50], 50, 3, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][100], 100, 1, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][150], 150, 3, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][200], 200, 1, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][250], 250, 3, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f)); - gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f)); + for (size_t i = 0; i < _numCars; i++) { + waypoint = CalculateWaypointDistribution(i, _numCars, gWaypointCountByPathIndex[0], 25); + gWorldInstance.AddActor(new ACar(a, b, &D_80164550[0][0], waypoint)); + } + + if (gModeSelection == VERSUS) { + Vec3f pos = {0, 0, 0}; + gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][50], 50, 3, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][100], 100, 1, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][150], 150, 3, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][200], 200, 1, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][250], 250, 3, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f)); + gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f)); + } } } diff --git a/src/engine/courses/WarioStadium.cpp b/src/engine/courses/WarioStadium.cpp index 44a8d5d1a..d60d754c0 100644 --- a/src/engine/courses/WarioStadium.cpp +++ b/src/engine/courses/WarioStadium.cpp @@ -114,6 +114,14 @@ WarioStadium::WarioStadium() { Props.Clouds = gWarioStadiumStars; Props.CloudList = gWarioStadiumStars; + + FVector finish; + finish.x = (gIsMirrorMode != 0) ? 13 + 12.0f : 13 - 12.0f; + finish.y = (f32) (0 - 15); + finish.z = -9; + + this->FinishlineSpawnPoint = finish; + Props.MinimapFinishlineX = 0; Props.MinimapFinishlineY = 0; @@ -156,14 +164,6 @@ void WarioStadium::LoadTextures() { } void WarioStadium::BeginPlay() { - Vec3f finish; - finish[0] = (gIsMirrorMode != 0) ? D_80164490->posX + 12.0f : D_80164490->posX - 12.0f; - (gIsMirrorMode != 0) ? D_80164490->posX + 12.0f : D_80164490->posX - 12.0f; - finish[1] = D_8015F8D0[1] = (f32) (D_80164490->posY - 15); - finish[2] = D_8015F8D0[2] = D_80164490->posZ; - - gWorldInstance.AddActor(new AFinishline(finish)); - spawn_all_item_boxes((struct ActorSpawnData*) LOAD_ASSET_RAW(d_course_wario_stadium_item_box_spawns)); Vec3f pos = { -131.0f, 83.0f, 286.0f }; diff --git a/src/engine/courses/YoshiValley.cpp b/src/engine/courses/YoshiValley.cpp index 9366f45ea..98d887b03 100644 --- a/src/engine/courses/YoshiValley.cpp +++ b/src/engine/courses/YoshiValley.cpp @@ -142,8 +142,6 @@ void YoshiValley::BeginPlay() { Vec3f velocity = { 0.0f, 0.0f, 0.0f }; Vec3s rotation = { 0, 0, 0 }; - gWorldInstance.AddActor(new AFinishline()); - spawn_foliage((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_yoshi_valley_tree_spawn)); spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_yoshi_valley_item_box_spawns)); vec3f_set(position, -2300.0f, 0.0f, 634.0f); diff --git a/src/engine/objects/Bat.cpp b/src/engine/objects/Bat.cpp index f32ef2d41..b90f7c857 100644 --- a/src/engine/objects/Bat.cpp +++ b/src/engine/objects/Bat.cpp @@ -19,19 +19,21 @@ const char* sBoardwalkTexList[] = { gTextureBat1, gTextureBat2, gTextureBat3, gT size_t OBat::_count = 0; OBat::OBat(const FVector& pos, const FRotation& rot) { - s32 objectId = indexObjectList1[0]; - init_texture_object(objectId, (uint8_t*)d_course_banshee_boardwalk_bat_tlut, sBoardwalkTexList, 0x20U, + + find_unused_obj_index(&_objectIndex); + + init_texture_object(_objectIndex, (uint8_t*)d_course_banshee_boardwalk_bat_tlut, sBoardwalkTexList, 0x20U, (u16) 0x00000040); - gObjectList[objectId].orientation[0] = rot.pitch; - gObjectList[objectId].orientation[1] = rot.roll; - gObjectList[objectId].orientation[2] = rot.yaw; // 0x8000 + gObjectList[_objectIndex].orientation[0] = rot.pitch; + gObjectList[_objectIndex].orientation[1] = rot.roll; + gObjectList[_objectIndex].orientation[2] = rot.yaw; // 0x8000 _count++; } void OBat::Tick() { s32 var_s2; - s32 temp_s0; + s32 objectIndex; Object* object; if (D_8018CFC8 != 0) { @@ -40,28 +42,28 @@ void OBat::Tick() { if (D_8018D000 != 0) { D_8018D000 -= 1; } - temp_s0 = indexObjectList1[0]; - func_80072E54(temp_s0, 0, 3, 1, 0, -1); - func_80073514(temp_s0); - object = &gObjectList[temp_s0]; - func_80073CB0(temp_s0, &object->primAlpha, -0x00001000, 0x00001000, 0x00000400, 0, -1); + objectIndex = _objectIndex; + func_80072E54(objectIndex, 0, 3, 1, 0, -1); + func_80073514(objectIndex); + object = &gObjectList[objectIndex]; + func_80073CB0(objectIndex, &object->primAlpha, -0x00001000, 0x00001000, 0x00000400, 0, -1); object->orientation[2] = object->primAlpha + 0x8000; if ((D_8018CFB0 != 0) || (D_8018CFC8 != 0)) { D_8018CFD8 = 0; for (var_s2 = 0; var_s2 < 40; var_s2++) { - temp_s0 = gObjectParticle2[var_s2]; - if (temp_s0 == -1) { + objectIndex = gObjectParticle2[var_s2]; + if (objectIndex == -1) { continue; } - object = &gObjectList[temp_s0]; + object = &gObjectList[objectIndex]; if (object->state == 0) { continue; } - OBat::func_8007D8D4(temp_s0, 1); - OBat::func_8007DAF8(temp_s0, 1); - OBat::func_8007D794(temp_s0); + OBat::func_8007D8D4(objectIndex, 1); + OBat::func_8007DAF8(objectIndex, 1); + OBat::func_8007D794(objectIndex); if (object->state == 0) { delete_object_wrapper(&gObjectParticle2[var_s2]); } @@ -74,19 +76,19 @@ void OBat::Tick() { if ((D_8018CFE8 != 0) || (D_8018D000 != 0)) { D_8018D010 = 0; for (var_s2 = 0; var_s2 < 30; var_s2++) { - temp_s0 = gObjectParticle3[var_s2]; - if (temp_s0 == -1) { + objectIndex = gObjectParticle3[var_s2]; + if (objectIndex == -1) { continue; } - object = &gObjectList[temp_s0]; + object = &gObjectList[objectIndex]; if (object->state == 0) { continue; } - OBat::func_8007D8D4(temp_s0, 2); - OBat::func_8007DAF8(temp_s0, 2); - OBat::func_8007D794(temp_s0); + OBat::func_8007D8D4(objectIndex, 2); + OBat::func_8007DAF8(objectIndex, 2); + OBat::func_8007D794(objectIndex); if (object->state == 0) { delete_object_wrapper(&gObjectParticle3[var_s2]); } @@ -103,7 +105,7 @@ void OBat::Draw(s32 cameraId) { s32 objectIndex; Camera* temp_s7; - objectIndex = indexObjectList1[0]; + objectIndex = _objectIndex; temp_s7 = &camera1[cameraId]; OBat::func_80046F60((u8*)gObjectList[objectIndex].activeTLUT, (u8*)gObjectList[objectIndex].activeTexture, 0x00000020, 0x00000040, 5); diff --git a/src/engine/objects/Bat.h b/src/engine/objects/Bat.h index 39a9e65d8..f9e0df074 100644 --- a/src/engine/objects/Bat.h +++ b/src/engine/objects/Bat.h @@ -56,4 +56,5 @@ private: FVector _pos; static size_t _count; size_t _idx; + s32 _objectIndex; }; diff --git a/src/engine/objects/Crab.cpp b/src/engine/objects/Crab.cpp index 3a71e075d..c722a9037 100644 --- a/src/engine/objects/Crab.cpp +++ b/src/engine/objects/Crab.cpp @@ -28,26 +28,24 @@ extern "C" { size_t OCrab::_count = 0; OCrab::OCrab(const FVector2D& start, const FVector2D& end) { - s32 objectId; _idx = _count; _start = start; _end = end; - objectId = indexObjectList1[_idx]; - init_object(objectId, 0); - gObjectList[objectId].pos[0] = gObjectList[objectId].origin_pos[0] = start.x * xOrientation; - gObjectList[objectId].pos[2] = gObjectList[objectId].origin_pos[2] = start.z; + find_unused_obj_index(&_objectIndex); - gObjectList[objectId].unk_01C[0] = end.x * xOrientation; - gObjectList[objectId].unk_01C[2] = end.z; + init_object(_objectIndex, 0); + gObjectList[_objectIndex].pos[0] = gObjectList[_objectIndex].origin_pos[0] = start.x * xOrientation; + gObjectList[_objectIndex].pos[2] = gObjectList[_objectIndex].origin_pos[2] = start.z; + + gObjectList[_objectIndex].unk_01C[0] = end.x * xOrientation; + gObjectList[_objectIndex].unk_01C[2] = end.z; _count++; } void OCrab::Tick(void) { - s32 objectIndex; - - objectIndex = indexObjectList1[_idx]; + s32 objectIndex = _objectIndex; if (gObjectList[objectIndex].state != 0) { OCrab::func_80082B34(objectIndex); func_8008A6DC(objectIndex, 500.0f); @@ -58,7 +56,7 @@ void OCrab::Tick(void) { void OCrab::Draw(s32 cameraId) { Camera* camera; - s32 objectIndex = indexObjectList1[_idx]; + s32 objectIndex = _objectIndex; if (gObjectList[objectIndex].state >= 2) { Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_hedgehog); camera = &camera1[cameraId]; @@ -74,11 +72,9 @@ void OCrab::Draw(s32 cameraId) { void OCrab::DrawModel(s32 cameraId) { s32 someIndex; - s32 test; - - test = indexObjectList1[_idx]; - func_8008A364(test, cameraId, 0x2AABU, 800); - if (is_obj_flag_status_active(test, VISIBLE) != 0) { + s32 objectIndex = _objectIndex; + func_8008A364(objectIndex, cameraId, 0x2AABU, 800); + if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { Camera *camera; s32 objectIndex; diff --git a/src/engine/objects/Crab.h b/src/engine/objects/Crab.h index 4cadd3b87..2d1ef5e93 100644 --- a/src/engine/objects/Crab.h +++ b/src/engine/objects/Crab.h @@ -46,4 +46,5 @@ private: FVector2D _end; static size_t _count; s32 _idx; + s32 _objectIndex; }; diff --git a/src/engine/objects/Flagpole.cpp b/src/engine/objects/Flagpole.cpp index 682f74915..7b5e5af20 100644 --- a/src/engine/objects/Flagpole.cpp +++ b/src/engine/objects/Flagpole.cpp @@ -20,13 +20,15 @@ OFlagpole::OFlagpole(const FVector& pos, s16 direction) { _pos = pos; _direction = direction; - init_object(indexObjectList1[_idx], 0); + find_unused_obj_index(&_objectIndex); + + init_object(_objectIndex, 0); _count++; } void OFlagpole::Tick() { // func_80083080 - s32 objectIndex = indexObjectList1[_idx]; + s32 objectIndex = _objectIndex; if (gObjectList[objectIndex].state != 0) { OFlagpole::func_80083018(objectIndex); @@ -35,7 +37,7 @@ void OFlagpole::Tick() { // func_80083080 } void OFlagpole::Draw(s32 cameraId) { // func_80055228 - s32 objectIndex = indexObjectList1[_idx]; + s32 objectIndex = _objectIndex; func_8008A364(objectIndex, cameraId, 0x4000U, 0x000005DC); if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { diff --git a/src/engine/objects/Flagpole.h b/src/engine/objects/Flagpole.h index 5824fcf18..034db865e 100644 --- a/src/engine/objects/Flagpole.h +++ b/src/engine/objects/Flagpole.h @@ -42,4 +42,5 @@ private: s16 _direction; static size_t _count; size_t _idx; + s32 _objectIndex; }; diff --git a/src/engine/objects/HotAirBalloon.cpp b/src/engine/objects/HotAirBalloon.cpp index 234eef6d9..917fd7354 100644 --- a/src/engine/objects/HotAirBalloon.cpp +++ b/src/engine/objects/HotAirBalloon.cpp @@ -27,11 +27,13 @@ OHotAirBalloon::OHotAirBalloon(const FVector& pos) { _visible = &mod; } - init_object(indexObjectList1[0], 0); + find_unused_obj_index(&_objectIndex); + + init_object(_objectIndex, 0); } void OHotAirBalloon::Tick() { - s32 objectIndex = indexObjectList1[0]; + s32 objectIndex = _objectIndex; if (*_visible) { if (gObjectList[objectIndex].state != 0) { @@ -49,7 +51,7 @@ void OHotAirBalloon::Tick() { void OHotAirBalloon::Draw(s32 cameraId) { s32 objectIndex; - objectIndex = indexObjectList1[0]; + objectIndex = _objectIndex; if (*_visible) { if (gGamestate != CREDITS_SEQUENCE) { func_8008A1D0(objectIndex, cameraId, 0x000005DC, 0x00000BB8); diff --git a/src/engine/objects/HotAirBalloon.h b/src/engine/objects/HotAirBalloon.h index 301e111c4..5dad406db 100644 --- a/src/engine/objects/HotAirBalloon.h +++ b/src/engine/objects/HotAirBalloon.h @@ -31,4 +31,5 @@ public: private: FVector _pos; bool *_visible; + s32 _objectIndex; }; diff --git a/src/engine/objects/Mole.cpp b/src/engine/objects/Mole.cpp index 7cc21e118..fdf5e7b08 100644 --- a/src/engine/objects/Mole.cpp +++ b/src/engine/objects/Mole.cpp @@ -22,64 +22,59 @@ extern "C" { #include "external.h" } -OMole::OMole(Vec3f pos) { +size_t OMole::_count = 0; - find_unused_obj_index(&indexObjectList1[0]); +OMole::OMole(FVector pos, OMoleGroup* group) { + _idx = _count; + _group = group; + + find_unused_obj_index(&_objectIndex); + + gObjectList[_objectIndex].pos[0] = pos.x * xOrientation; + gObjectList[_objectIndex].pos[1] = pos.y; + gObjectList[_objectIndex].pos[2] = pos.z; + + gObjectList[_objectIndex].origin_pos[0] = pos.x * xOrientation; + gObjectList[_objectIndex].origin_pos[1] = pos.y - 9.0; + gObjectList[_objectIndex].origin_pos[2] = pos.z; + + // This is probably the mole particles + find_unused_obj_index(&_moleIndex); + init_object(_moleIndex, 0); + gObjectList[_moleIndex].pos[0] = pos.x * xOrientation; + gObjectList[_moleIndex].pos[2] = pos.z; + func_800887C0(_moleIndex); + gObjectList[_moleIndex].sizeScaling = 0.7f; + + _count++; } void OMole::Tick() { - s32 var_s1; - s32 objectIndex; - - for (var_s1 = 0; var_s1 < D_8018D1C8; var_s1++) { - objectIndex = indexObjectList1[var_s1]; - if (gObjectList[objectIndex].state == 0) { - if (are_players_in_course_section(8, 9) != 0) { - func_80081FF4(objectIndex, 1); + if (_idx == 0) { + for (size_t i = 0; i < gObjectParticle2_SIZE; i++) { + s32 objectIndex = gObjectParticle2[i]; + if (gObjectList[objectIndex].state != 0) { + OMole::func_80081790(objectIndex); } - } else { - OMole::func_800821AC(objectIndex, 1); - } - } - - for (var_s1 = 0; var_s1 < D_8018D1D0; var_s1++) { - objectIndex = indexObjectList2[var_s1]; - if (gObjectList[objectIndex].state == 0) { - if (are_players_in_course_section(0x0010, 0x0013) != 0) { - OMole::func_80081FF4(objectIndex, 2); - } - } else { - OMole::func_800821AC(objectIndex, 2); - } - } - - for (var_s1 = 0; var_s1 < D_8018D1D8; var_s1++) { - objectIndex = indexObjectList3[var_s1]; - if (gObjectList[objectIndex].state == 0) { - if (are_players_in_course_section(0x0011, 0x0014) != 0) { - func_80081FF4(objectIndex, 3); - } - } else { - OMole::func_800821AC(objectIndex, 3); - } - } - - for (var_s1 = 0; var_s1 < gObjectParticle2_SIZE; var_s1++) { - objectIndex = gObjectParticle2[var_s1]; - if (gObjectList[objectIndex].state != 0) { - OMole::func_80081790(objectIndex); } } } void OMole::Draw(s32 cameraId) { + size_t i; + OMole::func_80054D00(_objectIndex, cameraId); + + OMole::func_80054EB8(); + if (_idx == 0) { + OMole::func_80054F04(cameraId); + } } void OMole::func_80081790(s32 objectIndex) { switch (gObjectList[objectIndex].state) { case 0: - break; /* irregular */ + break; case 1: if (func_80087E08(objectIndex, gObjectList[objectIndex].velocity[1], 0.3f, gObjectList[objectIndex].unk_034, gObjectList[objectIndex].orientation[1], 0x00000032) != 0) { @@ -94,10 +89,6 @@ void OMole::func_80081790(s32 objectIndex) { } } - - - - void OMole::func_80081AFC(s32 objectIndex, s32 arg1) { s8* sp2C; Object* object; @@ -119,7 +110,7 @@ void OMole::func_80081AFC(s32 objectIndex, s32 arg1) { case 0x3: if (object->unk_0AE == 0) { func_80086EAC(objectIndex, 2, 4); - func_8008153C(objectIndex); + OMole::func_8008153C(objectIndex); object_next_state(objectIndex); func_800C98B8(object->pos, object->velocity, SOUND_ARG_LOAD(0x19, 0x01, 0x80, 0x07)); } @@ -139,18 +130,21 @@ void OMole::func_80081AFC(s32 objectIndex, s32 arg1) { if (object->unk_0AE == 0) { clear_object_flag(objectIndex, 0x00000200); func_80072428(objectIndex); - switch (arg1) { /* switch 1; irregular */ - case 1: /* switch 1 */ - sp2C = D_8018D198; - break; - case 2: /* switch 1 */ - sp2C = D_8018D1A8; - break; - case 3: /* switch 1 */ - sp2C = D_8018D1B8; - break; - } - sp2C[object->type] = 0; + + _group->_moles[object->type].Active = false; + + // switch (arg1) { + // case 1: + // sp2C = D_8018D198; + // break; + // case 2: + // sp2C = D_8018D1A8; + // break; + // case 3: + // sp2C = D_8018D1B8; + // break; + // } + //sp2C[object->type] = 0; } break; case 0: @@ -162,17 +156,55 @@ void OMole::func_80081AFC(s32 objectIndex, s32 arg1) { } } +void OMole::func_8008153C(s32 objectIndex) { + UNUSED s32 stackPadding[3]; + s32 sp70; + s32 var_s1; + s32 var_s7; + s32 loopObjectIndex; + + if (gPlayerCountSelection1 == 1) { + sp70 = 8; + } else { + sp70 = 4; + } + + for (var_s7 = 0; var_s7 < sp70; var_s7++) { + for (var_s1 = 0; var_s1 < gObjectParticle2_SIZE; var_s1++) { + loopObjectIndex = gObjectParticle2[var_s1]; + + if (gObjectList[loopObjectIndex].state != 0) { + continue; + } + + u8* mole = (u8*) LOAD_ASSET_RAW(d_course_moo_moo_farm_mole_dirt); + init_object(loopObjectIndex, 0); + gObjectList[loopObjectIndex].activeTLUT = d_course_moo_moo_farm_mole_dirt; + gObjectList[loopObjectIndex].tlutList = mole; + gObjectList[loopObjectIndex].sizeScaling = 0.15f; + gObjectList[loopObjectIndex].velocity[1] = random_int(0x000AU); + gObjectList[loopObjectIndex].velocity[1] = (gObjectList[loopObjectIndex].velocity[1] * 0.1) + 4.8; + gObjectList[loopObjectIndex].unk_034 = random_int(5U); + gObjectList[loopObjectIndex].unk_034 = (gObjectList[loopObjectIndex].unk_034 * 0.01) + 0.8; + gObjectList[loopObjectIndex].orientation[1] = (0x10000 / sp70) * var_s1; + gObjectList[loopObjectIndex].origin_pos[0] = gObjectList[objectIndex].origin_pos[0]; + gObjectList[loopObjectIndex].origin_pos[1] = gObjectList[objectIndex].origin_pos[1] - 13.0; + gObjectList[loopObjectIndex].origin_pos[2] = gObjectList[objectIndex].origin_pos[2]; + break; + } + } +} + void OMole::func_80081D34(s32 objectIndex) { Player* player; - Camera* var_s4; - s32 var_s2; + Camera* camera; s32 var_s5; Object* object; var_s5 = 0; player = gPlayerOne; - var_s4 = camera1; - for (var_s2 = 0; var_s2 < D_8018D158; var_s2++, player++, var_s4++) { + camera = camera1; + for (size_t i = 0; i < D_8018D158; i++, player++, camera++) { if ((is_obj_flag_status_active(objectIndex, 0x00000200) != 0) && !(player->effects & 0x80000000) && (has_collided_with_player(objectIndex, player) != 0)) { if ((player->type & 0x8000) && !(player->type & 0x100)) { @@ -182,11 +214,11 @@ void OMole::func_80081D34(s32 objectIndex) { func_80072180(); } if (player->effects & 0x200) { - func_800C9060(var_s2, 0x1900A046U); + func_800C9060(i, 0x1900A046U); } else { player->soundEffects |= 2; } - object->direction_angle[1] = var_s4->rot[1]; + object->direction_angle[1] = camera->rot[1]; object->velocity[1] = (player->unk_094 / 2) + 3.0; object->unk_034 = player->unk_094 + 1.0; if (object->velocity[1] >= 5.0) { @@ -209,66 +241,23 @@ void OMole::func_80081D34(s32 objectIndex) { } } +static const char* frames[] = { + gTextureMole1, + gTextureMole2, + gTextureMole3, + gTextureMole4, + gTextureMole5, + gTextureMole6, + gTextureMole7, + d_course_moo_moo_farm_mole_dirt, +}; -void OMole::func_80081FF4(s32 objectIndex, s32 arg1) { - UNUSED s32 stackPadding0; - UNUSED s32 stackPadding1; - s32 moleCount; - s16 var_v1; - s16 offset; - s32 var_a0; - s8* var_a2; - - init_object(objectIndex, 0); - gObjectList[objectIndex].unk_04C = random_int(0x001EU) + 5; - switch (arg1) { /* irregular */ - case 1: - var_a2 = D_8018D198; - moleCount = NUM_GROUP1_MOLES; - offset = 0; - break; - case 2: - var_a2 = D_8018D1A8; - moleCount = NUM_GROUP2_MOLES; - offset = 24; - // offset = NUM_GROUP1_MOLES; - break; - case 3: - var_a2 = D_8018D1B8; - moleCount = NUM_GROUP3_MOLES; - offset = 57; - // offset = NUM_GROUP1_MOLES + NUM_GROUP2_MOLES; - break; - } - var_v1 = random_int(moleCount); - for (var_a0 = 0; var_a0 < moleCount; var_a0++) { - if (var_a2[var_v1] != 0) { - var_v1++; - if (var_v1 == moleCount) { - var_v1 = 0; - } - } else { - var_a2[var_v1] = 1; - gObjectList[objectIndex].type = var_v1; - break; - } - } - /* - Ideally `gMoleSpawns` wouldn't be a union at all and its just be a list of Vec3s - Even more ideally each mole group would have its own array for its spawns - gObjectList[objectIndex].origin_pos[0] = gMoleSpawns.asVec3sList[offset + var_v1][0] * xOrientation; - gObjectList[objectIndex].origin_pos[1] = gMoleSpawns.asVec3sList[offset + var_v1][1] - 9.0; - gObjectList[objectIndex].origin_pos[2] = gMoleSpawns.asVec3sList[offset + var_v1][2]; - */ - gObjectList[objectIndex].origin_pos[0] = gMoleSpawns.asFlatList[offset + (var_v1 * 3) + 0] * xOrientation; - gObjectList[objectIndex].origin_pos[1] = gMoleSpawns.asFlatList[offset + (var_v1 * 3) + 1] - 9.0; - gObjectList[objectIndex].origin_pos[2] = gMoleSpawns.asFlatList[offset + (var_v1 * 3) + 2]; -} void OMole::func_80081848(s32 objectIndex) { - u8* mole = (u8*) LOAD_ASSET_RAW(d_course_moo_moo_farm_mole_frames); - u8* tlut = (u8*) LOAD_ASSET_RAW(d_course_moo_moo_farm_mole_tlut); - init_texture_object(objectIndex, (u8*)d_course_moo_moo_farm_mole_tlut, (const char**) mole, 0x20U, (u16) 0x00000040); + init_texture_object(objectIndex, (u8*)d_course_moo_moo_farm_mole_tlut, (const char**) frames, 0x20U, (u16) 0x00000040); + //gObjectList[objectIndex].activeTexture = (const char*)d_course_moo_moo_farm_mole_frames; + //gObjectList[objectIndex].activeTLUT = (const char*)d_course_moo_moo_farm_mole_tlut; + gObjectList[objectIndex].sizeScaling = 0.15f; gObjectList[objectIndex].textureListIndex = 0; set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); @@ -358,9 +347,9 @@ void OMole::func_80054E10(s32 objectIndex) { void OMole::func_80054EB8() { s32 someIndex; - for (someIndex = 0; someIndex < NUM_TOTAL_MOLES; someIndex++) { - func_80054E10(gObjectParticle1[someIndex]); - } + //for (someIndex = 0; someIndex < NUM_TOTAL_MOLES; someIndex++) { + func_80054E10(_moleIndex); + //} } void OMole::func_80054D00(s32 objectIndex, s32 cameraId) { @@ -382,41 +371,24 @@ void OMole::func_80054D00(s32 objectIndex, s32 cameraId) { } void OMole::func_80054F04(s32 cameraId) { - s32 var_s2; - s32 objectIndex; - Camera* sp44; - Object* object; + Camera* camera = &camera1[cameraId]; - sp44 = &camera1[cameraId]; gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D0079C8); load_texture_block_rgba16_mirror((u8*) LOAD_ASSET_RAW(d_course_moo_moo_farm_mole_dirt), 0x00000010, 0x00000010); - for (var_s2 = 0; var_s2 < gObjectParticle2_SIZE; var_s2++) { - objectIndex = gObjectParticle2[var_s2]; - object = &gObjectList[objectIndex]; + +if (_idx == 0) { + for (size_t i = 0; i < gObjectParticle2_SIZE; i++) { + s32 objectIndex = gObjectParticle2[i]; + Object* object = &gObjectList[objectIndex]; if (object->state > 0) { func_8008A364(objectIndex, cameraId, 0x2AABU, 0x000000C8); if ((is_obj_flag_status_active(objectIndex, VISIBLE) != 0) && (gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX)) { - object->orientation[1] = func_800418AC(object->pos[0], object->pos[2], sp44->pos); + object->orientation[1] = func_800418AC(object->pos[0], object->pos[2], camera->pos); rsp_set_matrix_gObjectList(objectIndex); gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D006980); } } } +} gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); } - -void OMole::render_object_moles(s32 cameraId) { - s32 i; - - for (i = 0; i < NUM_GROUP1_MOLES; i++) { - OMole::func_80054D00(indexObjectList1[i], cameraId); - } - for (i = 0; i < NUM_GROUP2_MOLES; i++) { - OMole::func_80054D00(indexObjectList2[i], cameraId); - } - for (i = 0; i < NUM_GROUP3_MOLES; i++) { - OMole::func_80054D00(indexObjectList3[i], cameraId); - } - OMole::func_80054EB8(); - OMole::func_80054F04(cameraId); -} \ No newline at end of file diff --git a/src/engine/objects/Mole.h b/src/engine/objects/Mole.h index 7ff95c58c..7707b5383 100644 --- a/src/engine/objects/Mole.h +++ b/src/engine/objects/Mole.h @@ -3,6 +3,8 @@ #include #include #include "Object.h" +#include "CoreMath.h" +#include "MoleGroup.h" extern "C" { #include "macros.h" @@ -15,14 +17,11 @@ extern "C" { #include "some_data.h" } +class OMoleGroup; class OMole : public OObject { public: - enum Behaviour : uint16_t { - }; - -public: - explicit OMole(Vec3f pos); + explicit OMole(FVector pos, OMoleGroup* group); virtual void Tick() override; virtual void Draw(s32 cameraId) override; @@ -33,20 +32,18 @@ public: void render_object_moles(s32 cameraId); void func_80054D00(s32 objectIndex, s32 cameraId); void func_800821AC(s32 objectIndex, s32 arg1); - void func_80081FF4(s32 objectIndex, s32 arg1); void func_80081D34(s32 objectIndex); void func_80081AFC(s32 objectIndex, s32 arg1); void func_80081A88(s32 objectIndex); void func_80081924(s32 objectIndex); void func_80081848(s32 objectIndex); void func_80081790(s32 objectIndex); + void func_8008153C(s32 objectIndex); + s32 _objectIndex; + s32 _moleIndex; private: - s32 _idx; - s32 _state; - s32 _timer; - s32 _status; - bool _toggle; - - SplineData *spline; + static size_t _count; + size_t _idx; + OMoleGroup* _group; }; diff --git a/src/engine/objects/MoleGroup.cpp b/src/engine/objects/MoleGroup.cpp new file mode 100644 index 000000000..6e98edbbb --- /dev/null +++ b/src/engine/objects/MoleGroup.cpp @@ -0,0 +1,50 @@ +#include "MoleGroup.h" +#include "Mole.h" + +extern "C" { +#include "code_80057C60.h" +#include "update_objects.h" +#include "math_util.h" +#include "math_util_2.h" +} + +OMoleGroup::OMoleGroup(std::vector spawns) { + for (auto& pos : spawns) { + pos.x * xOrientation; + OMole* ptr = reinterpret_cast(gWorldInstance.AddObject(new OMole(pos, this))); + _moles.push_back({ptr, pos, false}); + } +} + +void OMoleGroup::Tick() { + for (auto &mole : _moles) { + if (gObjectList[mole.Mole->_objectIndex].state == 0) { + func_80081FF4(mole.Mole->_objectIndex); + } else { + mole.Mole->func_800821AC(mole.Mole->_objectIndex, 1); + } + } +} + +void OMoleGroup::func_80081FF4(s32 objectIndex) { + init_object(objectIndex, 0); + gObjectList[objectIndex].unk_04C = random_int(30) + 5; + + s16 mole = random_int(_moles.size() - 1); + for (size_t i = 0; i < _moles.size() - 1; i++) { + if (_moles[mole].Active == true) { + mole++; + if (mole == _moles.size()) { + mole = 0; + } + } else { // if not active + _moles[mole].Active = true; + gObjectList[objectIndex].type = mole; + break; + } + } + + gObjectList[objectIndex].origin_pos[0] = _moles[mole].Pos.x * xOrientation; + gObjectList[objectIndex].origin_pos[1] = _moles[mole].Pos.y - 9.0; + gObjectList[objectIndex].origin_pos[2] = _moles[mole].Pos.z; +} diff --git a/src/engine/objects/MoleGroup.h b/src/engine/objects/MoleGroup.h new file mode 100644 index 000000000..dfb920985 --- /dev/null +++ b/src/engine/objects/MoleGroup.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include +#include "World.h" +#include "CoreMath.h" +#include "Mole.h" + +class OMole; + +class OMoleGroup : public OObject { +public: + struct MoleEntry { + OMole* Mole; + FVector Pos; + bool Active; + }; + + explicit OMoleGroup(std::vector moles); + + virtual void Tick() override; + + void func_80081FF4(s32 objectIndex); + + + std::vector _moles; +}; diff --git a/src/engine/objects/Object.cpp b/src/engine/objects/Object.cpp index eb23b853e..d532dd566 100644 --- a/src/engine/objects/Object.cpp +++ b/src/engine/objects/Object.cpp @@ -20,3 +20,4 @@ void OObject::Expire() { } void OObject::Destroy() { PendingDestroy = true; } +void OObject::Reset() { } diff --git a/src/engine/objects/Object.h b/src/engine/objects/Object.h index c02deda23..b78b27240 100644 --- a/src/engine/objects/Object.h +++ b/src/engine/objects/Object.h @@ -22,4 +22,5 @@ public: virtual void Draw(s32 cameraId); virtual void Expire(); virtual void Destroy(); // Mark object for deletion at the start of the next frame + virtual void Reset(); }; diff --git a/src/engine/objects/Penguin.cpp b/src/engine/objects/Penguin.cpp index c690e1ef2..1eeb00ff4 100644 --- a/src/engine/objects/Penguin.cpp +++ b/src/engine/objects/Penguin.cpp @@ -33,22 +33,16 @@ extern "C" { extern s8 gPlayerCount; } -size_t OPenguin::_count = 0; OPenguin::OPenguin(Vec3f pos, u16 direction, PenguinType type, Behaviour behaviour) { - _idx = _count; _type = type; _bhv = behaviour; - if (_idx >= 32) { - printf("MAX penguin REACHED (32), skipping\n"); - return; - } + find_unused_obj_index(&_objectIndex); - s32 objectIndex = indexObjectList1[_idx]; - init_object(objectIndex, 0); + init_object(_objectIndex, 0); - Object *object = &gObjectList[objectIndex]; + Object *object = &gObjectList[_objectIndex]; object->origin_pos[0] = pos[0] * xOrientation; object->origin_pos[1] = pos[1]; object->origin_pos[2] = pos[2]; @@ -75,14 +69,11 @@ OPenguin::OPenguin(Vec3f pos, u16 direction, PenguinType type, Behaviour behavio object->boundingBoxSize = 0x000C; break; } - - _count++; } void OPenguin::Tick(void) { - s32 objectIndex; + s32 objectIndex = _objectIndex; - objectIndex = indexObjectList1[_idx]; if (gObjectList[objectIndex].state != 0) { if (_type == PenguinType::EMPEROR) { OPenguin::EmperorPenguin(objectIndex); @@ -90,7 +81,7 @@ void OPenguin::Tick(void) { OPenguin::OtherPenguin(objectIndex); } - OPenguin::Behaviours(objectIndex, _idx); + OPenguin::Behaviours(objectIndex); } if (func_80072320(objectIndex, 1) != 0) { func_80089820(objectIndex, 1.75f, 1.5f, 0x1900A046U); @@ -107,7 +98,7 @@ void OPenguin::Tick(void) { } void OPenguin::Draw(s32 cameraId) { - s32 objectIndex; + s32 objectIndex = _objectIndex; s32 temp_s1; s32 drawDistance; u16 var_s1; @@ -121,26 +112,26 @@ void OPenguin::Draw(s32 cameraId) { var_s3 = 0x00015F90; } - objectIndex = indexObjectList1[_idx]; + if (gObjectList[objectIndex].state >= 2) { - if (gPlayerCountSelection1 == 1) { + + // This code decreased draw dist if there's more players. + // The var_s1 = 0x4000 for everything is just a guess. + // It seems to check the angle of the camera. + // These changes were so instance indices are not required. + + //if (gPlayerCountSelection1 == 1) { var_s1 = 0x4000; - if (_idx == 0) { - drawDistance = 0x000005DC; - } else if (func_80072320(objectIndex, 8) != 0) { - drawDistance = 0x00000320; - } else { - drawDistance = 0x000003E8; - } - } else { - if (func_80072320(objectIndex, 8) != 0) { - drawDistance = 0x000001F4; - var_s1 = 0x4000; - } else { - drawDistance = 0x00000258; - var_s1 = 0x5555; - } - } + drawDistance = 1500; + //} else { + // if (func_80072320(objectIndex, 8) != 0) { + // drawDistance = 500; + // var_s1 = 0x4000; + // } else { + // drawDistance = 600; + // var_s1 = 0x5555; + // } + //} temp_s1 = func_8008A364(objectIndex, cameraId, var_s1, drawDistance); if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { func_800557B4(objectIndex, (u32) temp_s1, var_s3); @@ -148,7 +139,7 @@ void OPenguin::Draw(s32 cameraId) { } } -void OPenguin::Behaviours(s32 objectIndex, s32 arg1) { // func_800850B0 +void OPenguin::Behaviours(s32 objectIndex) { // func_800850B0 Object* object; object = &gObjectList[objectIndex]; @@ -157,7 +148,7 @@ void OPenguin::Behaviours(s32 objectIndex, s32 arg1) { // func_800850B0 OPenguin::func_80085080(objectIndex); break; case 2: - OPenguin::func_8008502C(objectIndex, arg1); + OPenguin::func_8008502C(objectIndex); break; case 3: OPenguin::func_80084D2C(objectIndex, 0); @@ -226,17 +217,17 @@ void OPenguin::func_80084D2C(s32 objectIndex, s32 arg1) { } break; case 3: - switch (arg1) { /* switch 1; irregular */ - case 0: /* switch 1 */ + switch (arg1) { + case 0: sp24 = 1.0f; break; - case 1: /* switch 1 */ + case 1: sp24 = 1.5f; break; - case 2: /* switch 1 */ + case 2: sp24 = 2.0f; break; - case 3: /* switch 1 */ + case 3: sp24 = 2.5f; break; } @@ -285,7 +276,7 @@ void OPenguin::func_80085080(s32 objectIndex) { func_800873F4(objectIndex); } -void OPenguin::func_8008502C(s32 objectIndex, s32 arg1) { +void OPenguin::func_8008502C(s32 objectIndex) { func_80088038(objectIndex, gObjectList[objectIndex].unk_01C[1], gObjectList[objectIndex].unk_0C6); object_calculate_new_pos_offset(objectIndex); func_800873F4(objectIndex); @@ -371,6 +362,8 @@ void OPenguin::OtherPenguin(s32 objectIndex) { } } +bool OPenguin::_toggle = false; + void OPenguin::InitOtherPenguin(s32 objectIndex) { Object* object; @@ -380,7 +373,7 @@ void OPenguin::InitOtherPenguin(s32 objectIndex) { object->vertex = (Vtx*) d_course_sherbet_land_unk_data11; //object->boundingBoxSize = 4; object->unk_09C = 2; - object->unk_04C = random_int(0x012CU); + object->unk_04C = random_int(300); set_object_flag(objectIndex, 0x04000220); // This code has been significantly refactored from the original func_800845C8 @@ -388,7 +381,15 @@ void OPenguin::InitOtherPenguin(s32 objectIndex) { switch(_bhv) { case Behaviour::CIRCLE: object->unk_01C[1] = Diameter; - object->unk_0C4 = (_idx << 0xF) & 0xFFFF; + + if (_toggle) { + object->unk_0C4 = 0x8000; + } else { + object->unk_0C4 = 0; + } + + _toggle = !_toggle; + //object->unk_0DD = 2; func_800722A4(objectIndex, 8); break; @@ -411,3 +412,7 @@ void OPenguin::InitOtherPenguin(s32 objectIndex) { object->type = get_animation_length(d_course_sherbet_land_unk_data11, 0); object_next_state(objectIndex); } + +void OPenguin::Reset() { + _toggle = false; +} diff --git a/src/engine/objects/Penguin.h b/src/engine/objects/Penguin.h index 63c2207c1..72ba16285 100644 --- a/src/engine/objects/Penguin.h +++ b/src/engine/objects/Penguin.h @@ -40,32 +40,22 @@ public: explicit OPenguin(Vec3f pos, u16 direction, PenguinType type, Behaviour behaviour); - ~OPenguin() { - _count--; - } - - static size_t GetCount() { - return _count; - } - - virtual void Tick() override; virtual void Draw(s32 cameraId) override; + virtual void Reset() override; private: - void Behaviours(s32 objectIndex, s32 arg1); + void Behaviours(s32 objectIndex); void EmperorPenguin(s32 objectIndex); void func_80085080(s32 objectIndex); - void func_8008502C(s32 objectIndex, s32 arg1); + void func_8008502C(s32 objectIndex); void func_80084D2C(s32 objectIndex, s32 arg1); void InitEmperorPenguin(s32 objectIndex); void OtherPenguin(s32 objectIndex); void InitOtherPenguin(s32 objectIndex); - static size_t _count; - s32 _idx; + static bool _toggle; + s32 _objectIndex; PenguinType _type; Behaviour _bhv; - - }; diff --git a/src/engine/objects/Podium.cpp b/src/engine/objects/Podium.cpp index 1922c98a5..d8f1e2ff2 100644 --- a/src/engine/objects/Podium.cpp +++ b/src/engine/objects/Podium.cpp @@ -29,45 +29,66 @@ 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); - } + find_unused_obj_index(&_podium1Index); + find_unused_obj_index(&_podium2Index); + find_unused_obj_index(&_podium3Index); + + //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); + init_object(_podium1Index, 0); + init_object(_podium2Index, 0); + init_object(_podium3Index, 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); - } + + if (gObjectList[_podium1Index].state != 0) { + OPodium::func_80086528(_podium1Index, 0); + OPodium::func_80086424(_podium1Index); + } + + if (gObjectList[_podium2Index].state != 0) { + OPodium::func_80086528(_podium2Index, 1); + OPodium::func_80086424(_podium2Index); + } + + if (gObjectList[_podium3Index].state != 0) { + OPodium::func_80086528(_podium3Index, 2); + OPodium::func_80086424(_podium3Index); } } void OPodium::Draw(s32 cameraId) { // func_80055F48 - for (size_t i = 0; i < NUM_PODIUMS; i++) { - Object* object; - - object = &gObjectList[indexObjectList1[i]]; + Object* object = &gObjectList[_podium1Index]; + 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); + } + + object = &gObjectList[_podium2Index]; + 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); + } + + object = &gObjectList[_podium3Index]; 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) { diff --git a/src/engine/objects/Podium.h b/src/engine/objects/Podium.h index ea79d7232..fafdfe63d 100644 --- a/src/engine/objects/Podium.h +++ b/src/engine/objects/Podium.h @@ -33,7 +33,8 @@ public: void func_80086528(s32 objectIndex, s32 arg1); private: - - s32 _idx; + s32 _podium1Index; + s32 _podium2Index; + s32 _podium3Index; FVector _pos; }; diff --git a/src/engine/objects/Seagull.cpp b/src/engine/objects/Seagull.cpp index cced70348..11043238f 100644 --- a/src/engine/objects/Seagull.cpp +++ b/src/engine/objects/Seagull.cpp @@ -31,12 +31,11 @@ SplineData* D_800E633C[] = { &D_800E6034, &D_800E60F0, &D_800E61B4, &D_800E6280 size_t OSeagull::_count = 0; -OSeagull::OSeagull(Vec3f pos) { - size_t objectIndex; +OSeagull::OSeagull(FVector pos) { _idx = _count; - _pos[0] = pos[0]; - _pos[1] = pos[1]; - _pos[2] = pos[2]; + _pos.x = pos.x; + _pos.y = pos.y; + _pos.z = pos.z; s16 randZ; s16 randX; @@ -45,18 +44,16 @@ OSeagull::OSeagull(Vec3f pos) { randY = random_int(20); randZ = random_int(200) + -100.0; - //for (i = 0; i < NUM_SEAGULLS; i++) { + find_unused_obj_index(&_objectIndex); + + init_object(_objectIndex, 0); - objectIndex = indexObjectList2[_idx]; - init_object(objectIndex, 0); - - - set_obj_origin_pos(objectIndex, pos[0], pos[1], pos[2]); + set_obj_origin_pos(_objectIndex, pos.x, pos.y, pos.z); if (_idx < (NUM_SEAGULLS / 2)) { - gObjectList[objectIndex].unk_0D5 = 0; + gObjectList[_objectIndex].unk_0D5 = 0; } else { - gObjectList[objectIndex].unk_0D5 = 1; + gObjectList[_objectIndex].unk_0D5 = 1; } _count++; @@ -64,7 +61,7 @@ OSeagull::OSeagull(Vec3f pos) { void OSeagull::Tick() { Object* object; - s32 objectIndex = indexObjectList2[_idx]; + s32 objectIndex = _objectIndex; object = &gObjectList[objectIndex]; if (object->state == 0) { @@ -83,10 +80,11 @@ void OSeagull::Tick() { if (gGamestate != CREDITS_SEQUENCE) { func_800C98B8(object->pos, D_80183E40, SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x43)); } else { - objectIndex = indexObjectList2[1]; - if (gCutsceneShotTimer <= 150) { - object = &gObjectList[objectIndex]; - func_800C98B8(object->pos, D_80183E40, SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x43)); + if (_idx == 1) { + if (gCutsceneShotTimer <= 150) { + object = &gObjectList[_objectIndex]; + func_800C98B8(object->pos, D_80183E40, SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x43)); + } } } } @@ -108,7 +106,7 @@ void OSeagull::Tick() { } void OSeagull::Draw(s32 cameraId) { // render_object_seagulls - s32 objectIndex = indexObjectList2[_idx]; + s32 objectIndex = _objectIndex; if (func_8008A364(objectIndex, cameraId, 0x5555U, 0x000005DC) < 0x9C401 && CVarGetInteger("gNoCulling", 0) == 0) { D_80165908 = 1; @@ -172,7 +170,7 @@ void OSeagull::func_8008241C(s32 objectIndex, s32 arg1) { randY = random_int(0x0014); randZ = random_int(0x00C8) + -100.0; - set_obj_origin_pos(objectIndex, (randX + _pos[0]) * xOrientation, randY + _pos[1], randZ + _pos[2]); + set_obj_origin_pos(objectIndex, (randX + _pos.x) * xOrientation, randY + _pos.y, randZ + _pos.z); set_obj_direction_angle(objectIndex, 0U, 0U, 0U); gObjectList[objectIndex].unk_034 = 1.0f; func_80086EF0(objectIndex); diff --git a/src/engine/objects/Seagull.h b/src/engine/objects/Seagull.h index c6898dcc2..a0e5cd233 100644 --- a/src/engine/objects/Seagull.h +++ b/src/engine/objects/Seagull.h @@ -19,7 +19,7 @@ extern "C" { //! @todo unk_0D5 needs to be a struct variable probably. What does it do? Behaviour? class OSeagull : public OObject { public: - explicit OSeagull(Vec3f pos); + explicit OSeagull(FVector pos); ~OSeagull() { _count--; @@ -38,7 +38,8 @@ public: void func_8008241C(s32 objectIndex, s32 arg1); void func_80082714(s32 objectIndex, s32 arg1); private: - Vec3f _pos; + s32 _objectIndex; + FVector _pos; static size_t _count; s32 _idx; bool _toggle; diff --git a/src/engine/objects/Snowman.cpp b/src/engine/objects/Snowman.cpp index c05f464ef..2052a8adb 100644 --- a/src/engine/objects/Snowman.cpp +++ b/src/engine/objects/Snowman.cpp @@ -20,31 +20,30 @@ OSnowman::OSnowman(const FVector& pos) { _idx = _count; _pos = pos; - s32 objectId = indexObjectList2[_idx]; - init_object(objectId, 0); - gObjectList[objectId].origin_pos[0] = pos.x * xOrientation; - gObjectList[objectId].origin_pos[1] = pos.y + 5.0 + 3.0; - gObjectList[objectId].origin_pos[2] = pos.z; - gObjectList[objectId].pos[0] = pos.x * xOrientation; - gObjectList[objectId].pos[1] = pos.y + 5.0 + 3.0; - gObjectList[objectId].pos[2] = pos.z; + find_unused_obj_index(&_headIndex); + init_object(_headIndex, 0); + gObjectList[_headIndex].origin_pos[0] = pos.x * xOrientation; + gObjectList[_headIndex].origin_pos[1] = pos.y + 5.0 + 3.0; + gObjectList[_headIndex].origin_pos[2] = pos.z; + gObjectList[_headIndex].pos[0] = pos.x * xOrientation; + gObjectList[_headIndex].pos[1] = pos.y + 5.0 + 3.0; + gObjectList[_headIndex].pos[2] = pos.z; - objectId = indexObjectList1[_idx]; - init_object(objectId, 0); - gObjectList[objectId].origin_pos[0] = pos.x * xOrientation; - gObjectList[objectId].origin_pos[1] = pos.y + 3.0; - gObjectList[objectId].origin_pos[2] = pos.z; - gObjectList[objectId].unk_0D5 = 0; // Section Id no longer used. + find_unused_obj_index(&_bodyIndex); + init_object(_bodyIndex, 0); + gObjectList[_bodyIndex].origin_pos[0] = pos.x * xOrientation; + gObjectList[_bodyIndex].origin_pos[1] = pos.y + 3.0; + gObjectList[_bodyIndex].origin_pos[2] = pos.z; + gObjectList[_bodyIndex].unk_0D5 = 0; // Section Id no longer used. - gObjectList[objectId].pos[0] = pos.x * xOrientation; - gObjectList[objectId].pos[1] = pos.y + 3.0; - gObjectList[objectId].pos[2] = pos.z; + gObjectList[_bodyIndex].pos[0] = pos.x * xOrientation; + gObjectList[_bodyIndex].pos[1] = pos.y + 3.0; + gObjectList[_bodyIndex].pos[2] = pos.z; _count++; } void OSnowman::Tick() { - s32 var_s0; s32 var_s3; s32 var_s4; s32 objectIndex; @@ -52,8 +51,8 @@ void OSnowman::Tick() { //! @todo quick hack to add the snow particles on hit. Need to separate into its own class if (_idx == 0) { - for (var_s0 = 0; var_s0 < gObjectParticle2_SIZE; var_s0++) { - objectIndex = gObjectParticle2[var_s0]; + for (size_t i = 0; i < gObjectParticle2_SIZE; i++) { + objectIndex = gObjectParticle2[i]; if (objectIndex == DELETED_OBJECT_ID) { continue; @@ -66,14 +65,13 @@ void OSnowman::Tick() { if (gObjectList[objectIndex].state != 0) { continue; } - delete_object_wrapper(&gObjectParticle2[var_s0]); - if (var_s0) {} // ?? + delete_object_wrapper(&gObjectParticle2[i]); } } //for (var_s0 = 0; var_s0 < NUM_SNOWMEN; var_s0++) { - var_s4 = indexObjectList1[_idx]; - var_s3 = indexObjectList2[_idx]; + var_s4 = _bodyIndex; + var_s3 = _headIndex; OSnowman::func_80083A94(var_s3); // snowman head OSnowman::func_80083C04(var_s4); // snowman body if (is_obj_index_flag_status_inactive(var_s4, 0x00001000) != 0) { @@ -113,7 +111,7 @@ void OSnowman::func_800836F0(Vec3f pos) { void OSnowman::DrawHead(s32 cameraId) { s32 objectIndex; Camera* camera = &camera1[cameraId]; - objectIndex = indexObjectList1[_idx]; + objectIndex = _bodyIndex; if (gObjectList[objectIndex].state >= 2) { func_8008A364(objectIndex, cameraId, 0x2AABU, 0x00000258); if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { @@ -127,7 +125,7 @@ void OSnowman::DrawHead(s32 cameraId) { (u8*)gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex, 0x00000040, 0x00000040, 0x00000040, 0x00000020); } - objectIndex = indexObjectList2[_idx]; + objectIndex = _headIndex; D_80183E80[0] = (s16) gObjectList[objectIndex].orientation[0]; D_80183E80[2] = (u16) gObjectList[objectIndex].orientation[2]; draw_2d_texture_at(gObjectList[objectIndex].pos, (u16*) D_80183E80, diff --git a/src/engine/objects/Snowman.h b/src/engine/objects/Snowman.h index e3e2a0138..ffa927769 100644 --- a/src/engine/objects/Snowman.h +++ b/src/engine/objects/Snowman.h @@ -46,9 +46,11 @@ public: void func_80083538(s32 objectIndex, Vec3f arg1, s32 arg2, s32 arg3); void func_8008379C(s32 objectIndex); - private: FVector _pos; static size_t _count; size_t _idx; + s32 _objectIndex; + s32 _headIndex; + s32 _bodyIndex; }; diff --git a/src/engine/objects/Thwomp.cpp b/src/engine/objects/Thwomp.cpp index afa12b03b..6a04f07bb 100644 --- a/src/engine/objects/Thwomp.cpp +++ b/src/engine/objects/Thwomp.cpp @@ -52,11 +52,9 @@ OThwomp::OThwomp(s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 prim _boundingBoxSize = boundingBoxSize; State = (States)behaviour; - if (_idx >= 32) { - printf("MAX THWOMPS REACHED (32), skipping\n"); - return; - } - s32 objectId = indexObjectList1[_idx]; + find_unused_obj_index(&_objectIndex); + + s32 objectId = _objectIndex; init_object(objectId, 0); gObjectList[objectId].origin_pos[0] = x * xOrientation; gObjectList[objectId].origin_pos[2] = z; @@ -79,9 +77,8 @@ void OThwomp::Tick60fps() { // func_80081210 s32 var_s2_3; s32 var_s4; - objectIndex = indexObjectList1[_idx]; - func_800722CC(objectIndex, 0x00000010); - OThwomp::SetVisibility(objectIndex); + func_800722CC(_objectIndex, 0x00000010); + OThwomp::SetVisibility(_objectIndex); OThwomp::func_8007F8D8(); @@ -92,26 +89,25 @@ void OThwomp::Tick60fps() { // func_80081210 D_80165834[1] += 0x200; } - objectIndex = indexObjectList1[_idx]; - if (gObjectList[objectIndex].state != 0) { + if (gObjectList[_objectIndex].state != 0) { switch (State) { case STATIONARY: - OThwomp::StationaryBehaviour(objectIndex); + OThwomp::StationaryBehaviour(_objectIndex); break; case MOVE_AND_ROTATE: - OThwomp::MoveAndRotateBehaviour(objectIndex); + OThwomp::MoveAndRotateBehaviour(_objectIndex); break; case MOVE_FAR: - OThwomp::MoveFarBehaviour(objectIndex); + OThwomp::MoveFarBehaviour(_objectIndex); break; case STATIONARY_FAST: - OThwomp::StationaryFastBehaviour(objectIndex); + OThwomp::StationaryFastBehaviour(_objectIndex); break; case JAILED: - OThwomp::JailedBehaviour(objectIndex); + OThwomp::JailedBehaviour(_objectIndex); break; case SLIDE: - OThwomp::SlidingBehaviour(objectIndex); + OThwomp::SlidingBehaviour(_objectIndex); break; } } @@ -121,27 +117,25 @@ void OThwomp::Tick60fps() { // func_80081210 player->tyres[FRONT_LEFT].unk_14 &= ~3; player->unk_046 &= ~0x0006; - objectIndex = indexObjectList1[_idx]; if (!(player->effects & BOO_EFFECT)) { - OThwomp::func_80080B28(objectIndex, var_s4); + OThwomp::func_80080B28(_objectIndex, var_s4); } - if (is_obj_flag_status_active(objectIndex, 0x00020000) != 0) { - OThwomp::SetPlayerCrushedEffect(objectIndex, player); + if (is_obj_flag_status_active(_objectIndex, 0x00020000) != 0) { + OThwomp::SetPlayerCrushedEffect(_objectIndex, player); } - if (is_obj_flag_status_active(objectIndex, 0x00010000) != 0) { - OThwomp::func_80080A4C(objectIndex, var_s4); + if (is_obj_flag_status_active(_objectIndex, 0x00010000) != 0) { + OThwomp::func_80080A4C(_objectIndex, var_s4); } } OThwomp::func_8007542C(3); - objectIndex = indexObjectList1[_idx]; - if (func_80072320(objectIndex, 0x00000020) == 0) { + if (func_80072320(_objectIndex, 0x00000020) == 0) { return; } - func_800722CC(objectIndex, 0x00000020); - OThwomp::AddParticles(objectIndex); + func_800722CC(_objectIndex, 0x00000020); + OThwomp::AddParticles(_objectIndex); for (var_s4 = 0; var_s4 < gObjectParticle2_SIZE; var_s4++) { objectIndex = gObjectParticle2[var_s4]; @@ -160,7 +154,7 @@ void OThwomp::Tick60fps() { // func_80081210 } void OThwomp::func_800810F4(s32 objectIndex) { - switch (gObjectList[objectIndex].state) { /* irregular */ + switch (gObjectList[objectIndex].state) { case 0: break; case 1: @@ -336,7 +330,6 @@ void OThwomp::SetVisibility(s32 objectIndex) { // func_8008A4CC void OThwomp::func_8007F8D8() { Player* player; - s32 objectIndex; s32 var_s0; s32 someIndex; s32 var_s4; @@ -345,11 +338,10 @@ void OThwomp::func_8007F8D8() { player = gPlayerOne; var_s4 = 1; - objectIndex = indexObjectList1[_idx]; - object = &gObjectList[objectIndex]; + object = &gObjectList[_objectIndex]; if (object->unk_0D5 == 3) { var_s0 = 0; - if ((object->state >= 2) && (func_80072354(objectIndex, 8) != 0)) { + if ((object->state >= 2) && (func_80072354(_objectIndex, 8) != 0)) { var_s0 = 1; } var_s4 *= var_s0; @@ -368,7 +360,6 @@ void OThwomp::func_8007F8D8() { s32 OThwomp::func_8007F75C(s32 playerId) { s32 someIndex; - s32 objectIndex; s32 temp_s7; s32 var_s6; s32 waypoint; @@ -377,17 +368,15 @@ s32 OThwomp::func_8007F75C(s32 playerId) { var_s6 = 0; if ((waypoint >= 0xAA) && (waypoint < 0xB5)) { temp_s7 = random_int(0x0032U) + 0x32; - objectIndex = indexObjectList1[_idx]; - if (gObjectList[objectIndex].unk_0D5 == 3) { + if (gObjectList[_objectIndex].unk_0D5 == 3) { var_s6 = 1; - OThwomp::func_8007F660(objectIndex, playerId, temp_s7); + OThwomp::func_8007F660(_objectIndex, playerId, temp_s7); } } else if ((waypoint >= 0xD7) && (waypoint < 0xE2)) { - objectIndex = indexObjectList1[_idx]; - if (gObjectList[objectIndex].unk_0D5 == 3) { + if (gObjectList[_objectIndex].unk_0D5 == 3) { var_s6 = 1; - OThwomp::func_8007F6C4(objectIndex, playerId); + OThwomp::func_8007F6C4(_objectIndex, playerId); } } return var_s6; @@ -668,7 +657,7 @@ Lights1 D_800E4680 = gdSPDefLights1(85, 85, 85, 255, 255, 255, 0, 0, 120); Lights1 D_800E4698 = gdSPDefLights1(85, 85, 85, 255, 255, 255, 0, 0, 120); void OThwomp::Draw(s32 cameraId) { - s32 objectIndex = 0; + s32 objectIndex = _objectIndex; s32 i; UNUSED s32 stackPadding0; s16 minusone, plusone; @@ -677,14 +666,12 @@ void OThwomp::Draw(s32 cameraId) { camera = &camera1[cameraId]; if (cameraId == PLAYER_ONE) { - objectIndex = indexObjectList1[_idx]; clear_object_flag(objectIndex, 0x00070000); func_800722CC(objectIndex, 0x00000110); } OThwomp::TranslateThwompLights(); - objectIndex = indexObjectList1[_idx]; minusone = gObjectList[objectIndex].unk_0DF - 1; plusone = gObjectList[objectIndex].unk_0DF + 1; diff --git a/src/engine/objects/Thwomp.h b/src/engine/objects/Thwomp.h index 22c674bb5..75aeaf1a0 100644 --- a/src/engine/objects/Thwomp.h +++ b/src/engine/objects/Thwomp.h @@ -113,6 +113,7 @@ public: private: static size_t _count; s32 _idx; + s32 _objectIndex; s16 _faceDirection; //! @todo Write this better. This effects the squish size and the bounding box size. // We should probably return to the programmer the pointer to the actor so they can do thwomp->squishSize = value. diff --git a/src/engine/objects/TrashBin.cpp b/src/engine/objects/TrashBin.cpp index 43d43b1fc..6aa556470 100644 --- a/src/engine/objects/TrashBin.cpp +++ b/src/engine/objects/TrashBin.cpp @@ -26,7 +26,9 @@ OTrashBin::OTrashBin(const FVector& pos, const FRotation& rotation, f32 scale, O _scale = scale; _bhv = bhv; - init_object(indexObjectList1[1], 0); + find_unused_obj_index(&_objectIndex); + + init_object(_objectIndex, 0); if (GetCourse() != GetBansheeBoardwalk()) { _drawBin = true; @@ -34,26 +36,23 @@ OTrashBin::OTrashBin(const FVector& pos, const FRotation& rotation, f32 scale, O } void OTrashBin::Tick() { - s32 objectIndex = indexObjectList1[1]; - OTrashBin::func_8007E00C(objectIndex); + OTrashBin::func_8007E00C(_objectIndex); switch(_bhv) { case STATIC: break; case MUNCHING: - func_8007DDC0(objectIndex); + func_8007DDC0(_objectIndex); break; } } void OTrashBin::Draw(s32 cameraId) { - s32 objectIndex; Object* object; - objectIndex = indexObjectList1[1]; - func_8008A364(objectIndex, cameraId, 0x5555U, 0x00000320); - if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { - object = &gObjectList[objectIndex]; + func_8008A364(_objectIndex, cameraId, 0x5555U, 0x00000320); + if (is_obj_flag_status_active(_objectIndex, VISIBLE) != 0) { + object = &gObjectList[_objectIndex]; if (object->state >= 2) { func_80043220(object->pos, object->orientation, object->sizeScaling, object->model); } diff --git a/src/engine/objects/TrashBin.h b/src/engine/objects/TrashBin.h index 2ef500f92..2ebe13e87 100644 --- a/src/engine/objects/TrashBin.h +++ b/src/engine/objects/TrashBin.h @@ -41,5 +41,6 @@ private: FRotation _rot; float _scale; size_t _idx; + s32 _objectIndex; bool _drawBin = false; }; diff --git a/src/engine/objects/Trophy.cpp b/src/engine/objects/Trophy.cpp index 4de758aab..54bd70d3e 100644 --- a/src/engine/objects/Trophy.cpp +++ b/src/engine/objects/Trophy.cpp @@ -1,6 +1,8 @@ #include "Trophy.h" #include "assets/common_data.h" #include "assets/data_segment2.h" +#include "port/Game.h" + extern "C" { #include "main.h" #include "defines.h" @@ -8,6 +10,7 @@ extern "C" { #include "code_80057C60.h" #include "assets/ceremony_data.h" #include "podium_ceremony_actors.h" +#include "engine/particles/StarEmitter.h" #include "math_util.h" #include "math_util_2.h" #include "data/some_data.h" @@ -18,12 +21,18 @@ extern "C" { } 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; + find_unused_obj_index(&_objectIndex); + + // If you're trying to place multiple trophies in the podium ceremony + // This will make the camera look at the last trophy spawned. + // Thus this will need to be changed if that's not desired. + gTrophyIndex = _objectIndex; + if (bhv == OTrophy::Behaviour::PODIUM_CEREMONY) { _toggleVisibility = &D_801658CE; } else { @@ -34,55 +43,57 @@ OTrophy::OTrophy(const FVector& pos, TrophyType trophy, Behaviour bhv) { // This allows spawning for mods if (*_toggleVisibility == true) { - init_object(objectIndex, 0); + init_object(_objectIndex, 0); } switch (trophy) { case TrophyType::GOLD: - gObjectList[objectIndex].model = (Gfx*)gold_trophy_dl10; + gObjectList[_objectIndex].model = (Gfx*)gold_trophy_dl10; break; case TrophyType::SILVER: - gObjectList[objectIndex].model = (Gfx*)gold_trophy_dl12; + gObjectList[_objectIndex].model = (Gfx*)gold_trophy_dl12; break; case TrophyType::BRONZE: - gObjectList[objectIndex].model = (Gfx*)gold_trophy_dl14; + gObjectList[_objectIndex].model = (Gfx*)gold_trophy_dl14; break; case TrophyType::GOLD_150: - gObjectList[objectIndex].model = (Gfx*)gold_trophy_dl11; + gObjectList[_objectIndex].model = (Gfx*)gold_trophy_dl11; break; case TrophyType::SILVER_150: - gObjectList[objectIndex].model = (Gfx*)gold_trophy_dl13; + gObjectList[_objectIndex].model = (Gfx*)gold_trophy_dl13; break; case TrophyType::BRONZE_150: - gObjectList[objectIndex].model = (Gfx*)gold_trophy_dl15; + 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); + 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; + gObjectList[_objectIndex].sizeScaling = 0.010f; break; } - Object *object = &gObjectList[objectIndex]; + 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; + + _emitter = reinterpret_cast(gWorldInstance.AddEmitter(new StarEmitter())); } void OTrophy::Tick() { // func_80086D80 - s32 objectIndex = indexObjectList1[3]; + s32 objectIndex = _objectIndex; s32 var_s0; // Fallback for podium ceremony where the trophy is not spawned until it is needed @@ -197,7 +208,7 @@ void OTrophy::Tick() { // func_80086D80 } void OTrophy::Draw(s32 cameraId) { - s32 listIndex = indexObjectList1[3]; + s32 listIndex = _objectIndex; Mat4 someMatrix1; Mat4 someMatrix2; Object* object; @@ -333,62 +344,8 @@ void OTrophy::func_80086C6C(s32 objectIndex) { } 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); + if (_emitter != nullptr) { + _emitter->Emit(sp24, D_801658F4); } } - -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 a227ef5b9..c2bb937ab 100644 --- a/src/engine/objects/Trophy.h +++ b/src/engine/objects/Trophy.h @@ -4,6 +4,7 @@ #include #include "Object.h" #include "World.h" +#include "engine/particles/StarEmitter.h" extern "C" { #include "macros.h" @@ -43,12 +44,11 @@ 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: + StarEmitter* _emitter; - s32 _idx; + s32 _objectIndex; TrophyType _trophy; FVector _spawnPos; Behaviour _bhv; diff --git a/src/engine/particles/StarEmitter.cpp b/src/engine/particles/StarEmitter.cpp index e700b4c8c..242e1a75a 100644 --- a/src/engine/particles/StarEmitter.cpp +++ b/src/engine/particles/StarEmitter.cpp @@ -12,30 +12,30 @@ extern "C" { #include "math_util_2.h" } -StarEmitter::StarEmitter(FVector pos) { - s32 objectIndex = add_unused_obj_index(gObjectParticle3, &gNextFreeObjectParticle3, gObjectParticle3_SIZE); +StarEmitter::StarEmitter() { + for (size_t i = 0; i < gObjectParticle3_SIZE; i++) { + ObjectIndex[i] = NULL_OBJECT_ID; + } +} + +void StarEmitter::Emit(Vec3f arg1, s32 arg2) { // func_80077138 + s32 objectIndex; s8 temp_v0_3; Vec3s sp30; - for (size_t i = 0; i < D_80165738; i++) { - find_unused_obj_index(&gObjectParticle3[i]); - init_object(gObjectParticle3[i], 0); - } + objectIndex = add_unused_obj_index(&ObjectIndex[0], &_next, gObjectParticle3_SIZE); if (objectIndex == NULL_OBJECT_ID) { return; - //func_80077138(objectIndex, arg0, arg1); } - D_801658F4 = 1; - - init_object(objectIndex, D_801658F4); + init_object(objectIndex, arg2); gObjectList[objectIndex].unk_0D5 = 0x0C; gObjectList[objectIndex].sizeScaling = 0.05f; - set_obj_origin_pos(objectIndex, pos.x, pos.y, pos.z); + 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 (D_801658F4) { + switch (arg2) { case 0: gObjectList[objectIndex].velocity[1] = -1.0f; gObjectList[objectIndex].unk_034 = (f32) ((random_int(0x004BU) * 0.01) + 0.25); @@ -81,15 +81,14 @@ void StarEmitter::Tick() { // func_80077640 Object* object; for (someIndex = 0; someIndex < gObjectParticle3_SIZE; someIndex++) { - objectIndex = gObjectParticle3[someIndex]; + objectIndex = ObjectIndex[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]); + delete_object_wrapper(&ObjectIndex[someIndex]); } } } @@ -107,16 +106,14 @@ void StarEmitter::Draw(s32 cameraId) { // func_80054BE8 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]; + temp_a0 = ObjectIndex[var_s0]; if ((temp_a0 != -1) && (gObjectList[temp_a0].state >= 2)) { - printf("Draw Star\n"); 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]; @@ -168,13 +165,11 @@ void StarEmitter::func_80077450(s32 objectIndex) { (func_80073B00(objectIndex, &gObjectList[objectIndex].primAlpha, 0x000000FF, 0, 0x00000010, 0, 0) != 0)) { func_80086F60(objectIndex); - //func_80072428(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; diff --git a/src/engine/particles/StarEmitter.h b/src/engine/particles/StarEmitter.h index 285c959f4..e1c6e0416 100644 --- a/src/engine/particles/StarEmitter.h +++ b/src/engine/particles/StarEmitter.h @@ -28,16 +28,17 @@ public: f32 Diameter = 0.0f; // Waddle in a circle around the spawn point at this diameter. uint16_t MirrorModeAngleOffset; - explicit StarEmitter(FVector pos); + explicit StarEmitter(); virtual void Tick() override; virtual void Draw(s32 cameraId) override; + void Emit(Vec3f arg1, s32 arg2); void func_80077428(s32 objectIndex); void func_80077584(s32 objectIndex); void func_80077450(s32 objectIndex); void func_80054AFC(s32 objectIndex, Vec3f arg1); private: - - s32 _idx; + s32 ObjectIndex[128]; + s32 _next = 0; }; diff --git a/src/port/Game.cpp b/src/port/Game.cpp index 5ac56da94..f016aec39 100644 --- a/src/port/Game.cpp +++ b/src/port/Game.cpp @@ -93,6 +93,8 @@ Cup* gBattleCup; ModelLoader gModelLoader; +s32 gTrophyIndex = NULL; + void CustomEngineInit() { gMarioRaceway = new MarioRaceway(); @@ -348,8 +350,16 @@ void CM_DrawActors(Camera* camera, struct Actor* actor) { } void CM_BeginPlay() { - if (gWorldInstance.CurrentCourse) { - gWorldInstance.CurrentCourse->BeginPlay(); + Course* course = gWorldInstance.CurrentCourse; + + if (course) { + + // Do not spawn finishline in credits or battle mode. And if bSpawnFinishline. + if ((gGamestate != CREDITS_SEQUENCE) && (gGamestate != BATTLE) && (course->bSpawnFinishline)) { + gWorldInstance.AddActor(new AFinishline(course->FinishlineSpawnPoint)); + } + + course->BeginPlay(); } } @@ -615,6 +625,7 @@ void CM_CleanWorld(void) { gWorldInstance.Objects.clear(); gWorldInstance.Emitters.clear(); gWorldInstance.Lakitus.clear(); + gWorldInstance.Reset(); } struct Actor* CM_AddBaseActor(void) { diff --git a/src/port/Game.h b/src/port/Game.h index 5ef93fa1d..96bfcbee8 100644 --- a/src/port/Game.h +++ b/src/port/Game.h @@ -11,6 +11,8 @@ extern "C" { #include "camera.h" #include "actor_types.h" +extern s32 gTrophyIndex; + Properties* CM_GetProps(); Properties* CM_GetPropsCourseId(s32 courseId); diff --git a/src/racing/actors.c b/src/racing/actors.c index 4b586cf75..9fc8059ef 100644 --- a/src/racing/actors.c +++ b/src/racing/actors.c @@ -830,6 +830,10 @@ void spawn_piranha_plants(struct ActorSpawnData* spawnData) { Vec3s startingRot; s32 temp; + if (gGamestate == CREDITS_SEQUENCE) { + return; + } + vec3f_set(startingVelocity, 0, 0, 0); vec3s_set(startingRot, 0, 0, 0); @@ -894,6 +898,10 @@ void spawn_foliage(struct ActorSpawnData* actor) { rotation[1] = 0; rotation[2] = 0; + if (gGamestate == CREDITS_SEQUENCE) { + return; + } + while (var_s3->pos[0] != END_OF_SPAWN_DATA) { position[0] = var_s3->pos[0] * gCourseDirection; position[2] = var_s3->pos[2]; @@ -958,7 +966,7 @@ void spawn_all_item_boxes(struct ActorSpawnData* spawnData) { struct ActorSpawnData* temp_s0 = spawnData; // struct ItemBox *itemBox; - if ((gModeSelection == TIME_TRIALS) || (gPlaceItemBoxes == 0)) { + if ((gModeSelection == TIME_TRIALS) || (gPlaceItemBoxes == 0) || (gGamestate == CREDITS_SEQUENCE)) { return; } diff --git a/src/render_objects.c b/src/render_objects.c index 409bab57c..d3fcaaa64 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -3956,50 +3956,6 @@ void func_800557B4(s32 objectIndex, u32 arg1, u32 arg2) { } } -void render_object_train_penguins(s32 cameraId) { - s32 i; - s32 objectIndex; - s32 temp_s1; - s32 var_a3; - u16 var_s1; - u32 var_s3; - - if (gPlayerCountSelection1 == 1) { - var_s3 = 0x0003D090; - } else if (gPlayerCountSelection1 == 2) { - var_s3 = 0x00027100; - } else { - var_s3 = 0x00015F90; - } - for (i = 0; i < NUM_PENGUINS; i++) { - objectIndex = indexObjectList1[i]; - if (gObjectList[objectIndex].state >= 2) { - if (gPlayerCountSelection1 == 1) { - var_s1 = 0x4000; - if (i == 0) { - var_a3 = 0x000005DC; - } else if (func_80072320(objectIndex, 8) != 0) { - var_a3 = 0x00000320; - } else { - var_a3 = 0x000003E8; - } - } else { - if (func_80072320(objectIndex, 8) != 0) { - var_a3 = 0x000001F4; - var_s1 = 0x4000; - } else { - var_a3 = 0x00000258; - var_s1 = 0x5555; - } - } - temp_s1 = func_8008A364(objectIndex, cameraId, var_s1, var_a3); - if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { - func_800557B4(objectIndex, (u32) temp_s1, var_s3); - } - } - } -} - void func_80055EF4(s32 objectIndex, UNUSED s32 arg1) { Object* object; diff --git a/src/render_objects.h b/src/render_objects.h index ee13cb47c..d4c45eed7 100644 --- a/src/render_objects.h +++ b/src/render_objects.h @@ -363,7 +363,6 @@ void render_object_seagulls(s32); void render_object_crabs(s32); void func_800557AC(void); 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_80055EF4(s32, s32); diff --git a/src/update_objects.c b/src/update_objects.c index 3f25e136f..55ae23246 100644 --- a/src/update_objects.c +++ b/src/update_objects.c @@ -3910,46 +3910,6 @@ void func_8007E4C4(void) { } } -void func_8008153C(s32 objectIndex) { - UNUSED s32 stackPadding[3]; - s32 sp70; - s32 var_s1; - s32 var_s7; - s32 loopObjectIndex; - - if (gPlayerCountSelection1 == 1) { - sp70 = 8; - } else { - sp70 = 4; - } - - for (var_s7 = 0; var_s7 < sp70; var_s7++) { - for (var_s1 = 0; var_s1 < gObjectParticle2_SIZE; var_s1++) { - loopObjectIndex = gObjectParticle2[var_s1]; - - if (gObjectList[loopObjectIndex].state != 0) { - continue; - } - - u8* mole = (u8*) LOAD_ASSET(d_course_moo_moo_farm_mole_dirt); - - init_object(loopObjectIndex, 0); - gObjectList[loopObjectIndex].activeTLUT = d_course_moo_moo_farm_mole_dirt; - gObjectList[loopObjectIndex].tlutList = mole; - gObjectList[loopObjectIndex].sizeScaling = 0.15f; - gObjectList[loopObjectIndex].velocity[1] = random_int(0x000AU); - gObjectList[loopObjectIndex].velocity[1] = (gObjectList[loopObjectIndex].velocity[1] * 0.1) + 4.8; - gObjectList[loopObjectIndex].unk_034 = random_int(5U); - gObjectList[loopObjectIndex].unk_034 = (gObjectList[loopObjectIndex].unk_034 * 0.01) + 0.8; - gObjectList[loopObjectIndex].orientation[1] = (0x10000 / sp70) * var_s1; - gObjectList[loopObjectIndex].origin_pos[0] = gObjectList[objectIndex].origin_pos[0]; - gObjectList[loopObjectIndex].origin_pos[1] = gObjectList[objectIndex].origin_pos[1] - 13.0; - gObjectList[loopObjectIndex].origin_pos[2] = gObjectList[objectIndex].origin_pos[2]; - break; - } - } -} - void func_80083F18(s32 objectIndex) { switch (gObjectList[objectIndex].state) { case 0: diff --git a/src/update_objects.h b/src/update_objects.h index 6f7b840c2..1e25698c1 100644 --- a/src/update_objects.h +++ b/src/update_objects.h @@ -282,14 +282,12 @@ void func_80081080(s32); void func_800810F4(s32); void func_80081208(void); void func_80081210(void); -void func_8008153C(s32); void func_80081790(s32); void func_80081848(s32); void func_80081924(s32); void func_80081A88(s32); void func_80081AFC(s32, s32); void func_80081D34(s32); -void func_80081FF4(s32, s32); void func_800821AC(s32, s32); void update_moles(void); void func_8008241C(s32, s32); @@ -353,7 +351,6 @@ void func_80086700(s32); void func_80086940(s32); void func_80086C14(s32); void func_80086C6C(s32); -void func_80086D80(void); extern f32 D_800E43B0[]; extern Vtx D_800E43F0[];