Add fix for obj_resolve_object_collisions

This commit is contained in:
Arceveti
2021-09-05 12:18:00 -07:00
parent 13db5a7d4e
commit 2d58bddd06
4 changed files with 32 additions and 9 deletions

View File

@@ -104,6 +104,8 @@
//#define PUPPYCAM
// Automatically calculate the optimal collision distance for an object based on its vertices.
#define AUTO_COLLISION_DISTANCE
// Makes obj_resolve_object_collisions work consistently
#define FIX_RESOLVE_OBJ_COLLISIONS
// HACKER QOL

View File

@@ -828,13 +828,13 @@ void load_object_collision_model(void) {
#endif
// If the object collision is supposed to be loaded more than the
// drawing distance of 4000, extend the drawing range.
// drawing distance, extend the drawing range.
if (gCurrentObject->oCollisionDistance > gCurrentObject->oDrawingDistance) {
gCurrentObject->oDrawingDistance = gCurrentObject->oCollisionDistance;
}
// Update if no Time Stop, in range, and in the current room.
if (!(gTimeStopState & TIME_STOP_ACTIVE) && marioDist < gCurrentObject->oCollisionDistance
if (!(gTimeStopState & TIME_STOP_ACTIVE) && (marioDist < gCurrentObject->oCollisionDistance)
&& !(gCurrentObject->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) {
collisionData++;
transform_object_vertices(&collisionData, vertexData);

View File

@@ -38,6 +38,9 @@
#define INTERACT_IGLOO_BARRIER /* 0x40000000 */ (1 << 30)
#define INTERACT_UNKNOWN_31 /* 0x80000000 */ (1 << 31)
#ifdef FIX_RESOLVE_OBJ_COLLISIONS
#define INTERACT_MASK_NO_OBJ_COLLISIONS (INTERACT_COIN | INTERACT_CAP | INTERACT_STRONG_WIND | INTERACT_STAR_OR_KEY | INTERACT_WARP | INTERACT_WATER_RING | INTERACT_FLAME)
#endif
// INTERACT_WARP
#define INT_SUBTYPE_FADING_WARP 0x00000001

View File

@@ -549,16 +549,33 @@ static void obj_update_blinking(s32 *blinkTimer, s16 baseCycleLength, s16 cycleL
static s32 obj_resolve_object_collisions(s32 *targetYaw) {
struct Object *otherObject;
f32 dx;
f32 dz;
f32 dx, dz;
s16 angle;
f32 radius;
f32 otherRadius;
f32 relativeRadius;
f32 newCenterX;
f32 newCenterZ;
f32 radius, otherRadius, relativeRadius;
if (o->numCollidedObjs != 0) {
#ifdef FIX_RESOLVE_OBJ_COLLISIONS
s32 i;
for ((i = 0); (i < o->numCollidedObjs); (i++)) {
otherObject = o->collidedObjs[i];
if (otherObject == gMarioObject) continue;
if (otherObject->oInteractType & INTERACT_MASK_NO_OBJ_COLLISIONS) continue;
dx = (o->oPosX - otherObject->oPosX);
dz = (o->oPosZ - otherObject->oPosZ);
radius = (( o->hurtboxRadius > 0) ? o->hurtboxRadius : o->hitboxRadius);
otherRadius = ((otherObject->hurtboxRadius > 0) ? otherObject->hurtboxRadius : otherObject->hitboxRadius);
relativeRadius = (radius + otherRadius);
if ((sqr(dx) + sqr(dz)) > sqr(relativeRadius)) continue;
angle = atan2s(dz, dx);
o->oPosX = (otherObject->oPosX + (relativeRadius * sins(angle)));
o->oPosZ = (otherObject->oPosZ + (relativeRadius * coss(angle)));
if ((targetYaw != NULL) && (abs_angle_diff(o->oMoveAngleYaw, angle) < 0x4000)) {
*targetYaw = (s16)((angle - o->oMoveAngleYaw) + angle + 0x8000);
return TRUE;
}
}
#else
f32 newCenterX, newCenterZ;
otherObject = o->collidedObjs[0];
if (otherObject != gMarioObject) {
//! If one object moves after collisions are detected and this code
@@ -588,6 +605,7 @@ static s32 obj_resolve_object_collisions(s32 *targetYaw) {
return TRUE;
}
}
#endif
}
return FALSE;