Path: blob/master/src/game/behaviors/bowser_flame.inc.c
7861 views
struct ObjectHitbox sGrowingBowserFlameHitbox = {1/* interactType: */ INTERACT_FLAME,2/* downOffset: */ 20,3/* damageOrCoinValue: */ 1,4/* health: */ 0,5/* numLootCoins: */ 0,6/* radius: */ 10,7/* height: */ 40,8/* hurtboxRadius: */ 0,9/* hurtboxHeight: */ 0,10};1112struct ObjectHitbox sBowserFlameHitbox = {13/* interactType: */ INTERACT_FLAME,14/* downOffset: */ 0,15/* damageOrCoinValue: */ 1,16/* health: */ 0,17/* numLootCoins: */ 0,18/* radius: */ 10,19/* height: */ 40,20/* hurtboxRadius: */ 0,21/* hurtboxHeight: */ 0,22};2324void bowser_flame_despawn(void) {25obj_mark_for_deletion(o);26spawn_object_with_scale(o, MODEL_NONE, bhvBlackSmokeUpward, 1.0f);27if (random_float() < 0.1) {28spawn_object(o, MODEL_YELLOW_COIN, bhvTemporaryYellowCoin);29}30}3132s32 bowser_flame_should_despawn(s32 maxTime) {33if (maxTime < o->oTimer) {34return TRUE;35}3637// Flames should despawn if they fall off the arena.38if (o->oFloorType == SURFACE_BURNING) {39return TRUE;40}41if (o->oFloorType == SURFACE_DEATH_PLANE) {42return TRUE;43}4445return FALSE;46}4748void bhv_flame_bowser_init(void) {49o->oAnimState = (s32)(random_float() * 10.0f);50o->oMoveAngleYaw = random_u16();51if (random_float() < 0.2) {52o->oVelY = 80.0f;53} else {54o->oVelY = 20.0f;55}56o->oForwardVel = 10.0f;57o->oGravity = -1.0f;58o->oFlameScale = random_float() + 1.0f;59}6061void bhv_flame_large_burning_out_init(void) {62o->oAnimState = (s32)(random_float() * 10.0f);63o->oMoveAngleYaw = random_u16();64o->oVelY = 10.0f;65o->oForwardVel = 0.0f;66o->oFlameScale = 7.0f;67}6869void bowser_flame_move(void) {70s32 timer;71timer = ((o->oFlameSpeedTimerOffset + gGlobalTimer) & 0x3F) << 10;72o->oPosX += sins(o->oMoveAngleYaw) * sins(timer) * 4.0f;73o->oPosZ += coss(o->oMoveAngleYaw) * sins(timer) * 4.0f;74}7576void bhv_flame_bowser_loop(void) {77cur_obj_update_floor_and_walls();78cur_obj_move_standard(78);79if (o->oVelY < -4.0f) {80o->oVelY = -4.0f;81}82if (o->oAction == 0) {83cur_obj_become_intangible();84bowser_flame_move();85if (o->oMoveFlags & OBJ_MOVE_LANDED) {86o->oAction++;87if (cur_obj_has_behavior(bhvFlameLargeBurningOut)) {88o->oFlameScale = 8.0f;89} else {90o->oFlameScale = random_float() * 2 + 6.0f;91}92o->oForwardVel = 0;93o->oVelY = 0;94o->oGravity = 0;95}96} else {97cur_obj_become_tangible();98if (o->oTimer > o->oFlameScale * 10 + 5.0f) {99o->oFlameScale -= 0.15;100if (o->oFlameScale <= 0) {101bowser_flame_despawn();102}103}104}105cur_obj_scale(o->oFlameScale);106o->oGraphYOffset = o->header.gfx.scale[1] * 14.0f;107obj_set_hitbox(o, &sBowserFlameHitbox);108}109110void bhv_flame_moving_forward_growing_init(void) {111o->oForwardVel = 30.0f;112obj_translate_xz_random(o, 80.0f);113o->oAnimState = (s32)(random_float() * 10.0f);114o->oFlameScale = 3.0f;115}116117void bhv_flame_moving_forward_growing_loop(void) {118UNUSED s32 unused;119UNUSED struct Object *flame;120obj_set_hitbox(o, &sGrowingBowserFlameHitbox);121o->oFlameScale = o->oFlameScale + 0.5;122cur_obj_scale(o->oFlameScale);123if (o->oMoveAnglePitch > 0x800) {124o->oMoveAnglePitch -= 0x200;125}126cur_obj_set_pos_via_transform();127cur_obj_update_floor_height();128if (o->oFlameScale > 30.0f) {129obj_mark_for_deletion(o);130}131if (o->oPosY < o->oFloorHeight) {132o->oPosY = o->oFloorHeight;133flame = spawn_object(o, MODEL_RED_FLAME, bhvFlameBowser);134obj_mark_for_deletion(o);135}136}137138void bhv_flame_floating_landing_init(void) {139o->oAnimState = (s32)(random_float() * 10.0f);140o->oMoveAngleYaw = random_u16();141if (o->oBehParams2ndByte != 0) {142o->oForwardVel = random_float() * 5.0f;143} else {144o->oForwardVel = random_float() * 70.0f;145}146o->oVelY = random_float() * 20.0f;147o->oGravity = -1.0f;148o->oFlameSpeedTimerOffset = random_float() * 64.0f;149}150151f32 sFlameFloatingYLimit[] = { -8.0f, -6.0f, -3.0f };152153void bhv_flame_floating_landing_loop(void) {154UNUSED s32 unused;155cur_obj_update_floor_and_walls();156cur_obj_move_standard(78);157bowser_flame_move();158if (bowser_flame_should_despawn(900)) {159obj_mark_for_deletion(o);160}161if (o->oVelY < sFlameFloatingYLimit[o->oBehParams2ndByte]) {162o->oVelY = sFlameFloatingYLimit[o->oBehParams2ndByte];163}164if (o->oMoveFlags & OBJ_MOVE_LANDED) {165if (o->oBehParams2ndByte == 0) {166spawn_object(o, MODEL_RED_FLAME, bhvFlameLargeBurningOut);167} else {168spawn_object(o, MODEL_NONE, bhvBlueFlamesGroup); //? wonder if they meant MODEL_BLUE_FLAME?169}170obj_mark_for_deletion(o);171}172o->oGraphYOffset = o->header.gfx.scale[1] * 14.0f;173}174175void bhv_blue_bowser_flame_init(void) {176obj_translate_xz_random(o, 80.0f);177o->oAnimState = (s32)(random_float() * 10.0f);178o->oVelY = 7.0f;179o->oForwardVel = 35.0f;180o->oFlameScale = 3.0f;181o->oFlameUnusedRand = random_float() * 0.5;182o->oGravity = 1.0f;183o->oFlameSpeedTimerOffset = (s32)(random_float() * 64.0f);184}185186void bhv_blue_bowser_flame_loop(void) {187s32 i;188obj_set_hitbox(o, &sGrowingBowserFlameHitbox);189if (o->oFlameScale < 16.0f) {190o->oFlameScale = o->oFlameScale + 0.5;191}192cur_obj_scale(o->oFlameScale);193cur_obj_update_floor_and_walls();194cur_obj_move_standard(78);195if (o->oTimer > 0x14) {196if (o->oBehParams2ndByte == 0) {197for (i = 0; i < 3; i++) {198spawn_object_relative_with_scale(0, 0, 0, 0, 5.0f, o, MODEL_RED_FLAME,199bhvFlameFloatingLanding);200}201} else {202spawn_object_relative_with_scale(1, 0, 0, 0, 8.0f, o, MODEL_BLUE_FLAME,203bhvFlameFloatingLanding);204spawn_object_relative_with_scale(2, 0, 0, 0, 8.0f, o, MODEL_BLUE_FLAME,205bhvFlameFloatingLanding);206}207obj_mark_for_deletion(o);208}209}210211void bhv_flame_bouncing_init(void) {212o->oAnimState = (s32)(random_float() * 10.0f);213o->oVelY = 30.0f;214o->oForwardVel = 20.0f;215o->oFlameScale = o->header.gfx.scale[0];216o->oFlameSpeedTimerOffset = (s32)(random_float() * 64.0f);217}218219void bhv_flame_bouncing_loop(void) {220struct Object *bowser;221if (o->oTimer == 0) {222o->oFlameBowser = cur_obj_nearest_object_with_behavior(bhvBowser);223}224bowser = o->oFlameBowser;225o->oForwardVel = 15.0f;226o->oBounciness = -1.0f;227cur_obj_scale(o->oFlameScale);228obj_set_hitbox(o, &sGrowingBowserFlameHitbox);229cur_obj_update_floor_and_walls();230cur_obj_move_standard(78);231if (bowser_flame_should_despawn(300)) {232obj_mark_for_deletion(o);233}234if (bowser != NULL) {235if (bowser->oHeldState == HELD_FREE) {236if (lateral_dist_between_objects(o, bowser) < 300.0f) {237obj_mark_for_deletion(o);238}239}240}241}242243void bhv_blue_flames_group_loop(void) {244struct Object *flame;245s32 i;246if (o->oTimer == 0) {247o->oMoveAngleYaw = obj_angle_to_object(o, gMarioObject);248o->oBlueFlameNextScale = 5.0f;249}250if (o->oTimer < 16) {251if ((o->oTimer & 1) == 0) {252for (i = 0; i < 3; i++) {253flame = spawn_object(o, MODEL_BLUE_FLAME, bhvFlameBouncing);254flame->oMoveAngleYaw += i * 0x5555;255flame->header.gfx.scale[0] = o->oBlueFlameNextScale;256}257o->oBlueFlameNextScale -= 0.5;258}259} else {260obj_mark_for_deletion(o);261}262}263264265