2019-08-25 04:46:40 +00:00
|
|
|
/**
|
|
|
|
* Behavior for bhvHiddenBlueCoin and bhvBlueCoinSwitch.
|
|
|
|
* bhvHiddenBlueCoin are the stationary blue coins that appear when
|
|
|
|
* you press a blue coin switch (a.k.a. bhvBlueCoinSwitch).
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update function for bhvHiddenBlueCoin.
|
|
|
|
*/
|
|
|
|
void bhv_hidden_blue_coin_loop(void) {
|
|
|
|
struct Object *blueCoinSwitch;
|
|
|
|
|
|
|
|
switch (o->oAction) {
|
|
|
|
case HIDDEN_BLUE_COIN_ACT_INACTIVE:
|
|
|
|
// Become invisible and intangible
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_disable_rendering();
|
|
|
|
cur_obj_become_intangible();
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
// Set action to HIDDEN_BLUE_COIN_ACT_WAITING after the blue coin switch is found.
|
2020-03-02 03:42:52 +00:00
|
|
|
o->oHiddenBlueCoinSwitch = cur_obj_nearest_object_with_behavior(bhvBlueCoinSwitch);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
if (o->oHiddenBlueCoinSwitch != NULL) {
|
|
|
|
o->oAction++;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
case HIDDEN_BLUE_COIN_ACT_WAITING:
|
|
|
|
// Wait until the blue coin switch starts ticking to activate.
|
|
|
|
blueCoinSwitch = o->oHiddenBlueCoinSwitch;
|
|
|
|
|
|
|
|
if (blueCoinSwitch->oAction == BLUE_COIN_SWITCH_ACT_TICKING) {
|
|
|
|
o->oAction++; // Set to HIDDEN_BLUE_COIN_ACT_ACTIVE
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
case HIDDEN_BLUE_COIN_ACT_ACTIVE:
|
|
|
|
// Become tangible
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_enable_rendering();
|
|
|
|
cur_obj_become_tangible();
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
// Delete the coin once collected
|
|
|
|
if (o->oInteractStatus & INT_STATUS_INTERACTED) {
|
|
|
|
spawn_object(o, MODEL_SPARKLES, bhvGoldenCoinSparkles);
|
2020-03-02 03:42:52 +00:00
|
|
|
obj_mark_for_deletion(o);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// After 200 frames of waiting and 20 2-frame blinks (for 240 frames total),
|
|
|
|
// delete the object.
|
2020-03-02 03:42:52 +00:00
|
|
|
if (cur_obj_wait_then_blink(200, 20)) {
|
|
|
|
obj_mark_for_deletion(o);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
o->oInteractStatus = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update function for bhvBlueCoinSwitch.
|
|
|
|
*/
|
|
|
|
void bhv_blue_coin_switch_loop(void) {
|
|
|
|
// The switch's model is 1/3 size.
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_scale(3.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
switch (o->oAction) {
|
|
|
|
case BLUE_COIN_SWITCH_ACT_IDLE:
|
|
|
|
// If Mario is on the switch and has ground-pounded,
|
|
|
|
// recede and get ready to start ticking.
|
|
|
|
if (gMarioObject->platform == o) {
|
|
|
|
if (gMarioStates->action == ACT_GROUND_POUND_LAND) {
|
|
|
|
// Set to BLUE_COIN_SWITCH_ACT_RECEDING
|
|
|
|
o->oAction++;
|
|
|
|
|
|
|
|
// Recede at a rate of 20 units/frame.
|
|
|
|
o->oVelY = -20.0f;
|
|
|
|
// Set gravity to 0 so it doesn't accelerate when receding.
|
|
|
|
o->oGravity = 0.0f;
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_play_sound_2(SOUND_GENERAL_SWITCH_DOOR_OPEN);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Have collision
|
|
|
|
load_object_collision_model();
|
|
|
|
|
|
|
|
break;
|
|
|
|
case BLUE_COIN_SWITCH_ACT_RECEDING:
|
|
|
|
// Recede for 6 frames before going invisible and ticking.
|
|
|
|
// This is probably an off-by-one error, since the switch is 100 units tall
|
|
|
|
// and recedes at 20 units/frame, which means it will fully recede after 5 frames.
|
|
|
|
if (o->oTimer > 5) {
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_hide();
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
// Set to BLUE_COIN_SWITCH_ACT_TICKING
|
|
|
|
o->oAction++;
|
|
|
|
// ???
|
|
|
|
o->oPosY = gMarioObject->oPosY - 40.0f;
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
// Spawn particles. There's a function that calls this same function
|
2020-03-02 03:42:52 +00:00
|
|
|
// with the same arguments, spawn_mist_particles, why didn't they just call that?
|
|
|
|
spawn_mist_particles_variable(0, 0, 46.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
} else {
|
|
|
|
// Have collision while receding
|
|
|
|
load_object_collision_model();
|
|
|
|
// Recede
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_move_using_fvel_and_gravity();
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
case BLUE_COIN_SWITCH_ACT_TICKING:
|
|
|
|
// Tick faster when the blue coins start blinking
|
|
|
|
if (o->oTimer < 200) {
|
2019-10-05 19:08:05 +00:00
|
|
|
play_sound(SOUND_GENERAL2_SWITCH_TICK_FAST, gDefaultSoundArgs);
|
2019-08-25 04:46:40 +00:00
|
|
|
} else {
|
2019-10-05 19:08:05 +00:00
|
|
|
play_sound(SOUND_GENERAL2_SWITCH_TICK_SLOW, gDefaultSoundArgs);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Delete the switch (which stops the sound) after the last coin is collected,
|
|
|
|
// or after the coins unload after the 240-frame timer expires.
|
2020-03-02 03:42:52 +00:00
|
|
|
if (cur_obj_nearest_object_with_behavior(bhvHiddenBlueCoin) == NULL || o->oTimer > 240) {
|
|
|
|
obj_mark_for_deletion(o);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|