
/**
 * 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
            }

            // fallthrough
        case BETA_CHEST_ACT_IDLE_OPEN:
            break;
    }
}
