diff options
-rw-r--r-- | NewerProject.yaml | 3 | ||||
-rw-r--r-- | bossMegaGoomba.yaml | 9 | ||||
-rw-r--r-- | include/common.h | 4 | ||||
-rwxr-xr-x | include/game.h | 25 | ||||
-rw-r--r-- | kamek_ntsc.x | 13 | ||||
-rw-r--r-- | kamek_ntsc2.x | 13 | ||||
-rw-r--r-- | kamek_pal.x | 13 | ||||
-rw-r--r-- | kamek_pal2.x | 13 | ||||
-rw-r--r-- | src/bossMegaGoomba.cpp | 456 | ||||
-rw-r--r-- | src/player.cpp | 35 | ||||
-rw-r--r-- | src/player.h | 11 | ||||
-rw-r--r-- | worldmap.yaml | 1 |
12 files changed, 595 insertions, 1 deletions
diff --git a/NewerProject.yaml b/NewerProject.yaml index 49d727d..36696f4 100644 --- a/NewerProject.yaml +++ b/NewerProject.yaml @@ -31,4 +31,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 a13d9e0..2c46371 100644 --- a/kamek_pal.x +++ b/kamek_pal.x @@ -417,6 +417,8 @@ SECTIONS { instance__10dFlagMgr_c = 0x8042A358; + clear__13ActivePhysicsFv = 0x8008c2c0; + removeFromList__13ActivePhysicsFv = 0x8008c380; addToList__13ActivePhysicsFv = 0x8008C330; initWithStruct__13ActivePhysicsFP8dActor_cPQ213ActivePhysics4Info = 0x8008C3E0; @@ -892,8 +894,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; @@ -1077,6 +1087,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
|