2019-08-25 04:46:40 +00:00
|
|
|
// coin.c.inc
|
|
|
|
|
|
|
|
struct ObjectHitbox sYellowCoinHitbox = {
|
|
|
|
/* interactType: */ INTERACT_COIN,
|
|
|
|
/* downOffset: */ 0,
|
|
|
|
/* damageOrCoinValue: */ 1,
|
|
|
|
/* health: */ 0,
|
|
|
|
/* numLootCoins: */ 0,
|
|
|
|
/* radius: */ 100,
|
|
|
|
/* height: */ 64,
|
|
|
|
/* hurtboxRadius: */ 0,
|
|
|
|
/* hurtboxHeight: */ 0,
|
|
|
|
};
|
|
|
|
|
|
|
|
s16 D_8032F2A4[][2] = { { 0, -150 }, { 0, -50 }, { 0, 50 }, { 0, 150 },
|
|
|
|
{ -50, 100 }, { -100, 50 }, { 50, 100 }, { 100, 50 } };
|
|
|
|
|
|
|
|
s32 bhv_coin_sparkles_init(void) {
|
2020-04-03 18:57:26 +00:00
|
|
|
if (o->oInteractStatus & INT_STATUS_INTERACTED && !(o->oInteractStatus & INT_STATUS_TOUCHED_BOB_OMB)) {
|
2019-08-25 04:46:40 +00:00
|
|
|
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
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
o->oInteractStatus = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void bhv_yellow_coin_init(void) {
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_set_behavior(bhvYellowCoin);
|
|
|
|
obj_set_hitbox(o, &sYellowCoinHitbox);
|
2019-08-25 04:46:40 +00:00
|
|
|
bhv_init_room();
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_update_floor_height();
|
2019-08-25 04:46:40 +00:00
|
|
|
if (500.0f < absf(o->oPosY - o->oFloorHeight))
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_set_model(MODEL_YELLOW_COIN_NO_SHADOW);
|
2019-08-25 04:46:40 +00:00
|
|
|
if (o->oFloorHeight < -10000.0f)
|
2020-03-02 03:42:52 +00:00
|
|
|
obj_mark_for_deletion(o);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void bhv_yellow_coin_loop(void) {
|
|
|
|
bhv_coin_sparkles_init();
|
|
|
|
o->oAnimState++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void bhv_temp_coin_loop(void) {
|
|
|
|
o->oAnimState++;
|
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
|
|
|
bhv_coin_sparkles_init();
|
|
|
|
}
|
|
|
|
|
|
|
|
void bhv_coin_init(void) {
|
2020-04-03 18:57:26 +00:00
|
|
|
o->oVelY = random_float() * 10.0f + 30 + o->oCoinUnk110;
|
|
|
|
o->oForwardVel = random_float() * 10.0f;
|
|
|
|
o->oMoveAngleYaw = random_u16();
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_set_behavior(bhvYellowCoin);
|
|
|
|
obj_set_hitbox(o, &sYellowCoinHitbox);
|
|
|
|
cur_obj_become_intangible();
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void bhv_coin_loop(void) {
|
|
|
|
struct Surface *sp1C;
|
|
|
|
s16 sp1A;
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_update_floor_and_walls();
|
|
|
|
cur_obj_if_hit_wall_bounce_away();
|
|
|
|
cur_obj_move_standard(-62);
|
2019-08-25 04:46:40 +00:00
|
|
|
if ((sp1C = o->oFloor) != NULL) {
|
|
|
|
if (o->oMoveFlags & OBJ_MOVE_ON_GROUND)
|
|
|
|
o->oSubAction = 1;
|
|
|
|
if (o->oSubAction == 1) {
|
2020-04-03 18:57:26 +00:00
|
|
|
o->oBounciness = 0;
|
2019-08-25 04:46:40 +00:00
|
|
|
if (sp1C->normal.y < 0.9) {
|
|
|
|
sp1A = atan2s(sp1C->normal.z, sp1C->normal.x);
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_rotate_yaw_toward(sp1A, 0x400);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (o->oTimer == 0)
|
2020-02-03 05:51:26 +00:00
|
|
|
#ifdef VERSION_US
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_play_sound_2(SOUND_GENERAL_COIN_SPURT_2);
|
2020-02-03 05:51:26 +00:00
|
|
|
#elif VERSION_EU
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_play_sound_2(SOUND_GENERAL_COIN_SPURT_EU);
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_play_sound_2(SOUND_GENERAL_COIN_SPURT);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
if (o->oVelY < 0)
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_become_tangible();
|
2019-08-25 04:46:40 +00:00
|
|
|
if (o->oMoveFlags & OBJ_MOVE_LANDED) {
|
|
|
|
#ifndef VERSION_JP
|
|
|
|
if (o->oMoveFlags & (OBJ_MOVE_ABOVE_DEATH_BARRIER | OBJ_MOVE_ABOVE_LAVA))
|
|
|
|
#else
|
|
|
|
if (o->oMoveFlags & OBJ_MOVE_ABOVE_LAVA)
|
|
|
|
#endif
|
2020-03-02 03:42:52 +00:00
|
|
|
obj_mark_for_deletion(o);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
#ifndef VERSION_JP
|
|
|
|
if (o->oMoveFlags & OBJ_MOVE_13) {
|
2019-10-05 19:08:05 +00:00
|
|
|
if (o->oCoinUnk1B0 < 5)
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_play_sound_2(0x30364081);
|
2019-10-05 19:08:05 +00:00
|
|
|
o->oCoinUnk1B0++;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
#else
|
|
|
|
if (o->oMoveFlags & OBJ_MOVE_13)
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_play_sound_2(SOUND_GENERAL_COIN_DROP);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2020-03-02 03:42:52 +00:00
|
|
|
if (cur_obj_wait_then_blink(400, 20))
|
|
|
|
obj_mark_for_deletion(o);
|
2019-08-25 04:46:40 +00:00
|
|
|
bhv_coin_sparkles_init();
|
|
|
|
}
|
|
|
|
|
|
|
|
void bhv_coin_formation_spawn_loop(void) {
|
|
|
|
if (o->oTimer == 0) {
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_set_behavior(bhvYellowCoin);
|
|
|
|
obj_set_hitbox(o, &sYellowCoinHitbox);
|
2019-08-25 04:46:40 +00:00
|
|
|
bhv_init_room();
|
2019-10-05 19:08:05 +00:00
|
|
|
if (o->oCoinUnkF8) {
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oPosY += 300.0f;
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_update_floor_height();
|
2019-08-25 04:46:40 +00:00
|
|
|
if (o->oPosY < o->oFloorHeight || o->oFloorHeight < -10000.0f)
|
2020-03-02 03:42:52 +00:00
|
|
|
obj_mark_for_deletion(o);
|
2019-08-25 04:46:40 +00:00
|
|
|
else
|
|
|
|
o->oPosY = o->oFloorHeight;
|
|
|
|
} else {
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_update_floor_height();
|
2019-08-25 04:46:40 +00:00
|
|
|
if (absf(o->oPosY - o->oFloorHeight) > 250.0f)
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_set_model(MODEL_YELLOW_COIN_NO_SHADOW);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (bhv_coin_sparkles_init())
|
2020-03-02 03:42:52 +00:00
|
|
|
o->parentObj->oCoinUnkF4 |= bit_shift_left(o->oBehParams2ndByte);
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oAnimState++;
|
|
|
|
}
|
|
|
|
if (o->parentObj->oAction == 2)
|
2020-03-02 03:42:52 +00:00
|
|
|
obj_mark_for_deletion(o);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
void spawn_coin_in_formation(s32 sp50, s32 sp54) {
|
2019-08-25 04:46:40 +00:00
|
|
|
struct Object *sp4C;
|
|
|
|
Vec3i sp40;
|
|
|
|
s32 sp3C = 1;
|
|
|
|
s32 sp38 = 1;
|
|
|
|
UNUSED s32 unused;
|
|
|
|
sp40[2] = 0;
|
|
|
|
sp40[0] = (sp40[1] = sp40[2]);
|
|
|
|
switch (sp54 & 7) {
|
|
|
|
case 0:
|
|
|
|
sp40[2] = 160 * (sp50 - 2);
|
|
|
|
if (sp50 > 4)
|
|
|
|
sp3C = 0;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
sp38 = 0;
|
|
|
|
sp40[1] = 160 * sp50 * 0.8; // 128 * sp50
|
|
|
|
if (sp50 > 4)
|
|
|
|
sp3C = 0;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
sp40[0] = sins(sp50 << 13) * 300.0f;
|
|
|
|
sp40[2] = coss(sp50 << 13) * 300.0f;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
sp38 = 0;
|
|
|
|
sp40[0] = coss(sp50 << 13) * 200.0f;
|
|
|
|
sp40[1] = sins(sp50 << 13) * 200.0f + 200.0f;
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
sp40[0] = D_8032F2A4[sp50][0];
|
|
|
|
sp40[2] = D_8032F2A4[sp50][1];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (sp54 & 0x10)
|
|
|
|
sp38 = 0;
|
|
|
|
if (sp3C) {
|
|
|
|
sp4C = spawn_object_relative(sp50, sp40[0], sp40[1], sp40[2], o, MODEL_YELLOW_COIN,
|
|
|
|
bhvCoinFormationSpawn);
|
2019-10-05 19:08:05 +00:00
|
|
|
sp4C->oCoinUnkF8 = sp38;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void bhv_coin_formation_init(void) {
|
2019-10-05 19:08:05 +00:00
|
|
|
o->oCoinUnkF4 = (o->oBehParams >> 8) & 0xFF;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void bhv_coin_formation_loop(void) {
|
|
|
|
s32 bitIndex;
|
|
|
|
switch (o->oAction) {
|
|
|
|
case 0:
|
|
|
|
if (o->oDistanceToMario < 2000.0f) {
|
|
|
|
for (bitIndex = 0; bitIndex < 8; bitIndex++) {
|
2019-10-05 19:08:05 +00:00
|
|
|
if (!(o->oCoinUnkF4 & (1 << bitIndex)))
|
2020-03-02 03:42:52 +00:00
|
|
|
spawn_coin_in_formation(bitIndex, o->oBehParams2ndByte);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
o->oAction++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
if (o->oDistanceToMario > 2100.0f)
|
|
|
|
o->oAction++;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
o->oAction = 0;
|
|
|
|
break;
|
|
|
|
}
|
2019-10-05 19:08:05 +00:00
|
|
|
|
|
|
|
// Casting to u8 doesn't seem to match
|
|
|
|
set_object_respawn_info_bits(o, o->oCoinUnkF4 & 0xFF);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
void coin_inside_boo_act_1(void) {
|
|
|
|
cur_obj_update_floor_and_walls();
|
|
|
|
cur_obj_if_hit_wall_bounce_away();
|
2019-08-25 04:46:40 +00:00
|
|
|
if (o->oMoveFlags & OBJ_MOVE_13)
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_play_sound_2(SOUND_GENERAL_COIN_DROP);
|
2019-08-25 04:46:40 +00:00
|
|
|
if (o->oTimer > 90 || (o->oMoveFlags & OBJ_MOVE_LANDED)) {
|
2020-03-02 03:42:52 +00:00
|
|
|
obj_set_hitbox(o, &sYellowCoinHitbox);
|
|
|
|
cur_obj_become_tangible();
|
|
|
|
cur_obj_set_behavior(bhvYellowCoin);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_move_standard(-30);
|
2019-08-25 04:46:40 +00:00
|
|
|
bhv_coin_sparkles_init();
|
2020-03-02 03:42:52 +00:00
|
|
|
if (cur_obj_has_model(MODEL_BLUE_COIN))
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oDamageOrCoinValue = 5;
|
2020-03-02 03:42:52 +00:00
|
|
|
if (cur_obj_wait_then_blink(400, 20))
|
|
|
|
obj_mark_for_deletion(o);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
void coin_inside_boo_act_0(void) {
|
2019-08-25 04:46:40 +00:00
|
|
|
s16 sp26;
|
|
|
|
f32 sp20;
|
|
|
|
struct Object *parent = o->parentObj;
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_become_intangible();
|
2019-08-25 04:46:40 +00:00
|
|
|
if (o->oTimer == 0 && gCurrLevelNum == LEVEL_BBH) {
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_set_model(MODEL_BLUE_COIN);
|
|
|
|
cur_obj_scale(0.7);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
2020-03-02 03:42:52 +00:00
|
|
|
obj_copy_pos(o, parent);
|
2019-08-25 04:46:40 +00:00
|
|
|
if (parent->oBooDeathStatus == BOO_DEATH_STATUS_DYING) {
|
|
|
|
o->oAction = 1;
|
|
|
|
sp26 = gMarioObject->oMoveAngleYaw;
|
|
|
|
sp20 = 3.0f;
|
|
|
|
o->oVelX = sins(sp26) * sp20;
|
|
|
|
o->oVelZ = coss(sp26) * sp20;
|
|
|
|
o->oVelY = 35.0f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
void (*sCoinInsideBooActions[])(void) = { coin_inside_boo_act_0, coin_inside_boo_act_1 };
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
void bhv_coin_inside_boo_loop(void) {
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_call_action_function(sCoinInsideBooActions);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void bhv_coin_sparkles_loop(void) {
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_scale(0.6f);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void bhv_golden_coin_sparkles_loop(void) {
|
|
|
|
struct Object *sp2C;
|
|
|
|
UNUSED s32 unused;
|
|
|
|
f32 sp24 = 30.0f;
|
|
|
|
sp2C = spawn_object(o, MODEL_SPARKLES, bhvCoinSparkles);
|
2020-04-03 18:57:26 +00:00
|
|
|
sp2C->oPosX += random_float() * sp24 - sp24 / 2;
|
|
|
|
sp2C->oPosZ += random_float() * sp24 - sp24 / 2;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|