From be753ae2200e91429df79963c782467677e8222f Mon Sep 17 00:00:00 2001 From: axollyon <20480418+axollyon@users.noreply.github.com> Date: Mon, 6 Mar 2023 20:49:39 -0500 Subject: [PATCH] Small improvements to object loading within rooms (#580) * Small improvements to object loading within rooms * Only check if Mario is in the same room as the object once * Implement object render distance within rooms (from thecozies) * Remove sLevelsWithRooms (also from thecozies) Honestly surprised this wasn't already in Hacker * Remove comment for sLevelsWithRooms in config_game * Make compatible with the painting objects PR Move room detection to get_room_at_pos (from Arceveti) * address enum comment --- include/config/config_game.h | 1 - src/engine/behavior_script.c | 19 +++++++++++---- src/engine/surface_collision.c | 14 +++++++++++ src/engine/surface_collision.h | 1 + src/game/object_helpers.c | 43 ++++++++++++++-------------------- src/game/object_helpers.h | 9 ++++++- 6 files changed, 54 insertions(+), 33 deletions(-) diff --git a/include/config/config_game.h b/include/config/config_game.h index 8653b02c3..387c4bdd2 100644 --- a/include/config/config_game.h +++ b/include/config/config_game.h @@ -6,7 +6,6 @@ /** * Enables some mechanics that change behavior depending on hardcoded level numbers. - * You may also need to change sLevelsWithRooms in object_helpers.c. * TODO: separate this into separate defines, behavior params, or make these mechanics otherwise dynamic. */ // #define ENABLE_VANILLA_LEVEL_SPECIFIC_CHECKS diff --git a/src/engine/behavior_script.c b/src/engine/behavior_script.c index fbd1934f1..7b63aa86f 100644 --- a/src/engine/behavior_script.c +++ b/src/engine/behavior_script.c @@ -820,11 +820,11 @@ void cur_obj_update(void) { BhvCommandProc bhvCmdProc; s32 bhvProcResult; + s32 inRoom = is_mario_in_room(); + if (!(objFlags & OBJ_FLAG_PROCESS_OUTSIDE_ROOM)) { - if (o->oRoom != -1 && gMarioCurrentRoom != 0 && !is_room_loaded()) { - cur_obj_disable_rendering(); - o->activeFlags |= ACTIVE_FLAG_IN_DIFFERENT_ROOM; - gNumRoomedObjectsNotInMarioRoom++; + if (inRoom == MARIO_OUTSIDE_ROOM) { + cur_obj_enable_disable_room_rendering(MARIO_OUTSIDE_ROOM); return; } } @@ -928,7 +928,16 @@ void cur_obj_update(void) { // Handle visibility of object if (o->oRoom != -1) { // If the object is in a room, only show it when Mario is in the room. - cur_obj_enable_rendering_if_mario_in_room(); + if ( + (objFlags & OBJ_FLAG_ACTIVE_FROM_AFAR) + || distanceFromMario < o->oDrawingDistance + ) { + cur_obj_enable_disable_room_rendering(inRoom); + o->activeFlags &= ~ACTIVE_FLAG_FAR_AWAY; + } else { + o->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE; + o->activeFlags |= ACTIVE_FLAG_FAR_AWAY; + } } else if ( o->collisionData == NULL && (objFlags & OBJ_FLAG_COMPUTE_DIST_TO_MARIO) diff --git a/src/engine/surface_collision.c b/src/engine/surface_collision.c index 2b1e4a3c3..a597b8e74 100644 --- a/src/engine/surface_collision.c +++ b/src/engine/surface_collision.c @@ -640,6 +640,20 @@ f32 find_room_floor(f32 x, f32 y, f32 z, struct Surface **pfloor) { return find_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) { + return floor->room; + } + } + return -1; +} + /** * Find the highest water floor under a given position and return the height. */ diff --git a/src/engine/surface_collision.h b/src/engine/surface_collision.h index aea42e2e2..4078163d6 100644 --- a/src/engine/surface_collision.h +++ b/src/engine/surface_collision.h @@ -55,6 +55,7 @@ ALWAYS_INLINE f32 find_mario_ceil(Vec3f pos, f32 height, struct Surface **ceil) f32 find_floor_height(f32 x, f32 y, f32 z); 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); +s32 get_room_at_pos(f32 x, f32 y, f32 z); s32 find_water_level_and_floor(s32 x, s32 y, s32 z, struct Surface **pfloor); s32 find_water_level(s32 x, s32 z); s32 find_poison_gas_level(s32 x, s32 z); diff --git a/src/game/object_helpers.c b/src/game/object_helpers.c index fd53862f7..fd276ff0d 100644 --- a/src/game/object_helpers.c +++ b/src/game/object_helpers.c @@ -28,8 +28,6 @@ #include "spawn_sound.h" #include "puppylights.h" -static s8 sLevelsWithRooms[] = { LEVEL_BBH, LEVEL_CASTLE, LEVEL_HMC, -1 }; - static s32 clear_move_flag(u32 *bitSet, s32 flag); Gfx *geo_update_projectile_pos_from_parent(s32 callContext, UNUSED struct GraphNode *node, Mat4 mtx) { @@ -1879,35 +1877,28 @@ s32 is_item_in_array(s8 item, s8 *array) { } void bhv_init_room(void) { - struct Surface *floor = NULL; - if (is_item_in_array(gCurrLevelNum, sLevelsWithRooms)) { - find_room_floor(o->oPosX, o->oPosY, o->oPosZ, &floor); - - if (floor != NULL) { - o->oRoom = floor->room; - return; - } - } - o->oRoom = -1; + o->oRoom = get_room_at_pos(o->oPosX, o->oPosY, o->oPosZ); } -u32 is_room_loaded(void) { - return gMarioCurrentRoom == o->oRoom - || gDoorAdjacentRooms[gMarioCurrentRoom][0] == o->oRoom - || gDoorAdjacentRooms[gMarioCurrentRoom][1] == o->oRoom; -} - -void cur_obj_enable_rendering_if_mario_in_room(void) { +s32 is_mario_in_room(void) { if (o->oRoom != -1 && gMarioCurrentRoom != 0) { if (is_room_loaded()) { - 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_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++; } } diff --git a/src/game/object_helpers.h b/src/game/object_helpers.h index f9d37377b..61b04d639 100644 --- a/src/game/object_helpers.h +++ b/src/game/object_helpers.h @@ -219,6 +219,12 @@ enum ObjScaleAxis { SCALE_AXIS_Z = (1 << 2), // 0x04 }; +enum MarioRoomStates { + MARIO_ROOM_UNDEFINED = -1, + MARIO_OUTSIDE_ROOM, + MARIO_INSIDE_ROOM +}; + void obj_set_hitbox(struct Object *obj, struct ObjectHitbox *hitbox); s32 cur_obj_wait_then_blink(s32 timeUntilBlinking, s32 numBlinks); s32 cur_obj_is_mario_ground_pounding_platform(void); @@ -236,7 +242,8 @@ 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); u32 is_room_loaded(void); -void cur_obj_enable_rendering_if_mario_in_room(void); +s32 is_mario_in_room(void); +void cur_obj_enable_disable_room_rendering(s32 inRoom); 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);