Path: blob/master/src/game/behaviors/activated_bf_plat.inc.c
7861 views
/**1* Behavior for bhvActivatedBackAndForthPlatform.2* There are only 2 of these in the game; the BitFS gray elevator3* and the BitS arrow platform.4* Note: The filename is abbreviated to avoid compiler seg fault on long paths5*/67/**8* Table of activated back-and-forth platform collision models.9* The second entry is unused. It corresponds to the mesh platform10* at the beginning of BitFS. In the game, it's a bhvPlatformOnTrack,11* which allows for more complex movement; its path is mostly a straight line12* except for where it dips into the lava. It seems the programmers13* had it as a bhvActivatedBackAndForthPlatform initially, which moves14* in a straight line, and wanted it to dip into the lava to make Mario have to15* move off of it. To do this, they changed it to a bhvPlatformOnTrack, but16* forgot to remove its entry in this table.17*/18static void const *sActivatedBackAndForthPlatformCollisionModels[] = {19/* ACTIVATED_BF_PLAT_TYPE_BITS_ARROW_PLAT */ bits_seg7_collision_0701AD54,20/* ACTIVATED_BF_PLAT_TYPE_BITFS_MESH_PLAT */ bitfs_seg7_collision_070157E0,21/* ACTIVATED_BF_PLAT_TYPE_BITFS_ELEVATOR */ bitfs_seg7_collision_0701512422};2324/**25* Activated back-and-forth platform initialization function.26*/27void bhv_activated_back_and_forth_platform_init(void) {28// Equivalent to the first behavior param byte & 3 (last 2 bits of the byte).29s32 platformType = ((u16)(o->oBehParams >> 16) & 0x0300) >> 8;3031// The BitS arrow platform should flip 180º (0x8000 angle units), but32// there is no reason for the other platforms to flip.33if (platformType != ACTIVATED_BF_PLAT_TYPE_BITS_ARROW_PLAT) {34o->oActivatedBackAndForthPlatformFlipRotation = 0;35} else {36o->oActivatedBackAndForthPlatformFlipRotation = 0x8000;37}3839o->collisionData =40segmented_to_virtual(sActivatedBackAndForthPlatformCollisionModels[platformType]);4142// Max distance the platform should move.43// Equivalent to 50 * (oBehParams2ndByte & 0x7F), i.e. 50 * (oBehParams2ndByte % 128).44// The maximum possible value of this is 50 * 127 = 6350.45// It's 50 * 97 = 4850 in BitS and 50 * 31 = 1550 in BitFS.46o->oActivatedBackAndForthPlatformMaxOffset = 50.0f * ((u16)(o->oBehParams >> 16) & 0x007F);4748if (platformType == ACTIVATED_BF_PLAT_TYPE_BITFS_ELEVATOR) {49o->oActivatedBackAndForthPlatformMaxOffset -= 12.0f;50}5152// Truthy/falsy value that determines the direction of movement.53// Equivalent to oBehParams2ndByte & 0x80, i.e. the most significant bit of oBehParams2ndByte.54o->oActivatedBackAndForthPlatformVertical = (u16)(o->oBehParams >> 16) & 0x0080;5556o->oActivatedBackAndForthPlatformStartYaw = o->oFaceAngleYaw;57}5859/**60* Activated back-and-forth platform update function.61*/62void bhv_activated_back_and_forth_platform_update(void) {63UNUSED s32 unused[3];6465// oVelY is used for vertical platforms' movement and also for66// horizontal platforms' dipping up/down when Mario gets on/off them67if (gMarioObject->platform == o) {68o->oVelY = -6.0f;69} else {70o->oVelY = 6.0f;71}7273// If the platform's velocity is set...74if (o->oActivatedBackAndForthPlatformVel != 0.0f) {75// ...wait until the countdown is 0 before moving.76// Since there's a 1 frame "lag" after the countdown is set to 20,77// and one more frame of "lag" after it finally reaches 0 here,78// Mario actually has to wait 22 frames before the platform starts moving.79if (o->oActivatedBackAndForthPlatformCountdown != 0) {80o->oActivatedBackAndForthPlatformCountdown -= 1;81} else {82// After the wait period is over, we start moving, by adding the velocity83// to the positional offset.84o->oActivatedBackAndForthPlatformOffset += o->oActivatedBackAndForthPlatformVel;8586// clamp_f32 returns whether the value needed to be clamped.87// So if the offset got out of bounds (i.e. platform has reached an end of its path),88// or Mario is over 3000 units away, the platform will reset the wait timer and flip around.89if (clamp_f32(&o->oActivatedBackAndForthPlatformOffset, 0.0f,90o->oActivatedBackAndForthPlatformMaxOffset)91||92// The platform will not reset if Mario goes far away and it's travelling backwards93(o->oActivatedBackAndForthPlatformVel > 0.0f && o->oDistanceToMario > 3000.0f)) {94// Reset the wait timer95o->oActivatedBackAndForthPlatformCountdown = 20;9697// oVelY is only negative if Mario is on the platform,98// so if Mario is on the platform or the platform is going forwards when it resets,99// the platform will reverse directions. Otherwise, it will stop.100// This means that if Mario touches the platform initially, then gets off,101// it will do a full round trip then stop (assuming Mario stays within 3000 units).102if (o->oVelY < 0.0f || o->oActivatedBackAndForthPlatformVel > 0.0f) {103o->oActivatedBackAndForthPlatformVel = -o->oActivatedBackAndForthPlatformVel;104} else {105o->oActivatedBackAndForthPlatformVel = 0.0f;106}107108// Make the platform face the opposite way if it should.109// This is for the BitS arrow platform, which has an indicated direction.110o->oFaceAngleYaw += o->oActivatedBackAndForthPlatformFlipRotation;111}112}113} else {114// oVelY is only negative if Mario is on the platform115if (o->oVelY < 0.0f) {116o->oActivatedBackAndForthPlatformVel = 10.0f;117}118119// Set waiting countdown to 20 frames120o->oActivatedBackAndForthPlatformCountdown = 20;121}122123// Save the object's current position to a safe location.124obj_perform_position_op(POS_OP_SAVE_POSITION);125126// Update the object's position.127// If the platform moves vertically...128if (o->oActivatedBackAndForthPlatformVertical != FALSE) {129// ...set its position to its original position + the offset.130o->oPosY = o->oHomeY + o->oActivatedBackAndForthPlatformOffset;131} else {132// Otherwise, dip down 20 units if Mario gets on the horizontal platform, and undo if he gets133// off.134o->oPosY += o->oVelY;135clamp_f32(&o->oPosY, o->oHomeY - 20.0f, o->oHomeY);136137// Update the position using the object's home (original position), facing angle, and offset.138// This has to be done manually when the platform is vertical because only the yaw is used139// by this function; it doesn't update the Y position.140obj_set_dist_from_home(-o->oActivatedBackAndForthPlatformOffset);141}142143// Compute the object's velocity using the old saved position.144obj_perform_position_op(POS_OP_COMPUTE_VELOCITY);145}146147148