Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding documentation to Mr I's Logic #97

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions include/object_fields.h
Original file line number Diff line number Diff line change
Expand Up @@ -710,13 +710,13 @@
#define /*0x1AC*/ oMrBlizzardTargetMoveYaw OBJECT_FIELD_S32(0x49)

/* Mr. I */
#define /*0x0F4*/ oMrIUnkF4 OBJECT_FIELD_S32(0x1B)
#define /*0x0FC*/ oMrIUnkFC OBJECT_FIELD_S32(0x1D)
#define /*0x100*/ oMrIUnk100 OBJECT_FIELD_S32(0x1E)
#define /*0x104*/ oMrIUnk104 OBJECT_FIELD_S32(0x1F)
#define /*0x108*/ oMrIUnk108 OBJECT_FIELD_S32(0x20)
#define /*0x0F4*/ oMrITurnCountdown OBJECT_FIELD_S32(0x1B)
#define /*0x0FC*/ oMrITurnDistance OBJECT_FIELD_S32(0x1D)
#define /*0x100*/ oMrITurnDirection OBJECT_FIELD_S32(0x1E)
#define /*0x104*/ oMrIShotTimer OBJECT_FIELD_S32(0x1F)
#define /*0x108*/ oMrIShotTimerMax OBJECT_FIELD_S32(0x20)
#define /*0x10C*/ oMrIScale OBJECT_FIELD_F32(0x21)
#define /*0x110*/ oMrIUnk110 OBJECT_FIELD_S32(0x22)
#define /*0x110*/ oMrIBlinking OBJECT_FIELD_S32(0x22)

/* Object Respawner */
#define /*0x0F4*/ oRespawnerModelToRespawn OBJECT_FIELD_S32(0x1B)
Expand Down
165 changes: 85 additions & 80 deletions src/game/behaviors/mr_i.inc.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,13 @@ void bhv_mr_i_particle_loop(void) {

void spawn_mr_i_particle(void) {
struct Object *particle;
f32 sp18 = o->header.gfx.scale[1];
f32 mr_i_size = o->header.gfx.scale[1];

// sets particle spawn point to 50u above Mr I and 90u forwards
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;
particle->oPosY += 50.0f * mr_i_size;
particle->oPosX += sins(o->oMoveAngleYaw) * 90.0f * mr_i_size;
particle->oPosZ += coss(o->oMoveAngleYaw) * 90.0f * mr_i_size;

cur_obj_play_sound_2(SOUND_OBJ_MRI_SHOOT);
}
Expand All @@ -71,7 +72,7 @@ void bhv_mr_i_body_loop(void) {
} else {
o->oAnimState++;
if (o->oAnimState == 15) {
o->parentObj->oMrIUnk110 = 0;
o->parentObj->oMrITurnDirection = 0;
}
}

Expand All @@ -80,58 +81,59 @@ void bhv_mr_i_body_loop(void) {
}
}

