summaryrefslogtreecommitdiff
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
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 '')
-rw-r--r--NewerProject.yaml3
-rw-r--r--bossMegaGoomba.yaml9
-rw-r--r--include/common.h4
-rwxr-xr-xinclude/game.h25
-rw-r--r--kamek_ntsc.x13
-rw-r--r--kamek_ntsc2.x13
-rw-r--r--kamek_pal.x13
-rw-r--r--kamek_pal2.x13
-rw-r--r--src/bossMegaGoomba.cpp456
-rw-r--r--src/player.cpp35
-rw-r--r--src/player.h11
-rw-r--r--worldmap.yaml1
12 files changed, 595 insertions, 1 deletions
diff --git a/NewerProject.yaml b/NewerProject.yaml
index e3806e7..102ad32 100644
--- a/NewerProject.yaml
+++ b/NewerProject.yaml
@@ -29,4 +29,5 @@ modules:
- processed/compression.yaml
# - processed/crowdclapper.yaml
- processed/blocksnake.yaml
- - processed/classic_controller.yaml
+# - processed/classic_controller.yaml
+ - processed/bossMegaGoomba.yaml
diff --git a/bossMegaGoomba.yaml b/bossMegaGoomba.yaml
new file mode 100644
index 0000000..144e5ac
--- /dev/null
+++ b/bossMegaGoomba.yaml
@@ -0,0 +1,9 @@
+---
+# Replaces AC_BLOCK_GROUP
+
+source_files: [../src/bossMegaGoomba.cpp]
+hooks:
+ - name: MegaGoombaBuild
+ type: add_func_pointer
+ src_addr_pal: 0x80952e10
+ target_func: 'daMegaGoomba_c::build(void)'
diff --git a/include/common.h b/include/common.h
index 2e7dc80..e212eb4 100644
--- a/include/common.h
+++ b/include/common.h
@@ -44,6 +44,8 @@ typedef struct { f32 x, y, z; } VEC3, Vec, *VecPtr, Point3d, *Point3dPtr;
typedef struct { s16 x; s16 y; s16 z; }S16Vec, *S16VecPtr;
typedef struct { f32 x, y, z, w; } Quaternion, *QuaternionPtr, Qtrn, *QtrnPtr;
+typedef struct { f32 frame, value, slope; } HermiteKey;
+
extern "C" const char * strrchr ( const char * str, int character );
extern "C" int strcmp ( const char * str1, const char * str2 );
@@ -84,6 +86,8 @@ int memcmp(const void *ptr1, const void *ptr2, unsigned int num);
void *AllocFromGameHeap1(u32 size);
void FreeFromGameHeap1(void *block);
+float GetHermiteCurveValue(float current_frame, HermiteKey* keys, unsigned int key_count);
+
/* Archive */
/*#ifdef REGION_PAL
#define ARC_TABLE ((*((void**)0x8042A318))+4)
diff --git a/include/game.h b/include/game.h
index c57a93d..b6b07dd 100755
--- a/include/game.h
+++ b/include/game.h
@@ -2199,5 +2199,30 @@ inline u8 *getResource(const char *arcName, const char *fileName) {
return GetRes((void*)(((u8*)DVDClass)+4), arcName, fileName);
}
+inline void scaleDown(Vec* scale, float amt) { scale->x -= amt; scale->y -= amt; scale->z -= amt; }
+inline void scaleUp(Vec* scale, float amt) { scale->x -= amt; scale->y -= amt; scale->z -= amt; }
+inline void setNewActivePhysicsRect(dStageActor_c* actor, Vec* scale) {
+ float amtX = scale->x;
+ float amtY = scale->y;
+
+ ActivePhysics::Info info;
+ info.xDistToCenter = 0.0;
+ info.yDistToCenter = 3.0 * amtY;
+ info.xDistToEdge = 4.0 * amtX;
+ info.yDistToEdge = 4.0 * amtY;
+
+ info.category1 = actor->aPhysics.info.category1;
+ info.category2 = actor->aPhysics.info.category2;
+ info.bitfield1 = actor->aPhysics.info.bitfield1;
+ info.bitfield2 = actor->aPhysics.info.bitfield2;
+ info.unkShort1C = actor->aPhysics.info.unkShort1C;
+ info.callback = actor->aPhysics.info.callback;
+
+ OSReport("Making new Physics Class and adding to the list\n");
+ actor->aPhysics.removeFromList();
+ actor->aPhysics.initWithStruct(actor, &info);
+ actor->aPhysics.addToList();
+}
+
#endif
diff --git a/kamek_ntsc.x b/kamek_ntsc.x
index 802aba3..a9e44b5 100644
--- a/kamek_ntsc.x
+++ b/kamek_ntsc.x
@@ -403,6 +403,8 @@ SECTIONS {
instance__10dFlagMgr_c = 0x8042A078;
+ clear__13ActivePhysicsFv = 0x8008C2C0;
+ removeFromList__13ActivePhysicsFv = 0x8008C380;
addToList__13ActivePhysicsFv = 0x8008C330;
initWithStruct__13ActivePhysicsFP8dActor_cPQ213ActivePhysics4Info = 0x8008C3E0;
@@ -878,8 +880,16 @@ SECTIONS {
PSMTXScaleApply = 0x801C0C90;
PSMTXMultVec = 0x801C1160;
+ PSVECAdd = 0x801C13F0;
+ PSVECSubtract = 0x801C1420;
PSVECScale = 0x801C1450;
PSVECNormalize = 0x801C1470;
+ /*PSVECSquareMag*/
+ PSVECMag = 0x801C14C0;
+ PSVECDotProduct = 0x801C1510;
+ PSVECCrossProduct = 0x801C1530;
+ PSVECSquareDistance = 0x801C1570;
+ PSVECDistance = 0x801C1650;
C_MTXLookAt = 0x801C0DA0;
C_MTXFrustum = 0x801C11C0;
@@ -1063,6 +1073,9 @@ SECTIONS {
SomeWipeClass = 0x8042A440;
QueryGlobal5758 = 0x800B3B50;
+ GetHermiteCurveValue = 0x8017D520;
+ GetHermiteCurveValue__FfP10HermiteKeyUi = 0x8017D520;
+
.text : {
FILL (0)
diff --git a/kamek_ntsc2.x b/kamek_ntsc2.x
index 730ff74..7402da7 100644
--- a/kamek_ntsc2.x
+++ b/kamek_ntsc2.x
@@ -403,6 +403,8 @@ SECTIONS {
instance__10dFlagMgr_c = 0x8042A078;
+ clear__13ActivePhysicsFv = 0x8008C2C0;
+ removeFromList__13ActivePhysicsFv = 0x8008C380;
addToList__13ActivePhysicsFv = 0x8008C330;
initWithStruct__13ActivePhysicsFP8dActor_cPQ213ActivePhysics4Info = 0x8008C3E0;
@@ -878,8 +880,16 @@ SECTIONS {
PSMTXScaleApply = 0x801C0C90;
PSMTXMultVec = 0x801C1160;
+ PSVECAdd = 0x801C13F0;
+ PSVECSubtract = 0x801C1420;
PSVECScale = 0x801C1450;
PSVECNormalize = 0x801C1470;
+ /*PSVECSquareMag*/
+ PSVECMag = 0x801C14C0;
+ PSVECDotProduct = 0x801C1510;
+ PSVECCrossProduct = 0x801C1530;
+ PSVECSquareDistance = 0x801C1570;
+ PSVECDistance = 0x801C1650;
C_MTXLookAt = 0x801C0DA0;
C_MTXFrustum = 0x801C11C0;
@@ -1063,6 +1073,9 @@ SECTIONS {
SomeWipeClass = 0x8042A440;
QueryGlobal5758 = 0x800B3B50;
+ GetHermiteCurveValue = 0x8017D520;
+ GetHermiteCurveValue__FfP10HermiteKeyUi = 0x8017D520;
+
.text : {
FILL (0)
diff --git a/kamek_pal.x b/kamek_pal.x
index 8535c2c..2b545b8 100644
--- a/kamek_pal.x
+++ b/kamek_pal.x
@@ -403,6 +403,8 @@ SECTIONS {
instance__10dFlagMgr_c = 0x8042A358;
+ clear__13ActivePhysicsFv = 0x8008c2c0;
+ removeFromList__13ActivePhysicsFv = 0x8008c380;
addToList__13ActivePhysicsFv = 0x8008C330;
initWithStruct__13ActivePhysicsFP8dActor_cPQ213ActivePhysics4Info = 0x8008C3E0;
@@ -878,8 +880,16 @@ SECTIONS {
PSMTXScaleApply = 0x801C0DD0;
PSMTXMultVec = 0x801C12A0;
+ PSVECAdd = 0x801c1530;
+ PSVECSubtract = 0x801c1560;
PSVECScale = 0x801C1590;
PSVECNormalize = 0x801C15B0;
+ /*PSVECSquareMag*/
+ PSVECMag = 0x801c1600;
+ PSVECDotProduct = 0x801c1650;
+ PSVECCrossProduct = 0x801c1670;
+ PSVECSquareDistance = 0x801c16b0;
+ PSVECDistance = 0x801c1790;
C_MTXLookAt = 0x801C0EE0;
C_MTXFrustum = 0x801C1300;
@@ -1063,6 +1073,9 @@ SECTIONS {
SomeWipeClass = 0x8042A720;
QueryGlobal5758 = 0x800B3B50;
+ GetHermiteCurveValue = 0x8017d660;
+ GetHermiteCurveValue__FfP10HermiteKeyUi = 0x8017d660;
+
.text : {
FILL (0)
diff --git a/kamek_pal2.x b/kamek_pal2.x
index 1c25357..94c45e4 100644
--- a/kamek_pal2.x
+++ b/kamek_pal2.x
@@ -403,6 +403,8 @@ SECTIONS {
instance__10dFlagMgr_c = 0xDEADBEEF;
+ clear__13ActivePhysicsFv = 0xDEADBEEF;
+ removeFromList__13ActivePhysicsFv = 0xDEADBEEF;
addToList__13ActivePhysicsFv = 0xDEADBEEF;
initWithStruct__13ActivePhysicsFP8dActor_cPQ213ActivePhysics4Info = 0xDEADBEEF;
@@ -878,8 +880,16 @@ SECTIONS {
PSMTXScaleApply = 0xDEADBEEF;
PSMTXMultVec = 0xDEADBEEF;
+ PSVECAdd = 0xDEADBEEF;
+ PSVECSubtract = 0xDEADBEEF;
PSVECScale = 0xDEADBEEF;
PSVECNormalize = 0xDEADBEEF;
+ /*PSVECSquareMag*/
+ PSVECMag = 0xDEADBEEF;
+ PSVECDotProduct = 0xDEADBEEF;
+ PSVECCrossProduct = 0xDEADBEEF;
+ PSVECSquareDistance = 0xDEADBEEF;
+ PSVECDistance = 0xDEADBEEF;
C_MTXLookAt = 0xDEADBEEF;
C_MTXFrustum = 0xDEADBEEF;
@@ -1063,6 +1073,9 @@ SECTIONS {
SomeWipeClass = 0xDEADBEEF;
QueryGlobal5758 = 0xDEADBEEF;
+ GetHermiteCurveValue = 0xDEADBEEF;
+ GetHermiteCurveValue__FfP10HermiteKeyUi = 0xDEADBEEF;
+
.text : {
FILL (0)
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() { }
diff --git a/src/player.cpp b/src/player.cpp
new file mode 100644
index 0000000..ec638d4
--- /dev/null
+++ b/src/player.cpp
@@ -0,0 +1,35 @@
+#include "player.h"
+
+// Please set your dStageActor_c's z coordinate
+// Please check return for -1
+char NearestPlayer(dStageActor_c* actor) {
+ char nearest = -1;
+ float current = 3000000.0;
+
+ OSReport("FINDING NEAREST PLAYER\n");
+ for(char ii = 0; ii < 4; ii++) {
+ OSReport("K, let's check out Player %d\n", ii);
+ dStageActor_c* player = GetSpecificPlayerActor(ii);
+ if(!player) {
+ OSReport("Player %d is NULL\n", ii);
+ continue;
+ }
+ OSReport("Player %d is ok\n", ii);
+ OSReport("[%f,%f,%f] - [%f,%f,%f]\n",
+ actor->pos.x, actor->pos.y, actor->pos.z,
+ player->pos.x, player->pos.y, player->pos.z);
+ float distance = VECDistance(&actor->pos, &player->pos);
+ OSReport("Distance: %f [%f]\n", distance, current);
+ if(distance < current) {
+ current = distance;
+ nearest = ii;
+ OSReport("Nearest is now %d\n", ii);
+ }
+ }
+ OSReport("NearestPlayer returning %d\n", nearest);
+ if(nearest < 0) {
+ OSReport("***FIX ME IMMEDIATELY***\n***NEED Z COORDINATES FOR ACTOR***\n");
+ }
+ return nearest;
+}
+
diff --git a/src/player.h b/src/player.h
new file mode 100644
index 0000000..d225083
--- /dev/null
+++ b/src/player.h
@@ -0,0 +1,11 @@
+#ifndef __PLAYER_H
+#define __PLAYER_H
+
+#include <common.h>
+#include <game.h>
+
+extern "C" dStageActor_c* GetSpecificPlayerActor(int number);
+char NearestPlayer(dStageActor_c* actor);
+
+#endif
+
diff --git a/worldmap.yaml b/worldmap.yaml
index c59db28..c49748d 100644
--- a/worldmap.yaml
+++ b/worldmap.yaml
@@ -6,6 +6,7 @@ source_files:
- ../src/levelinfo.cpp
- ../src/layoutlib.S
- ../src/scene.S
+ - ../src/player.cpp
hooks:
- name: BuildWorldMap