Object changes and qol features

Removed obj collision near camera, causes crashes (superseded by collision distance fix)

Improved room states and door room states, better room checks now uses room id

More object now call bhv_init_room, room can now use drawing distance
This commit is contained in:
AloXado320 2023-07-21 14:58:49 -05:00
parent e7586d0c68
commit 53756582c0
17 changed files with 245 additions and 203 deletions

View file

@ -354,8 +354,8 @@ const BehaviorScript bhvStarDoor[] = {
BEGIN_LOOP(), BEGIN_LOOP(),
CALL_NATIVE(bhv_star_door_loop), CALL_NATIVE(bhv_star_door_loop),
#if !FIX_STAR_DOOR_ROOM_RENDER #if !FIX_STAR_DOOR_ROOM_RENDER
CALL_NATIVE(bhv_star_door_loop_2),
CALL_NATIVE(load_object_collision_model), CALL_NATIVE(load_object_collision_model),
CALL_NATIVE(bhv_door_rendering_loop),
#endif #endif
END_LOOP(), END_LOOP(),
}; };
@ -2629,6 +2629,7 @@ const BehaviorScript bhvExclamationBox[] = {
OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE),
SET_FLOAT(oCollisionDistance, 300), SET_FLOAT(oCollisionDistance, 300),
SET_HOME(), SET_HOME(),
CALL_NATIVE(bhv_init_room), // added, common object
BEGIN_LOOP(), BEGIN_LOOP(),
CALL_NATIVE(bhv_exclamation_box_loop), CALL_NATIVE(bhv_exclamation_box_loop),
END_LOOP(), END_LOOP(),
@ -3850,6 +3851,7 @@ const BehaviorScript bhvMessagePanel[] = {
DROP_TO_FLOOR(), DROP_TO_FLOOR(),
SET_HITBOX(/*Radius*/ 150, /*Height*/ 80), SET_HITBOX(/*Radius*/ 150, /*Height*/ 80),
SET_INT(oWoodenPostTotalMarioAngle, 0), SET_INT(oWoodenPostTotalMarioAngle, 0),
CALL_NATIVE(bhv_init_room), // added, common object
CALL_NATIVE(load_object_static_model), CALL_NATIVE(load_object_static_model),
BEGIN_LOOP(), BEGIN_LOOP(),
SET_INT(oIntangibleTimer, 0), SET_INT(oIntangibleTimer, 0),
@ -5655,6 +5657,7 @@ const BehaviorScript bhvActivatedBackAndForthPlatform[] = {
const BehaviorScript bhvRecoveryHeart[] = { const BehaviorScript bhvRecoveryHeart[] = {
BEGIN(OBJ_LIST_LEVEL), BEGIN(OBJ_LIST_LEVEL),
OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)),
CALL_NATIVE(bhv_init_room), // added, common object
BEGIN_LOOP(), BEGIN_LOOP(),
CALL_NATIVE(bhv_recovery_heart_loop), CALL_NATIVE(bhv_recovery_heart_loop),
END_LOOP(), END_LOOP(),
@ -6055,6 +6058,7 @@ const BehaviorScript bhvRedCoinStarMarker[] = {
DROP_TO_FLOOR(), DROP_TO_FLOOR(),
ADD_FLOAT(oPosY, 60), ADD_FLOAT(oPosY, 60),
#endif #endif
CALL_NATIVE(bhv_init_room), // added, common object
CALL_NATIVE(bhv_red_coin_star_marker_init), CALL_NATIVE(bhv_red_coin_star_marker_init),
BEGIN_LOOP(), BEGIN_LOOP(),
ADD_INT(oFaceAngleYaw, 0x100), ADD_INT(oFaceAngleYaw, 0x100),

View file

@ -43,9 +43,6 @@
// Automatically calculates the optimal collision distance for an object based on it's vertices. // Automatically calculates the optimal collision distance for an object based on it's vertices.
#define AUTO_COLLISION_DISTANCE (0 || QOL_FEATURES) #define AUTO_COLLISION_DISTANCE (0 || QOL_FEATURES)
// Allows objects to use camera distance to determine whether to load collision if the camera is closer than Mario.
#define LOAD_OBJECT_COLLISION_NEAR_CAMERA (0 || QOL_FEATURES)
/// Use the floor's normal instead of a triangle of find_floor if the floor isn't steep /// Use the floor's normal instead of a triangle of find_floor if the floor isn't steep
#define FAST_FLOOR_ALIGN (0 || QOL_FEATURES) #define FAST_FLOOR_ALIGN (0 || QOL_FEATURES)

View file

@ -16,7 +16,7 @@
/// Fixes Mario interact shell start action while in air /// Fixes Mario interact shell start action while in air
#define FIX_MARIO_KOOPA_SHELL_ACTION (0 || QOL_FIXES) #define FIX_MARIO_KOOPA_SHELL_ACTION (0 || QOL_FIXES)
/// Hold A when bouncing on an enemy to go higher like in classic games. /// Hold A when bouncing on an enemy to go higher like in classic games
#define JUMP_ENEMY_BOUNCE_BOOST (0 || QOL_FEATURES) #define JUMP_ENEMY_BOUNCE_BOOST (0 || QOL_FEATURES)
/// Changes obj_resolve_object_collisions to work consistently /// Changes obj_resolve_object_collisions to work consistently
@ -25,7 +25,7 @@
/// Fixes missing floor update in push_mario_out_of_object /// Fixes missing floor update in push_mario_out_of_object
#define FIX_PUSH_MARIO_OUT_OF_OBJECT_FLOOR (0 || QOL_FIXES || COLLISION_FIXES) #define FIX_PUSH_MARIO_OUT_OF_OBJECT_FLOOR (0 || QOL_FIXES || COLLISION_FIXES)
/// Makes rooms code use find_room_floor, and improves bhv_init_room /// Makes rooms code use room ids to check for a room rather than a floor
#define BETTER_ROOM_CHECKS (0 || QOL_FEATURES || COLLISION_FIXES) #define BETTER_ROOM_CHECKS (0 || QOL_FEATURES || COLLISION_FIXES)
/******************* /*******************
@ -128,9 +128,12 @@
/// Makes Koopa Shell respawn on exclamation boxes like caps /// Makes Koopa Shell respawn on exclamation boxes like caps
#define KOOPA_SHELL_BOXES_RESPAWN (0 || QOL_FEATURES) #define KOOPA_SHELL_BOXES_RESPAWN (0 || QOL_FEATURES)
/// Makes Mr I being able to shoot his particle in any direction. /// Makes Mr I being able to shoot his particle in any direction
#define MR_I_PITCH_SHOOTING (0 || QOL_FEATURES) #define MR_I_PITCH_SHOOTING (0 || QOL_FEATURES)
/// Makes an object active only if it's on it's room if it exists
#define PROCESS_ONLY_ON_ROOM_PARENT (0 || QOL_FEATURES)
/// Makes coin formation on ground have better coin position, fixes misaligned coins /// Makes coin formation on ground have better coin position, fixes misaligned coins
#define BETTER_COIN_FORMATION_GROUND (0 || QOL_FEATURES || COLLISION_FIXES) #define BETTER_COIN_FORMATION_GROUND (0 || QOL_FEATURES || COLLISION_FIXES)

View file

@ -48,11 +48,17 @@
#define OBJ_FLAG_DONT_CALC_COLL_DIST (0 << 0) #define OBJ_FLAG_DONT_CALC_COLL_DIST (0 << 0)
#endif #endif
#if OBJ_OPACITY_BY_CAM_DIST #if OBJ_OPACITY_BY_CAM_DIST
#define OBJ_FLAG_OPACITY_FROM_CAMERA_DIST (1 << 21) // 0x00010000 #define OBJ_FLAG_OPACITY_FROM_CAMERA_DIST (1 << 21) // 0x00200000
#else #else
#define OBJ_FLAG_OPACITY_FROM_CAMERA_DIST (0 << 0) #define OBJ_FLAG_OPACITY_FROM_CAMERA_DIST (0 << 0)
#endif #endif
#define OBJ_FLAG_30 (1 << 30) // 0x40000000 #if PROCESS_ONLY_ON_ROOM_PARENT
#define OBJ_FLAG_ONLY_PROCESS_INSIDE_ROOM (1 << 23) // 0x00800000
#else
#define OBJ_FLAG_ONLY_PROCESS_INSIDE_ROOM (0 << 0)
#endif
#define OBJ_FLAG_HITBOX_WAS_SET (1 << 30) // 0x40000000
/* oHeldState */ /* oHeldState */
#define HELD_FREE 0 #define HELD_FREE 0

View file

@ -428,10 +428,10 @@
#define /*0x0F4*/ oDonutPlatformSpawnerSpawnedPlatforms OBJECT_FIELD_S32(0x1B) #define /*0x0F4*/ oDonutPlatformSpawnerSpawnedPlatforms OBJECT_FIELD_S32(0x1B)
/* Door */ /* Door */
#define /*0x088*/ oDoorUnk88 OBJECT_FIELD_S32(0x00) #define /*0x088*/ oDoorIsRendering OBJECT_FIELD_S32(0x00)
#define /*0x0F8*/ oDoorUnkF8 OBJECT_FIELD_S32(0x1C) #define /*0x0F8*/ oDoorSelfRoom OBJECT_FIELD_S32(0x1C)
#define /*0x0FC*/ oDoorUnkFC OBJECT_FIELD_S32(0x1D) #define /*0x0FC*/ oDoorForwardRoom OBJECT_FIELD_S32(0x1D)
#define /*0x100*/ oDoorUnk100 OBJECT_FIELD_S32(0x1E) #define /*0x100*/ oDoorBackwardRoom OBJECT_FIELD_S32(0x1E)
/* Dorrie */ /* Dorrie */
#define /*0x0F4*/ oDorrieDistToHome OBJECT_FIELD_F32(0x1B) #define /*0x0F4*/ oDorrieDistToHome OBJECT_FIELD_F32(0x1B)

View file

@ -883,6 +883,16 @@ void cur_obj_update(void) {
BhvCommandProc bhvCmdProc; BhvCommandProc bhvCmdProc;
s32 bhvProcResult; s32 bhvProcResult;
s32 inRoom = cur_obj_is_mario_in_room();
#if PROCESS_ONLY_ON_ROOM_PARENT
// Activates objects only if is inside a room associated with it.
if (inRoom == MARIO_OUTSIDE_ROOM && (objFlags & OBJ_FLAG_ONLY_PROCESS_INSIDE_ROOM)) {
cur_obj_disable_rendering_in_room();
return;
}
#endif
// Calculate the distance from the object to Mario. // Calculate the distance from the object to Mario.
if (objFlags & OBJ_FLAG_COMPUTE_DIST_TO_MARIO) { if (objFlags & OBJ_FLAG_COMPUTE_DIST_TO_MARIO) {
gCurrentObject->oDistanceToMario = dist_between_objects(gCurrentObject, gMarioObject); gCurrentObject->oDistanceToMario = dist_between_objects(gCurrentObject, gMarioObject);
@ -969,7 +979,23 @@ void cur_obj_update(void) {
// Handle visibility of object // Handle visibility of object
if (gCurrentObject->oRoom != -1) { if (gCurrentObject->oRoom != -1) {
// If the object is in a room, only show it when Mario is in the room. // If the object is in a room, only show it when Mario is in the room.
cur_obj_enable_rendering_if_mario_in_room(); #ifndef NODRAWINGDISTANCE
if ((objFlags & OBJ_FLAG_ACTIVE_FROM_AFAR)|| distanceFromMario < gCurrentObject->oDrawingDistance)
#endif
{
if (inRoom == MARIO_OUTSIDE_ROOM) {
cur_obj_disable_rendering_in_room();
} else if (inRoom == MARIO_INSIDE_ROOM) {
cur_obj_enable_rendering_in_room();
}
gCurrentObject->activeFlags &= ~ACTIVE_FLAG_FAR_AWAY;
}
#ifndef NODRAWINGDISTANCE
else {
gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
gCurrentObject->activeFlags |= ACTIVE_FLAG_FAR_AWAY;
}
#endif
} else if ((objFlags & OBJ_FLAG_COMPUTE_DIST_TO_MARIO) && gCurrentObject->collisionData == NULL) { } else if ((objFlags & OBJ_FLAG_COMPUTE_DIST_TO_MARIO) && gCurrentObject->collisionData == NULL) {
if (!(objFlags & OBJ_FLAG_ACTIVE_FROM_AFAR)) { if (!(objFlags & OBJ_FLAG_ACTIVE_FROM_AFAR)) {
// If the object has a render distance, check if it should be shown. // If the object has a render distance, check if it should be shown.

View file

@ -872,6 +872,23 @@ f32 find_room_floor(f32 x, f32 y, f32 z, struct Surface **pfloor) {
return find_static_floor(x, y, z, pfloor); return find_static_floor(x, y, z, pfloor);
} }
/**
* Get the room index at a given position.
*/
s32 get_room_at_pos(f32 x, f32 y, f32 z) {
if (gCurrentArea->surfaceRooms != NULL) {
struct Surface *floor;
find_room_floor(x, y, z, &floor);
if (floor != NULL) {
return floor->room;
}
}
return -1;
}
#if WATER_SURFACES #if WATER_SURFACES
/** /**
* Find the highest water floor under a given position and return the height. * Find the highest water floor under a given position and return the height.

View file

@ -69,6 +69,7 @@ f32 find_static_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor);
f32 find_dynamic_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor); f32 find_dynamic_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor);
f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor); f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor);
f32 find_room_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor); f32 find_room_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor);
s32 get_room_at_pos(f32 x, f32 y, f32 z);
#if WATER_SURFACES #if WATER_SURFACES
s32 find_water_level_and_floor(s32 x, s32 z, struct Surface **pfloor); s32 find_water_level_and_floor(s32 x, s32 z, struct Surface **pfloor);
#endif #endif

View file

@ -810,37 +810,37 @@ TerrainData sDynamicVertices[900];
* Transform an object's vertices, reload them, and render the object. * Transform an object's vertices, reload them, and render the object.
*/ */
void load_object_collision_model(void) { void load_object_collision_model(void) {
TerrainData *collisionData = gCurrentObject->collisionData; struct Object* obj = gCurrentObject;
f32 marioDist = gCurrentObject->oDistanceToMario;
// On an object's first frame, the distance is set to F32_MAX. TerrainData *collisionData = obj->collisionData;
// If the distance hasn't been updated, update it now.
if (gCurrentObject->oDistanceToMario == F32_MAX) { f32 sqrLateralDist;
marioDist = dist_between_objects(gCurrentObject, gMarioObject); vec3f_get_lateral_dist_squared(&obj->oPosX, &gMarioObject->oPosX, &sqrLateralDist);
}
f32 verticalMarioDiff = (gMarioObject->oPosY - obj->oPosY);
#if AUTO_COLLISION_DISTANCE #if AUTO_COLLISION_DISTANCE
f32 colDist; f32 colDist;
if (collisionData == NULL) { if (collisionData == NULL) {
// No collision data, so no collision distance. // No collision data, so no collision distance.
colDist = 0.0f; colDist = 0.0f;
} else if (!(gCurrentObject->oFlags & OBJ_FLAG_DONT_CALC_COLL_DIST)) { } else if (!(obj->oFlags & OBJ_FLAG_DONT_CALC_COLL_DIST)) {
gCurrentObject->oFlags |= OBJ_FLAG_DONT_CALC_COLL_DIST; obj->oFlags |= OBJ_FLAG_DONT_CALC_COLL_DIST;
// Calculate a new collision distance based on the collision data. // Calculate a new collision distance based on the collision data.
colDist = get_optimal_collision_distance(gCurrentObject); colDist = get_optimal_collision_distance(obj);
} else { } else {
// Use existing collision distance. // Use existing collision distance.
colDist = gCurrentObject->oCollisionDistance; colDist = obj->oCollisionDistance;
} }
#else #else
f32 colDist = gCurrentObject->oCollisionDistance; f32 colDist = obj->oCollisionDistance;
#endif #endif
f32 drawDist = gCurrentObject->oDrawingDistance; f32 drawDist = obj->oDrawingDistance;
// ex-alo change // ex-alo change
// Ensure the object is allocated to set default collision and drawing distance // Ensure the object is allocated to set default collision and drawing distance
if (gCurrentObject->activeFlags & ACTIVE_FLAG_ALLOCATED && collisionData != NULL) { if (obj->activeFlags & ACTIVE_FLAG_ALLOCATED && collisionData != NULL) {
if (colDist == 0.0f) colDist = 1000.0f; if (colDist == 0.0f) colDist = 1000.0f;
if (drawDist == 0.0f) drawDist = 4000.0f; if (drawDist == 0.0f) drawDist = 4000.0f;
} }
@ -851,19 +851,15 @@ void load_object_collision_model(void) {
drawDist = colDist; drawDist = colDist;
} }
#if LOAD_OBJECT_COLLISION_NEAR_CAMERA s32 inColRadius = (
// Ensure the object is rendered and limit max camera distance to the drawing distance. (sqrLateralDist < sqr(colDist))
if (gCurrentObject->header.gfx.node.flags & GRAPH_RENDER_ACTIVE) { && (verticalMarioDiff > 0 || verticalMarioDiff > -colDist)
f32 camDist = vec3_mag(gCurrentObject->header.gfx.cameraToObject); && (verticalMarioDiff < 0 || verticalMarioDiff < (colDist + 2000.0f))
if (marioDist > camDist) { );
marioDist = CLAMP(camDist, 1.0f, drawDist);
}
}
#endif
// Update if no Time Stop, in range, and in the current room. // Update if no Time Stop, in range, and in the current room.
if (!(gTimeStopState & TIME_STOP_ACTIVE) && marioDist < colDist if (!(gTimeStopState & TIME_STOP_ACTIVE) && inColRadius
&& !(gCurrentObject->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) { && !(obj->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) {
collisionData++; collisionData++;
transform_object_vertices(&collisionData, sDynamicVertices); transform_object_vertices(&collisionData, sDynamicVertices);
@ -873,18 +869,26 @@ void load_object_collision_model(void) {
} }
} }
f32 marioDist = obj->oDistanceToMario;
// On an object's first frame, the distance is set to F32_MAX.
// If the distance hasn't been updated, update it now.
if (marioDist == F32_MAX) {
marioDist = dist_between_objects(obj, gMarioObject);
}
#ifndef NODRAWINGDISTANCE #ifndef NODRAWINGDISTANCE
if (marioDist < drawDist) { if (marioDist < drawDist) {
gCurrentObject->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE; obj->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE;
} else { } else {
gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE; obj->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
} }
#else #else
gCurrentObject->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE; obj->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE;
#endif #endif
gCurrentObject->oCollisionDistance = colDist; obj->oCollisionDistance = colDist;
gCurrentObject->oDrawingDistance = drawDist; obj->oDrawingDistance = drawDist;
} }
/** /**

View file

@ -3,7 +3,7 @@
void spawn_mist_particles_variable(s32 count, s32 offsetY, f32 size); void spawn_mist_particles_variable(s32 count, s32 offsetY, f32 size);
void bhv_spawn_star_no_level_exit(u32); void bhv_spawn_star_no_level_exit(u32);
void bhv_star_door_loop_2(void); void bhv_door_rendering_loop(void);
void spawn_triangle_break_particles(s16 numTris, s16 triModel, f32 triSize, s16 triAnimState); void spawn_triangle_break_particles(s16 numTris, s16 triModel, f32 triSize, s16 triAnimState);
void spawn_mist_from_global(void); void spawn_mist_from_global(void);

View file

@ -67,9 +67,7 @@ void bhv_door_loop(void) {
switch (o->oAction) { switch (o->oAction) {
case 0: case 0:
cur_obj_init_animation_with_sound(0); cur_obj_init_animation_with_sound(0);
#if FIX_STAR_DOOR_ROOM_RENDER
load_object_collision_model(); load_object_collision_model();
#endif
break; break;
case 1: case 1:
door_animation_and_reset(1); door_animation_and_reset(1);
@ -89,85 +87,75 @@ void bhv_door_loop(void) {
break; break;
} }
#if !FIX_STAR_DOOR_ROOM_RENDER bhv_door_rendering_loop();
if (o->oAction == 0) {
load_object_collision_model();
}
#endif
bhv_star_door_loop_2();
} }
#if BETTER_ROOM_CHECKS #if BETTER_ROOM_CHECKS
#define FIND_FLOOR_DOOR find_room_floor #define GET_ROOM_DOOR(x, y, z, r) r = get_room_at_pos(x, y, z);
#else #else
#define FIND_FLOOR_DOOR find_floor #define GET_ROOM_DOOR(x, y, z, r) \
find_room_floor(x, y, z, &floor); \
if (floor != NULL) r = floor->room;
#endif #endif
void bhv_door_init(void) { void bhv_door_init(void) {
const f32 checkDist = 200.0f;
#if !BETTER_ROOM_CHECKS
struct Surface *floor; struct Surface *floor;
#endif
f32 x = o->oPosX; f32 x = o->oPosX;
f32 y = o->oPosY; f32 y = o->oPosY;
f32 z = o->oPosZ; f32 z = o->oPosZ;
FIND_FLOOR_DOOR(x, y, z, &floor); GET_ROOM_DOOR(x, y, z, o->oDoorSelfRoom);
if (floor != NULL) {
o->oDoorUnkF8 = floor->room;
}
x = o->oPosX + sins(o->oMoveAngleYaw) * 200.0f; x = o->oPosX + sins(o->oMoveAngleYaw) * checkDist;
z = o->oPosZ + coss(o->oMoveAngleYaw) * 200.0f; z = o->oPosZ + coss(o->oMoveAngleYaw) * checkDist;
FIND_FLOOR_DOOR(x, y, z, &floor);
if (floor != NULL) {
o->oDoorUnkFC = floor->room;
}
x = o->oPosX + sins(o->oMoveAngleYaw) * -200.0f; GET_ROOM_DOOR(x, y, z, o->oDoorForwardRoom);
z = o->oPosZ + coss(o->oMoveAngleYaw) * -200.0f;
FIND_FLOOR_DOOR(x, y, z, &floor);
if (floor != NULL) {
o->oDoorUnk100 = floor->room;
}
if (o->oDoorUnkF8 > 0 && o->oDoorUnkF8 < 60) { x = o->oPosX + sins(o->oMoveAngleYaw) * -checkDist;
gDoorAdjacentRooms[o->oDoorUnkF8][0] = o->oDoorUnkFC; z = o->oPosZ + coss(o->oMoveAngleYaw) * -checkDist;
gDoorAdjacentRooms[o->oDoorUnkF8][1] = o->oDoorUnk100;
GET_ROOM_DOOR(x, y, z, o->oDoorBackwardRoom);
if (
// Ensure the room number is in bounds.
o->oDoorSelfRoom > 0 && o->oDoorSelfRoom < ARRAY_COUNT(gDoorAdjacentRooms)
#if !BETTER_ROOM_CHECKS
// Only set gDoorAdjacentRooms for transition rooms.
&& o->oDoorSelfRoom != o->oDoorForwardRoom
&& o->oDoorSelfRoom != o->oDoorBackwardRoom
&& o->oDoorForwardRoom != o->oDoorBackwardRoom
#endif
) {
gDoorAdjacentRooms[o->oDoorSelfRoom].forwardRoom = o->oDoorForwardRoom;
gDoorAdjacentRooms[o->oDoorSelfRoom].backwardRoom = o->oDoorBackwardRoom;
} }
} }
#undef FIND_FLOOR_DOOR #undef GET_ROOM_DOOR
void bhv_star_door_loop_2(void) { void bhv_door_rendering_loop(void) {
s32 sp4 = FALSE; struct TransitionRoomData* transitionRoom = &gDoorAdjacentRooms[gMarioCurrentRoom];
if (gMarioCurrentRoom != 0) { o->oDoorIsRendering = (
if (o->oDoorUnkF8 == gMarioCurrentRoom) { gMarioCurrentRoom == 0 || // Mario is in the "global" room.
sp4 = TRUE; gMarioCurrentRoom == o->oDoorSelfRoom || // Mario is in the same room as the door.
} else if (gMarioCurrentRoom == o->oDoorUnkFC) { gMarioCurrentRoom == o->oDoorForwardRoom || // Mario is in the door's forward room.
sp4 = TRUE; gMarioCurrentRoom == o->oDoorBackwardRoom || // Mario is in the door's backward room.
} else if (gMarioCurrentRoom == o->oDoorUnk100) { transitionRoom->forwardRoom == o->oDoorForwardRoom || // The transition room's forward room is in the same room as this door's forward room.
sp4 = TRUE; transitionRoom->forwardRoom == o->oDoorBackwardRoom || // The transition room's forward room is in the same room as this door's backward room.
} else if (gDoorAdjacentRooms[gMarioCurrentRoom][0] == o->oDoorUnkFC) { transitionRoom->backwardRoom == o->oDoorForwardRoom || // The transition room's backward room is in the same room as this door's forward room.
sp4 = TRUE; transitionRoom->backwardRoom == o->oDoorBackwardRoom // The transition room's backward room is in the same room as this door's backward room.
} else if (gDoorAdjacentRooms[gMarioCurrentRoom][0] == o->oDoorUnk100) { );
sp4 = TRUE;
} else if (gDoorAdjacentRooms[gMarioCurrentRoom][1] == o->oDoorUnkFC) {
sp4 = TRUE;
} else if (gDoorAdjacentRooms[gMarioCurrentRoom][1] == o->oDoorUnk100) {
sp4 = TRUE;
}
} else {
sp4 = TRUE;
}
if (sp4 == TRUE) { if (o->oDoorIsRendering) {
o->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE; o->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE;
D_8035FEE4++; gNumDoorRenderCount++;
} } else {
if (!sp4) {
o->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE; o->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
} }
o->oDoorUnk88 = sp4;
} }

View file

@ -8,8 +8,7 @@ void star_door_update_pos(void) {
} }
void bhv_star_door_loop(void) { void bhv_star_door_loop(void) {
UNUSED u8 filler[4]; struct Object *doorObj = cur_obj_nearest_object_with_behavior(bhvStarDoor);
struct Object *sp18 = cur_obj_nearest_object_with_behavior(bhvStarDoor);
switch (o->oAction) { switch (o->oAction) {
case 0: case 0:
@ -17,7 +16,7 @@ void bhv_star_door_loop(void) {
if (o->oInteractStatus & (INT_STATUS_UNK16 | INT_STATUS_UNK17)) { if (o->oInteractStatus & (INT_STATUS_UNK16 | INT_STATUS_UNK17)) {
o->oAction = 1; o->oAction = 1;
} }
if (sp18 != NULL && sp18->oAction != 0) { if (doorObj != NULL && doorObj->oAction != 0) {
o->oAction = 1; o->oAction = 1;
} }
break; break;
@ -65,8 +64,8 @@ void bhv_star_door_loop(void) {
if (o->oAction != 2) { if (o->oAction != 2) {
load_object_collision_model(); load_object_collision_model();
} }
bhv_star_door_loop_2(); bhv_door_rendering_loop();
#endif #endif
} }

View file

@ -292,7 +292,7 @@ void reset_debug_objectinfo(void) {
gObjectCounter = 0; gObjectCounter = 0;
sDebugStringArrPrinted = FALSE; sDebugStringArrPrinted = FALSE;
D_8035FEE2 = 0; D_8035FEE2 = 0;
D_8035FEE4 = 0; gNumDoorRenderCount = 0;
set_print_state_info(gDebugPrintState1, 20, 185, 40, 200, -15); set_print_state_info(gDebugPrintState1, 20, 185, 40, 200, -15);
set_print_state_info(gDebugPrintState2, 180, 30, 0, 150, 15); set_print_state_info(gDebugPrintState2, 180, 30, 0, 150, 15);

View file

@ -159,35 +159,41 @@ Gfx *geo_switch_anim_state(s32 callContext, struct GraphNode *node, UNUSED void
} }
Gfx *geo_switch_area(s32 callContext, struct GraphNode *node, UNUSED void *context) { Gfx *geo_switch_area(s32 callContext, struct GraphNode *node, UNUSED void *context) {
struct Surface *floor;
struct GraphNodeSwitchCase *switchCase = (struct GraphNodeSwitchCase *) node; struct GraphNodeSwitchCase *switchCase = (struct GraphNodeSwitchCase *) node;
#if BETTER_ROOM_CHECKS
if (callContext == GEO_CONTEXT_RENDER) { RoomData room;
if (gMarioObject == NULL) { #define ROOM_ID(r) r
switchCase->selectedCase = 0; #define CHECK_ROOM room
} else { #else
Vec3f focusPos = { gMarioObject->oPosX, gMarioObject->oPosY, gMarioObject->oPosZ }; struct Surface *floor;
#if ROOM_OBJECT_CAMERA_FOCUS #define ROOM_ID(r) floor->r
if (gCutsceneFocus != NULL) { #define CHECK_ROOM floor
vec3f_copy(focusPos, gLakituState.pos);
}
#endif #endif
// ex-alo change
// Better room area check (with objects if QOL features is enabled)
if (gCurrentArea->surfaceRooms != NULL) {
find_room_floor(focusPos[0], focusPos[1], focusPos[2], &floor);
} else {
floor = gMarioState->floor;
}
if (floor) { if (callContext == GEO_CONTEXT_RENDER && gMarioObject != NULL) {
gMarioCurrentRoom = floor->room; Vec3f focusPos = { gMarioObject->oPosX, gMarioObject->oPosY, gMarioObject->oPosZ };
s16 roomCase = floor->room - 1; #if ROOM_OBJECT_CAMERA_FOCUS
print_debug_top_down_objectinfo("areainfo %d", floor->room); if (gCutsceneFocus != NULL) {
vec3f_copy(focusPos, gLakituState.pos);
}
#endif
if (roomCase >= 0) { #if BETTER_ROOM_CHECKS
switchCase->selectedCase = roomCase; room = get_room_at_pos(focusPos[0], focusPos[1], focusPos[2]);
} #else
if (gCurrentArea->surfaceRooms != NULL) {
find_room_floor(focusPos[0], focusPos[1], focusPos[2], &floor);
} else {
floor = gMarioState->floor;
}
#endif
if (CHECK_ROOM) {
gMarioCurrentRoom = ROOM_ID(room);
print_debug_top_down_objectinfo("areainfo %d", ROOM_ID(room));
if (ROOM_ID(room) > 0) {
switchCase->selectedCase = (ROOM_ID(room) - 1);
} }
} }
} else { } else {
@ -1992,8 +1998,8 @@ void cur_obj_spawn_particles(struct SpawnParticlesInfo *info) {
} }
void obj_set_hitbox(struct Object *obj, struct ObjectHitbox *hitbox) { void obj_set_hitbox(struct Object *obj, struct ObjectHitbox *hitbox) {
if (!(obj->oFlags & OBJ_FLAG_30)) { if (!(obj->oFlags & OBJ_FLAG_HITBOX_WAS_SET)) {
obj->oFlags |= OBJ_FLAG_30; obj->oFlags |= OBJ_FLAG_HITBOX_WAS_SET;
obj->oInteractType = hitbox->interactType; obj->oInteractType = hitbox->interactType;
obj->oDamageOrCoinValue = hitbox->damageOrCoinValue; obj->oDamageOrCoinValue = hitbox->damageOrCoinValue;
@ -2228,10 +2234,11 @@ s32 is_item_in_array(s8 item, s8 *array) {
return FALSE; return FALSE;
} }
UNUSED static void stub_obj_helpers_5(void) {
}
#if BETTER_ROOM_CHECKS #if BETTER_ROOM_CHECKS
void bhv_init_room(void) {
o->oRoom = get_room_at_pos(o->oPosX, o->oPosY, o->oPosZ);
}
#else
void bhv_init_room(void) { void bhv_init_room(void) {
struct Surface *floor = NULL; struct Surface *floor = NULL;
if (gCurrentArea->surfaceRooms != NULL) { if (gCurrentArea->surfaceRooms != NULL) {
@ -2244,63 +2251,33 @@ void bhv_init_room(void) {
} }
o->oRoom = -1; o->oRoom = -1;
} }
#else
void bhv_init_room(void) {
struct Surface *floor;
f32 floorHeight;
if (gCurrentArea->surfaceRooms != NULL) {
floorHeight = find_floor(o->oPosX, o->oPosY, o->oPosZ, &floor);
if (floor != NULL) {
if (floor->room != 0) {
o->oRoom = floor->room;
} else {
// Floor probably belongs to a platform object. Try looking
// underneath it
find_floor(o->oPosX, floorHeight - 100.0f, o->oPosZ, &floor);
if (floor != NULL) {
//! Technically possible that the room could still be 0 here
o->oRoom = floor->room;
}
}
}
} else {
o->oRoom = -1;
}
}
#endif #endif
void cur_obj_enable_rendering_if_mario_in_room(void) { s32 cur_obj_is_mario_in_room(void) {
register s32 marioInRoom;
if (o->oRoom != -1 && gMarioCurrentRoom != 0) { if (o->oRoom != -1 && gMarioCurrentRoom != 0) {
if (gMarioCurrentRoom == o->oRoom) { if (gMarioCurrentRoom == o->oRoom // Object is in Mario's room.
marioInRoom = TRUE; || gDoorAdjacentRooms[gMarioCurrentRoom].forwardRoom == o->oRoom // Object is in the transition room's forward room.
} else if (gDoorAdjacentRooms[gMarioCurrentRoom][0] == o->oRoom) { || gDoorAdjacentRooms[gMarioCurrentRoom].backwardRoom == o->oRoom // Object is in the transition room's backward room.
marioInRoom = TRUE; ) {
} else if (gDoorAdjacentRooms[gMarioCurrentRoom][1] == o->oRoom) { return MARIO_INSIDE_ROOM;
marioInRoom = TRUE;
#if BETTER_ROOM_CHECKS
} else if (gDoorAdjacentRooms[o->oRoom][0] == gMarioCurrentRoom) {
marioInRoom = TRUE;
} else if (gDoorAdjacentRooms[o->oRoom][1] == gMarioCurrentRoom) {
marioInRoom = TRUE;
#endif
} else {
marioInRoom = FALSE;
} }
if (marioInRoom) { return MARIO_OUTSIDE_ROOM;
cur_obj_enable_rendering();
o->activeFlags &= ~ACTIVE_FLAG_IN_DIFFERENT_ROOM;
gNumRoomedObjectsInMarioRoom++;
} else {
cur_obj_disable_rendering();
o->activeFlags |= ACTIVE_FLAG_IN_DIFFERENT_ROOM;
gNumRoomedObjectsNotInMarioRoom++;
}
} }
return MARIO_ROOM_UNDEFINED;
}
void cur_obj_enable_rendering_in_room(void) {
cur_obj_enable_rendering();
o->activeFlags &= ~ACTIVE_FLAG_IN_DIFFERENT_ROOM;
gNumRoomedObjectsInMarioRoom++;
}
void cur_obj_disable_rendering_in_room(void) {
cur_obj_disable_rendering();
o->activeFlags |= ACTIVE_FLAG_IN_DIFFERENT_ROOM;
gNumRoomedObjectsNotInMarioRoom++;
} }
s32 cur_obj_set_hitbox_and_die_if_attacked(struct ObjectHitbox *hitbox, s32 deathSound, s32 noLootCoins) { s32 cur_obj_set_hitbox_and_die_if_attacked(struct ObjectHitbox *hitbox, s32 deathSound, s32 noLootCoins) {

View file

@ -205,9 +205,17 @@ s16 cur_obj_reflect_move_angle_off_wall(void);
#define WAYPOINT_MASK_00FF 0x00FF #define WAYPOINT_MASK_00FF 0x00FF
#define WAYPOINT_FLAGS_PLATFORM_ON_TRACK_PAUSE 3 #define WAYPOINT_FLAGS_PLATFORM_ON_TRACK_PAUSE 3
#define PATH_NONE 0 enum PathStatus {
#define PATH_REACHED_END -1 PATH_REACHED_END = -1,
#define PATH_REACHED_WAYPOINT 1 PATH_NONE,
PATH_REACHED_WAYPOINT,
};
enum MarioRoomStates {
MARIO_ROOM_UNDEFINED = -1,
MARIO_OUTSIDE_ROOM,
MARIO_INSIDE_ROOM
};
void obj_set_hitbox(struct Object *obj, struct ObjectHitbox *hitbox); void obj_set_hitbox(struct Object *obj, struct ObjectHitbox *hitbox);
s32 cur_obj_wait_then_blink(s32 timeUntilBlinking, s32 numBlinks); s32 cur_obj_wait_then_blink(s32 timeUntilBlinking, s32 numBlinks);
@ -228,7 +236,9 @@ void spawn_base_star_with_no_lvl_exit(void);
s32 cur_obj_mario_far_away(void); s32 cur_obj_mario_far_away(void);
s32 is_mario_moving_fast_or_in_air(s32 speedThreshold); s32 is_mario_moving_fast_or_in_air(s32 speedThreshold);
s32 is_item_in_array(s8 item, s8 *array); s32 is_item_in_array(s8 item, s8 *array);
void cur_obj_enable_rendering_if_mario_in_room(void); s32 cur_obj_is_mario_in_room(void);
void cur_obj_enable_rendering_in_room(void);
void cur_obj_disable_rendering_in_room(void);
s32 cur_obj_set_hitbox_and_die_if_attacked(struct ObjectHitbox *hitbox, s32 deathSound, s32 noLootCoins); s32 cur_obj_set_hitbox_and_die_if_attacked(struct ObjectHitbox *hitbox, s32 deathSound, s32 noLootCoins);
void obj_explode_and_spawn_coins(f32 mistParticleSize, s32 sp1C); void obj_explode_and_spawn_coins(f32 mistParticleSize, s32 sp1C);
void obj_set_collision_data(struct Object *obj, const void *segAddr); void obj_set_collision_data(struct Object *obj, const void *segAddr);

View file

@ -141,10 +141,10 @@ struct MemoryPool *gObjectMemoryPool;
s16 gCollisionFlags = COLLISION_FLAGS_NONE; s16 gCollisionFlags = COLLISION_FLAGS_NONE;
TerrainData *gEnvironmentRegions; TerrainData *gEnvironmentRegions;
s32 gEnvironmentLevels[20]; s32 gEnvironmentLevels[20];
RoomData gDoorAdjacentRooms[60][2]; struct TransitionRoomData gDoorAdjacentRooms[MAX_NUM_TRANSITION_ROOMS];
s16 gMarioCurrentRoom; s16 gMarioCurrentRoom;
s16 D_8035FEE2; s16 D_8035FEE2;
s16 D_8035FEE4; s16 gNumDoorRenderCount;
s16 gTHIWaterDrained; s16 gTHIWaterDrained;
s16 gTTCSpeedSetting; s16 gTTCSpeedSetting;
s16 gMarioShotFromCannon; s16 gMarioShotFromCannon;
@ -547,10 +547,7 @@ void clear_objects(void) {
gMarioObject = NULL; gMarioObject = NULL;
gMarioCurrentRoom = 0; gMarioCurrentRoom = 0;
for (i = 0; i < 60; i++) { bzero(gDoorAdjacentRooms, sizeof(gDoorAdjacentRooms));
gDoorAdjacentRooms[i][0] = 0;
gDoorAdjacentRooms[i][1] = 0;
}
debug_unknown_level_select_check(); debug_unknown_level_select_check();

View file

@ -108,12 +108,25 @@ enum CollisionFlags {
}; };
extern s16 gCollisionFlags; extern s16 gCollisionFlags;
extern TerrainData *gEnvironmentRegions; extern TerrainData *gEnvironmentRegions;
extern s32 gEnvironmentLevels[20]; extern s32 gEnvironmentLevels[20];
extern RoomData gDoorAdjacentRooms[60][2];
/**
* The maximum number of door/transition rooms that load two rooms of objects at once.
*/
#define MAX_NUM_TRANSITION_ROOMS 60
struct TransitionRoomData {
/*0x00*/ RoomData forwardRoom;
/*0x01*/ RoomData backwardRoom;
}; /*0x02*/
extern struct TransitionRoomData gDoorAdjacentRooms[MAX_NUM_TRANSITION_ROOMS];
extern s16 gMarioCurrentRoom; extern s16 gMarioCurrentRoom;
extern s16 D_8035FEE2; extern s16 D_8035FEE2;
extern s16 D_8035FEE4; extern s16 gNumDoorRenderCount;
extern s16 gTHIWaterDrained; extern s16 gTHIWaterDrained;
extern s16 gTTCSpeedSetting; extern s16 gTTCSpeedSetting;
extern s16 gMarioShotFromCannon; extern s16 gMarioShotFromCannon;