#include #include #include #include #include "boss.h" const char* SSarcNameList [] = { "Shynja", NULL }; void ChucklesAndKnuckles(ActivePhysics *apThis, ActivePhysics *apOther); class daSamurshai : public daBoss { int onCreate(); int onDelete(); int onExecute(); int onDraw(); mHeapAllocator_c allocator; nw4r::g3d::ResFile resFile; m3d::mdl_c bodyModel; m3d::anmChr_c chrAnimation; mEf::es2 effect; int isBigBoss; int timer; int jumpCounter; char damage; char isDown; Vec initialPos; float XSpeed; u32 cmgr_returnValue; dStageActor_c *chosenOne; bool topHurts; bool slowDown; bool isBouncing; ActivePhysics Chuckles; ActivePhysics Knuckles; static daSamurshai *build(); void bindAnimChr_and_setUpdateRate(const char* name, int unk, float unk2, float rate); void updateModelMatrices(); bool calculateTileCollisions(); // void spriteCollision(ActivePhysics *apThis, ActivePhysics *apOther); void playerCollision(ActivePhysics *apThis, ActivePhysics *apOther); void yoshiCollision(ActivePhysics *apThis, ActivePhysics *apOther); void collisionCat3_StarPower(ActivePhysics *apThis, ActivePhysics *apOther); void collisionCat14_YoshiFire(ActivePhysics *apThis, ActivePhysics *apOther); void collisionCatD_GroundPound(ActivePhysics *apThis, ActivePhysics *apOther); void collisionCat7_WMWaggleWater(ActivePhysics *apThis, ActivePhysics *apOther); void collisionCat7_WMWaggleWaterYoshi(ActivePhysics *apThis, ActivePhysics *apOther); void collisionCat9_RollingObject(ActivePhysics *apThis, ActivePhysics *apOther); void collisionCat1_Fireball_E_Explosion(ActivePhysics *apThis, ActivePhysics *apOther); bool collisionCat2_IceBall_15_YoshiIce(ActivePhysics *apThis, ActivePhysics *apOther); void collisionCat13_Hammer(ActivePhysics *apThis, ActivePhysics *apOther); void collisionCatA_PenguinMario(ActivePhysics *apThis, ActivePhysics *apOther); void _vf148(); void _vf14C(); int randomPlayer(); USING_STATES(daSamurshai); DECLARE_STATE(Intro); DECLARE_STATE(Walk); DECLARE_STATE(Turn); DECLARE_STATE(Chop); DECLARE_STATE(ChargeSlash); DECLARE_STATE(Uppercut); DECLARE_STATE(SpinAttack); DECLARE_STATE(Damage); DECLARE_STATE(Outro); }; daSamurshai *daSamurshai::build() { void *buffer = AllocFromGameHeap1(sizeof(daSamurshai)); return new(buffer) daSamurshai; } /////////////////////// // Externs and States /////////////////////// extern "C" int SmoothRotation(short* rot, u16 amt, int unk2); CREATE_STATE(daSamurshai, Intro); CREATE_STATE(daSamurshai, Walk); CREATE_STATE(daSamurshai, Turn); CREATE_STATE(daSamurshai, Chop); CREATE_STATE(daSamurshai, ChargeSlash); CREATE_STATE(daSamurshai, Uppercut); CREATE_STATE(daSamurshai, SpinAttack); CREATE_STATE(daSamurshai, Damage); CREATE_STATE(daSamurshai, Outro); //////////////////////// // Collision Functions //////////////////////// void ChucklesAndKnuckles(ActivePhysics *apThis, ActivePhysics *apOther) { ((dEn_c*)apThis->owner)->_vf220(apOther->owner); } void daSamurshai::playerCollision(ActivePhysics *apThis, ActivePhysics *apOther) { char hitType = usedForDeterminingStatePress_or_playerCollision(this, apThis, apOther, 2); if (topHurts == true) { this->dEn_c::playerCollision(apThis, apOther); this->_vf220(apOther->owner); } else if ((hitType == 1) || (hitType == 3)) { apOther->someFlagByte |= 2; if (this->isDown == 0) { this->playEnemyDownSound1(); damage += 4; if (damage > 15) { doStateChange(&StateID_Outro); } else { doStateChange(&StateID_Damage); } } } else { this->dEn_c::playerCollision(apThis, apOther); this->_vf220(apOther->owner); } this->isDead = 0; this->flags_4FC |= (1<<(31-7)); this->counter_504[apOther->owner->which_player] = 0; } void daSamurshai::yoshiCollision(ActivePhysics *apThis, ActivePhysics *apOther) { this->playerCollision(apThis, apOther); } void daSamurshai::collisionCatD_GroundPound(ActivePhysics *apThis, ActivePhysics *apOther) { } void daSamurshai::collisionCat7_WMWaggleWater(ActivePhysics *apThis, ActivePhysics *apOther) { apOther->someFlagByte |= 2; if (topHurts == true) { this->dEn_c::playerCollision(apThis, apOther); this->_vf220(apOther->owner); } else if (this->isDown == 0) { damage += 6; if (damage > 15) { doStateChange(&StateID_Outro); } else { doStateChange(&StateID_Damage); } } this->isDead = 0; this->flags_4FC |= (1<<(31-7)); this->counter_504[apOther->owner->which_player] = 0; } void daSamurshai::collisionCat7_WMWaggleWaterYoshi(ActivePhysics *apThis, ActivePhysics *apOther) { this->collisionCat7_WMWaggleWater(apThis, apOther); } void daSamurshai::collisionCat9_RollingObject(ActivePhysics *apThis, ActivePhysics *apOther) { if (this->isDown == 0) { damage += 3; if (damage > 2) { doStateChange(&StateID_Outro); } else { doStateChange(&StateID_Damage); } } } void daSamurshai::collisionCat3_StarPower(ActivePhysics *apThis, ActivePhysics *apOther){ } void daSamurshai::collisionCatA_PenguinMario(ActivePhysics *apThis, ActivePhysics *apOther){ if (this->isDown == 0) { damage += 3; if (damage > 15) { doStateChange(&StateID_Outro); } else { doStateChange(&StateID_Damage); } } this->isDead = 0; this->flags_4FC |= (1<<(31-7)); this->counter_504[apOther->owner->which_player] = 0; } void daSamurshai::collisionCat14_YoshiFire(ActivePhysics *apThis, ActivePhysics *apOther){ damage += 4; SpawnEffect("Wm_mr_fireball_hit", 0, &apOther->owner->pos, &apOther->owner->rot, &apOther->owner->scale); PlaySoundAsync(this, SE_OBJ_FIREBALL_DISAPP); if (damage > 15) { doStateChange(&StateID_Outro); } } void daSamurshai::collisionCat1_Fireball_E_Explosion(ActivePhysics *apThis, ActivePhysics *apOther) { damage += 1; SpawnEffect("Wm_mr_fireball_hit", 0, &apOther->owner->pos, &apOther->owner->rot, &apOther->owner->scale); PlaySoundAsync(this, SE_OBJ_FIREBALL_DISAPP); if (damage > 15) { doStateChange(&StateID_Outro); } } bool daSamurshai::collisionCat2_IceBall_15_YoshiIce(ActivePhysics *apThis, ActivePhysics *apOther) { return true; } void daSamurshai::collisionCat13_Hammer(ActivePhysics *apThis, ActivePhysics *apOther) { damage += 2; this->spawnHitEffectAtPosition((Vec2){apOther->owner->pos.x, apOther->owner->pos.y}); if (damage > 15) { doStateChange(&StateID_Outro); } } bool daSamurshai::calculateTileCollisions() { // Returns true if sprite should turn, false if not. HandleXSpeed(); HandleYSpeed(); doSpriteMovement(); cmgr_returnValue = collMgr.CollidedWithTile(); collMgr.execute(); if (isBouncing) { stuffRelatingToCollisions(0.1875f, 1.0f, 0.5f); if (speed.y != 0.0f) isBouncing = false; } float xDelta = pos.x - last_pos.x; if (xDelta >= 0.0f) direction = 0; else direction = 1; if (collMgr.CollidedWithTile()) { // Walking into a tile branch if (cmgr_returnValue == 0) isBouncing = true; if (speed.x != 0.0f) { //playWmEnIronEffect(); } speed.y = 0.0f; // u32 blah = collMgr.s_80070760(); // u8 one = (blah & 0xFF); // static const float incs[5] = {0.00390625f, 0.0078125f, 0.015625f, 0.0234375f, 0.03125f}; // x_speed_inc = incs[one]; max_speed.x = (direction == 1) ? -1.0f : 1.0f; } else { x_speed_inc = 0.0f; } // Bouncing checks if (_34A & 4) { Vec v = (Vec){0.0f, 1.0f, 0.0f}; collMgr.parent_speed_ptr = &v; if (collMgr.SomethingSemiImportant(collMgr.bitfield_for_checks)) speed.y = 0.0f; collMgr.parent_speed_ptr = &speed; } else { if (collMgr.SomethingSemiImportant(collMgr.bitfield_for_checks)) speed.y = 0.0f; } collMgr.s_8006FA40(0); // Switch Direction if (collMgr.bitfield_for_checks & (0x15 << direction)) { if (collMgr.CollidedWithTile()) { isBouncing = true; } return true; } return false; } void daSamurshai::bindAnimChr_and_setUpdateRate(const char* name, int unk, float unk2, float rate) { nw4r::g3d::ResAnmChr anmChr = this->resFile.GetResAnmChr(name); this->chrAnimation.bind(&this->bodyModel, anmChr, unk); this->bodyModel.bindAnim(&this->chrAnimation, unk2); this->chrAnimation.setUpdateRate(rate); } int daSamurshai::onCreate() { isBigBoss = settings & 0xF; // Model Setup allocator.link(-1, GameHeaps[0], 0, 0x20); this->resFile.data = getResource("Shynja", "g3d/Shynja.brres"); nw4r::g3d::ResMdl mdl = this->resFile.GetResMdl("Model"); bodyModel.setup(mdl, &allocator, 0x224, 1, 0); // Animations start here nw4r::g3d::ResAnmChr anmChr = this->resFile.GetResAnmChr("c18_IDLE_R"); this->chrAnimation.setup(mdl, anmChr, &this->allocator, 0); allocator.unlink(); // Character Setup scale = (Vec){20.0, 20.0, 20.0}; pos.y = pos.y + 40.0; rot.x = 0; // X is vertical axis rot.y = 0xD800; // Y is horizontal axis rot.z = 0; // Z is ... an axis >.> direction = 1; // Heading left. speed.x = 0.0; speed.y = 0.0; XSpeed = 2.0; x_speed_inc = 0.2; initialPos = pos; topHurts = false; // Physics ActivePhysics::Info HitMeBaby; HitMeBaby.xDistToCenter = 0.0; HitMeBaby.yDistToCenter = 12.0; HitMeBaby.xDistToEdge = 14.0; HitMeBaby.yDistToEdge = 12.0; HitMeBaby.category1 = 0x3; HitMeBaby.category2 = 0x0; HitMeBaby.bitfield1 = 0x4F; HitMeBaby.bitfield2 = 0xffbafffe; HitMeBaby.unkShort1C = 0; HitMeBaby.callback = &dEn_c::collisionCallback; this->aPhysics.initWithStruct(this, &HitMeBaby); this->aPhysics.addToList(); // Tile collider // These fucking rects do something for the tile rect spriteSomeRectX = 28.0f; spriteSomeRectY = 32.0f; _320 = 0.0f; _324 = 16.0f; // These structs tell stupid collider what to collide with - these are from koopa troopa static const u8 one[16] = {0,0,0,1, 0,0,0xC0,0, 0,0,0x40,0, 0,0,0,0}; static const u8 two[12] = {0,0,0,0, 0,0,0,0, 0,0,0xC0,0}; static const u8 three[16] = {0,0,0,1, 0,0,0x60,0, 0,0,0x90,0, 0,0,0x60,0}; collMgr.Init(this, one, two, three); collMgr.execute(); cmgr_returnValue = collMgr.CollidedWithTile(); if (collMgr.CollidedWithTile()) isBouncing = false; else isBouncing = true; // Sword Physics // Chuckles is left, Knuckles is Right ActivePhysics::Info iChuckles; ActivePhysics::Info iKnuckles; iChuckles.xDistToCenter = -27.0; iChuckles.yDistToCenter = 12.0; iChuckles.xDistToEdge = 27.0; iChuckles.yDistToEdge = 10.0; iKnuckles.xDistToCenter = 27.0; iKnuckles.yDistToCenter = 12.0; iKnuckles.xDistToEdge = 27.0; iKnuckles.yDistToEdge = 10.0; iKnuckles.category1 = iChuckles.category1 = 0x3; iKnuckles.category2 = iChuckles.category2 = 0x0; iKnuckles.bitfield1 = iChuckles.bitfield1 = 0x4F; iKnuckles.bitfield2 = iChuckles.bitfield2 = 0x6; iKnuckles.unkShort1C = iChuckles.unkShort1C = 0x0; iKnuckles.callback = iChuckles.callback = ChucklesAndKnuckles; Chuckles.initWithStruct(this, &iChuckles); Knuckles.initWithStruct(this, &iKnuckles); doStateChange(&StateID_Intro); this->onExecute(); return true; } int daSamurshai::onDelete() { return true; } int daSamurshai::onExecute() { acState.execute(); updateModelMatrices(); return true; } int daSamurshai::onDraw() { bodyModel.scheduleForDrawing(); bodyModel._vf1C(); return true; } void daSamurshai::updateModelMatrices() { // This won't work with wrap because I'm lazy. matrix.translation(pos.x, pos.y - 2.0, pos.z); matrix.applyRotationYXZ(&rot.x, &rot.y, &rot.z); bodyModel.setDrawMatrix(matrix); bodyModel.setScale(&scale); bodyModel.calcWorld(false); } /////////////// // Intro State /////////////// void daSamurshai::beginState_Intro() { this->timer = 0; SetupKameck(this, Kameck); } void daSamurshai::executeState_Intro() { this->timer += 1; bool ret; ret = GrowBoss(this, Kameck, 1.0, 5.0, 0, this->timer); if (ret) { PlaySound(this, SE_EMY_KURI_CHANGE_BIG); doStateChange(&StateID_Walk); } } void daSamurshai::endState_Intro() { CleanupKameck(this, Kameck); } /////////////// // Walk State /////////////// int daSamurshai::randomPlayer() { int players[4]; int playerCount = 0; for (int i = 0; i < 4; i++) { if (Player_Active[i] != 0 && Player_Lives[Player_ID[i]] > 0) { players[playerCount] = i; playerCount++; } } return players[MakeRandomNumber(playerCount)]; } void daSamurshai::beginState_Walk() { bindAnimChr_and_setUpdateRate("c18_IDLE_R2", 1, 0.0, 2.0); chosenOne = GetSpecificPlayerActor(this->randomPlayer()); this->max_speed.x = (this->direction) ? -this->XSpeed : this->XSpeed; this->speed.x = (direction) ? -0.6f : 0.6f; x_speed_inc = 0.2; this->max_speed.y = -4.0; this->speed.y = -4.0; this->y_speed_inc = -0.1875; } void daSamurshai::executeState_Walk() { float xDistance = pos.x - chosenOne->pos.x; float yDistance = pos.y - chosenOne->pos.y; OSReport("Distance: %f, %f", xDistance, yDistance); if ((xDistance > 64.0) && (direction == 0)) { doStateChange(&StateID_Turn); } if ((xDistance < -64.0) && (direction == 1)) { doStateChange(&StateID_Turn); } if (xDistance < 0.0) { xDistance = -xDistance; } // Condition for Chop if (xDistance < 32.0) { doStateChange(&StateID_Chop); } // Condition For Charge Slash if (isBigBoss) { if ((xDistance < 96.0) && (xDistance > 64.0)) { int charge = MakeRandomNumber(100); if (charge > 90) { doStateChange(&StateID_ChargeSlash); } } } // Aerial Attacks! if (yDistance > 24.0) { // Condition For Spin Attack if (xDistance < 32.0) { doStateChange(&StateID_SpinAttack); } // Condition for Uppercut if ((xDistance < 48.0) && (xDistance > 64.0)) { doStateChange(&StateID_Uppercut); } } bool ret = calculateTileCollisions(); if (ret) { doStateChange(&StateID_Turn); } if(this->chrAnimation.isAnimationDone()) { this->chrAnimation.setCurrentFrame(0.0); } } void daSamurshai::endState_Walk() { } /////////////// // Turn State /////////////// void daSamurshai::beginState_Turn() { this->speed.x = (direction) ? -0.5f : 0.5f; this->direction ^= 1; x_speed_inc = 0.0; } void daSamurshai::executeState_Turn() { if(this->chrAnimation.isAnimationDone()) { this->chrAnimation.setCurrentFrame(0.0); } u16 amt = (this->direction == 0) ? 0x2800 : 0xD800; int done = SmoothRotation(&this->rot.y, amt, 0x1000); if(done) { this->doStateChange(&StateID_Walk); } } void daSamurshai::endState_Turn() { } /////////////// // Chop State /////////////// void daSamurshai::beginState_Chop() { bindAnimChr_and_setUpdateRate("c18_H_CUT_R", 1, 0.0, 1.0); } void daSamurshai::executeState_Chop() { PlaySoundAsync(this, SE_EMY_CRASHER_PUNCH); if (this->direction == 1) { SpawnEffect("Wm_ob_itemget_ring", 0, &(Vec){pos.x - 18.0, pos.y + 16.0, pos.z}, &(S16Vec){0,0,0}, &(Vec){1.5, 0.5, 1.5}); Chuckles.addToList(); } else { SpawnEffect("Wm_ob_itemget_ring", 0, &(Vec){pos.x + 18.0, pos.y + 16.0, pos.z}, &(S16Vec){0,0,0}, &(Vec){1.5, 0.5, 1.5}); Knuckles.addToList(); } if(this->chrAnimation.isAnimationDone()) { if (this->direction == 1) { SpawnEffect("Wm_ob_flagget_light", 0, &(Vec){pos.x - 38.0, pos.y + 16.0, pos.z}, &(S16Vec){0,0,0}, &(Vec){1.0, 1.0, 1.0}); SpawnEffect("Wm_en_hanapetal", 0, &(Vec){pos.x - 38.0, pos.y + 16.0, pos.z}, &(S16Vec){0,0,0}, &(Vec){2.0, 2.0, 2.0}); Chuckles.removeFromList(); } else { SpawnEffect("Wm_ob_flagget_light", 0, &(Vec){pos.x + 38.0, pos.y + 16.0, pos.z}, &(S16Vec){0,0,0}, &(Vec){1.0, 1.0, 1.0}); SpawnEffect("Wm_en_hanapetal", 0, &(Vec){pos.x + 38.0, pos.y + 16.0, pos.z}, &(S16Vec){0,0,0}, &(Vec){2.0, 2.0, 2.0}); Knuckles.removeFromList(); } PlaySoundAsync(this, SE_EMY_BIG_PAKKUN_DAMAGE_1); doStateChange(&StateID_Walk); } } void daSamurshai::endState_Chop() { } /////////////// // ChargeSlash State /////////////// void daSamurshai::beginState_ChargeSlash() { this->timer = 0; this->speed.x = 0.0; this->max_speed.x = (this->direction) ? -8.0 : 8.0; } void daSamurshai::executeState_ChargeSlash() { if (this->timer == 0) { bindAnimChr_and_setUpdateRate("c18_OB_IDLE_R", 1, 0.0, 1.0); if (this->direction == 1) SpawnEffect("Wm_ob_keyget02_lighit", 0, &(Vec){pos.x + 7.0, pos.y + 14.0, pos.z - 5500.0}, &(S16Vec){0,0,0}, &(Vec){0.8, 0.8, 0.8}); else SpawnEffect("Wm_ob_keyget02_lighit", 0, &(Vec){pos.x - 7.0, pos.y + 14.0, pos.z + 5500.0}, &(S16Vec){0,0,0}, &(Vec){0.8, 0.8, 0.8}); } if (this->timer == 40) { speed.x = (direction) ? -8.0f : 8.0f; topHurts = true; } if (this->timer > 41) { if (slowDown == false) { float xDistance = pos.x - chosenOne->pos.x; if (xDistance < 8.0) { bindAnimChr_and_setUpdateRate("c18_H_CUT_R", 1, 0.0, 2.0); SpawnEffect("Wm_ob_itemget_ring", 0, &(Vec){pos.x, pos.y + 16.0, pos.z}, &(S16Vec){0,0,0}, &(Vec){2.0, 0.2, 1.5}); slowDown == true; } } else { speed.x = speed.x / 1.5; } if (speed.x == 0.0) { topHurts = false; timer = 500; } else { effect.spawn("Wm_mr_p_iceslip", 0, &(Vec){pos.x, pos.y, pos.z}, &(S16Vec){0,0,0}, &(Vec){1.5, 1.5, 1.5}); SpawnEffect("Wm_en_hanapetal", 0, &pos, &(S16Vec){0,0,0}, &(Vec){1.5, 1.5, 1.5}); } } if (this->timer == 550) { doStateChange(&StateID_Walk); } bool ret = calculateTileCollisions(); if (ret) { if (slowDown = false) { bindAnimChr_and_setUpdateRate("c18_H_CUT_R", 1, 0.0, 2.0); SpawnEffect("Wm_ob_itemget_ring", 0, &(Vec){pos.x, pos.y + 16.0, pos.z}, &(S16Vec){0,0,0}, &(Vec){2.0, 0.2, 1.5}); slowDown == true; } speed.x = 0.0; } this->timer += 1; } void daSamurshai::endState_ChargeSlash() { slowDown = false; } /////////////// // Uppercut State /////////////// void daSamurshai::beginState_Uppercut() { bindAnimChr_and_setUpdateRate("c18_H_SHOT_R", 1, 0.0, 1.0); slowDown = false; } void daSamurshai::executeState_Uppercut() { if ((slowDown) && (this->chrAnimation.isAnimationDone())) { doStateChange(&StateID_Walk); } if (slowDown) { return; } if ((int)this->chrAnimation.getCurrentFrame() == 34) { topHurts = true; PlaySoundAsync(this, SE_EMY_CRASHER_PUNCH); speed.y = 2.0; y_speed_inc = -0.1875; if (this->direction == 1) { SpawnEffect("Wm_ob_itemget_ring", 0, &(Vec){pos.x - 18.0, pos.y + 16.0, pos.z}, &(S16Vec){0,0,0}, &(Vec){0.5, 1.5, 1.5}); Chuckles.addToList(); } else { SpawnEffect("Wm_ob_itemget_ring", 0, &(Vec){pos.x + 18.0, pos.y + 16.0, pos.z}, &(S16Vec){0,0,0}, &(Vec){0.5, 1.5, 1.5}); Knuckles.addToList(); } } if ((this->chrAnimation.isAnimationDone()) && (speed.y != 0)) { if (topHurts) { if (this->direction == 1) { SpawnEffect("Wm_ob_flagget_light", 0, &(Vec){pos.x - 38.0, pos.y + 16.0, pos.z}, &(S16Vec){0,0,0}, &(Vec){1.0, 1.0, 1.0}); SpawnEffect("Wm_en_hanapetal", 0, &(Vec){pos.x - 38.0, pos.y + 16.0, pos.z}, &(S16Vec){0,0,0}, &(Vec){2.0, 2.0, 2.0}); Chuckles.removeFromList(); } else { SpawnEffect("Wm_ob_flagget_light", 0, &(Vec){pos.x + 38.0, pos.y + 16.0, pos.z}, &(S16Vec){0,0,0}, &(Vec){1.0, 1.0, 1.0}); SpawnEffect("Wm_en_hanapetal", 0, &(Vec){pos.x + 38.0, pos.y + 16.0, pos.z}, &(S16Vec){0,0,0}, &(Vec){2.0, 2.0, 2.0}); Knuckles.removeFromList(); } PlaySoundAsync(this, SE_EMY_BIG_PAKKUN_DAMAGE_1); topHurts = false; } } if ((this->chrAnimation.isAnimationDone()) && (speed.y == 0.0)) { bindAnimChr_and_setUpdateRate("c18_DIVING_STEAL_R", 1, 0.0, 1.0); slowDown = true; } bool ret = calculateTileCollisions(); } void daSamurshai::endState_Uppercut() { slowDown = false; } /////////////// // SpinAttack State /////////////// void daSamurshai::beginState_SpinAttack() { bindAnimChr_and_setUpdateRate("c18_NORMAL_STEAL_R", 1, 0.0, 1.0); } void daSamurshai::executeState_SpinAttack() { if((int)this->chrAnimation.getCurrentFrame() == 20) { topHurts = true; PlaySoundAsync(this, SE_EMY_CRASHER_PUNCH); speed.y = 3.0; y_speed_inc = -0.1875; if (this->direction == 1) { Chuckles.addToList(); } else { Knuckles.addToList(); } } if (((int)chrAnimation.getCurrentFrame() > 20) && ((int)this->chrAnimation.getCurrentFrame() < 60)) { scale = (Vec){1.0, 1.0, 1.0}; if (this->direction == 1) { effect.spawn("Wm_mr_spinjump", 0, &(Vec){pos.x - 18.0, pos.y + 16.0, pos.z}, &(S16Vec){0,0,0}, &scale); } else { effect.spawn("Wm_mr_spinjump", 0, &(Vec){pos.x + 18.0, pos.y + 16.0, pos.z}, &(S16Vec){0,0,0}, &scale); } } if((int)this->chrAnimation.getCurrentFrame() == 65) { topHurts = false; PlaySoundAsync(this, SE_EMY_CRASHER_PUNCH); if (this->direction == 1) { Chuckles.removeFromList(); } else { Knuckles.removeFromList(); } } if ((this->chrAnimation.isAnimationDone()) && (speed.y == 0.0)) { doStateChange(&StateID_Walk); } bool ret = calculateTileCollisions(); } void daSamurshai::endState_SpinAttack() { } /////////////// // Damage State /////////////// void daSamurshai::beginState_Damage() { bindAnimChr_and_setUpdateRate("c18_L_DMG_F_1_R", 1, 0.0, 2.0); this->max_speed.x = 0; this->speed.x = 0; this->x_speed_inc = 0; this->max_speed.y = -2.0; this->speed.y = -2.0; this->y_speed_inc = -0.1875; this->timer = 0; this->isDown = 1; } void daSamurshai::executeState_Damage() { calculateTileCollisions(); // effect.spawn("Wm_en_spindamage", 0, &(Vec){pos.x, pos.y + 24.0, 0}, &(S16Vec){0,0,0}, &(Vec){1.0, 1.0, 1.0}); if (this->chrAnimation.isAnimationDone() && (collMgr.SomethingSemiImportant(collMgr.bitfield_for_checks))) { if (timer == 0) { bindAnimChr_and_setUpdateRate("c18_L_DMG_F_3_R", 1, 0.0, 2.0); timer = 1; } else if (timer == 1) { bindAnimChr_and_setUpdateRate("c18_L_DMG_F_4_R", 1, 0.0, 1.0); timer = 2; } else if (timer == 2) { doStateChange(&StateID_Walk); } } } void daSamurshai::endState_Damage() { this->isDown = 0; this->rot.y = (direction) ? 0xD800 : 0x2800; } /////////////// // Outro State /////////////// void daSamurshai::beginState_Outro() { OutroSetup(this); this->aPhysics.removeFromList(); } void daSamurshai::executeState_Outro() { if (this->dying == 1) { if (this->timer > 180) { ExitStage(WORLD_MAP, 0, BEAT_LEVEL, MARIO_WIPE); } if (this->timer == 60) { PlayerVictoryCries(this); } this->timer += 1; return; } bool ret; ret = ShrinkBoss(this, &pos, 1.0, this->timer); if (ret == true) { BossExplode(this, &pos); this->dying = 1; this->timer = 0; } else { PlaySound(this, SE_EMY_BIG_KURIBO_DOWN); } this->timer += 1; } void daSamurshai::endState_Outro() { }