2019-08-25 04:46:40 +00:00
|
|
|
/**
|
|
|
|
* Behavior for bhvPiranhaPlantBubble and bhvPiranhaPlantWakingBubbles.
|
|
|
|
*
|
|
|
|
* This controls the bubble that grows and shrinks from a Piranha Plant's nose
|
|
|
|
* as it sleeps, and the smaller bubbles that explode outwards when the Piranha
|
|
|
|
* Plant is woken up.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Main loop for bhvPiranhaPlantWakingBubbles. Initialize a random 3D velocity
|
|
|
|
* vector, then follow its path according to gravity.
|
|
|
|
*/
|
|
|
|
void bhv_piranha_plant_waking_bubbles_loop(void) {
|
|
|
|
if (o->oTimer == 0) {
|
2020-04-03 18:57:26 +00:00
|
|
|
o->oVelY = random_float() * 10.0f + 5.0f;
|
|
|
|
o->oForwardVel = random_float() * 10.0f + 5.0f;
|
|
|
|
o->oMoveAngleYaw = random_u16();
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_move_using_fvel_and_gravity();
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Main loop for bhvPiranhaPlantBubble. After it is initialized, the bubble
|
|
|
|
* will grow and shrink continuously while the Piranha Plant sleeps. If the
|
|
|
|
* Piranha Plant ever stops sleeping, the bubble will disappear and spawn many
|
|
|
|
* bubbles to appear to burst. After bursting, the bubble is reinitialized
|
|
|
|
* and the cycle can repeat.
|
|
|
|
*/
|
|
|
|
void bhv_piranha_plant_bubble_loop(void) {
|
|
|
|
struct Object *parent = o->parentObj; // the Piranha Plant
|
|
|
|
f32 scale = 0;
|
|
|
|
s32 i;
|
|
|
|
s32 frame = parent->header.gfx.unk38.animFrame;
|
|
|
|
// TODO: rename lastFrame if it is inaccurate
|
|
|
|
s32 lastFrame = parent->header.gfx.unk38.curAnim->unk08 - 2;
|
|
|
|
s32 UNUSED unused;
|
|
|
|
f32 doneShrinkingFrame; // the first frame after shrinking is done
|
|
|
|
f32 beginGrowingFrame; // the frame just before growing begins
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_set_pos_relative(parent, 0, 72.0f, 180.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
switch (o->oAction) {
|
|
|
|
case PIRANHA_PLANT_BUBBLE_ACT_IDLE:
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_disable_rendering();
|
2019-08-25 04:46:40 +00:00
|
|
|
scale = 0;
|
|
|
|
|
|
|
|
if (parent->oAction == PIRANHA_PLANT_ACT_SLEEPING) {
|
|
|
|
o->oAction++; // move to PIRANHA_PLANT_BUBBLE_ACT_GROW_SHRINK_LOOP
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PIRANHA_PLANT_BUBBLE_ACT_GROW_SHRINK_LOOP:
|
|
|
|
if (parent->oDistanceToMario < parent->oDrawingDistance) {
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_enable_rendering();
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
if (parent->oAction == PIRANHA_PLANT_ACT_SLEEPING) {
|
|
|
|
/**
|
|
|
|
* Set the frame after shrinking is done to be slightly before
|
|
|
|
* halfway through the animation, and the frame before growing
|
|
|
|
* slightly after halfway. This leaves about 8 frames during
|
|
|
|
* which the bubble is at its smallest, where its scale is 1.0f.
|
|
|
|
*/
|
|
|
|
doneShrinkingFrame = lastFrame / 2.0f - 4.0f;
|
|
|
|
beginGrowingFrame = lastFrame / 2.0f + 4.0f;
|
|
|
|
|
|
|
|
// Note that the bubble always starts this loop at its largest.
|
|
|
|
if (frame < doneShrinkingFrame) {
|
|
|
|
// Shrink from 5.0f to 1.0f.
|
|
|
|
scale = coss(frame / doneShrinkingFrame * 0x4000) * 4.0f + 1.0;
|
|
|
|
} else if (frame > beginGrowingFrame) {
|
|
|
|
// Grow from 1.0f to 5.0f.
|
|
|
|
scale = sins((
|
|
|
|
// they should have used beginGrowingFrame here:
|
|
|
|
(frame - (lastFrame / 2.0f + 4.0f)) / beginGrowingFrame)
|
|
|
|
* 0x4000)
|
|
|
|
* 4.0f
|
|
|
|
+ 1.0;
|
|
|
|
} else {
|
|
|
|
// Stay at 1.0f for a few frames.
|
|
|
|
scale = 1.0f;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Piranha Plant is no longer sleeping.
|
|
|
|
o->oAction++; // move to PIRANHA_PLANT_BUBBLE_ACT_BURST
|
|
|
|
}
|
|
|
|
} else {
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_disable_rendering();
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PIRANHA_PLANT_BUBBLE_ACT_BURST:
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_disable_rendering();
|
2019-08-25 04:46:40 +00:00
|
|
|
scale = 0;
|
|
|
|
|
|
|
|
// Spawn 15 small bubbles to make it look like this bubble burst.
|
|
|
|
for (i = 0; i < 15; i++) {
|
|
|
|
try_to_spawn_object(0, 1.0f, o, MODEL_BUBBLE, bhvPiranhaPlantWakingBubbles);
|
|
|
|
}
|
|
|
|
|
|
|
|
o->oAction = PIRANHA_PLANT_BUBBLE_ACT_IDLE;
|
|
|
|
scale = 1.0f; // this has no effect; it is set to 0 in the idle state
|
|
|
|
break;
|
|
|
|
}
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_scale(scale);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|