2019-08-25 04:46:40 +00:00
|
|
|
// mr_i.c.inc
|
|
|
|
|
|
|
|
// this is actually the MrI particle loop function. piranha
|
|
|
|
// plant code later on reuses this function.
|
|
|
|
void bhv_piranha_particle_loop(void) {
|
|
|
|
if (o->oTimer == 0) {
|
2020-04-03 18:57:26 +00:00
|
|
|
o->oVelY = 20.0f + 20.0f * random_float();
|
|
|
|
o->oForwardVel = 20.0f + 20.0f * random_float();
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
void mr_i_piranha_particle_act_0(void) {
|
|
|
|
cur_obj_scale(3.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oForwardVel = 20.0f;
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_update_floor_and_walls();
|
2019-08-25 04:46:40 +00:00
|
|
|
if (0x8000 & o->oInteractStatus)
|
|
|
|
o->oAction = 1;
|
2020-06-02 16:44:34 +00:00
|
|
|
else if ((o->oTimer >= 101) || (0x200 & o->oMoveFlags) || o->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM) {
|
2020-03-02 03:42:52 +00:00
|
|
|
obj_mark_for_deletion(o);
|
|
|
|
spawn_mist_particles();
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
void mr_i_piranha_particle_act_1(void) {
|
2019-08-25 04:46:40 +00:00
|
|
|
s32 i;
|
2020-03-02 03:42:52 +00:00
|
|
|
obj_mark_for_deletion(o);
|
2019-08-25 04:46:40 +00:00
|
|
|
for (i = 0; i < 10; i++)
|
|
|
|
spawn_object(o, MODEL_PURPLE_MARBLE, bhvPurpleParticle);
|
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
void (*sMrIParticleActions[])(void) = { mr_i_piranha_particle_act_0, mr_i_piranha_particle_act_1 };
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
void bhv_mr_i_particle_loop(void) {
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_call_action_function(sMrIParticleActions);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
void spawn_mr_i_particle(void) {
|
2019-08-25 04:46:40 +00:00
|
|
|
struct Object *particle;
|
|
|
|
f32 sp18 = o->header.gfx.scale[1];
|
|
|
|
particle = spawn_object(o, MODEL_PURPLE_MARBLE, bhvMrIParticle);
|
|
|
|
particle->oPosY += 50.0f * sp18;
|
|
|
|
particle->oPosX += sins(o->oMoveAngleYaw) * 90.0f * sp18;
|
|
|
|
particle->oPosZ += coss(o->oMoveAngleYaw) * 90.0f * sp18;
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_play_sound_2(SOUND_OBJ_MRI_SHOOT);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void bhv_mr_i_body_loop(void) {
|
2020-03-02 03:42:52 +00:00
|
|
|
obj_copy_pos_and_angle(o, o->parentObj);
|
2020-06-02 16:44:34 +00:00
|
|
|
if (!(o->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) {
|
2020-03-02 03:42:52 +00:00
|
|
|
obj_copy_scale(o, o->parentObj);
|
|
|
|
obj_set_parent_relative_pos(o, 0, 0, o->header.gfx.scale[1] * 100.0f);
|
|
|
|
obj_build_transform_from_pos_and_angle(o, 44, 15);
|
|
|
|
obj_translate_local(o, 6, 44);
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oFaceAnglePitch = o->oMoveAnglePitch;
|
|
|
|
o->oGraphYOffset = o->header.gfx.scale[1] * 100.f;
|
|
|
|
}
|
2019-10-05 19:08:05 +00:00
|
|
|
if (o->parentObj->oMrIUnk110 != 1)
|
|
|
|
o->oAnimState = -1;
|
2019-08-25 04:46:40 +00:00
|
|
|
else {
|
2019-10-05 19:08:05 +00:00
|
|
|
o->oAnimState++;
|
|
|
|
if (o->oAnimState == 15)
|
|
|
|
o->parentObj->oMrIUnk110 = 0;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
2020-06-02 16:44:34 +00:00
|
|
|
if (o->parentObj->activeFlags == ACTIVE_FLAG_DEACTIVATED)
|
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 mr_i_act_3(void) {
|
2019-08-25 04:46:40 +00:00
|
|
|
s16 sp36;
|
|
|
|
s16 sp34;
|
|
|
|
f32 sp30;
|
|
|
|
f32 sp2C;
|
|
|
|
UNUSED u8 pad[8];
|
|
|
|
f32 sp20;
|
|
|
|
f32 sp1C;
|
|
|
|
if (o->oBehParams2ndByte)
|
|
|
|
sp1C = 2.0f;
|
|
|
|
else
|
|
|
|
sp1C = 1.0f;
|
2019-10-05 19:08:05 +00:00
|
|
|
if (o->oMrIUnk100 < 0)
|
2019-08-25 04:46:40 +00:00
|
|
|
sp34 = 0x1000;
|
|
|
|
else
|
|
|
|
sp34 = -0x1000;
|
|
|
|
sp2C = (o->oTimer + 1) / 96.0f;
|
|
|
|
if (o->oTimer < 64) {
|
|
|
|
sp36 = o->oMoveAngleYaw;
|
|
|
|
o->oMoveAngleYaw += sp34 * coss(0x4000 * sp2C);
|
|
|
|
if (sp36 < 0 && o->oMoveAngleYaw >= 0)
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_play_sound_2(SOUND_OBJ2_MRI_SPINNING);
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oMoveAnglePitch = (1.0 - coss(0x4000 * sp2C)) * -0x4000;
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_shake_y(4.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
} else if (o->oTimer < 96) {
|
|
|
|
if (o->oTimer == 64)
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_play_sound_2(SOUND_OBJ_MRI_DEATH);
|
2019-08-25 04:46:40 +00:00
|
|
|
sp30 = (f32)(o->oTimer - 63) / 32;
|
|
|
|
o->oMoveAngleYaw += sp34 * coss(0x4000 * sp2C);
|
|
|
|
o->oMoveAnglePitch = (1.0 - coss(0x4000 * sp2C)) * -0x4000;
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_shake_y((s32)((1.0f - sp30) * 4)); // trucating the f32?
|
2019-08-25 04:46:40 +00:00
|
|
|
sp20 = coss(0x4000 * sp30) * 0.4 + 0.6;
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_scale(sp20 * sp1C);
|
2019-08-25 04:46:40 +00:00
|
|
|
} else if (o->oTimer < 104) {
|
2019-10-05 19:08:05 +00:00
|
|
|
// do nothing
|
|
|
|
} else if (o->oTimer < 168) {
|
2019-08-25 04:46:40 +00:00
|
|
|
if (o->oTimer == 104) {
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_become_intangible();
|
|
|
|
spawn_mist_particles();
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oMrISize = sp1C * 0.6;
|
|
|
|
if (o->oBehParams2ndByte) {
|
|
|
|
o->oPosY += 100.0f;
|
2020-03-02 03:42:52 +00:00
|
|
|
spawn_default_star(1370, 2000.0f, -320.0f);
|
|
|
|
obj_mark_for_deletion(o);
|
2019-08-25 04:46:40 +00:00
|
|
|
} else
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_spawn_loot_blue_coin();
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
o->oMrISize -= 0.2 * sp1C;
|
|
|
|
if (o->oMrISize < 0)
|
|
|
|
o->oMrISize = 0;
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_scale(o->oMrISize);
|
2019-08-25 04:46:40 +00:00
|
|
|
} else
|
2020-03-02 03:42:52 +00:00
|
|
|
obj_mark_for_deletion(o);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2020-06-02 16:44:34 +00:00
|
|
|
void mr_i_act_2(void) {
|
2019-08-25 04:46:40 +00:00
|
|
|
s16 sp1E;
|
|
|
|
s16 sp1C;
|
|
|
|
sp1E = o->oMoveAngleYaw;
|
|
|
|
if (o->oTimer == 0) {
|
|
|
|
if (o->oBehParams2ndByte)
|
2019-10-05 19:08:05 +00:00
|
|
|
o->oMrIUnkF4 = 200;
|
2019-08-25 04:46:40 +00:00
|
|
|
else
|
2019-10-05 19:08:05 +00:00
|
|
|
o->oMrIUnkF4 = 120;
|
|
|
|
o->oMrIUnkFC = 0;
|
|
|
|
o->oMrIUnk100 = 0;
|
|
|
|
o->oMrIUnk104 = 0;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
obj_turn_toward_object(o, gMarioObject, 0x10, 0x800);
|
|
|
|
obj_turn_toward_object(o, gMarioObject, 0x0F, 0x400);
|
|
|
|
sp1C = sp1E - (s16)(o->oMoveAngleYaw);
|
|
|
|
if (!sp1C) {
|
2019-10-05 19:08:05 +00:00
|
|
|
o->oMrIUnkFC = 0;
|
|
|
|
o->oMrIUnk100 = 0;
|
2019-08-25 04:46:40 +00:00
|
|
|
} else if (sp1C > 0) {
|
2019-10-05 19:08:05 +00:00
|
|
|
if (o->oMrIUnk100 > 0)
|
|
|
|
o->oMrIUnkFC += sp1C;
|
2019-08-25 04:46:40 +00:00
|
|
|
else
|
2019-10-05 19:08:05 +00:00
|
|
|
o->oMrIUnkFC = 0;
|
|
|
|
o->oMrIUnk100 = 1;
|
2019-08-25 04:46:40 +00:00
|
|
|
} else {
|
2019-10-05 19:08:05 +00:00
|
|
|
if (o->oMrIUnk100 < 0)
|
|
|
|
o->oMrIUnkFC -= sp1C;
|
2019-08-25 04:46:40 +00:00
|
|
|
else
|
2019-10-05 19:08:05 +00:00
|
|
|
o->oMrIUnkFC = 0;
|
|
|
|
o->oMrIUnk100 = -1;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
2019-10-05 19:08:05 +00:00
|
|
|
if (!o->oMrIUnkFC)
|
|
|
|
o->oMrIUnkF4 = 120;
|
|
|
|
if (o->oMrIUnkFC > 1 << 16)
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oAction = 3;
|
2019-10-05 19:08:05 +00:00
|
|
|
o->oMrIUnkF4 -= 1;
|
|
|
|
if (!o->oMrIUnkF4) {
|
|
|
|
o->oMrIUnkF4 = 120;
|
|
|
|
o->oMrIUnkFC = 0;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
2019-10-05 19:08:05 +00:00
|
|
|
if (o->oMrIUnkFC < 5000) {
|
|
|
|
if (o->oMrIUnk104 == o->oMrIUnk108)
|
|
|
|
o->oMrIUnk110 = 1;
|
|
|
|
if (o->oMrIUnk104 == o->oMrIUnk108 + 20) {
|
2020-03-02 03:42:52 +00:00
|
|
|
spawn_mr_i_particle();
|
2019-10-05 19:08:05 +00:00
|
|
|
o->oMrIUnk104 = 0;
|
2020-04-03 18:57:26 +00:00
|
|
|
o->oMrIUnk108 = (s32)(random_float() * 50.0f + 50.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
2019-10-05 19:08:05 +00:00
|
|
|
o->oMrIUnk104++;
|
2019-08-25 04:46:40 +00:00
|
|
|
} else {
|
2019-10-05 19:08:05 +00:00
|
|
|
o->oMrIUnk104 = 0;
|
2020-04-03 18:57:26 +00:00
|
|
|
o->oMrIUnk108 = (s32)(random_float() * 50.0f + 50.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
if (o->oDistanceToMario > 800.0f)
|
|
|
|
o->oAction = 1;
|
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
void mr_i_act_1(void) {
|
2019-08-25 04:46:40 +00:00
|
|
|
s16 sp1E;
|
|
|
|
s16 sp1C;
|
|
|
|
s16 sp1A;
|
2020-03-02 03:42:52 +00:00
|
|
|
sp1E = obj_angle_to_object(o, gMarioObject);
|
2019-08-25 04:46:40 +00:00
|
|
|
sp1C = abs_angle_diff(o->oMoveAngleYaw, sp1E);
|
|
|
|
sp1A = abs_angle_diff(o->oMoveAngleYaw, gMarioObject->oFaceAngleYaw);
|
|
|
|
if (o->oTimer == 0) {
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_become_tangible();
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oMoveAnglePitch = 0;
|
2019-10-05 19:08:05 +00:00
|
|
|
o->oMrIUnk104 = 30;
|
2020-04-03 18:57:26 +00:00
|
|
|
o->oMrIUnk108 = random_float() * 20.0f;
|
2019-10-05 19:08:05 +00:00
|
|
|
if (o->oMrIUnk108 & 1)
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oAngleVelYaw = -256;
|
|
|
|
else
|
|
|
|
o->oAngleVelYaw = 256;
|
|
|
|
}
|
|
|
|
if (sp1C < 1024 && sp1A > 0x4000) {
|
|
|
|
if (o->oDistanceToMario < 700.0f)
|
|
|
|
o->oAction = 2;
|
|
|
|
else
|
2019-10-05 19:08:05 +00:00
|
|
|
o->oMrIUnk104++;
|
2019-08-25 04:46:40 +00:00
|
|
|
} else {
|
|
|
|
o->oMoveAngleYaw += o->oAngleVelYaw;
|
2019-10-05 19:08:05 +00:00
|
|
|
o->oMrIUnk104 = 30;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
2019-10-05 19:08:05 +00:00
|
|
|
if (o->oMrIUnk104 == o->oMrIUnk108 + 60)
|
|
|
|
o->oMrIUnk110 = 1;
|
|
|
|
if (o->oMrIUnk108 + 80 < o->oMrIUnk104) {
|
|
|
|
o->oMrIUnk104 = 0;
|
2020-04-03 18:57:26 +00:00
|
|
|
o->oMrIUnk108 = random_float() * 80.0f;
|
2020-03-02 03:42:52 +00:00
|
|
|
spawn_mr_i_particle();
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
void mr_i_act_0(void) {
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifndef VERSION_JP
|
2020-03-02 03:42:52 +00:00
|
|
|
obj_set_angle(o, 0, 0, 0);
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
|
|
|
o->oMoveAnglePitch = 0;
|
|
|
|
o->oMoveAngleYaw = 0;
|
|
|
|
o->oMoveAngleRoll = 0;
|
|
|
|
#endif
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_scale(o->oBehParams2ndByte + 1);
|
2019-08-25 04:46:40 +00:00
|
|
|
if (o->oTimer == 0)
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_set_pos_to_home();
|
2019-08-25 04:46:40 +00:00
|
|
|
if (o->oDistanceToMario < 1500.0f)
|
|
|
|
o->oAction = 1;
|
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
void (*sMrIActions[])(void) = { mr_i_act_0, mr_i_act_1, mr_i_act_2, mr_i_act_3 };
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
struct ObjectHitbox sMrIHitbox = {
|
|
|
|
/* interactType: */ INTERACT_DAMAGE,
|
|
|
|
/* downOffset: */ 0,
|
|
|
|
/* damageOrCoinValue: */ 2,
|
|
|
|
/* health: */ 2,
|
|
|
|
/* numLootCoins: */ 5,
|
|
|
|
/* radius: */ 80,
|
|
|
|
/* height: */ 150,
|
|
|
|
/* hurtboxRadius: */ 0,
|
|
|
|
/* hurtboxHeight: */ 0,
|
|
|
|
};
|
|
|
|
|
|
|
|
void bhv_mr_i_loop(void) {
|
2020-03-02 03:42:52 +00:00
|
|
|
obj_set_hitbox(o, &sMrIHitbox);
|
|
|
|
cur_obj_call_action_function(sMrIActions);
|
2019-08-25 04:46:40 +00:00
|
|
|
if (o->oAction != 3)
|
2020-06-02 16:44:34 +00:00
|
|
|
if (o->oDistanceToMario > 3000.0f || o->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oAction = 0;
|
|
|
|
o->oInteractStatus = 0;
|
|
|
|
}
|