diff options
Diffstat (limited to '')
-rw-r--r-- | src/bossMegaGoomba.cpp | 456 |
1 files changed, 456 insertions, 0 deletions
diff --git a/src/bossMegaGoomba.cpp b/src/bossMegaGoomba.cpp new file mode 100644 index 0000000..65bbdb2 --- /dev/null +++ b/src/bossMegaGoomba.cpp @@ -0,0 +1,456 @@ +#include <common.h> +#include <game.h> +#include <g3dhax.h> + +#include "player.h" + +class daMegaGoomba_c : public dEn_c { + int onCreate(); + int onDelete(); + int onExecute(); + int onDraw(); + + mHeapAllocator_c allocator; + m3d::mdl_c bodyModel; + + float timer; + nw4r::ut::Rect Bounding; + float dying; + + HermiteKey keysX[0x10]; + unsigned int Xkey_count; + HermiteKey keysY[0x10]; + unsigned int Ykey_count; +// HermiteKey keysZ[0x10]; +// unsigned int Zkey_count; + + char life; + bool takeHit(char count); + + void dieFall_Execute(); + static daMegaGoomba_c *build(); + + void updateModelMatrices(); + +// bool preSpriteCollision(ActivePhysics *apThis, ActivePhysics *apOther); +// bool prePlayerCollision(ActivePhysics *apThis, ActivePhysics *apOther); +// bool preYoshiCollision(ActivePhysics *apThis, ActivePhysics *apOther); + +// bool stageActorCollision(ActivePhysics *apThis, ActivePhysics *apOther); +// void spriteCollision(ActivePhysics *apThis, ActivePhysics *apOther); +// void playerCollision(ActivePhysics *apThis, ActivePhysics *apOther); +// void yoshiCollision(ActivePhysics *apThis, ActivePhysics *apOther); + + void collisionCat1_Fireball_E_Explosion(ActivePhysics *apThis, ActivePhysics *apOther); + bool collisionCat2_IceBall_15_YoshiIce(ActivePhysics *apThis, ActivePhysics *apOther); + void collisionCat3_StarPower(ActivePhysics *apThis, ActivePhysics *apOther); + void collisionCat5_Mario(ActivePhysics *apThis, ActivePhysics *apOther); + void collisionCat9_RollingObject(ActivePhysics *apThis, ActivePhysics *apOther); + void collisionCatA_PenguinMario(ActivePhysics *apThis, ActivePhysics *apOther); + void collisionCatD_GroundPound(ActivePhysics *apThis, ActivePhysics *apOther); + void collisionCat11_PipeCannon(ActivePhysics *apThis, ActivePhysics *apOther); + void collisionCat13_Hammer(ActivePhysics *apThis, ActivePhysics *apOther); + void collisionCat14_YoshiFire(ActivePhysics *apThis, ActivePhysics *apOther); + void _vf120(ActivePhysics *apThis, ActivePhysics *apOther); + void _vf110(ActivePhysics *apThis, ActivePhysics *apOther); + void _vf108(ActivePhysics *apThis, ActivePhysics *apOther); + + USING_STATES(daMegaGoomba_c); + DECLARE_STATE(Grow); + DECLARE_STATE(Shrink); + DECLARE_STATE(Walk); + DECLARE_STATE(Jump); + DECLARE_STATE(Launch); +}; + +//extern void * HandleXSpeed(daMegaGoomba_c*); +//extern void * HandleYSpeed(daMegaGoomba_c*); + +daMegaGoomba_c *daMegaGoomba_c::build() { + void *buffer = AllocFromGameHeap1(sizeof(daMegaGoomba_c)); + return new(buffer) daMegaGoomba_c; +} + + +extern "C" void *HandleXSpeed(daMegaGoomba_c *); +extern "C" void *HandleYSpeed(daMegaGoomba_c *); +extern "C" void *UpdateObjectPosBasedOnSpeedValues_real(daMegaGoomba_c *); +extern "C" u32 GenerateRandomNumber(int max); +extern "C" u8 dSprite_c__getXDirectionOfFurthestPlayerRelativeToVEC3(daMegaGoomba_c *, Vec pos); +extern "C" dStageActor_c *CreateActor(u16 classID, int settings, Vec pos, char rot, char layer); +extern "C" dStageActor_c *GetSpecificPlayerActor(int number); + + +CREATE_STATE(daMegaGoomba_c, Grow); +CREATE_STATE(daMegaGoomba_c, Shrink); +CREATE_STATE(daMegaGoomba_c, Walk); +CREATE_STATE(daMegaGoomba_c, Jump); +CREATE_STATE(daMegaGoomba_c, Launch); + + +//TODO better fix for possible bug with sign (ex. life=120; count=-9;) +bool daMegaGoomba_c::takeHit(char count) { + int c = count; + int l = this->life; + if(l - c > 127) { + c = 127 - l; + } + this->life -= c; + doStateChange(&StateID_Shrink); + setNewActivePhysicsRect(this, &this->scale); + return (life <= 0) ? true : false; +} + +#define ACTIVATE 1 +#define DEACTIVATE 0 + +//bool daMegaGoomba_c::preSpriteCollision(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("preSpriteCollision\n"); return false; } +//bool daMegaGoomba_c::prePlayerCollision(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("prePlayerCollision\n"); return false; } +//bool daMegaGoomba_c::preYoshiCollision(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("preYoshiCollision\n"); return false; } + + +//bool daMegaGoomba_c::stageActorCollision(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("stageActorCollision\n"); return true; } +//void daMegaGoomba_c::spriteCollision(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("spriteCollision\n"); } +/*void daMegaGoomba_c::playerCollision(ActivePhysics *apThis, ActivePhysics *apOther) { + this->_vf220(apOther->owner); + OSReport("I hit Mario.\n"); +}*/ +//void daMegaGoomba_c::yoshiCollision(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("yoshiCollision\n"); } + + +void daMegaGoomba_c::collisionCat1_Fireball_E_Explosion(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("Hit Fireball\n"); } +bool daMegaGoomba_c::collisionCat2_IceBall_15_YoshiIce(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("Hit Iceball\n"); return false; } +void daMegaGoomba_c::collisionCat3_StarPower(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("Hit StarMario\n"); } +void daMegaGoomba_c::collisionCat5_Mario(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("MarioHit\n"); } +void daMegaGoomba_c::collisionCat9_RollingObject(ActivePhysics *apThis, ActivePhysics *apOther) { + OSReport("Hit Rolling Object\n"); + if(this->takeHit(1)) + doStateChange(&StateID_DieFall); +} +void daMegaGoomba_c::collisionCatA_PenguinMario(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("Penguin Attack\n"); } +void daMegaGoomba_c::collisionCatD_GroundPound(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("Groundpound\n"); } +void daMegaGoomba_c::collisionCat11_PipeCannon(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("PipeCannon Hit\n"); } +void daMegaGoomba_c::collisionCat13_Hammer(ActivePhysics *apThis, ActivePhysics *apOther) { + OSReport("Hit Hammer\n"); + if(this->takeHit(1)) + doStateChange(&StateID_DieFall); +} +void daMegaGoomba_c::collisionCat14_YoshiFire(ActivePhysics *apThis, ActivePhysics *apOther) { + OSReport("Hit Yoshi Fire\n"); + if(this->takeHit(1)) + doStateChange(&StateID_DieFall); +} +void daMegaGoomba_c::_vf120(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("_vf120:\n"); } +void daMegaGoomba_c::_vf110(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("_vf110:\n"); } +void daMegaGoomba_c::_vf108(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("_vf108:\n"); } + + + +//TODO make this real perty like +void daMegaGoomba_c::dieFall_Execute() { + + this->timer = this->timer + 1.0; + + this->dying = this->dying + 0.15; + + this->pos.x = this->pos.x + 0.15; + this->pos.y = this->pos.y + ((-0.2 * (this->dying*this->dying)) + 5); + + this->dEn_c::dieFall_Execute(); +} + +int daMegaGoomba_c::onCreate() { + + OSReport("Creating the MegaGoomba Model\n"); + allocator.link(-1, GameHeaps[0], 0, 0x20); + + nw4r::g3d::ResFile rf(getResource("kuribo", "g3d/t02.brres")); + bodyModel.setup(rf.GetResMdl("kuribo"), &allocator, 0x224, 1, 0); + SetupTextures_Enemy(&bodyModel, 0); + + allocator.unlink(); + + OSReport("Creating MegaGoomba's Physics Struct\n"); + + // Keeping naming + ActivePhysics::Info HitMeBaby; + HitMeBaby.xDistToCenter = 0.0; + HitMeBaby.yDistToCenter = 18.0; + HitMeBaby.xDistToEdge = 24.0; + HitMeBaby.yDistToEdge = 24.0; + + //TODO find data for a fun, yet challenging, battle + HitMeBaby.category1 = 0x3; + HitMeBaby.category2 = 0x0; + HitMeBaby.bitfield1 = 0x4f; + HitMeBaby.bitfield2 = 0xffba7ffe; + HitMeBaby.unkShort1C = 0; + HitMeBaby.callback = &dEn_c::collisionCallback; + + + OSReport("Making the Physics Class and adding to the list\n"); + this->aPhysics.initWithStruct(this, &HitMeBaby); + this->aPhysics.addToList(); + + pos.y -= 20.0; + pos.z = 3000.0; + rot.x = rot.y = rot.z = speed.x = dying = 0.0; + direction = 0; + life = 3; + //TODO 1) allow setting bounding rect with settings + //TODO 2) don't use bounding rect. use wall/floor/ceiling detection + Bounding.left = pos.x - 350.0; + Bounding.top = pos.y + 500.0; + Bounding.right = pos.x + 350.0; + Bounding.bottom = pos.y; + + OSReport("Setting MegaGoomba's State\n"); + doStateChange(&StateID_Grow); + + OSReport("Going to Execute MegaGoomba\n"); + this->onExecute(); + return true; +} + +int daMegaGoomba_c::onDelete() { + return true; +} + +int daMegaGoomba_c::onExecute() { + acState.execute(); + updateModelMatrices(); + + if (this->aPhysics.result1 == 1) { + + char PlayerID = NearestPlayer(this); + if(PlayerID > 0) { + dStageActor_c *Player = GetSpecificPlayerActor(PlayerID); + this->_vf220(Player); + } + } + + return true; +} + +int daMegaGoomba_c::onDraw() { + bodyModel.scheduleForDrawing(); + return true; +} + + +void daMegaGoomba_c::updateModelMatrices() { + // Bounds checking + // TODO possibly change to a state change + if(this->pos.x < this->Bounding.left) { + this->direction = !this->direction; + this->speed.x = -this->speed.x; + this->pos.x = this->Bounding.left; + } else if (this->pos.x > this->Bounding.right) { + this->direction = !this->direction; + this->speed.x = -this->speed.x; + this->pos.x = this->Bounding.right; + } + if(this->pos.y < this->Bounding.bottom) { + this->speed.y = 0.0; + this->pos.y = this->Bounding.bottom; + } else if (this->pos.y > this->Bounding.top) { + this->speed.y = 0.0; + this->pos.y = this->Bounding.bottom; + } + + // 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); +} + + +// Grow State +void daMegaGoomba_c::beginState_Grow() { + this->timer = 1.0; + + float start, end, shift1, shift2; + start = 59.0; + shift1 = 90.0; + shift2 = 120.0; + end = 139.0; + /* keysX[i] = { frame, value, slope }; */ + Xkey_count = 7; + keysX[0] = (HermiteKey){ start, 1.0, 1.0 }; + keysX[1] = (HermiteKey){ (start+shift1)/2, 2.0, 1.0 }; + keysX[2] = (HermiteKey){ shift1, 4.0, 1.0 }; + keysX[3] = (HermiteKey){ (shift1+shift2)/2, 3.0, 1.0 }; + keysX[3] = (HermiteKey){ shift2, 6.0, 1.0 }; + keysX[3] = (HermiteKey){ (shift2+end)/2, 5.0, 1.0 }; + keysX[6] = (HermiteKey){ end, 7.0, 1.0 }; +} +void daMegaGoomba_c::executeState_Grow() { + + this->timer += 1.0; + + if ((this->timer > 60.0) && (this->timer < 140.0)) { + + float modifier = GetHermiteCurveValue(this->timer, this->keysX, Xkey_count); + this->scale = (Vec){modifier, modifier, modifier}; + setNewActivePhysicsRect(this, &this->scale); + + } + //TODO grow sound + //if(this->timer == 60.0) + // playSound(SE_GROW); + + if (this->timer > 170.0) { doStateChange(&StateID_Walk); } + +} +void daMegaGoomba_c::endState_Grow() { } + + +// Shrink State +void daMegaGoomba_c::beginState_Shrink() { + this->timer = 1.0; + Xkey_count = 4; + keysX[0] = (HermiteKey){ 0.0, this->scale.x, 1.0 }; + keysX[1] = (HermiteKey){ 20.0, this->scale.x - 2.0, 1.0 }; + keysX[2] = (HermiteKey){ 40.0, this->scale.x, 1.0 }; + keysX[3] = (HermiteKey){ 59.0, this->scale.x - 2.0, 1.0 }; +} +void daMegaGoomba_c::executeState_Shrink() { + this->timer += 1.0; + + float modifier = GetHermiteCurveValue(this->timer, this->keysX, Xkey_count); + this->scale = (Vec){modifier, modifier, modifier}; + setNewActivePhysicsRect(this, &this->scale); + + //TODO shrink sound + //if(this->timer == 2.0) + // playSound(SE_SHRINK); + + if (this->timer > 60.0) { doStateChange(&StateID_Walk); } +} +void daMegaGoomba_c::endState_Shrink() { } + + + +// Launch State - Launches some small goombas up in arcs +void daMegaGoomba_c::beginState_Launch() { + this->timer = 0.0; +} +void daMegaGoomba_c::executeState_Launch() { + + if (this->timer < 120.0) { + // 3 shakes per second, exactly 24 shakes overall + this->rot.y = sin(this->timer * 3.14 / 5) * 4000; + + dStageActor_c *spawner = NULL; + // 120ticks / 40numbers * 2cases = 6avg kuribo + int randChoice = GenerateRandomNumber(40); + int randChoiceX = GenerateRandomNumber(12); + int randChoiceY = GenerateRandomNumber(12); + switch(randChoice) { + case 0: + case 1: + spawner = CreateActor(EN_KURIBO, 0, this->pos, 0, 0); + spawner->speed.x = randChoiceX - 6.0; + spawner->speed.y = randChoiceY * 1.0; + spawner->scale = (Vec){1.0, 1.0, 1.0}; + break; + case 2: + spawner = CreateActor(EN_BEANS_KURIBO, 0, this->pos, 0, 0); + spawner->speed.x = randChoiceX - 12.0; + spawner->speed.y = randChoiceY * 1.0; + spawner->scale = (Vec){1.0, 1.0, 1.0}; + break; + default: + break; + }; + } + + if (this->timer > 150.0) { doStateChange(&StateID_Walk); } + this->timer = this->timer + 1.0; +} +void daMegaGoomba_c::endState_Launch() { + this->rot.y = 0; +} + +// Jump State +void daMegaGoomba_c::beginState_Jump() { + this->timer = 1.0; + + //Variables for choosing a curve + float jump_height = 36.0; + float delta = (this->direction) ? -24.0 : 24.0; + float fullTime = 90.0; + //Key count + Xkey_count = 2; + Ykey_count = 3; + + //Initial Position + keysX[0] = (HermiteKey){ 0.0, this->pos.x, 0.0 }; + keysY[0] = (HermiteKey){ 0.0, this->pos.y, 0.8 }; + + //Middle Position + keysY[1] = (HermiteKey){ (fullTime/2.0), this->pos.y + jump_height, 0.0 }; + + //End Position + keysX[1] = (HermiteKey){ fullTime, this->pos.x + delta, 0.0 }; + keysY[2] = (HermiteKey){ fullTime, this->pos.y, 0.8 }; + +} +void daMegaGoomba_c::executeState_Jump() { + + this->pos.x = GetHermiteCurveValue(this->timer, this->keysX, Xkey_count); + this->pos.y = GetHermiteCurveValue(this->timer, this->keysY, Ykey_count); + + float TimerMax = 91.0; + if (this->timer > TimerMax) { + doStateChange(&StateID_Walk); + } + + this->timer = this->timer + 1.0; + +} +void daMegaGoomba_c::endState_Jump() { } + + +// Walk State +void daMegaGoomba_c::beginState_Walk() { + this->timer = 1.0; + this->direction = dSprite_c__getXDirectionOfFurthestPlayerRelativeToVEC3(this, this->pos); + //TODO add rot.changing on switching directions until animations added +} +void daMegaGoomba_c::executeState_Walk() { + + float delta = (this->direction) ? -0.5 : 0.5; + this->pos.x += delta; + + int Choice; + float TimerMax = 150.0; + if (this->timer > TimerMax) { + + Choice = GenerateRandomNumber(4); + switch(Choice) { + case 0: + doStateChange(&StateID_Jump); + break; + case 1: + doStateChange(&StateID_Launch); + break; + case 2: + break; + //FIXME test case for sound effects + //case 3: + // break; + default: + this->direction = dSprite_c__getXDirectionOfFurthestPlayerRelativeToVEC3(this, pos); + this->timer = 0; + break; + }; + + } + + this->timer = this->timer + 1.0; +} +void daMegaGoomba_c::endState_Walk() { } |