summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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