// death action
void mr_i_act_3(void) {
s16 sp36;
s16 sp34;
f32 sp30;
f32 sp2C;
s16 move_angle_yaw;
s16 turn_direction_factor;
f32 scale_factor;
f32 turning_speed;
UNUSED u8 filler[8];
f32 sp20;
f32 sp1C;
f32 scale;
f32 big_mr_i_factor;

if (o->oBhvParams2ndByte != 0) {
sp1C = 2.0f;
big_mr_i_factor = 2.0f;
} else {
sp1C = 1.0f;
big_mr_i_factor = 1.0f;
}

if (o->oMrIUnk100 < 0) {
sp34 = 0x1000;
if (o->oMrITurnDirection < 0) {
turn_direction_factor = 0x1000;
} else {
sp34 = -0x1000;
turn_direction_factor = -0x1000;
}

sp2C = (o->oTimer + 1) / 96.0f;
turning_speed = (o->oTimer + 1) / 96.0f;

if (o->oTimer < 64) {
sp36 = o->oMoveAngleYaw;
o->oMoveAngleYaw += sp34 * coss(0x4000 * sp2C);
move_angle_yaw = o->oMoveAngleYaw;
o->oMoveAngleYaw += turn_direction_factor * coss(0x4000 * turning_speed);

if (sp36 < 0 && o->oMoveAngleYaw >= 0) {
if (move_angle_yaw < 0 && o->oMoveAngleYaw >= 0) {
cur_obj_play_sound_2(SOUND_OBJ2_MRI_SPINNING);
}

o->oMoveAnglePitch = (1.0 - coss(0x4000 * sp2C)) * -0x4000;
o->oMoveAnglePitch = (1.0 - coss(0x4000 * turning_speed)) * -0x4000;
cur_obj_shake_y(4.0f);
} else if (o->oTimer < 96) {
if (o->oTimer == 64) {
cur_obj_play_sound_2(SOUND_OBJ_MRI_DEATH);
}

sp30 = (f32)(o->oTimer - 63) / 32;
o->oMoveAngleYaw += sp34 * coss(0x4000 * sp2C);
o->oMoveAnglePitch = (1.0 - coss(0x4000 * sp2C)) * -0x4000;
scale_factor = (f32)(o->oTimer - 63) / 32;
o->oMoveAngleYaw += turn_direction_factor * coss(0x4000 * turning_speed);
o->oMoveAnglePitch = (1.0 - coss(0x4000 * turning_speed)) * -0x4000;

cur_obj_shake_y((s32)((1.0f - sp30) * 4)); // trucating the f32?
sp20 = coss(0x4000 * sp30) * 0.4 + 0.6;
cur_obj_scale(sp20 * sp1C);
cur_obj_shake_y((s32)((1.0f - scale_factor) * 4)); // trucating the f32?
scale = coss(0x4000 * scale_factor) * 0.4 + 0.6;
cur_obj_scale(scale * big_mr_i_factor);
} else if (o->oTimer < 104) {
// do nothing
} else if (o->oTimer < 168) {
if (o->oTimer == 104) {
cur_obj_become_intangible();
spawn_mist_particles();
o->oMrIScale = sp1C * 0.6;
o->oMrIScale = big_mr_i_factor * 0.6;
if (o->oBhvParams2ndByte != 0) {
o->oPosY += 100.0f;
spawn_default_star(1370, 2000.0f, -320.0f);
Expand All @@ -141,7 +143,7 @@ void mr_i_act_3(void) {
}
}

o->oMrIScale -= 0.2 * sp1C;
o->oMrIScale -= 0.2 * big_mr_i_factor;

if (o->oMrIScale < 0) {
o->oMrIScale = 0;
Expand All @@ -153,119 +155,122 @@ void mr_i_act_3(void) {
}
}

// locked onto Mario action
void mr_i_act_2(void) {
s16 sp1E = o->oMoveAngleYaw;
s16 sp1C;
s16 move_angle_yaw = o->oMoveAngleYaw;
s16 move_angle_delta;

if (o->oTimer == 0) {
if (o->oBhvParams2ndByte != 0) {
o->oMrIUnkF4 = 200;
o->oMrITurnCountdown = 200;
} else {
o->oMrIUnkF4 = 120;
o->oMrITurnCountdown = 120;
}
o->oMrIUnkFC = 0;
o->oMrIUnk100 = 0;
o->oMrIUnk104 = 0;
o->oMrITurnDistance = 0;
o->oMrITurnDirection = 0;
o->oMrIShotTimer = 0;
}

obj_turn_toward_object(o, gMarioObject, 0x10, 0x800);
obj_turn_toward_object(o, gMarioObject, 0x0F, 0x400);
obj_turn_toward_object(o, gMarioObject, O_MOVE_ANGLE_YAW_INDEX, 0x800);
obj_turn_toward_object(o, gMarioObject, O_MOVE_ANGLE_PITCH_INDEX, 0x400);

sp1C = sp1E - (s16)(o->oMoveAngleYaw);
move_angle_delta = move_angle_yaw - (s16)(o->oMoveAngleYaw);

if (sp1C == 0) {
o->oMrIUnkFC = 0;
o->oMrIUnk100 = 0;
} else if (sp1C > 0) {
if (o->oMrIUnk100 > 0) {
o->oMrIUnkFC += sp1C;
if (move_angle_delta == 0) {
o->oMrITurnDistance = 0;
o->oMrITurnDirection = 0;
} else if (move_angle_delta > 0) {
if (o->oMrITurnDirection > 0) {
o->oMrITurnDistance += move_angle_delta;
} else {
o->oMrIUnkFC = 0;
o->oMrITurnDistance = 0;
}
o->oMrIUnk100 = 1;
o->oMrITurnDirection = 1;
} else {
if (o->oMrIUnk100 < 0) {
o->oMrIUnkFC -= sp1C;
if (o->oMrITurnDirection < 0) {
o->oMrITurnDistance -= move_angle_delta;
} else {
o->oMrIUnkFC = 0;
o->oMrITurnDistance = 0;
}
o->oMrIUnk100 = -1;
o->oMrITurnDirection = -1;
}

if (o->oMrIUnkFC == 0) {
o->oMrIUnkF4 = 120;
if (o->oMrITurnDistance == 0) {
o->oMrITurnCountdown = 120;
}
if (o->oMrIUnkFC > 65536) {
if (o->oMrITurnDistance > 65536) {
o->oAction = 3;
}

o->oMrIUnkF4--;
o->oMrITurnCountdown--;

if (o->oMrIUnkF4 == 0) {
o->oMrIUnkF4 = 120;
o->oMrIUnkFC = 0;
if (o->oMrITurnCountdown == 0) {
o->oMrITurnCountdown = 120;
o->oMrITurnDistance = 0;
}

if (o->oMrIUnkFC < 5000) {
if (o->oMrIUnk104 == o->oMrIUnk108) {
o->oMrIUnk110 = 1;
if (o->oMrITurnDistance < 5000) {
if (o->oMrIShotTimer == o->oMrIShotTimerMax) {
o->oMrIBlinking = 1;
}

if (o->oMrIUnk104 == o->oMrIUnk108 + 20) {
if (o->oMrIShotTimer == o->oMrIShotTimerMax + 20) {
spawn_mr_i_particle();
o->oMrIUnk104 = 0;
o->oMrIUnk108 = (s32)(random_float() * 50.0f + 50.0f);
o->oMrIShotTimer = 0;
o->oMrIShotTimerMax = (s32)(random_float() * 50.0f + 50.0f);
}
o->oMrIUnk104++;
o->oMrIShotTimer++;
} else {
o->oMrIUnk104 = 0;
o->oMrIUnk108 = (s32)(random_float() * 50.0f + 50.0f);
o->oMrIShotTimer = 0;
o->oMrIShotTimerMax = (s32)(random_float() * 50.0f + 50.0f);
}

if (o->oDistanceToMario > 800.0f) {
o->oAction = 1;
}
}

// casually turning around action
void mr_i_act_1(void) {
s16 sp1E = obj_angle_to_object(o, gMarioObject);
s16 sp1C = abs_angle_diff(o->oMoveAngleYaw, sp1E);
s16 sp1A = abs_angle_diff(o->oMoveAngleYaw, gMarioObject->oFaceAngleYaw);
s16 angle_to_mario = obj_angle_to_object(o, gMarioObject);
s16 angle_to_mario_diff = abs_angle_diff(o->oMoveAngleYaw, angle_to_mario);
s16 eye_contact_diff = abs_angle_diff(o->oMoveAngleYaw, gMarioObject->oFaceAngleYaw);

if (o->oTimer == 0) {
cur_obj_become_tangible();
o->oMoveAnglePitch = 0;
o->oMrIUnk104 = 30;
o->oMrIUnk108 = random_float() * 20.0f;
if (o->oMrIUnk108 & 1) {
o->oMrIShotTimer = 30;
o->oMrIShotTimerMax = random_float() * 20.0f;
if (o->oMrIShotTimerMax & 1) {
o->oAngleVelYaw = -256;
} else {
o->oAngleVelYaw = 256;
}
}

if (sp1C < 1024 && sp1A > 0x4000) {
if (angle_to_mario_diff < 1024 && eye_contact_diff > 0x4000) {
if (o->oDistanceToMario < 700.0f) {
o->oAction = 2;
} else {
o->oMrIUnk104++;
o->oMrIShotTimer++;
}
} else {
o->oMoveAngleYaw += o->oAngleVelYaw;
o->oMrIUnk104 = 30;
o->oMrIShotTimer = 30;
}

if (o->oMrIUnk104 == o->oMrIUnk108 + 60) {
if (o->oMrIShotTimer == o->oMrIShotTimerMax + 60) {
o->oMrIUnk110 = 1;
}

if (o->oMrIUnk104 > o->oMrIUnk108 + 80) {
o->oMrIUnk104 = 0;
o->oMrIUnk108 = random_float() * 80.0f;
if (o->oMrIShotTimer > o->oMrIShotTimerMax + 80) {
o->oMrIShotTimer = 0;
o->oMrIShotTimerMax = random_float() * 80.0f;
spawn_mr_i_particle();
}
}

// Mr I init action
void mr_i_act_0(void) {
#ifndef VERSION_JP
obj_set_angle(o, 0, 0, 0);
Expand Down