From 4d5d95ec2c70578627353e40047462c82ac695c1 Mon Sep 17 00:00:00 2001 From: Stephen Simpson Date: Wed, 19 Oct 2011 12:27:26 -0500 Subject: added player and sprite collision to MG added a Turn state to MG semi-fixed collision box for MG --- src/bossMegaGoomba.cpp | 349 +++++++++++++++++++++++++++++++++++-------------- src/player.cpp | 4 +- 2 files changed, 256 insertions(+), 97 deletions(-) (limited to 'src') diff --git a/src/bossMegaGoomba.cpp b/src/bossMegaGoomba.cpp index bac2516..34f521e 100644 --- a/src/bossMegaGoomba.cpp +++ b/src/bossMegaGoomba.cpp @@ -34,6 +34,7 @@ class daMegaGoomba_c : public dEn_c { unsigned int Ykey_count; char life; + bool already_hit; //TODO use these for MegaGecko testing of params u32 marker1_start; @@ -58,13 +59,13 @@ class daMegaGoomba_c : public dEn_c { void setupBodyModel(); void updateModelMatrices(); -// bool preSpriteCollision(ActivePhysics *apThis, ActivePhysics *apOther); -// bool prePlayerCollision(ActivePhysics *apThis, ActivePhysics *apOther); + 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 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); @@ -85,8 +86,10 @@ class daMegaGoomba_c : public dEn_c { DECLARE_STATE(Grow); DECLARE_STATE(Shrink); DECLARE_STATE(Walk); + DECLARE_STATE(Turn); DECLARE_STATE(Jump); DECLARE_STATE(Launch); + //DECLARE_STATE(SomethingCool); }; daMegaGoomba_c *daMegaGoomba_c::build() { @@ -94,6 +97,32 @@ daMegaGoomba_c *daMegaGoomba_c::build() { return new(buffer) daMegaGoomba_c; } +void HexDump(char* address, u32 length) { + length = (length + 0x1f) & ~0x1f; + char line[0x11] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + for(u32 ii=0; ii < length; ii += 0x10) { + for(u32 jj=0; jj < 0x10; jj++) { + if((address[ii+jj] < 0x20) || (address[ii+jj] > 0x7e)) { + line[jj] = '.'; + }else{ + line[jj] = address[ii+jj]; + } + } + OSReport("%08x: %04x %04x %04x %04x %04x %04x %04x %04x |%s|\n", + (u32)(address+ii), + *(u16*)(address+ii+0x00), + *(u16*)(address+ii+0x02), + *(u16*)(address+ii+0x04), + *(u16*)(address+ii+0x06), + *(u16*)(address+ii+0x08), + *(u16*)(address+ii+0x0a), + *(u16*)(address+ii+0x0c), + *(u16*)(address+ii+0x0e), + line); + for(u32 jj=0; jj<0x10; jj++) line[jj] = 0; + } +} + extern "C" void *PlaySound(daMegaGoomba_c *, int soundID); @@ -106,45 +135,113 @@ extern "C" u8 dSprite_c__getXDirectionOfFurthestPlayerRelativeToVEC3(daMegaGoomb extern "C" dStageActor_c *CreateActor(u16 classID, int settings, Vec pos, char rot, char layer); extern "C" dStageActor_c *GetSpecificPlayerActor(int number); +//FIXME make this dEn_c->used... +extern "C" char usedForDeterminingStatePress_or_playerCollision(dEn_c* t, ActivePhysics *apThis, ActivePhysics *apOther, int unk1); +extern "C" void doSpriteMovement(dStageActor_c* actor); +extern "C" int SomeStrangeModification(dStageActor_c* actor); +extern "C" int CollidedWithTile(u8* c_1EC); +extern "C" void DoStuffAndMarkDead(dStageActor_c *actor, Vec vector, float unk); +extern "C" int SmoothRotation(short* rot, u16 amt, int unk2); + CREATE_STATE(daMegaGoomba_c, Grow); CREATE_STATE(daMegaGoomba_c, Shrink); CREATE_STATE(daMegaGoomba_c, Walk); +CREATE_STATE(daMegaGoomba_c, Turn); CREATE_STATE(daMegaGoomba_c, Jump); CREATE_STATE(daMegaGoomba_c, Launch); +//CREATE_STATE(daMegaGoomba_c, SomethingCool); //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; + if(!this->already_hit) { + int c = count; + int l = this->life; + if(l - c > 127) { + c = 127 - l; + } + this->life -= c; + this->XSpeed += 0.25; + this->JumpHeight += 12.0; + this->JumpDist += 12.0; + this->JumpTime += 5.0; + doStateChange(&StateID_Shrink); + this->already_hit = true; } - this->life -= c; - this->XSpeed += 0.25; - this->JumpHeight += 12.0; - this->JumpDist += 12.0; - this->JumpTime += 5.0; - 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::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::spriteCollision(ActivePhysics *apThis, ActivePhysics *apOther) { + OSReport("spriteCollision\n"); + float me = apThis->firstFloatArray[3]; + if(((this->direction == 1) && (me > 0.0)) || ((this->direction == 0) && (me < 0.0))) { + dStateBase_c* state = this->acState.getCurrentState(); + if(!state->isEqual(&StateID_Turn)) { + doStateChange(&StateID_Turn); + } + } +} + +void daMegaGoomba_c::playerCollision(ActivePhysics *apThis, ActivePhysics *apOther) { + OSReport("Mario collision.\n"); + + //FIXME rename and make part of dStageActor_c + char ret = usedForDeterminingStatePress_or_playerCollision(this, apThis, apOther, 0); + if(ret == 1) { // regular jump + // _vf2D8 == play_SE_EMY_KURIBO_M_SPLIT + //this->_vf2D8(); + // _vf2DC == nullsub() + //this->_vf2DC(); + apOther->someFlagByte |= 2; + OSReport("ret == 1; doStateChange('&StateID_SomethingCool');\n"); + if(this->takeHit(1)) + doStateChange(&StateID_DieFall); + } else if(ret == 3) { // spinning + // _vf2D8 == play_SE_EMY_KURIBO_M_SPLIT + //this->_vf2D8(); + // _vf2DC == nullsub() + //this->_vf2DC(); + apOther->someFlagByte |= 2; + OSReport("ret == 3; doStateChange('&StateID_SomethingCool');\n"); + if(this->takeHit(1)) + doStateChange(&StateID_DieFall); + //this->doStateChange(&StateID_SomethingCool); + } else if(ret == 0) { + OSReport("calling dEn_c::playerCollsiion(apThis, apOther);\n"); + this->dEn_c::playerCollision(apThis, apOther); + this->_vf220(apOther->owner); + } else if(ret == 2) { + OSReport("Y U USIN' MINIMARIO?\n"); + } else { + OSReport("usedForDeter...() returned %d\n", ret); + } + + //FIXME hack to make multiple playerCollisions work + this->isDead = 0; + this->flags_4FC |= (1<<(31-7)); + if(apOther->owner->_38D > 3) { + OSReport("!!!ATTENTION!!!\napOther->owner->_38D > 3\n"); + }else{ + this->counter_504[apOther->owner->_38D] = 0; + } +} + //void daMegaGoomba_c::yoshiCollision(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("yoshiCollision\n"); } @@ -184,7 +281,7 @@ void daMegaGoomba_c::bindAnimChr_and_setUpdateRate(const char* name, int unk, fl void daMegaGoomba_c::dieFall_Begin() { // DOESN'T LOOK GOOD //this->bindAnimChr_and_setUpdateRate("damage", 0, 0.0, 1.0); - //dSprite_c::dieFall_Begin(); + this->dEn_c::dieFall_Begin(); } //TODO make this real perty like void daMegaGoomba_c::dieFall_Execute() { @@ -199,32 +296,6 @@ void daMegaGoomba_c::dieFall_Execute() { this->dEn_c::dieFall_Execute(); } -void HexDump(char* address, u32 length) { - length = (length + 0x1f) & ~0x1f; - char line[0x11] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - for(u32 ii=0; ii < length; ii += 0x10) { - for(u32 jj=0; jj < 0x10; jj++) { - if((address[ii+jj] < 0x20) || (address[ii+jj] > 0x7e)) { - line[jj] = '.'; - }else{ - line[jj] = address[ii+jj]; - } - } - OSReport("%08x: %04x %04x %04x %04x %04x %04x %04x %04x |%s|\n", - (u32)(address+ii), - *(u16*)(address+ii+0x00), - *(u16*)(address+ii+0x02), - *(u16*)(address+ii+0x04), - *(u16*)(address+ii+0x06), - *(u16*)(address+ii+0x08), - *(u16*)(address+ii+0x0a), - *(u16*)(address+ii+0x0c), - *(u16*)(address+ii+0x0e), - line); - for(u32 jj=0; jj<0x10; jj++) line[jj] = 0; - } -} - void daMegaGoomba_c::setupBodyModel() { allocator.link(-1, GameHeaps[0], 0, 0x20); @@ -280,6 +351,14 @@ int daMegaGoomba_c::onCreate() { OSReport("Creating MG's body model\n"); setupBodyModel(); + // FROM 80033288 + this->max_speed.y = -4.0; + this->_518 = 2; + //sub_80034060 + this->_36D = 0; + //FIXME add this method + //this->_vf2BC(); + OSReport("Creating MegaGoomba's Physics Struct\n"); //TODO find data for a fun, yet challenging, battle ActivePhysics::Info HitMeBaby; @@ -300,13 +379,15 @@ int daMegaGoomba_c::onCreate() { //sub_80034060(); //FIXME move this stuff elsewhere - pos.y -= 16.0; + //pos.y -= 16.0; + speed.y = 0.0; pos.z = 3000.0; - speed.x = dying = 0.0; + dying = 0.0; rot.x = rot.z = 0; rot.y = 0x2000; // 0x2000 is left. 0xe000 is for right. direction = 0; life = 3; + already_hit = false; //TODO 1) allow setting bounding rect with settings //TODO 2) don't use bounding rect. use wall/floor/ceiling detection Bounding.left = pos.x - 212.0; @@ -323,6 +404,7 @@ int daMegaGoomba_c::onCreate() { this->pickedChoice = -1; // 2.0 is good final speed this->XSpeed = 1.5; + this->x_speed_inc = 0.1; this->JumpHeight = 48.0; this->JumpDist = 64.0; this->JumpTime = 50.0; @@ -340,9 +422,17 @@ int daMegaGoomba_c::onDelete() { } int daMegaGoomba_c::onExecute() { + //80033450 acState.execute(); + //if(CheckSomethingEnemyRelated()) + // sub_80033f10(this); + //else + // dStageActor_c__checkZoneBoundaries(this, 0); + //// dont do updateModelMatrices //// + updateModelMatrices(); + /* if (this->aPhysics.result1 == 1) { char PlayerID = NearestPlayer(this); @@ -351,12 +441,40 @@ int daMegaGoomba_c::onExecute() { this->_vf220(Player); } } + */ + +#if 0 + int ret2 = SomeStrangeModification(this); + OSReport("Bitfield88: %08x\n", *(u32*)&this->classAt1EC[0x88]); +#else + /* + if(this->life > 0) { + if(this->pos.x < this->Bounding.left) { + OSReport("Too far left: %f %f\n", this->pos.x, this->Bounding.left); + doStateChange(&StateID_Turn); + this->pos.x = Bounding.left + 4.0; + } else if (this->pos.x > this->Bounding.right) { + OSReport("Too far right: %f %f\n", this->pos.x, this->Bounding.right); + doStateChange(&StateID_Turn); + this->pos.x = Bounding.right - 4.0; + } + 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; + } + } + */ +#endif return true; } int daMegaGoomba_c::onDraw() { bodyModel.scheduleForDrawing(); + //DONT DO REST HERE// bodyModel._vf1C(); animationPat.process(); /* SRT TESTS @@ -367,29 +485,6 @@ int daMegaGoomba_c::onDraw() { void daMegaGoomba_c::updateModelMatrices() { - // Bounds checking // move to onExecute(); - // TODO possibly change to a state change - if(this->life > 0) { - if(this->pos.x < this->Bounding.left) { - this->direction = !this->direction; - rot.y = (this->direction) ? 0xe000 : 0x2000; - this->speed.x = -this->speed.x; - this->pos.x = this->Bounding.left; - } else if (this->pos.x > this->Bounding.right) { - this->direction = !this->direction; - rot.y = (this->direction) ? 0xe000 : 0x2000; - 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); @@ -443,27 +538,31 @@ void daMegaGoomba_c::endState_Grow() { } 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 }; + keysX[0] = (HermiteKey){ 0.0, this->scale.y, 1.0 }; + keysX[1] = (HermiteKey){ 20.0, this->scale.y - 2.0, 1.0 }; + keysX[2] = (HermiteKey){ 40.0, this->scale.y, 1.0 }; + keysX[3] = (HermiteKey){ 59.0, this->scale.y - 2.0, 1.0 }; // using this to stop walk animation - this->animationChr.setCurrentFrame(600.0); + this->animationChr.setCurrentFrame(900.0); + Vec tempVec = (Vec){0.0, 0.0, 0.0}; + setNewActivePhysicsRect(this, &tempVec ); } 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); if(this->timer == 2.0) PlaySound(this, SE_EMY_KURIBO_L_DAMAGE_02); if (this->timer > 60.0) { doStateChange(&StateID_Walk); } } -void daMegaGoomba_c::endState_Shrink() { } +void daMegaGoomba_c::endState_Shrink() { + setNewActivePhysicsRect(this, &this->scale); + this->already_hit = false; +} @@ -473,7 +572,7 @@ void daMegaGoomba_c::beginState_Launch() { rot.y = 0x0; // using this to stop walk animation - this->animationChr.setCurrentFrame(600.0); + this->animationChr.setCurrentFrame(900.0); } void daMegaGoomba_c::executeState_Launch() { @@ -484,26 +583,26 @@ void daMegaGoomba_c::executeState_Launch() { dStageActor_c *spawner = NULL; // 120ticks / 120numbers * 3cases = 3avg kuribo int randChoice = GenerateRandomNumber(120); - int randChoiceX = GenerateRandomNumber(12); + int randChoiceX = GenerateRandomNumber(10); int randChoiceY = GenerateRandomNumber(7); 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 + 3.0; + spawner->speed.x = randChoiceX - 5.0; + spawner->speed.y = randChoiceY + 6.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 - 6.0; - spawner->speed.y = randChoiceY + 3.0; + spawner->speed.x = randChoiceX - 5.0; + spawner->speed.y = randChoiceY + 6.0; spawner->scale = (Vec){1.0, 1.0, 1.0}; break; case 3: spawner = CreateActor(EN_PATA_KURIBO, 0, this->pos, 0, 0); - spawner->speed.x = randChoiceX - 6.0; - spawner->speed.y = randChoiceY + 3.0; + spawner->speed.x = randChoiceX - 5.0; + spawner->speed.y = randChoiceY + 6.0; spawner->scale = (Vec){1.0, 1.0, 1.0}; break; default: @@ -542,7 +641,7 @@ void daMegaGoomba_c::beginState_Jump() { keysY[2] = (HermiteKey){ fullTime, this->pos.y, 0.8 }; // using this to stop walk animation - this->animationChr.setCurrentFrame(600.0); + this->animationChr.setCurrentFrame(900.0); } void daMegaGoomba_c::executeState_Jump() { @@ -560,11 +659,58 @@ void daMegaGoomba_c::executeState_Jump() { void daMegaGoomba_c::endState_Jump() { } +// Turn State +void daMegaGoomba_c::beginState_Turn() { + /* + this->direction = !this->direction; + rot.y = (this->direction) ? 0xe000 : 0x2000; + this->speed.x = 0.0; + this->max_speed.x = (this->direction) ? -this->XSpeed : this->XSpeed; + */ + this->direction ^= 1; + this->speed.x = 0.0; + this->speed.y = 0.0; +} +void daMegaGoomba_c::executeState_Turn() { + this->bodyModel._vf1C(); + this->animationPat.process(); + + //FIXME removed falling goomba with these 2 lines out +#if 0 + HandleYSpeed(this); + doSpriteMovement(this); +#endif + + //nullsub(); + //this->_vf2D0(); + //int ret = Kuribo_References0x274(); + int ret = SomeStrangeModification(this); + //OSReport("SomeStrangeModification() : %08x [%08x]\n", ret, *(u32*)&this->classAt1EC[0x88]); + if(ret & 1) + this->speed.y = 0.0; + if(ret & 4) + this->pos.x = this->last_pos.x; + DoStuffAndMarkDead(this, this->pos, 1.0); + u16 amt = (this->direction == 0) ? 0x2000 : 0xE000; + int done = SmoothRotation(&this->rot.y, amt, 0x200); + if(done) { + this->doStateChange(&StateID_Walk); + } +} +void daMegaGoomba_c::endState_Turn() { + this->max_speed.x = (this->direction) ? -this->XSpeed : this->XSpeed; +} + + // Walk State void daMegaGoomba_c::beginState_Walk() { this->timer = 1.0; + + //inline this piece of code this->direction = dSprite_c__getXDirectionOfFurthestPlayerRelativeToVEC3(this, this->pos); rot.y = (this->direction) ? 0xe000 : 0x2000; + this->speed.x = 0.0; + this->max_speed.x = (this->direction) ? -this->XSpeed : this->XSpeed; //SETUP WALK ANIMATION// bindAnimChr_and_setUpdateRate("walk", 1, 0.0, 1.0); @@ -591,11 +737,21 @@ void daMegaGoomba_c::executeState_Walk() { this->animationChr.setCurrentFrame(0.0); //HandleAcceleration(this); - //HandleXSpeed(this); - //UpdateObjectPosBasedOnSpeedValues_real(this); + HandleXSpeed(this); + //HandleYSpeed(this); + UpdateObjectPosBasedOnSpeedValues_real(this); //DoGravityMaybe(); - float delta = (this->direction) ? -this->XSpeed : this->XSpeed; + + if(CollidedWithTile(this->classAt1EC)) { + OSReport("CollidedWithTile() : true [%08x]\n", *(u32*)&this->classAt1EC[0x88]); + } + int ret2 = SomeStrangeModification(this); + OSReport("Bitfield88: %08x [%08x]\n", *(u32*)&this->classAt1EC[0x88], ret2); + + /* + float delta = (this->direction) ? -this->speed.x : this->speed.x; this->pos.x += delta; + */ int Choice; float TimerMax = 150.0; @@ -611,11 +767,14 @@ void daMegaGoomba_c::executeState_Walk() { doStateChange(&StateID_Jump); break; case 1: +#if 0 doStateChange(&StateID_Launch); +#endif break; default: - this->direction = dSprite_c__getXDirectionOfFurthestPlayerRelativeToVEC3(this, pos); - rot.y = (this->direction) ? 0xe000 : 0x2000; + int new_dir = dSprite_c__getXDirectionOfFurthestPlayerRelativeToVEC3(this, pos); + if(this->direction != new_dir) + doStateChange(&StateID_Turn); this->timer = 0; break; }; diff --git a/src/player.cpp b/src/player.cpp index d70c19c..d5c54aa 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -39,9 +39,9 @@ void setNewActivePhysicsRect(dStageActor_c* actor, Vec* scale) { ActivePhysics::Info info; info.xDistToCenter = 0.0; - info.yDistToCenter = 3.0 * amtY; + info.yDistToCenter = 7.65 * amtY; info.xDistToEdge = 4.0 * amtX; - info.yDistToEdge = 4.0 * amtY; + info.yDistToEdge = 7.7 * amtY; info.category1 = actor->aPhysics.info.category1; info.category2 = actor->aPhysics.info.category2; -- cgit v1.2.3