#include #include #include #include #include #include "effects.h" #include "player.h" // Shy Guy Settings // // Nybble 5: Shy Guy Types // 9 - Walker // 0 - Pacing Walker // 1 - Sleeper // 2 - Jumper // 6 - Judo Master // 7 - Spike Thrower // 3 - Ballooneer Horizontal // 4 - Ballooneer Vertical // 5 - Ballooneer Circular // 10 - Walking Giatn // 8 - Pacing Giant // // Nybble 6: Colour // 0 - Red // 1 - Blue // 2 - Green // 3 - Cyan // 4 - Purple // // Nybble 7: Balloon Colour // 0 - Red // 1 - Blue (not working) // // Nybble 8: Ballooneer Carries // 0 - Nothing // 1 - ??? // // Nybble 9: Distance Moved // # - Distance for Pacing Walker, Pacing Giants, and Ballooneers // // I_kinoko, I_fireflower, I_propeller_model, I_iceflower, I_star, I_penguin - model names // anmChr - wait2 class daShyGuy : public dEn_c { int onCreate(); int onDelete(); int onExecute(); int onDraw(); mHeapAllocator_c allocator; nw4r::g3d::ResFile resFile; nw4r::g3d::ResFile anmFile; nw4r::g3d::ResFile balloonFile; m3d::mdl_c bodyModel; m3d::mdl_c balloonModel; m3d::mdl_c balloonModelB; m3d::anmChr_c chrAnimation; int type; int timer; int jumpCounter; float Baseline; char damage; char isDown; char renderBalloon; Vec initialPos; int distance; float XSpeed; u32 cmgr_returnValue; bool isBouncing; static daShyGuy *build(); void bindAnimChr_and_setUpdateRate(const char* name, int unk, float unk2, float rate); void updateModelMatrices(); void shyCollisionCallback(ActivePhysics *apThis, ActivePhysics *apOther); // void spriteCollision(ActivePhysics *apThis, ActivePhysics *apOther); void playerCollision(ActivePhysics *apThis, ActivePhysics *apOther); void yoshiCollision(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); USING_STATES(daShyGuy); DECLARE_STATE(Walk); DECLARE_STATE(Turn); DECLARE_STATE(RealWalk); DECLARE_STATE(RealTurn); DECLARE_STATE(Jump); DECLARE_STATE(Sleep); DECLARE_STATE(Balloon_H); DECLARE_STATE(Balloon_V); DECLARE_STATE(Balloon_C); DECLARE_STATE(Judo); DECLARE_STATE(Spike); DECLARE_STATE(GoDizzy); DECLARE_STATE(BalloonDrop); DECLARE_STATE(FireKnockBack); DECLARE_STATE(FlameHit); DECLARE_STATE(Recover); }; daShyGuy *daShyGuy::build() { void *buffer = AllocFromGameHeap1(sizeof(daShyGuy)); return new(buffer) daShyGuy; } /////////////////////// // Externs and States /////////////////////// extern "C" void *PlaySound(daShyGuy *, int soundID); extern "C" dStageActor_c *CreateActor(u16 classID, int settings, Vec pos, char rot, char layer); extern "C" u8 dSprite_c__getXDirectionOfFurthestPlayerRelativeToVEC3(daShyGuy *, Vec pos); //FIXME make this dEn_c->used... extern "C" char usedForDeterminingStatePress_or_playerCollision(dEn_c* t, ActivePhysics *apThis, ActivePhysics *apOther, int unk1); extern "C" int SomeStrangeModification(dStageActor_c* actor); extern "C" void DoStuffAndMarkDead(dStageActor_c *actor, Vec vector, float unk); extern "C" int SmoothRotation(short* rot, u16 amt, int unk2); CREATE_STATE(daShyGuy, Walk); CREATE_STATE(daShyGuy, Turn); CREATE_STATE(daShyGuy, RealWalk); CREATE_STATE(daShyGuy, RealTurn); CREATE_STATE(daShyGuy, Jump); CREATE_STATE(daShyGuy, Sleep); CREATE_STATE(daShyGuy, Balloon_H); CREATE_STATE(daShyGuy, Balloon_V); CREATE_STATE(daShyGuy, Balloon_C); CREATE_STATE(daShyGuy, Judo); CREATE_STATE(daShyGuy, Spike); CREATE_STATE(daShyGuy, GoDizzy); CREATE_STATE(daShyGuy, BalloonDrop); CREATE_STATE(daShyGuy, FireKnockBack); CREATE_STATE(daShyGuy, FlameHit); CREATE_STATE(daShyGuy, Recover); //////////////////////// // Collision Functions //////////////////////// // Collision callback to help shy guy not die at inappropriate times and ruin the dinner void daShyGuy::shyCollisionCallback(ActivePhysics *apThis, ActivePhysics *apOther) { if (apOther->owner->name != 89) { this->collisionCallback(apThis, apOther); } } // spriteCollision(ActivePhysics *apThis, ActivePhysics *apOther) { // if (apThis->owner->shyGuyState == #notPickupable) { Do Normal Things; } // else { Shy Guy is in throwy mode, and should kill enemies instead; } // } void daShyGuy::playerCollision(ActivePhysics *apThis, ActivePhysics *apOther) { dStateBase_c *stateVar; dStateBase_c *deathState; if (this->type < 6) { // Regular Shy Guys stateVar = &StateID_GoDizzy; deathState = &StateID_DieFall; } else if (this->type > 8) { // Giants stateVar = &StateID_DieFall; deathState = &StateID_DieFall; } else { // Ballooneers stateVar = &StateID_BalloonDrop; deathState = &StateID_DieFumi; } char hitType; if (this->isDown == 0) { hitType = usedForDeterminingStatePress_or_playerCollision(this, apThis, apOther, 2); } else { // Shy Guy is in throwy mode hitType = usedForDeterminingStatePress_or_playerCollision(this, apThis, apOther, 0); } if(hitType == 1) { // regular jump apOther->someFlagByte |= 2; if (this->isDown == 0) { doStateChange(stateVar); } else { // Shy Guy is in throwy mode - kill it with fire doStateChange(deathState); } } else if(hitType == 3) { // spinning jump or whatever? apOther->someFlagByte |= 2; if (this->isDown == 0) { doStateChange(stateVar); } else { // Shy Guy is in throwy mode - kill it with fire doStateChange(deathState); } } else if(hitType == 0) { this->dEn_c::playerCollision(apThis, apOther); this->_vf220(apOther->owner); } // else if(hitType == 2) { \\ Minimario? } // fix multiple player collisions via megazig this->isDead = 0; this->flags_4FC |= (1<<(31-7)); if(apOther->owner->which_player > 3) { OSReport("!!!ATTENTION!!!\napOther->owner->which_player > 3\n"); }else{ this->counter_504[apOther->owner->which_player] = 0; } } void daShyGuy::yoshiCollision(ActivePhysics *apThis, ActivePhysics *apOther) { this->playerCollision(apThis, apOther); } void daShyGuy::collisionCatD_GroundPound(ActivePhysics *apThis, ActivePhysics *apOther) { doStateChange(&StateID_DieFall); } void daShyGuy::collisionCat9_RollingObject(ActivePhysics *apThis, ActivePhysics *apOther) { doStateChange(&StateID_DieFall); } void daShyGuy::collisionCat1_Fireball_E_Explosion(ActivePhysics *apThis, ActivePhysics *apOther) { this->damage += 1; dStateBase_c *stateVar; if (this->type > 3) { // Jumpers stateVar = &StateID_DieSmoke; } else if (this->type < 6) { // Regular Shy Guys Except Jumper stateVar = &StateID_FireKnockBack; } else if (this->type > 8) { // Giants return; } else { // Ballooneers stateVar = &StateID_FlameHit; } if (this->damage > 2) { doStateChange(&StateID_DieSmoke); } else { doStateChange(stateVar); } } // void daShyGuy::collisionCat2_IceBall_15_YoshiIce(ActivePhysics *apThis, ActivePhysics *apOther) { // doStateChange(&StateID_DieFall); // } void daShyGuy::collisionCat13_Hammer(ActivePhysics *apThis, ActivePhysics *apOther) { doStateChange(&StateID_DieFall); } void daShyGuy::bindAnimChr_and_setUpdateRate(const char* name, int unk, float unk2, float rate) { nw4r::g3d::ResAnmChr anmChr = this->anmFile.GetResAnmChr(name); this->chrAnimation.bind(&this->bodyModel, anmChr, unk); this->bodyModel.bindAnim(&this->chrAnimation, unk2); this->chrAnimation.setUpdateRate(rate); } int daShyGuy::onCreate() { this->type = this->settings >> 28 & 0xF; int anim = this->settings >> 24 & 0xF; int baln = this->settings >> 20 & 0xF; this->distance = this->settings >> 12 & 0xF; if (type == 3) {this->renderBalloon = 1;} else if (type == 4) {this->renderBalloon = 1;} else if (type == 5) {this->renderBalloon = 1;} else {this->renderBalloon = 0;} OSReport("Creating the ShyGuy Model\n"); allocator.link(-1, GameHeaps[0], 0, 0x20); // Shy Guy Colours if (anim == 0) { this->resFile.data = getResource("lemmy_ball", "g3d/ShyGuyRed.brres"); } else if (anim == 1) { this->resFile.data = getResource("lemmy_ball", "g3d/ShyGuyBlue.brres"); } else if (anim == 2) { this->resFile.data = getResource("lemmy_ball", "g3d/ShyGuyGreen.brres"); } else if (anim == 3) { this->resFile.data = getResource("lemmy_ball", "g3d/ShyGuyCyan.brres"); } else if (anim == 4) { this->resFile.data = getResource("lemmy_ball", "g3d/ShyGuyPurple.brres"); } nw4r::g3d::ResMdl mdl = this->resFile.GetResMdl("body_h"); bodyModel.setup(mdl, &allocator, 0x224, 1, 0); // Balloon Model this->balloonFile.data = getResource("lemmy_ball", "g3d/balloon.brres"); nw4r::g3d::ResMdl mdlB = this->balloonFile.GetResMdl("ballon"); balloonModel.setup(mdlB, &allocator, 0x224, 1, 0); balloonModelB.setup(mdlB, &allocator, 0x224, 1, 0); // Animations start here this->anmFile.data = getResource("lemmy_ball", "g3d/ShyGuyAnimations.brres"); nw4r::g3d::ResAnmChr anmChr = this->anmFile.GetResAnmChr("c18_IDLE_R"); this->chrAnimation.setup(mdl, anmChr, &this->allocator, 0); allocator.unlink(); OSReport("Setting ShyGuy's Size to 1.0\n"); this->scale = (Vec){20.0, 20.0, 20.0}; OSReport("Creating ShyGuy's Physics Struct\n"); ActivePhysics::Info HitMeBaby; if (type == 8 || type == 10) { this->scale = (Vec){40.0, 40.0, 40.0}; HitMeBaby.xDistToCenter = 0.0; HitMeBaby.yDistToCenter = 24.0; HitMeBaby.xDistToEdge = 28.0; HitMeBaby.yDistToEdge = 24.0; } else { 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 = 0x8828E; HitMeBaby.unkShort1C = 0; HitMeBaby.callback = shyCollisionCallback; OSReport("Making the Physics Class and adding to the list\n"); this->aPhysics.initWithStruct(this, &HitMeBaby); this->aPhysics.addToList(); // Tile collider OSReport("Making the Tile collider Class\n"); _320 = 0.0f; _324 = 16.0f; spriteSomeRectX = 16.0f; spriteSomeRectY = 16.0f; _338 = 256.0f; _33C = 256.0f; _340 = 256.0f + 80.0f; _344 = 256.0f + 80.0f; static const u8 one[16] = {0x01,0x80,0x41,0x01, 0xFF,0xFF,0x80,0x00, 0x00,0x00,0x70,0x00, 0x00,0x00,0xE0,0x00}; static const u8 two[16] = {0x00,0x00,0x00,0x01, 0xFF,0xFF,0x80,0x00, 0x00,0x00,0x70,0x00, 0xFF,0xFF,0x20,0x00}; static const u8 three[16] = {0x01,0x80,0x41,0x01, 0xFF,0xFF,0x90,0x00, 0x00,0x00,0x80,0x00, 0x00,0x00,0xE0,0x00}; collMgr.Init(this, two, one, three); collMgr.execute(); cmgr_returnValue = collMgr.CollidedWithTile(); if (collMgr.CollidedWithTile()) isBouncing = false; else isBouncing = true; // Stuff I do understand OSReport("Setting up ShyGuy's Box of Goodies\n"); this->pos.y = this->pos.y + 30.0; // X is vertical axis this->rot.x = 0; // X is vertical axis this->rot.y = 0xD800; // Y is horizontal axis this->rot.z = 0; // Z is ... an axis >.> this->direction = 1; // Heading left. this->speed.x = 0; this->speed.y = 0.0; this->x_speed_inc = 0.1; this->Baseline = this->pos.y; this->XSpeed = 1.0; if (type == 0) { doStateChange(&StateID_Walk); } else if (type == 1) { doStateChange(&StateID_Sleep); } else if (type == 2) { doStateChange(&StateID_Jump); } else if (type == 3) { doStateChange(&StateID_Balloon_H); } else if (type == 4) { doStateChange(&StateID_Balloon_V); } else if (type == 5) { doStateChange(&StateID_Balloon_C); } else if (type == 6) { doStateChange(&StateID_Judo); } else if (type == 7) { doStateChange(&StateID_Spike); } else if (type == 8) { doStateChange(&StateID_Walk); } else if (type == 9) { doStateChange(&StateID_RealWalk); } else if (type == 10) { doStateChange(&StateID_RealWalk); } OSReport("Going to Execute ShyGuy\n"); this->onExecute(); return true; } int daShyGuy::onDelete() { return true; } int daShyGuy::onExecute() { acState.execute(); updateModelMatrices(); // if (this->aPhysics.result1 == 1) { // char PlayerID = NearestPlayer(this); // dStageActor_c *Player = GetSpecificPlayerActor(PlayerID); // this->_vf220(Player); // } return true; } int daShyGuy::onDraw() { bodyModel.scheduleForDrawing(); bodyModel._vf1C(); balloonModel.scheduleForDrawing(); balloonModelB.scheduleForDrawing(); return true; } void daShyGuy::updateModelMatrices() { // This won't work with wrap because I'm lazy. matrix.translation(pos.x, pos.y, pos.z); matrix.applyRotationYXZ(&rot.x, &rot.y, &rot.z); bodyModel.setDrawMatrix(matrix); bodyModel.setScale(&scale); bodyModel.calcWorld(false); if (this->renderBalloon == 1) { matrix.translation(pos.x, pos.y - 30.0, pos.z); balloonModel.setDrawMatrix(matrix); balloonModel.setScale(1.5, 1.5, 1.5); balloonModel.calcWorld(false); balloonModelB.setDrawMatrix(matrix); balloonModelB.setScale(1.5, 1.5, 1.5); balloonModelB.calcWorld(false); } } /////////////// // Walk State /////////////// void daShyGuy::beginState_Walk() { bindAnimChr_and_setUpdateRate("c18_EV_WIN_2_R", 1, 0.0, 1.5); this->timer = 0; if (this->direction == 1) { this->rot.y = 0xD800; } else { this->rot.y = 0x2800; } } void daShyGuy::executeState_Walk() { if (this->direction == 1) { this->pos.x -= 0.5; } else { this->pos.x += 0.5; } if(this->chrAnimation.isAnimationDone()) if (this->timer > (this->distance * 32)) { doStateChange(&StateID_Turn); } else { this->chrAnimation.setCurrentFrame(0.0); } this->timer = this->timer + 1; } void daShyGuy::endState_Walk() { } /////////////// // Turn State /////////////// void daShyGuy::beginState_Turn() { bindAnimChr_and_setUpdateRate("c18_IDLE_R", 1, 0.0, 1.0); this->timer = 0; } void daShyGuy::executeState_Turn() { int modifier = sin(this->timer * 3.14 / 30.0) * 0x5000; if (this->direction == 1) { this->rot.y = 0xD800 + modifier; } else { this->rot.y = 0x2800 - modifier; } if (this->timer >= 15) { doStateChange(&StateID_Walk); } if(this->chrAnimation.isAnimationDone()) { this->chrAnimation.setCurrentFrame(0.0); } this->timer += 1; } void daShyGuy::endState_Turn() { if (this->direction == 1) { this->direction = 0; } else { this->direction = 1; } } /////////////// // Jump State /////////////// void daShyGuy::beginState_Jump() { this->timer = 0; this->jumpCounter = 0; } void daShyGuy::executeState_Jump() { // Always face Mario u8 facing = dSprite_c__getXDirectionOfFurthestPlayerRelativeToVEC3(this, this->pos); if (facing != this->direction) { this->direction = facing; if (this->direction == 1) { this->rot.y = 0xD800; } else { this->rot.y = 0x2800; } } // Shy Guy is on ground if (this->pos.y < this->Baseline) { bindAnimChr_and_setUpdateRate("c18_IDLE_R", 1, 0.0, 1.0); this->timer = this->timer + 1; // Make him wait for 0.5 seconds if (this->timer > 30) { if(this->chrAnimation.isAnimationDone()) this->chrAnimation.setCurrentFrame(0.0); this->speed.x = 0; this->speed.y = 0; } // Then Jump! else { if (this->jumpCounter == 3) { this->jumpCounter = 0; } this->pos.y = this->Baseline + 1; this->timer = 0; this->jumpCounter = this->jumpCounter + 1; if (this->jumpCounter == 3) { bindAnimChr_and_setUpdateRate("c18_NORMAL_STEAL_R", 1, 0.0, 1.0); this->speed.y = 8.0; PlaySound(this, SE_PLY_JUMPDAI_HIGH); } else { bindAnimChr_and_setUpdateRate("c18_EV_WIN_1_R", 1, 0.0, 1.0); this->speed.y = 6.0; PlaySound(this, SE_PLY_JUMPDAI); } OSReport("Takeoff Initiated"); } } // While he's jumping, it's time for gravity. else { this->speed.y = this->speed.y - 0.15; if (this->jumpCounter == 3) { if(this->chrAnimation.isAnimationDone()) this->chrAnimation.setCurrentFrame(0.0); } else { if(this->chrAnimation.isAnimationDone()) this->chrAnimation.setCurrentFrame(0.0); } } this->HandleXSpeed(); this->HandleYSpeed(); this->UpdateObjectPosBasedOnSpeedValuesReal(); } void daShyGuy::endState_Jump() { } /////////////// // Sleep State /////////////// void daShyGuy::beginState_Sleep() { bindAnimChr_and_setUpdateRate("c18_EV_LOSE_2_R", 1, 0.0, 1.0); this->rot.y = 0x0000; } void daShyGuy::executeState_Sleep() { if(this->chrAnimation.isAnimationDone()) this->chrAnimation.setCurrentFrame(0.0); } void daShyGuy::endState_Sleep() { } /////////////// // Balloon H State /////////////// void daShyGuy::beginState_Balloon_H() { bindAnimChr_and_setUpdateRate("c18_L_DMG_F_3_R", 1, 0.0, 1.0); this->timer = 0; this->initialPos = this->pos; this->rot.x = 0xFE00; this->rot.y = 0; } void daShyGuy::executeState_Balloon_H() { // Makes him bob up and down this->pos.y = this->initialPos.y + ( sin(this->timer * 3.14 / 60.0) * 6.0 ); // Makes him move side to side this->pos.x = this->initialPos.x + ( sin(this->timer * 3.14 / 600.0) * (float)this->distance * 8.0); this->timer = this->timer + 1; if(this->chrAnimation.isAnimationDone()) this->chrAnimation.setCurrentFrame(0.0); } void daShyGuy::endState_Balloon_H() { } /////////////// // Balloon V State /////////////// void daShyGuy::beginState_Balloon_V() { bindAnimChr_and_setUpdateRate("c18_L_DMG_F_3_R", 1, 0.0, 1.0); this->timer = 0; this->initialPos = this->pos; this->rot.x = 0xFE00; this->rot.y = 0; } void daShyGuy::executeState_Balloon_V() { // Makes him bob up and down this->pos.x = this->initialPos.x + ( sin(this->timer * 3.14 / 60.0) * 6.0 ); // Makes him move side to side this->pos.y = this->initialPos.y + ( sin(this->timer * 3.14 / 600.0) * (float)this->distance * 8.0 ); this->timer = this->timer + 1; if(this->chrAnimation.isAnimationDone()) this->chrAnimation.setCurrentFrame(0.0); } void daShyGuy::endState_Balloon_V() { } /////////////// // Balloon C State /////////////// void daShyGuy::beginState_Balloon_C() { bindAnimChr_and_setUpdateRate("c18_L_DMG_F_3_R", 1, 0.0, 1.0); this->timer = 0; this->initialPos = this->pos; this->rot.x = 0xFE00; this->rot.y = 0; } void daShyGuy::executeState_Balloon_C() { // Makes him bob up and down this->pos.x = this->initialPos.x + ( sin(this->timer * 3.14 / 600.0) * (float)this->distance * 8.0 ); // Makes him move side to side this->pos.y = this->initialPos.y + ( cos(this->timer * 3.14 / 600.0) * (float)this->distance * 8.0 ); this->timer = this->timer + 1; if(this->chrAnimation.isAnimationDone()) this->chrAnimation.setCurrentFrame(0.0); } void daShyGuy::endState_Balloon_C() { } /////////////// // Judo State /////////////// void daShyGuy::beginState_Judo() { this->timer = 0; } void daShyGuy::executeState_Judo() { // chargin 476? 673? 760? 768? 808? 966? if (this->timer == 0) { bindAnimChr_and_setUpdateRate("c18_OB_IDLE_R", 1, 0.0, 1.0); } this->timer = this->timer + 1; if (this->timer == 80) { if (this->direction == 1) { CreateEffect(&(Vec){this->pos.x + 7.0, this->pos.y + 14.0, this->pos.z + 5600.0}, &(S16Vec){0,0,0}, &(Vec){0.8, 0.8, 0.8}, 966); } else { CreateEffect(&(Vec){this->pos.x - 7.0, this->pos.y + 14.0, this->pos.z}, &(S16Vec){0,0,0}, &(Vec){0.8, 0.8, 0.8}, 966); } } if (this->timer < 120) { // Always face Mario u8 facing = dSprite_c__getXDirectionOfFurthestPlayerRelativeToVEC3(this, this->pos); if (facing != this->direction) { this->direction = facing; if (this->direction == 1) { this->rot.y = 0xD800; } else { this->rot.y = 0x2800; } } if(this->chrAnimation.isAnimationDone()) this->chrAnimation.setCurrentFrame(0.0); } else if (this->timer == 120) { bindAnimChr_and_setUpdateRate("c18_H_CUT_R", 1, 0.0, 1.0); } else if (this->timer == 132) { PlaySound(this, SE_EMY_CRASHER_PUNCH); if (this->direction == 1) { CreateEffect(&(Vec){this->pos.x - 18.0, this->pos.y + 16.0, this->pos.z}, &(S16Vec){0,0,0}, &(Vec){1.5, 1.5, 1.5}, 123); changeActivePhysicsRect(this, 0.0, 12.0, 54.0, 12.0); } else { CreateEffect(&(Vec){this->pos.x + 18.0, this->pos.y + 16.0, this->pos.z}, &(S16Vec){0,0,0}, &(Vec){1.5, 1.5, 1.5}, 124); changeActivePhysicsRect(this, 20.0, 12.0, 34.0, 12.0); } } else { if(this->chrAnimation.isAnimationDone()) { if (this->direction == 1) { CreateEffect(&(Vec){this->pos.x - 38.0, this->pos.y + 16.0, this->pos.z}, &(S16Vec){0,0,0}, &(Vec){1.0, 1.0, 1.0}, 171); } else { CreateEffect(&(Vec){this->pos.x + 38.0, this->pos.y + 16.0, this->pos.z}, &(S16Vec){0,0,0}, &(Vec){1.0, 1.0, 1.0}, 171); } this->timer = 0; PlaySound(this, SE_EMY_BIG_PAKKUN_DAMAGE_1); changeActivePhysicsRect(this, 0.0, 12.0, 14.0, 12.0); } } } void daShyGuy::endState_Judo() { } /////////////// // Spike State /////////////// void daShyGuy::beginState_Spike() { this->timer = 0; } void daShyGuy::executeState_Spike() { if (this->timer == 0) { bindAnimChr_and_setUpdateRate("c18_OB_IDLE_R", 1, 0.0, 1.0); } this->timer = this->timer + 1; if (this->timer < 120) { // Always face Mario u8 facing = dSprite_c__getXDirectionOfFurthestPlayerRelativeToVEC3(this, this->pos); if (facing != this->direction) { this->direction = facing; if (this->direction == 1) { this->rot.y = 0xD800; } else { this->rot.y = 0x2800; } } if(this->chrAnimation.isAnimationDone()) this->chrAnimation.setCurrentFrame(0.0); } else if (this->timer == 120) { bindAnimChr_and_setUpdateRate("c18_H_SHOT_R", 1, 0.0, 1.0); } else if (this->timer == 160) { PlaySound(this, SE_EMY_KANIBO_THROW); Vec pos; pos.x = this->pos.x; pos.y = this->pos.y; pos.z = this->pos.z; if (this->direction == 1) { dStageActor_c *spawned = CreateActor(89, 0x2, pos, 0, 0); spawned->scale.x = 0.5; spawned->scale.y = 0.5; spawned->scale.z = 0.5; spawned->speed.x = -2.0; spawned->speed.y = 2.0; } else { dStageActor_c *spawned = CreateActor(89, 0x12, pos, 0, 0); spawned->scale.x = 0.5; spawned->scale.y = 0.5; spawned->scale.z = 0.5; spawned->speed.x = 2.0; spawned->speed.y = 2.0; } } else { if(this->chrAnimation.isAnimationDone()) { this->timer = 0; } } } void daShyGuy::endState_Spike() { } /////////////// // Real Walk State /////////////// void daShyGuy::beginState_RealWalk() { //inline this piece of code bindAnimChr_and_setUpdateRate("c18_EV_WIN_2_R", 1, 0.0, 1.5); this->max_speed.y = -4.0; this->speed.x = this->speed.z = 0.0; this->max_speed.x = (this->direction) ? -this->XSpeed : this->XSpeed; this->speed.y = -4.0; this->y_speed_inc = -0.1875; } void daShyGuy::executeState_RealWalk() { this->HandleXSpeed(); this->HandleYSpeed(); this->doSpriteMovement(); u16 amt = (this->direction == 0) ? 0x2800 : 0xD800; SmoothRotation(&this->rot.y, amt, 0x200); int ret = SomeStrangeModification(this); if(ret & 1) this->speed.y = 0.0; u32 bitfield = this->collMgr.bitfield_for_checks; if(bitfield & (0x15<direction)) { this->pos.x = this->last_pos.x; this->doStateChange(&StateID_RealTurn); } // collisionMgr_c ??? Seems like a useful function, not sure if it's mapped in game.h as something else, though u32 bitfield2 = this->collMgr.directional_bitfields[this->direction]; if(bitfield2) { this->doStateChange(&StateID_RealTurn); } DoStuffAndMarkDead(this, this->pos, 1.0); if(this->chrAnimation.isAnimationDone()) { this->chrAnimation.setCurrentFrame(0.0); } } void daShyGuy::endState_RealWalk() { } /////////////// // Real Turn State /////////////// void daShyGuy::beginState_RealTurn() { bindAnimChr_and_setUpdateRate("c18_IDLE_R", 1, 0.0, 1.0); this->direction ^= 1; this->speed.x = 0.0; } void daShyGuy::executeState_RealTurn() { if(this->chrAnimation.isAnimationDone()) { this->chrAnimation.setCurrentFrame(0.0); } this->HandleYSpeed(); this->doSpriteMovement(); int ret = SomeStrangeModification(this); if(ret & 1) this->speed.y = 0.0; if(ret & 4) this->pos.x = this->last_pos.x; DoStuffAndMarkDead(this, this->pos, 1.0); u16 amt = (this->direction == 0) ? 0x2800 : 0xD800; int done = SmoothRotation(&this->rot.y, amt, 0x200); if(done) { this->doStateChange(&StateID_RealWalk); } } void daShyGuy::endState_RealTurn() { this->max_speed.x = (this->direction) ? -this->XSpeed : this->XSpeed; } /////////////// // GoDizzy State /////////////// void daShyGuy::beginState_GoDizzy() { bindAnimChr_and_setUpdateRate("c18_L_DMG_F_1_R", 1, 0.0, 1.0); this->max_speed.y = -4.0; this->speed.x = 0; this->speed.y = -4.0; this->y_speed_inc = -0.1875; this->timer = 0; this->jumpCounter = 0; this->isDown = 1; } void daShyGuy::executeState_GoDizzy() { this->HandleYSpeed(); this->doSpriteMovement(); // Needs tile collision shit here, because jumpers can get hit and fall downwards. if (this->jumpCounter == 0) { if(this->chrAnimation.isAnimationDone()) { this->jumpCounter = 1; bindAnimChr_and_setUpdateRate("c18_L_DMG_F_3_R", 1, 0.0, 1.0); } } else { if(this->chrAnimation.isAnimationDone()) { this->chrAnimation.setCurrentFrame(0.0); } if (this->timer > 600) { doStateChange(&StateID_Recover) } this->timer += 1; } } void daShyGuy::endState_GoDizzy() {} /////////////// // BalloonDrop State /////////////// void daShyGuy::beginState_BalloonDrop() { this->isDown = 1; } void daShyGuy::executeState_BalloonDrop() { } void daShyGuy::endState_BalloonDrop() {} /////////////// // FireKnockBack State /////////////// void daShyGuy::beginState_FireKnockBack() { bindAnimChr_and_setUpdateRate("c18_C_BLOCK_BREAK_R", 1, 0.0, 1.0); // this->max_speed.x = (this->direction) ? -this->XSpeed : this->XSpeed; } void daShyGuy::executeState_FireKnockBack() { // move backwards here if(this->chrAnimation.isAnimationDone()) { // set state according to type } } void daShyGuy::endState_FireKnockBack() {} /////////////// // FlameHit State /////////////// void daShyGuy::beginState_FlameHit() { bindAnimChr_and_setUpdateRate("c18_L_DMG_F_4_R", 1, 0.0, 1.0); } void daShyGuy::executeState_FlameHit() { if(this->chrAnimation.isAnimationDone()) { // set state according to type } } void daShyGuy::endState_FlameHit() {} /////////////// // Recover State /////////////// void daShyGuy::beginState_Recover() { bindAnimChr_and_setUpdateRate("c18_L_DMG_F_4_R", 1, 0.0, 1.0); } void daShyGuy::executeState_Recover() { // Don't forget the tile collision shiz if(this->chrAnimation.isAnimationDone()) { // set state according to type } } void daShyGuy::endState_Recover() { this->isDown = 0; }