diff --git a/data/behavior_data.c b/data/behavior_data.c index 8962915c..2e2c2dc1 100644 --- a/data/behavior_data.c +++ b/data/behavior_data.c @@ -86,15 +86,15 @@ enum BehaviorCommands { /*0x0F*/ BHV_CMD_ADD_INT, /*0x10*/ BHV_CMD_SET_INT, /*0x11*/ BHV_CMD_OR_INT, - /*0x12*/ BHV_CMD_BIT_CLEAR, - /*0x13*/ BHV_CMD_SET_INT_RAND_RSHIFT, - /*0x14*/ BHV_CMD_SET_RANDOM_FLOAT, - /*0x15*/ BHV_CMD_SET_RANDOM_INT, - /*0x16*/ BHV_CMD_ADD_RANDOM_FLOAT, - /*0x17*/ BHV_CMD_ADD_INT_RAND_RSHIFT, - /*0x18*/ BHV_CMD_NOP_1, - /*0x19*/ BHV_CMD_NOP_2, - /*0x1A*/ BHV_CMD_NOP_3, + /*0x12*/ BHV_CMD_OR_LONG, + /*0x13*/ BHV_CMD_BIT_CLEAR, + /*0x14*/ BHV_CMD_SET_INT_RAND_RSHIFT, + /*0x15*/ BHV_CMD_SET_RANDOM_FLOAT, + /*0x16*/ BHV_CMD_SET_RANDOM_INT, + /*0x17*/ BHV_CMD_ADD_RANDOM_FLOAT, + /*0x18*/ BHV_CMD_ADD_INT_RAND_RSHIFT, + /*0x19*/ BHV_CMD_NOP_1, + /*0x1A*/ BHV_CMD_NOP_2, /*0x1B*/ BHV_CMD_SET_MODEL, /*0x1C*/ BHV_CMD_SPAWN_CHILD, /*0x1D*/ BHV_CMD_DEACTIVATE, @@ -204,6 +204,12 @@ enum BehaviorCommands { #define OR_INT(field, value) \ BC_BBH(BHV_CMD_OR_INT, field, value) +// Performs a bitwise OR with the specified field and the given (32 bit) integer. +// Usually used to set an object's flags which use values above 16 bits. +#define OR_LONG(field, value) \ + BC_BB(BHV_CMD_OR_LONG, field), \ + BC_W(value) + // Performs a bit clear with the specified short. Unused in favor of the 32-bit version. #define BIT_CLEAR(field, value) \ BC_BBH(BHV_CMD_BIT_CLEAR, field, value) @@ -243,10 +249,6 @@ enum BehaviorCommands { #define CMD_NOP_2(field) \ BC_BB(BHV_CMD_NOP_2, field) -// No operation. Unused. -#define CMD_NOP_3(field) \ - BC_BB(BHV_CMD_NOP_3, field) - // Sets the current model ID of the object. #define SET_MODEL(modelID) \ BC_B0H(BHV_CMD_SET_MODEL, modelID) @@ -300,8 +302,6 @@ enum BehaviorCommands { #define BEGIN_REPEAT_UNUSED(count) \ BC_BB(BHV_CMD_BEGIN_REPEAT_UNUSED, count) -#define OR_LONG(field, value) LOAD_ANIMATIONS(field, value) - // Loads the animations for the object. is always set to oAnimations. #define LOAD_ANIMATIONS(field, anims) \ BC_BB(BHV_CMD_LOAD_ANIMATIONS, field), \ diff --git a/src/engine/behavior_script.c b/src/engine/behavior_script.c index 5bc76f69..299eec42 100644 --- a/src/engine/behavior_script.c +++ b/src/engine/behavior_script.c @@ -359,7 +359,7 @@ static s32 bhv_cmd_set_int_unused(void) { return BHV_PROC_CONTINUE; } -// Command 0x14: Sets the specified field to a random float in the given range. +// Command 0x15: Sets the specified field to a random float in the given range. // Usage: SET_RANDOM_FLOAT(field, min, range) static s32 bhv_cmd_set_random_float(void) { u8 field = BHV_CMD_GET_2ND_U8(0); @@ -372,7 +372,7 @@ static s32 bhv_cmd_set_random_float(void) { return BHV_PROC_CONTINUE; } -// Command 0x15: Sets the specified field to a random integer in the given range. +// Command 0x16: Sets the specified field to a random integer in the given range. // Usage: SET_RANDOM_INT(field, min, range) static s32 bhv_cmd_set_random_int(void) { u8 field = BHV_CMD_GET_2ND_U8(0); @@ -385,7 +385,7 @@ static s32 bhv_cmd_set_random_int(void) { return BHV_PROC_CONTINUE; } -// Command 0x13: Gets a random short, right shifts it the specified amount and adds min to it, then sets the specified field to that value. +// Command 0x14: Gets a random short, right shifts it the specified amount and adds min to it, then sets the specified field to that value. // Usage: SET_INT_RAND_RSHIFT(field, min, rshift) static s32 bhv_cmd_set_int_rand_rshift(void) { u8 field = BHV_CMD_GET_2ND_U8(0); @@ -398,7 +398,7 @@ static s32 bhv_cmd_set_int_rand_rshift(void) { return BHV_PROC_CONTINUE; } -// Command 0x16: Adds a random float in the given range to the specified field. +// Command 0x17: Adds a random float in the given range to the specified field. // Usage: ADD_RANDOM_FLOAT(field, min, range) static s32 bhv_cmd_add_random_float(void) { u8 field = BHV_CMD_GET_2ND_U8(0); @@ -411,7 +411,7 @@ static s32 bhv_cmd_add_random_float(void) { return BHV_PROC_CONTINUE; } -// Command 0x17: Gets a random short, right shifts it the specified amount and adds min to it, then adds the value to the specified field. Unused. +// Command 0x18: Gets a random short, right shifts it the specified amount and adds min to it, then adds the value to the specified field. Unused. // Usage: ADD_INT_RAND_RSHIFT(field, min, rshift) static s32 bhv_cmd_add_int_rand_rshift(void) { u8 field = BHV_CMD_GET_2ND_U8(0); @@ -463,7 +463,20 @@ static s32 bhv_cmd_or_int(void) { return BHV_PROC_CONTINUE; } -// Command 0x12: Performs a bit clear with the specified short. Unused. +// Command 0x12: Performs a bitwise OR with the specified field and the given (32 bit) integer. +// Usually used to set an object's flags which use values above 16 bits. +// Usage: OR_LONG(field, value) +static s32 bhv_cmd_or_long(void) { + u8 field = BHV_CMD_GET_2ND_U8(0); + u32 value = BHV_CMD_GET_U32(1); + + cur_obj_or_int(field, value); + + gCurBhvCommand += 2; + return BHV_PROC_CONTINUE; +} + +// Command 0x13: Performs a bit clear with the specified short. Unused. // Usage: BIT_CLEAR(field, value) static s32 bhv_cmd_bit_clear(void) { u8 field = BHV_CMD_GET_2ND_U8(0); @@ -510,7 +523,7 @@ static s32 bhv_cmd_drop_to_floor(void) { return BHV_PROC_CONTINUE; } -// Command 0x18: No operation. Unused. +// Command 0x19: No operation. Unused. // Usage: CMD_NOP_1(field) static s32 bhv_cmd_nop_1(void) { UNUSED u8 field = BHV_CMD_GET_2ND_U8(0); @@ -520,15 +533,6 @@ static s32 bhv_cmd_nop_1(void) { } // Command 0x1A: No operation. Unused. -// Usage: CMD_NOP_3(field) -static s32 bhv_cmd_nop_3(void) { - UNUSED u8 field = BHV_CMD_GET_2ND_U8(0); - - gCurBhvCommand++; - return BHV_PROC_CONTINUE; -} - -// Command 0x19: No operation. Unused. // Usage: CMD_NOP_2(field) static s32 bhv_cmd_nop_2(void) { UNUSED u8 field = BHV_CMD_GET_2ND_U8(0); @@ -773,6 +777,7 @@ static BhvCommandProc BehaviorCmdTable[] = { /*BHV_CMD_ADD_INT */ bhv_cmd_add_int, /*BHV_CMD_SET_INT */ bhv_cmd_set_int, /*BHV_CMD_OR_INT */ bhv_cmd_or_int, + /*BHV_CMD_OR_LONG */ bhv_cmd_or_long, /*BHV_CMD_BIT_CLEAR */ bhv_cmd_bit_clear, /*BHV_CMD_SET_INT_RAND_RSHIFT */ bhv_cmd_set_int_rand_rshift, /*BHV_CMD_SET_RANDOM_FLOAT */ bhv_cmd_set_random_float, @@ -781,7 +786,6 @@ static BhvCommandProc BehaviorCmdTable[] = { /*BHV_CMD_ADD_INT_RAND_RSHIFT */ bhv_cmd_add_int_rand_rshift, /*BHV_CMD_NOP_1 */ bhv_cmd_nop_1, /*BHV_CMD_NOP_2 */ bhv_cmd_nop_2, - /*BHV_CMD_NOP_3 */ bhv_cmd_nop_3, /*BHV_CMD_SET_MODEL */ bhv_cmd_set_model, /*BHV_CMD_SPAWN_CHILD */ bhv_cmd_spawn_child, /*BHV_CMD_DEACTIVATE */ bhv_cmd_deactivate, diff --git a/src/engine/surface_load.c b/src/engine/surface_load.c index d3753755..4474bbb2 100644 --- a/src/engine/surface_load.c +++ b/src/engine/surface_load.c @@ -699,13 +699,11 @@ static TerrainData sVertexData[600]; void load_object_collision_model(void) { PUPPYPRINT_GET_SNAPSHOT(); TerrainData *collisionData = o->collisionData; - f32 marioDist = o->oDistanceToMario; - // On an object's first frame, the distance is set to 19000.0f. - // If the distance hasn't been updated, update it now. - if (o->oDistanceToMario == 19000.0f) { - marioDist = dist_between_objects(o, gMarioObject); - } + f32 sqrLateralDist; + vec3f_get_lateral_dist_squared(&o->oPosVec, &gMarioObject->oPosVec, &sqrLateralDist); + + f32 verticalMarioDiff = gMarioObject->oPosY - o->oPosY; #ifdef AUTO_COLLISION_DISTANCE if (!(o->oFlags & OBJ_FLAG_DONT_CALC_COLL_DIST)) { @@ -718,11 +716,17 @@ void load_object_collision_model(void) { if (o->oCollisionDistance > o->oDrawingDistance) { o->oDrawingDistance = o->oCollisionDistance; } + + s32 inColRadius = ( + (sqrLateralDist < sqr(o->oCollisionDistance)) + && (verticalMarioDiff > 0 || verticalMarioDiff > -o->oCollisionDistance) + && (verticalMarioDiff < 0 || verticalMarioDiff < o->oCollisionDistance + 2000.f) + ); // Update if no Time Stop, in range, and in the current room. if ( !(gTimeStopState & TIME_STOP_ACTIVE) - && (marioDist < o->oCollisionDistance) + && inColRadius && !(o->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM) ) { collisionData++; @@ -733,6 +737,15 @@ void load_object_collision_model(void) { load_object_surfaces(&collisionData, sVertexData, TRUE); } } + + f32 marioDist = o->oDistanceToMario; + + // On an object's first frame, the distance is set to 19000.0f. + // If the distance hasn't been updated, update it now. + if (marioDist == 19000.0f) { + marioDist = dist_between_objects(o, gMarioObject); + } + COND_BIT((marioDist < o->oDrawingDistance), o->header.gfx.node.flags, GRAPH_RENDER_ACTIVE); profiler_collision_update(first); }