mr_i.inc.c (8035B)
1 // mr_i.inc.c 2 3 // this is actually the MrI particle loop function. piranha 4 // plant code later on reuses this function. 5 void bhv_piranha_particle_loop(void) { 6 if (o->oTimer == 0) { 7 o->oVelY = 20.0f + 20.0f * random_float(); 8 o->oForwardVel = 20.0f + 20.0f * random_float(); 9 o->oMoveAngleYaw = random_u16(); 10 } 11 cur_obj_move_using_fvel_and_gravity(); 12 } 13 14 void mr_i_piranha_particle_act_0(void) { 15 cur_obj_scale(3.0f); 16 o->oForwardVel = 20.0f; 17 cur_obj_update_floor_and_walls(); 18 19 if (o->oInteractStatus & INT_STATUS_INTERACTED) { 20 o->oAction = 1; 21 } else if ((o->oTimer > 100) || (o->oMoveFlags & OBJ_MOVE_HIT_WALL) 22 || (o->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) { 23 obj_mark_for_deletion(o); 24 spawn_mist_particles(); 25 } 26 } 27 28 void mr_i_piranha_particle_act_1(void) { 29 s32 i; 30 obj_mark_for_deletion(o); 31 for (i = 0; i < 10; i++) { 32 spawn_object(o, MODEL_PURPLE_MARBLE, bhvPurpleParticle); 33 } 34 } 35 36 void (*sMrIParticleActions[])(void) = { 37 mr_i_piranha_particle_act_0, 38 mr_i_piranha_particle_act_1, 39 }; 40 41 void bhv_mr_i_particle_loop(void) { 42 cur_obj_call_action_function(sMrIParticleActions); 43 } 44 45 void spawn_mr_i_particle(void) { 46 struct Object *particle; 47 f32 sp18 = o->header.gfx.scale[1]; 48 49 particle = spawn_object(o, MODEL_PURPLE_MARBLE, bhvMrIParticle); 50 particle->oPosY += 50.0f * sp18; 51 particle->oPosX += sins(o->oMoveAngleYaw) * 90.0f * sp18; 52 particle->oPosZ += coss(o->oMoveAngleYaw) * 90.0f * sp18; 53 54 cur_obj_play_sound_2(SOUND_OBJ_MRI_SHOOT); 55 } 56 57 void bhv_mr_i_body_loop(void) { 58 obj_copy_pos_and_angle(o, o->parentObj); 59 60 if (!(o->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) { 61 obj_copy_scale(o, o->parentObj); 62 obj_set_parent_relative_pos(o, 0, 0, o->header.gfx.scale[1] * 100.0f); 63 obj_build_transform_from_pos_and_angle(o, 44, 15); 64 obj_translate_local(o, 6, 44); 65 o->oFaceAnglePitch = o->oMoveAnglePitch; 66 o->oGraphYOffset = o->header.gfx.scale[1] * 100.0f; 67 } 68 69 if (o->parentObj->oMrIUnk110 != 1) { 70 o->oAnimState = -1; 71 } else { 72 o->oAnimState++; 73 if (o->oAnimState == 15) { 74 o->parentObj->oMrIUnk110 = 0; 75 } 76 } 77 78 if (o->parentObj->activeFlags == ACTIVE_FLAG_DEACTIVATED) { 79 obj_mark_for_deletion(o); 80 } 81 } 82 83 void mr_i_act_3(void) { 84 s16 sp36; 85 s16 sp34; 86 f32 sp30; 87 f32 sp2C; 88 UNUSED u8 filler[8]; 89 f32 sp20; 90 f32 sp1C; 91 92 if (o->oBhvParams2ndByte != 0) { 93 sp1C = 2.0f; 94 } else { 95 sp1C = 1.0f; 96 } 97 98 if (o->oMrIUnk100 < 0) { 99 sp34 = 0x1000; 100 } else { 101 sp34 = -0x1000; 102 } 103 104 sp2C = (o->oTimer + 1) / 96.0f; 105 106 if (o->oTimer < 64) { 107 sp36 = o->oMoveAngleYaw; 108 o->oMoveAngleYaw += sp34 * coss(0x4000 * sp2C); 109 110 if (sp36 < 0 && o->oMoveAngleYaw >= 0) { 111 cur_obj_play_sound_2(SOUND_OBJ2_MRI_SPINNING); 112 } 113 114 o->oMoveAnglePitch = (1.0 - coss(0x4000 * sp2C)) * -0x4000; 115 cur_obj_shake_y(4.0f); 116 } else if (o->oTimer < 96) { 117 if (o->oTimer == 64) { 118 cur_obj_play_sound_2(SOUND_OBJ_MRI_DEATH); 119 } 120 121 sp30 = (f32)(o->oTimer - 63) / 32; 122 o->oMoveAngleYaw += sp34 * coss(0x4000 * sp2C); 123 o->oMoveAnglePitch = (1.0 - coss(0x4000 * sp2C)) * -0x4000; 124 125 cur_obj_shake_y((s32)((1.0f - sp30) * 4)); // trucating the f32? 126 sp20 = coss(0x4000 * sp30) * 0.4 + 0.6; 127 cur_obj_scale(sp20 * sp1C); 128 } else if (o->oTimer < 104) { 129 // do nothing 130 } else if (o->oTimer < 168) { 131 if (o->oTimer == 104) { 132 cur_obj_become_intangible(); 133 spawn_mist_particles(); 134 o->oMrIScale = sp1C * 0.6; 135 if (o->oBhvParams2ndByte != 0) { 136 o->oPosY += 100.0f; 137 spawn_default_star(1370, 2000.0f, -320.0f); 138 obj_mark_for_deletion(o); 139 } else { 140 cur_obj_spawn_loot_blue_coin(); 141 } 142 } 143 144 o->oMrIScale -= 0.2 * sp1C; 145 146 if (o->oMrIScale < 0) { 147 o->oMrIScale = 0; 148 } 149 150 cur_obj_scale(o->oMrIScale); 151 } else { 152 obj_mark_for_deletion(o); 153 } 154 } 155 156 void mr_i_act_2(void) { 157 s16 sp1E = o->oMoveAngleYaw; 158 s16 sp1C; 159 160 if (o->oTimer == 0) { 161 if (o->oBhvParams2ndByte != 0) { 162 o->oMrIUnkF4 = 200; 163 } else { 164 o->oMrIUnkF4 = 120; 165 } 166 o->oMrIUnkFC = 0; 167 o->oMrIUnk100 = 0; 168 o->oMrIUnk104 = 0; 169 } 170 171 obj_turn_toward_object(o, gMarioObject, 0x10, 0x800); 172 obj_turn_toward_object(o, gMarioObject, 0x0F, 0x400); 173 174 sp1C = sp1E - (s16)(o->oMoveAngleYaw); 175 176 if (sp1C == 0) { 177 o->oMrIUnkFC = 0; 178 o->oMrIUnk100 = 0; 179 } else if (sp1C > 0) { 180 if (o->oMrIUnk100 > 0) { 181 o->oMrIUnkFC += sp1C; 182 } else { 183 o->oMrIUnkFC = 0; 184 } 185 o->oMrIUnk100 = 1; 186 } else { 187 if (o->oMrIUnk100 < 0) { 188 o->oMrIUnkFC -= sp1C; 189 } else { 190 o->oMrIUnkFC = 0; 191 } 192 o->oMrIUnk100 = -1; 193 } 194 195 if (o->oMrIUnkFC == 0) { 196 o->oMrIUnkF4 = 120; 197 } 198 if (o->oMrIUnkFC > 65536) { 199 o->oAction = 3; 200 } 201 202 o->oMrIUnkF4--; 203 204 if (o->oMrIUnkF4 == 0) { 205 o->oMrIUnkF4 = 120; 206 o->oMrIUnkFC = 0; 207 } 208 209 if (o->oMrIUnkFC < 5000) { 210 if (o->oMrIUnk104 == o->oMrIUnk108) { 211 o->oMrIUnk110 = 1; 212 } 213 214 if (o->oMrIUnk104 == o->oMrIUnk108 + 20) { 215 spawn_mr_i_particle(); 216 o->oMrIUnk104 = 0; 217 o->oMrIUnk108 = (s32)(random_float() * 50.0f + 50.0f); 218 } 219 o->oMrIUnk104++; 220 } else { 221 o->oMrIUnk104 = 0; 222 o->oMrIUnk108 = (s32)(random_float() * 50.0f + 50.0f); 223 } 224 225 if (o->oDistanceToMario > 800.0f) { 226 o->oAction = 1; 227 } 228 } 229 230 void mr_i_act_1(void) { 231 s16 sp1E = obj_angle_to_object(o, gMarioObject); 232 s16 sp1C = abs_angle_diff(o->oMoveAngleYaw, sp1E); 233 s16 sp1A = abs_angle_diff(o->oMoveAngleYaw, gMarioObject->oFaceAngleYaw); 234 235 if (o->oTimer == 0) { 236 cur_obj_become_tangible(); 237 o->oMoveAnglePitch = 0; 238 o->oMrIUnk104 = 30; 239 o->oMrIUnk108 = random_float() * 20.0f; 240 if (o->oMrIUnk108 & 1) { 241 o->oAngleVelYaw = -256; 242 } else { 243 o->oAngleVelYaw = 256; 244 } 245 } 246 247 if (sp1C < 1024 && sp1A > 0x4000) { 248 if (o->oDistanceToMario < 700.0f) { 249 o->oAction = 2; 250 } else { 251 o->oMrIUnk104++; 252 } 253 } else { 254 o->oMoveAngleYaw += o->oAngleVelYaw; 255 o->oMrIUnk104 = 30; 256 } 257 258 if (o->oMrIUnk104 == o->oMrIUnk108 + 60) { 259 o->oMrIUnk110 = 1; 260 } 261 262 if (o->oMrIUnk104 > o->oMrIUnk108 + 80) { 263 o->oMrIUnk104 = 0; 264 o->oMrIUnk108 = random_float() * 80.0f; 265 spawn_mr_i_particle(); 266 } 267 } 268 269 void mr_i_act_0(void) { 270 #ifndef VERSION_JP 271 obj_set_angle(o, 0, 0, 0); 272 #else 273 o->oMoveAnglePitch = 0; 274 o->oMoveAngleYaw = 0; 275 o->oMoveAngleRoll = 0; 276 #endif 277 cur_obj_scale(o->oBhvParams2ndByte + 1); 278 279 if (o->oTimer == 0) { 280 cur_obj_set_pos_to_home(); 281 } 282 283 if (o->oDistanceToMario < 1500.0f) { 284 o->oAction = 1; 285 } 286 } 287 288 void (*sMrIActions[])(void) = { 289 mr_i_act_0, 290 mr_i_act_1, 291 mr_i_act_2, 292 mr_i_act_3, 293 }; 294 295 struct ObjectHitbox sMrIHitbox = { 296 /* interactType: */ INTERACT_DAMAGE, 297 /* downOffset: */ 0, 298 /* damageOrCoinValue: */ 2, 299 /* health: */ 2, 300 /* numLootCoins: */ 5, 301 /* radius: */ 80, 302 /* height: */ 150, 303 /* hurtboxRadius: */ 0, 304 /* hurtboxHeight: */ 0, 305 }; 306 307 void bhv_mr_i_loop(void) { 308 obj_set_hitbox(o, &sMrIHitbox); 309 cur_obj_call_action_function(sMrIActions); 310 311 if (o->oAction != 3) { 312 if ((o->oDistanceToMario > 3000.0f) || (o->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) { 313 o->oAction = 0; 314 } 315 } 316 317 o->oInteractStatus = 0; 318 }