Fix rooms and doors (#601)

* Fix rooms and doors

* Update object_helpers.c

* Update object_list_processor.h

* Update object_list_processor.c

* Fix formatting

* Revert a formatting

* Clean up geo_switch_area

* Clean up geo_switch_area (more)

* Move TransitionRoomData struct

* Revert star door collision check optimization

* Move load_object_collision_model and bhv_door_rendering_loop back out of star_door.inc.c

* Combine metal door model IDs

* Revert metal door sound fixes
This commit is contained in:
Arceveti
2023-03-17 12:05:57 -04:00
committed by GitHub
parent f7bdca7533
commit 171f377412
9 changed files with 97 additions and 84 deletions

View File

@@ -403,8 +403,8 @@ const BehaviorScript bhvStarDoor[] = {
SET_INT(oIntangibleTimer, 0),
BEGIN_LOOP(),
CALL_NATIVE(bhv_star_door_loop),
CALL_NATIVE(bhv_door_rendering_loop),
CALL_NATIVE(load_object_collision_model),
CALL_NATIVE(bhv_door_rendering_loop),
END_LOOP(),
};

View File

@@ -2,8 +2,8 @@
const RoomData inside_castle_seg7_area_1_rooms[] = {
1, 9, 9, 1, 9, 9, 9, 9, // 0-7
9, 9, 1, 1, 1, 9, 9, 17, // 8-15
1, 9, 9, 9, 9, 9, 17, 9, // 16-23
9, 9, 9, 9, 9, 9, 9, 9, // 24-31
1, 17, 17, 9, 17, 9, 17, 9, // 16-23
9, 9, 17, 9, 9, 9, 9, 9, // 24-31
8, 8, 8, 8, 8, 8, 8, 8, // 32-39
8, 8, 8, 8, 8, 8, 8, 8, // 40-47
8, 8, 8, 8, 8, 8, 8, 8, // 48-55

View File

@@ -820,13 +820,11 @@ void cur_obj_update(void) {
BhvCommandProc bhvCmdProc;
s32 bhvProcResult;
s32 inRoom = is_mario_in_room();
s32 inRoom = cur_obj_is_mario_in_room();
if (objFlags & OBJ_FLAG_ONLY_PROCESS_INSIDE_ROOM) {
if (inRoom == MARIO_OUTSIDE_ROOM) {
cur_obj_enable_disable_room_rendering(MARIO_OUTSIDE_ROOM);
return;
}
if (inRoom == MARIO_OUTSIDE_ROOM && (objFlags & OBJ_FLAG_ONLY_PROCESS_INSIDE_ROOM)) {
cur_obj_disable_rendering_in_room();
return;
}
// Calculate the distance from the object to Mario.
@@ -932,7 +930,11 @@ void cur_obj_update(void) {
(objFlags & OBJ_FLAG_ACTIVE_FROM_AFAR)
|| distanceFromMario < o->oDrawingDistance
) {
cur_obj_enable_disable_room_rendering(inRoom);
if (inRoom == MARIO_OUTSIDE_ROOM) {
cur_obj_disable_rendering_in_room();
} else if (inRoom == MARIO_INSIDE_ROOM) {
cur_obj_enable_rendering_in_room();
}
o->activeFlags &= ~ACTIVE_FLAG_FAR_AWAY;
} else {
o->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;

View File

@@ -650,7 +650,8 @@ f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor) {
}
f32 find_room_floor(f32 x, f32 y, f32 z, struct Surface **pfloor) {
gCollisionFlags |= (COLLISION_FLAG_RETURN_FIRST | COLLISION_FLAG_EXCLUDE_DYNAMIC | COLLISION_FLAG_INCLUDE_INTANGIBLE);
gCollisionFlags |= (COLLISION_FLAG_EXCLUDE_DYNAMIC | COLLISION_FLAG_INCLUDE_INTANGIBLE);
return find_floor(x, y, z, pfloor);
}
@@ -660,11 +661,14 @@ f32 find_room_floor(f32 x, f32 y, f32 z, struct Surface **pfloor) {
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) {
if (floor != NULL) {
return floor->room;
}
}
return -1;
}

View File

@@ -65,6 +65,7 @@ void bhv_door_loop(void) {
switch (o->oAction) {
case DOOR_ACT_CLOSED:
cur_obj_init_animation_with_sound(DOOR_ANIM_CLOSED);
load_object_collision_model();
break;
case DOOR_ACT_PULLED:
door_animation_and_reset(DOOR_ANIM_PULLED);
@@ -83,49 +84,55 @@ void bhv_door_loop(void) {
play_warp_door_open_noise();
break;
}
if (o->oAction == DOOR_ACT_CLOSED) {
load_object_collision_model();
}
bhv_door_rendering_loop();
}
void bhv_door_init(void) {
const f32 checkDist = 200.0f;
f32 x = o->oPosX;
f32 y = o->oPosY;
f32 z = o->oPosZ;
struct Surface *floor;
find_room_floor(x, y, z, &floor);
if (floor != NULL) o->oDoorSelfRoom = floor->room;
o->oDoorSelfRoom = get_room_at_pos(x, y, z);
x = o->oPosX + sins(o->oMoveAngleYaw) * 200.0f;
z = o->oPosZ + coss(o->oMoveAngleYaw) * 200.0f;
x = o->oPosX + (sins(o->oMoveAngleYaw) * checkDist);
z = o->oPosZ + (coss(o->oMoveAngleYaw) * checkDist);
find_room_floor(x, y, z, &floor);
if (floor != NULL) o->oDoorForwardRoom = floor->room;
o->oDoorForwardRoom = get_room_at_pos(x, y, z);
x = o->oPosX + sins(o->oMoveAngleYaw) * -200.0f;
z = o->oPosZ + coss(o->oMoveAngleYaw) * -200.0f;
x = o->oPosX + (sins(o->oMoveAngleYaw) * -checkDist);
z = o->oPosZ + (coss(o->oMoveAngleYaw) * -checkDist);
find_room_floor(x, y, z, &floor);
if (floor != NULL) o->oDoorBackwardRoom = floor->room;
o->oDoorBackwardRoom = get_room_at_pos(x, y, z);
if (o->oDoorSelfRoom > 0 && o->oDoorSelfRoom < 60) {
gDoorAdjacentRooms[o->oDoorSelfRoom][0] = o->oDoorForwardRoom;
gDoorAdjacentRooms[o->oDoorSelfRoom][1] = o->oDoorBackwardRoom;
if (
// Ensure the room number is in bounds.
o->oDoorSelfRoom > 0 && o->oDoorSelfRoom < ARRAY_COUNT(gDoorAdjacentRooms)
// Only set gDoorAdjacentRooms for transition rooms.
&& o->oDoorSelfRoom != o->oDoorForwardRoom
&& o->oDoorSelfRoom != o->oDoorBackwardRoom
&& o->oDoorForwardRoom != o->oDoorBackwardRoom
) {
gDoorAdjacentRooms[o->oDoorSelfRoom].forwardRoom = o->oDoorForwardRoom;
gDoorAdjacentRooms[o->oDoorSelfRoom].backwardRoom = o->oDoorBackwardRoom;
}
}
void bhv_door_rendering_loop(void) {
struct TransitionRoomData* transitionRoom = &gDoorAdjacentRooms[gMarioCurrentRoom];
o->oDoorIsRendering = (
gMarioCurrentRoom == 0
|| gMarioCurrentRoom == o->oDoorSelfRoom
|| gMarioCurrentRoom == o->oDoorForwardRoom
|| gMarioCurrentRoom == o->oDoorBackwardRoom
|| gDoorAdjacentRooms[gMarioCurrentRoom][0] == o->oDoorForwardRoom
|| gDoorAdjacentRooms[gMarioCurrentRoom][0] == o->oDoorBackwardRoom
|| gDoorAdjacentRooms[gMarioCurrentRoom][1] == o->oDoorForwardRoom
|| gDoorAdjacentRooms[gMarioCurrentRoom][1] == o->oDoorBackwardRoom
gMarioCurrentRoom == 0 || // Mario is in the "global" room.
gMarioCurrentRoom == o->oDoorSelfRoom || // Mario is in the same room as the door.
gMarioCurrentRoom == o->oDoorForwardRoom || // Mario is in the door's forward room.
gMarioCurrentRoom == o->oDoorBackwardRoom || // Mario is in the door's backward room.
transitionRoom->forwardRoom == o->oDoorForwardRoom || // The transition room's forward room is in the same room as this door's forward room.
transitionRoom->forwardRoom == o->oDoorBackwardRoom || // The transition room's forward room is in the same room as this door's backward room.
transitionRoom->backwardRoom == o->oDoorForwardRoom || // The transition room's backward room is in the same room as this door's forward room.
transitionRoom->backwardRoom == o->oDoorBackwardRoom // The transition room's backward room is in the same room as this door's backward room.
);
COND_BIT(o->oDoorIsRendering, o->header.gfx.node.flags, GRAPH_RENDER_ACTIVE);
}

View File

@@ -119,33 +119,21 @@ Gfx *geo_switch_anim_state(s32 callContext, struct GraphNode *node, UNUSED void
}
Gfx *geo_switch_area(s32 callContext, struct GraphNode *node, UNUSED void *context) {
struct Surface *floor;
struct GraphNodeSwitchCase *switchCase = (struct GraphNodeSwitchCase *) node;
RoomData room;
if (callContext == GEO_CONTEXT_RENDER) {
if (gMarioObject == NULL) {
switchCase->selectedCase = 0;
} else {
#ifdef ENABLE_VANILLA_LEVEL_SPECIFIC_CHECKS
if (gCurrLevelNum == LEVEL_BBH) {
// In BBH, check for a floor manually, since there is an intangible floor. In custom hacks this can be removed.
find_room_floor(gMarioObject->oPosX, gMarioObject->oPosY, gMarioObject->oPosZ, &floor);
} else {
// Since no intangible floors are nearby, use Mario's floor instead.
floor = gMarioState->floor;
}
#else
floor = gMarioState->floor;
#endif
if (floor) {
gMarioCurrentRoom = floor->room;
s16 roomCase = floor->room - 1;
print_debug_top_down_objectinfo("areainfo %d", floor->room);
if (callContext == GEO_CONTEXT_RENDER && gMarioObject != NULL) {
room = get_room_at_pos(
gMarioObject->oPosX,
gMarioObject->oPosY,
gMarioObject->oPosZ
);
if (roomCase >= 0) {
switchCase->selectedCase = roomCase;
}
}
gMarioCurrentRoom = room;
print_debug_top_down_objectinfo("areainfo %d", room);
if (room > 0) {
switchCase->selectedCase = (room - 1);
}
} else {
switchCase->selectedCase = 0;
@@ -1880,30 +1868,31 @@ void bhv_init_room(void) {
o->oRoom = get_room_at_pos(o->oPosX, o->oPosY, o->oPosZ);
}
s32 is_mario_in_room(void) {
s32 cur_obj_is_mario_in_room(void) {
if (o->oRoom != -1 && gMarioCurrentRoom != 0) {
if (
gMarioCurrentRoom == o->oRoom ||
gDoorAdjacentRooms[gMarioCurrentRoom][0] == o->oRoom ||
gDoorAdjacentRooms[gMarioCurrentRoom][1] == o->oRoom
if (gMarioCurrentRoom == o->oRoom // Object is in Mario's room.
|| gDoorAdjacentRooms[gMarioCurrentRoom].forwardRoom == o->oRoom // Object is in the transition room's forward room.
|| gDoorAdjacentRooms[gMarioCurrentRoom].backwardRoom == o->oRoom // Object is in the transition room's backward room.
) {
return MARIO_INSIDE_ROOM;
}
return MARIO_OUTSIDE_ROOM;
}
return MARIO_ROOM_UNDEFINED;
}
void cur_obj_enable_disable_room_rendering(s32 inRoom) {
if (inRoom == MARIO_INSIDE_ROOM) {
cur_obj_enable_rendering();
o->activeFlags &= ~ACTIVE_FLAG_IN_DIFFERENT_ROOM;
gNumRoomedObjectsInMarioRoom++;
} else if (inRoom == MARIO_OUTSIDE_ROOM) {
cur_obj_disable_rendering();
o->activeFlags |= ACTIVE_FLAG_IN_DIFFERENT_ROOM;
gNumRoomedObjectsNotInMarioRoom++;
}
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) {

View File

@@ -241,8 +241,9 @@ void cur_obj_call_action_function(ObjActionFunc actionFunctions[]);
s32 cur_obj_mario_far_away(void);
s32 is_mario_moving_fast_or_in_air(s32 speedThreshold);
s32 is_item_in_array(s8 item, s8 *array);
s32 is_mario_in_room(void);
void cur_obj_enable_disable_room_rendering(s32 inRoom);
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);
void obj_explode_and_spawn_coins(f32 mistSize, s32 coinType);
void obj_set_collision_data(struct Object *obj, const void *segAddr);

View File

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

View File

@@ -109,9 +109,22 @@ enum CollisionFlags {
};
extern s16 gCollisionFlags;
extern TerrainData *gEnvironmentRegions;
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 gTHIWaterDrained;
extern s16 gTTCSpeedSetting;