mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-10-19 19:52:39 +00:00
155 lines
4.4 KiB
C
155 lines
4.4 KiB
C
/**
|
|
* This is the behavior file for the tilting inverted pyramids in BitFS/LLL.
|
|
* The object essentially just tilts and moves Mario with it.
|
|
*/
|
|
|
|
/**
|
|
* Creates a transform matrix on a variable passed in from given normals
|
|
* and the object's position.
|
|
*/
|
|
void create_transform_from_normals(Mat4 transform, f32 xNorm, f32 yNorm, f32 zNorm) {
|
|
Vec3f normal;
|
|
Vec3f pos;
|
|
|
|
pos[0] = o->oPosX;
|
|
pos[1] = o->oPosY;
|
|
pos[2] = o->oPosZ;
|
|
|
|
normal[0] = xNorm;
|
|
normal[1] = yNorm;
|
|
normal[2] = zNorm;
|
|
|
|
mtxf_align_terrain_normal(transform, normal, pos, 0);
|
|
}
|
|
|
|
/**
|
|
* Initialize the object's transform matrix with Y being up.
|
|
*/
|
|
void bhv_platform_normals_init(void) {
|
|
Mat4 *transform = &o->transform;
|
|
|
|
o->oTiltingPyramidNormalX = 0.0f;
|
|
o->oTiltingPyramidNormalY = 1.0f;
|
|
o->oTiltingPyramidNormalZ = 0.0f;
|
|
|
|
create_transform_from_normals(*transform, 0.0f, 1.0f, 0.0f);
|
|
}
|
|
|
|
/**
|
|
* Returns a value that is src incremented/decremented by inc towards goal
|
|
* until goal is reached. Does not overshoot.
|
|
*/
|
|
f32 approach_by_increment(f32 goal, f32 src, f32 inc) {
|
|
f32 newVal;
|
|
|
|
if (src <= goal) {
|
|
if (goal - src < inc) {
|
|
newVal = goal;
|
|
} else {
|
|
newVal = src + inc;
|
|
}
|
|
} else if (goal - src > -inc) {
|
|
newVal = goal;
|
|
} else {
|
|
newVal = src - inc;
|
|
}
|
|
|
|
return newVal;
|
|
}
|
|
|
|
/**
|
|
* Main behavior for the tilting pyramids in LLL/BitFS. These platforms calculate rough normals from Mario's position,
|
|
* then gradually tilt back moving Mario with them.
|
|
*/
|
|
void bhv_tilting_inverted_pyramid_loop(void) {
|
|
f32 dx;
|
|
f32 dy;
|
|
f32 dz;
|
|
f32 d;
|
|
|
|
Vec3f dist;
|
|
Vec3f posBeforeRotation;
|
|
Vec3f posAfterRotation;
|
|
|
|
// Mario's position
|
|
f32 mx;
|
|
f32 my;
|
|
f32 mz;
|
|
|
|
s32 marioOnPlatform = FALSE;
|
|
UNUSED s32 unused;
|
|
Mat4 *transform = &o->transform;
|
|
UNUSED s32 unused2[7];
|
|
|
|
f32 x = 0;
|
|
f32 y = 0;
|
|
f32 z = 0;
|
|
u8 playersTouched = 0;
|
|
for (int i = 0; i < MAX_PLAYERS; i++) {
|
|
if (!is_player_active(&gMarioStates[i])) { continue; }
|
|
if (gMarioStates[i].marioObj->platform != o) { continue; }
|
|
x += gMarioStates[i].marioObj->oPosX;
|
|
y += gMarioStates[i].marioObj->oPosY;
|
|
z += gMarioStates[i].marioObj->oPosZ;
|
|
playersTouched++;
|
|
if (i == 0) { marioOnPlatform = TRUE; }
|
|
}
|
|
|
|
if (playersTouched > 0) {
|
|
x /= (f32)playersTouched;
|
|
y /= (f32)playersTouched;
|
|
z /= (f32)playersTouched;
|
|
get_mario_pos(&mx, &my, &mz);
|
|
|
|
dist[0] = x - o->oPosX;
|
|
dist[1] = y - o->oPosY;
|
|
dist[2] = z - o->oPosZ;
|
|
linear_mtxf_mul_vec3f(*transform, posBeforeRotation, dist);
|
|
|
|
dx = x - o->oPosX;
|
|
dy = 500.0f;
|
|
dz = z - o->oPosZ;
|
|
d = sqrtf(dx * dx + dy * dy + dz * dz);
|
|
|
|
//! Always true since dy = 500, making d >= 500.
|
|
if (d != 0.0f) {
|
|
// Normalizing
|
|
d = 1.0 / d;
|
|
dx *= d;
|
|
dy *= d;
|
|
dz *= d;
|
|
} else {
|
|
dx = 0.0f;
|
|
dy = 1.0f;
|
|
dz = 0.0f;
|
|
}
|
|
|
|
/*if (o->oTiltingPyramidMarioOnPlatform == TRUE)
|
|
marioOnPlatform++;*/
|
|
|
|
o->oTiltingPyramidMarioOnPlatform = TRUE;
|
|
} else {
|
|
dx = 0.0f;
|
|
dy = 1.0f;
|
|
dz = 0.0f;
|
|
o->oTiltingPyramidMarioOnPlatform = FALSE;
|
|
}
|
|
|
|
// Approach the normals by 0.01f towards the new goal, then create a transform matrix and orient the object.
|
|
// Outside of the other conditionals since it needs to tilt regardless of whether Mario is on.
|
|
o->oTiltingPyramidNormalX = approach_by_increment(dx, o->oTiltingPyramidNormalX, 0.01f);
|
|
o->oTiltingPyramidNormalY = approach_by_increment(dy, o->oTiltingPyramidNormalY, 0.01f);
|
|
o->oTiltingPyramidNormalZ = approach_by_increment(dz, o->oTiltingPyramidNormalZ, 0.01f);
|
|
create_transform_from_normals(*transform, o->oTiltingPyramidNormalX, o->oTiltingPyramidNormalY, o->oTiltingPyramidNormalZ);
|
|
|
|
// If Mario is on the platform, adjust his position for the platform tilt.
|
|
if (marioOnPlatform != FALSE) {
|
|
linear_mtxf_mul_vec3f(*transform, posAfterRotation, dist);
|
|
mx += posAfterRotation[0] - posBeforeRotation[0];
|
|
my += posAfterRotation[1] - posBeforeRotation[1];
|
|
mz += posAfterRotation[2] - posBeforeRotation[2];
|
|
set_mario_pos(mx, my, mz);
|
|
}
|
|
|
|
o->header.gfx.throwMatrix = transform;
|
|
}
|