Implement kart chase

This commit is contained in:
MegaMech
2024-11-17 20:56:53 -07:00
parent 8414e8847c
commit a3cea25d30
4 changed files with 155 additions and 62 deletions
+6 -6
View File
@@ -185,8 +185,8 @@ void TestCourse::SpawnActors() {
ACTOR_RAILROAD_CROSSING));
rrxing->crossingTrigger = crossing1;
Vec3f pos = {-80, 7, -20};
gWorldInstance.AddActor(new ACloud(pos));
//Vec3f pos = {-80, 7, -20};
//gWorldInstance.AddActor(new ACloud(pos));
}
// Likely sets minimap boundaries
@@ -265,13 +265,13 @@ void TestCourse::SpawnVehicles() {
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);
//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};
gWorldInstance.AddBombKart(pos, &D_80164550[0][25], 25, 2, 0.8333333f);
gWorldInstance.AddBombKart(pos, &D_80164550[0][45], 45, 3, 0.8333333f);
gWorldInstance.AddBombKart(pos, &D_80164550[0][25], 25, 4, 0.8333333f);
gWorldInstance.AddBombKart(pos, &D_80164550[0][45], 45, 4, 0.8333333f);
}
+140 -54
View File
@@ -22,6 +22,7 @@ extern "C" {
#include "defines.h"
#include "code_80005FD0.h"
#include "math_util_2.h"
#include "collision.h"
extern s8 gPlayerCount;
}
@@ -50,6 +51,9 @@ OBombKart::OBombKart(Vec3f pos, TrackWaypoint* waypoint, uint16_t waypointIndex,
Pos[0] = _pos[0];
Pos[1] = _pos[1];
Pos[2] = _pos[2];
_spawnPos[0] = _pos[0];
_spawnPos[1] = _pos[1];
_spawnPos[2] = _pos[2];
CenterY = _pos[1];
WheelPos[0][0] = _pos[0];
WheelPos[0][1] = _pos[1];
@@ -97,10 +101,8 @@ void OBombKart::Tick() {
f32 temp_f2;
f32 temp_f2_4;
f32 sp94;
f32 var_f20;
f32 sp88;
f32 var_f22;
f32 var_f24;
Vec3f newPos;
States state;
u16 bounceTimer;
UNUSED u16 sp4C;
@@ -117,9 +119,9 @@ void OBombKart::Tick() {
}
if (((Unk_4A != 1) || (GetCourse() == GetPodiumCeremony()))) {
var_f22 = Pos[0];
var_f20 = Pos[1];
var_f24 = Pos[2];
newPos[0] = Pos[0];
newPos[1] = Pos[1];
newPos[2] = Pos[2];
waypoint = WaypointIndex;
unk_3C = Unk_3C;
someRot = SomeRot;
@@ -129,9 +131,9 @@ void OBombKart::Tick() {
if (GetCourse() == GetPodiumCeremony()) {
if (D_8016347E == 1) {
player = gPlayerFour;
temp_f0 = var_f22 - player->pos[0];
temp_f2 = var_f20 - player->pos[1];
temp_f12 = var_f24 - player->pos[2];
temp_f0 = newPos[0] - player->pos[0];
temp_f2 = newPos[2] - player->pos[1];
temp_f12 = newPos[2] - player->pos[2];
if ((((temp_f0 * temp_f0) + (temp_f2 * temp_f2)) + (temp_f12 * temp_f12)) < 25.0f) {
circleTimer = 0;
state = States::EXPLODE;
@@ -144,9 +146,9 @@ void OBombKart::Tick() {
for (size_t i = 0; i < gPlayerCount; i++) {
player = &gPlayers[i];
if (!(player->effects & 0x80000000)) {
temp_f0 = var_f22 - player->pos[0];
temp_f2 = var_f20 - player->pos[1];
temp_f12 = var_f24 - player->pos[2];
temp_f0 = newPos[0] - player->pos[0];
temp_f2 = newPos[1] - player->pos[1];
temp_f12 = newPos[2] - player->pos[2];
if ((((temp_f0 * temp_f0) + (temp_f2 * temp_f2)) + (temp_f12 * temp_f12)) < 25.0f) {
state = States::EXPLODE;
circleTimer = 0;
@@ -167,12 +169,12 @@ void OBombKart::Tick() {
sp118 = coss(temp_t6) * 25.0;
temp_f0_3 = sins(temp_t6) * 25.0;
temp_v0_2 = &D_80164550[0][waypoint];
var_f22 = temp_v0_2->posX + sp118;
var_f20 = CenterY + 3.5f;
var_f24 = temp_v0_2->posZ + temp_f0_3;
D_80162FB0[0] = var_f22;
D_80162FB0[1] = var_f20;
D_80162FB0[2] = var_f24;
newPos[0] = temp_v0_2->posX + sp118;
newPos[1] = CenterY + 3.5f;
newPos[2] = temp_v0_2->posZ + temp_f0_3;
D_80162FB0[0] = newPos[0];
D_80162FB0[1] = newPos[1];
D_80162FB0[2] = newPos[2];
temp_t7 = (((circleTimer + 1) % 360) * 0xFFFF) / 360;
sp118 = coss(temp_t7) * 25.0;
temp_f0_3 = sins(temp_t7) * 25.0;
@@ -187,12 +189,12 @@ void OBombKart::Tick() {
sp118 = coss(temp_t6) * 25.0;
temp_f0_3 = sins(temp_t6) * 25.0;
temp_v0_2 = &D_80164550[0][waypoint];
var_f22 = temp_v0_2->posX + sp118;
var_f20 = CenterY + 3.5f;
var_f24 = temp_v0_2->posZ + temp_f0_3;
D_80162FB0[0] = var_f22;
D_80162FB0[1] = var_f20;
D_80162FB0[2] = var_f24;
newPos[0] = temp_v0_2->posX + sp118;
newPos[1] = CenterY + 3.5f;
newPos[2] = temp_v0_2->posZ + temp_f0_3;
D_80162FB0[0] = newPos[0];
D_80162FB0[1] = newPos[1];
D_80162FB0[2] = newPos[2];
temp_t7 = (((circleTimer + 1) % 360) * 0xFFFF) / 360;
sp118 = coss(temp_t7) * 25.0;
temp_f0_3 = sins(temp_t7) * 25.0;
@@ -202,7 +204,7 @@ void OBombKart::Tick() {
someRot = (get_angle_between_two_vectors(D_80162FB0, D_80162FC0) * 0xFFFF) / 65520;
break;
case States::STATIONARY:
var_f20 = CenterY + 3.5f;
newPos[1] = CenterY + 3.5f;
someRot = 0;
break;
@@ -210,7 +212,7 @@ void OBombKart::Tick() {
if ((D_8016347C == 0) || (gNearestWaypointByPlayerId[3] < 5)) {
break;
} else {
waypoint = func_8000D2B4(var_f22, var_f20, var_f24, waypoint, 3);
waypoint = func_8000D2B4(newPos[0], newPos[1], newPos[2], waypoint, 3);
if ((waypoint < 0) || (gWaypointCountByPathIndex[3] < waypoint)) {
waypoint = 0;
}
@@ -225,29 +227,36 @@ void OBombKart::Tick() {
D_80162FC0[2] = temp_v0_4->posZ;
someRot = (get_angle_between_two_vectors(D_80162FB0, D_80162FC0) * 0xFFFF) / 65520;
} else {
D_80162FB0[0] = var_f22;
D_80162FB0[1] = var_f20;
D_80162FB0[2] = var_f24;
D_80162FB0[0] = newPos[0];
D_80162FB0[1] = newPos[1];
D_80162FB0[2] = newPos[2];
D_80162FC0[0] = -2409.197f;
D_80162FC0[1] = 0.0f;
D_80162FC0[2] = -355.254f;
someRot = (get_angle_between_two_vectors(D_80162FB0, D_80162FC0) * 0xFFFF) / 65520;
}
temp_f14 = ((D_80162FB0[0] + D_80162FC0[0]) * 0.5f) - var_f22;
temp_f16 = ((D_80162FB0[2] + D_80162FC0[2]) * 0.5f) - var_f24;
temp_f14 = ((D_80162FB0[0] + D_80162FC0[0]) * 0.5f) - newPos[0];
temp_f16 = ((D_80162FB0[2] + D_80162FC0[2]) * 0.5f) - newPos[2];
temp_f0_4 = sqrtf((temp_f14 * temp_f14) + (temp_f16 * temp_f16));
if (temp_f0_4 > 0.01f) {
var_f22 += (Unk_3C * temp_f14) / temp_f0_4;
var_f24 += (Unk_3C * temp_f16) / temp_f0_4;
newPos[0] += (Unk_3C * temp_f14) / temp_f0_4;
newPos[2] += (Unk_3C * temp_f16) / temp_f0_4;
} else {
var_f22 += temp_f14 / 5.0f;
var_f24 += temp_f16 / 5.0f;
newPos[0] += temp_f14 / 5.0f;
newPos[2] += temp_f16 / 5.0f;
}
var_f20 = calculate_surface_height(var_f22, 2000.0f, var_f24, _Collision.meshIndexZX) + 3.5f;
if (var_f20 < (-1000.0)) {
var_f20 = Pos[1];
newPos[1] = calculate_surface_height(newPos[0], 2000.0f, newPos[2], _Collision.meshIndexZX) + 3.5f;
if (newPos[1] < (-1000.0)) {
newPos[1] = Pos[1];
}
check_bounding_collision(&_Collision, 10.0f, var_f22, var_f20, var_f24);
check_bounding_collision(&_Collision, 10.0f, newPos[0], newPos[1], newPos[2]);
}
break;
case States::CHASE:
if (!_target) {
_target = OBombKart::FindTarget();
} else {
OBombKart::Chase(_target, newPos);
}
break;
case States::EXPLODE:
@@ -259,7 +268,7 @@ void OBombKart::Tick() {
D_80162FC0[0] = temp_v0_4->posX;
D_80162FC0[1] = temp_v0_4->posY;
D_80162FC0[2] = temp_v0_4->posZ;
var_f20 += 3.0f - (circleTimer * 0.3f);
newPos[1] += 3.0f - (circleTimer * 0.3f);
someRot = (get_angle_between_two_vectors(D_80162FB0, D_80162FC0) * 0xFFFF) / 65520;
break;
default:
@@ -271,7 +280,7 @@ void OBombKart::Tick() {
sp118 = coss(0xFFFF - someRot) * circleTimer;
var_f18 = sins(0xFFFF - someRot) * circleTimer;
circleTimer++;
temp_f2_4 = (var_f20 - 2.3f) + (sp108 / 3.0f);
temp_f2_4 = (newPos[1] - 2.3f) + (sp108 / 3.0f);
spAC = temp_f2_4;
spA0 = temp_f2_4;
sp94 = temp_f2_4;
@@ -282,7 +291,7 @@ void OBombKart::Tick() {
} else {
sp118 = coss(0xFFFF - someRot) * 1.5f;
var_f18 = sins(0xFFFF - someRot) * 1.5f;
temp_f16_2 = var_f20 - 2.3f;
temp_f16_2 = newPos[1] - 2.3f;
temp_f12_3 = (bounceTimer % 3) * 0.15f;
temp_f14_2 = temp_f16_2 - temp_f12_3;
temp_f12_4 = temp_f16_2 + temp_f12_3;
@@ -290,25 +299,25 @@ void OBombKart::Tick() {
sp94 = temp_f14_2;
spA0 = temp_f12_4;
sp88 = temp_f12_4;
var_f20 += sins((bounceTimer * 0x13FFEC) / 360);
newPos[1] += sins((bounceTimer * 0x13FFEC) / 360);
bounceTimer = (bounceTimer + 1) % 18;
}
WheelPos[0][0] = (sp118 - var_f18) + var_f22;
WheelPos[0][0] = (sp118 - var_f18) + newPos[0];
WheelPos[0][1] = spAC;
WheelPos[0][2] = (var_f18 + sp118) + var_f24;
WheelPos[1][0] = (var_f18 + sp118) + var_f22;
WheelPos[0][2] = (var_f18 + sp118) + newPos[2];
WheelPos[1][0] = (var_f18 + sp118) + newPos[0];
WheelPos[1][1] = spA0;
WheelPos[1][2] = (var_f18 - sp118) + var_f24;
WheelPos[2][0] = ((-sp118) - var_f18) + var_f22;
WheelPos[1][2] = (var_f18 - sp118) + newPos[2];
WheelPos[2][0] = ((-sp118) - var_f18) + newPos[0];
WheelPos[2][1] = sp94;
WheelPos[2][2] = ((-var_f18) + sp118) + var_f24;
WheelPos[3][0] = ((-sp118) + var_f18) + var_f22;
WheelPos[2][2] = ((-var_f18) + sp118) + newPos[2];
WheelPos[3][0] = ((-sp118) + var_f18) + newPos[0];
WheelPos[3][1] = sp88;
WheelPos[3][2] = ((-var_f18) - sp118) + var_f24;
Pos[0] = var_f22;
Pos[1] = var_f20;
Pos[2] = var_f24;
WheelPos[3][2] = ((-var_f18) - sp118) + newPos[2];
Pos[0] = newPos[0];
Pos[1] = newPos[1];
Pos[2] = newPos[2];
WaypointIndex = waypoint;
Unk_3C = unk_3C;
SomeRot = someRot;
@@ -447,3 +456,80 @@ void OBombKart::Waypoint(s32 screenId) {
void OBombKart::Collision(s32 playerId, Player* player) {
}
Player* OBombKart::FindTarget() {
for (size_t i = 0; i < gPlayerCount; i++) {
if (is_within_distance_2d(Pos[0], Pos[2], gPlayers[i].pos[0], gPlayers[i].pos[2], 500)) {
return &gPlayers[i];
}
}
return NULL;
}
void OBombKart::Chase(Player* player, Vec3f pos) {
f32 speed = 2.7f; // Speed the kart uses in a chase
if (!player) return; // Ensure player is valid
// Calculate the directional vector toward the player
Vec3f direction;
direction[0] = player->pos[0] - pos[0];
direction[1] = player->pos[1] - pos[1];
direction[2] = player->pos[2] - pos[2];
// Calculate the distance in the XZ plane
f32 xz_dist = sqrtf((direction[0] * direction[0]) + (direction[2] * direction[2]));
printf("dist: %f\n", xz_dist);
// Reset distance
if (xz_dist > 700.0f) {
_target = NULL;
pos[0] = _spawnPos[0];
pos[1] = _spawnPos[1];
pos[2] = _spawnPos[2];
return;
}
// Break off the chase if player has boo item
if (player->effects & BOO_EFFECT) {
_target = NULL;
pos[0] = _spawnPos[0];
pos[1] = _spawnPos[1];
pos[2] = _spawnPos[2];
return;
}
if (xz_dist > 0.0f) {
// Normalize the direction vector in the XZ plane
direction[0] /= xz_dist;
direction[2] /= xz_dist;
// Scale the movement by a fixed step size
const f32 stepSize = speed; // Adjust step size for desired speed
pos[0] += direction[0] * stepSize;
pos[2] += direction[2] * stepSize;
}
// Store the new position for collision checks
Vec3f newPosition;
newPosition[0] = pos[0];
newPosition[1] = pos[1];
newPosition[2] = pos[2];
newPosition[1] = calculate_surface_height(pos[0], 2000.0f, pos[2], _Collision.meshIndexZX) + 3.5f;
// Perform collision detection and update position
// actor_terrain_collision(&_Collision, 4.0f, Pos[0], Pos[1], Pos[2],
// newPosition[0], newPosition[1], newPosition[2]);
// Update position based on collision results
pos[0] = newPosition[0];
pos[1] = newPosition[1];
pos[2] = newPosition[2];
check_bounding_collision(&_Collision, 10.0f, pos[0], pos[1], pos[2]);
}
+9
View File
@@ -27,6 +27,7 @@ private:
CCW,
CW,
STATIONARY,
CHASE,
EXPLODE,
PODIUM_CEREMONY,
};
@@ -61,4 +62,12 @@ public:
void SomeRender(Vec3f arg1);
void LoadMtx();
void Waypoint(s32 screenId);
private:
Player* FindTarget();
void Chase(Player*, Vec3f pos);
Vec3f _spawnPos;
Player* _target = NULL;
};
-2
View File
@@ -188,8 +188,6 @@ void func_80291198(void) {
}
void render_mario_raceway_pipe(void) {
if (gScreenModeSelection == SCREEN_MODE_1P) {
// d_course_mario_raceway_packed_dl_8E8
gSPDisplayList(gDisplayListHead++, ((uintptr_t) segmented_gfx_to_virtual(0x070008E8)));