summaryrefslogtreecommitdiff
path: root/src/bossMegaGoomba.cpp
diff options
context:
space:
mode:
authorStephen Simpson <megazig@gmail.com>2011-10-10 16:04:33 -0500
committerStephen Simpson <megazig@gmail.com>2011-10-10 16:04:33 -0500
commita61758720db96f59e0fb82aab9f326d37e186a11 (patch)
tree8df4117f3723132afa42ecd35e28189b3b69196b /src/bossMegaGoomba.cpp
parent9cde0784c0d82a4e95d7ff7195537d3a519efeb9 (diff)
downloadkamek-a61758720db96f59e0fb82aab9f326d37e186a11.tar.gz
kamek-a61758720db96f59e0fb82aab9f326d37e186a11.zip
got MountainGoomba to a working condition
added Hermite Interpolation into linker and common.h added player.cpp and player.h for some common functions removed classic controller hack from NewerProject.yaml added more PSVEC functions to linker
Diffstat (limited to 'src/bossMegaGoomba.cpp')
-rw-r--r--src/bossMegaGoomba.cpp456
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() { }