sm64pc/src/game/behaviors/beta_chest.inc.c

71 lines
2.5 KiB
C

/**
* Behavior for bhvBetaChestBottom and bhvBetaChestLid.
* These are apparently the beta versions of chests.
* They do not spawn stars or appear in groups; they only
* open and spawn an air bubble. In other words, they're
* practically the same as underwater chests in-game, except
* without any star-giving or puzzle functionality.
*/
/**
* Init function for bhvBetaChestBottom.
*/
void bhv_beta_chest_bottom_init(void) {
// Set the object's model
cur_obj_set_model(MODEL_TREASURE_CHEST_BASE);
// ??? Pointless code?
// Maybe chests were originally intended to have random yaws.
// Shoshinkai 1995 footage shows chests in DDD scattered around
// a point with different yaws. Maybe this feature was lazily
// cancelled by setting the yaw to 0, right before this beta
// object was discarded?
o->oMoveAngleYaw = random_u16();
o->oMoveAngleYaw = 0;
// Spawn the chest lid 97 units in the +Y direction and 77 units in the -Z direction.
spawn_object_relative(0, 0, 97, -77, o, MODEL_TREASURE_CHEST_LID, bhvBetaChestLid);
}
/**
* Update function for bhvBetaChestBottom.
* This gives the chest a "virtual hitbox" that pushes Mario away
* with radius 200 units and height 200 units.
*/
void bhv_beta_chest_bottom_loop(void) {
cur_obj_push_mario_away_from_cylinder(200.0f, 200.0f);
}
/**
* Update function for bhvBetaChestLid.
* The chest lid handles all the logic of the chest,
* namely opening the chest and spawning an air bubble.
*/
void bhv_beta_chest_lid_loop(void) {
switch (o->oAction) {
case BETA_CHEST_ACT_IDLE_CLOSED:
if (dist_between_objects(o->parentObj, gMarioObject) < 300.0f) {
o->oAction++; // Set to BETA_CHEST_ACT_OPENING
}
break;
case BETA_CHEST_ACT_OPENING:
if (o->oTimer == 0) {
// Spawn the bubble 80 units in the -Y direction and 120 units in the +Z direction.
spawn_object_relative(0, 0, -80, 120, o, MODEL_BUBBLE, bhvWaterAirBubble);
play_sound(SOUND_GENERAL_CLAM_SHELL1, o->header.gfx.cameraToObject);
}
// Rotate the lid 0x400 (1024) angle units per frame backwards.
// When the lid becomes vertical, stop rotating.
o->oFaceAnglePitch -= 0x400;
if (o->oFaceAnglePitch < -0x4000) {
o->oAction++; // Set to BETA_CHEST_ACT_IDLE_OPEN
}
// Fall-through
case BETA_CHEST_ACT_IDLE_OPEN:
break;
}
}