diff options
Diffstat (limited to '')
-rw-r--r-- | src/bossCaptainBowser.cpp | 399 |
1 files changed, 399 insertions, 0 deletions
diff --git a/src/bossCaptainBowser.cpp b/src/bossCaptainBowser.cpp new file mode 100644 index 0000000..ce85f29 --- /dev/null +++ b/src/bossCaptainBowser.cpp @@ -0,0 +1,399 @@ +#include <common.h> +#include <game.h> +#include <g3dhax.h> +#include <sfx.h> +#include <stage.h> +#include "boss.h" + +void ShipPhysicsCallback(daBoss *self, dStageActor_c *other) { + OSReport("Physics"); + if (other->name == EN_CANNON_BULLET) { + + } + +} + + +class daCaptainBowser : public daBoss { +public: + int onCreate(); + int onDelete(); + int onExecute(); + int onDraw(); + + mHeapAllocator_c allocator; + nw4r::g3d::ResFile resFile; + nw4r::g3d::ResFile shipFile; + + m3d::mdl_c bodyModel; + m3d::mdl_c shipModel; + + m3d::anmChr_c chrAnimation; + m3d::anmChr_c shipAnm; + + Physics ShipPhysics; + + char isAngry; + char isInvulnerable; + // int isInvulnerableCountdown; + // int isTurningCountdown; + // char charging; + // int flashing; + + static daCaptainBowser *build(); + + void bindAnimChr_and_setUpdateRate(const char* name, int unk, float unk2, float rate); + + void spriteCollision(ActivePhysics *apThis, ActivePhysics *apOther); + void playerCollision(ActivePhysics *apThis, ActivePhysics *apOther); + + void addScoreWhenHit(void *other); + + USING_STATES(daCaptainBowser); + DECLARE_STATE(Wait); + DECLARE_STATE(Throw); + DECLARE_STATE(Fire); + + DECLARE_STATE(Roar); + DECLARE_STATE(Damage); + + DECLARE_STATE(Intro); + DECLARE_STATE(Outro); + +}; + +daCaptainBowser *daCaptainBowser::build() { + void *buffer = AllocFromGameHeap1(sizeof(daCaptainBowser)); + return new(buffer) daCaptainBowser; +} + +/////////////////////// +// Externs and States +/////////////////////// + + CREATE_STATE(daCaptainBowser, Wait); + CREATE_STATE(daCaptainBowser, Throw); + CREATE_STATE(daCaptainBowser, Fire); + + CREATE_STATE(daCaptainBowser, Roar); + CREATE_STATE(daCaptainBowser, Damage); + + CREATE_STATE(daCaptainBowser, Intro); + CREATE_STATE(daCaptainBowser, Outro); + + + +//////////////////////// +// Collision Functions +//////////////////////// + void daCaptainBowser::addScoreWhenHit(void *other) { }; + + void daCaptainBowser::spriteCollision(ActivePhysics *apThis, ActivePhysics *apOther) { + if (apOther->owner->name == EN_CANNON_BULLET) { //time to get hurt + if (this->isInvulnerable) { + return; + } + this->damage += 1; + + if (this->damage == 10) { doStateChange(&StateID_Roar); } + else if (this->damage > 20) { doStateChange(&StateID_Outro); } + else { doStateChange(&StateID_Damage); } + } + else { dEn_c::spriteCollision(apThis, apOther); } + } + + void daCaptainBowser::playerCollision(ActivePhysics *apThis, ActivePhysics *apOther) { + DamagePlayer(this, apThis, apOther); + } + + + +void daCaptainBowser::bindAnimChr_and_setUpdateRate(const char* name, int unk, float unk2, float rate) { + nw4r::g3d::ResAnmChr anmChr = this->resFile.GetResAnmChr(name); + this->chrAnimation.bind(&this->bodyModel, anmChr, unk); + this->bodyModel.bindAnim(&this->chrAnimation, unk2); + this->chrAnimation.setUpdateRate(rate); +} + +int daCaptainBowser::onCreate() { + + // Model creation + allocator.link(-1, GameHeaps[0], 0, 0x20); + + // B-b-b-bad boy Bowsaa + this->resFile.data = getResource("koopa", "g3d/koopa.brres"); + nw4r::g3d::ResMdl mdl = this->resFile.GetResMdl("koopa"); + bodyModel.setup(mdl, &allocator, 0x224, 1, 0); + SetupTextures_Boss(&bodyModel, 0); + + nw4r::g3d::ResAnmChr anmChr = this->resFile.GetResAnmChr("kp_wait"); + this->chrAnimation.setup(mdl, anmChr, &this->allocator, 0); + + + // A ship off the ol' block + this->shipFile.data = getResource("KoopaShip", "g3d/KoopaShip.brres"); + nw4r::g3d::ResMdl mdlShip = this->shipFile.GetResMdl("KoopaShip"); + shipModel.setup(mdlShip, &allocator, 0x224, 1, 0); + // SetupTextures_MapObj(&shipModel, 0); + + nw4r::g3d::ResAnmChr anmChrShip = this->shipFile.GetResAnmChr("KoopaShip"); + this->shipAnm.setup(mdlShip, anmChrShip, &this->allocator, 0); + this->shipAnm.bind(&this->shipModel, anmChrShip, 1); + this->shipModel.bindAnim(&this->shipAnm, 0.0); + this->shipAnm.setUpdateRate(1.0); + + + allocator.unlink(); + + // Prep the goods + this->scale = (Vec){0.57, 0.57, 0.57}; + + + // Ship Physics! + // Normal rects are { left, top, right, bottom } + // Callbacks are Touching upwards, Touching Downwards, and unknown + + ShipPhysics.baseSetup(this, &ShipPhysicsCallback, 0, 0, 1, 0); + + ShipPhysics.x = 8.0; + ShipPhysics.y = 20.0; + + ShipPhysics.diameter = 12.0 * 16.0; + ShipPhysics.isRound = 1; + + this->ShipPhysics.addToList(); + + + // Bowser Physics! + ActivePhysics::Info BowserPhysics; + BowserPhysics.xDistToCenter = -152.0; + BowserPhysics.yDistToCenter = 152.0; + + BowserPhysics.xDistToEdge = 38.0; + BowserPhysics.yDistToEdge = 38.0; + + BowserPhysics.category1 = 0x3; + BowserPhysics.category2 = 0x0; + BowserPhysics.bitfield1 = 0x4F; + BowserPhysics.bitfield2 = 0x8028E; + BowserPhysics.unkShort1C = 0; + BowserPhysics.callback = &dEn_c::collisionCallback; + + this->aPhysics.initWithStruct(this, &BowserPhysics); + this->aPhysics.addToList(); + + + // State Changers + doStateChange(&StateID_Wait); + + return true; +} + +int daCaptainBowser::onDelete() { + return true; +} + +int daCaptainBowser::onExecute() { + acState.execute(); + this->ShipPhysics.update(); + + bodyModel._vf1C(); + shipModel._vf1C(); + + if(this->shipAnm.isAnimationDone()) { + this->shipAnm.setCurrentFrame(0.0); + } + + return true; +} + +int daCaptainBowser::onDraw() { + matrix.translation(pos.x-146.0, pos.y+122.0, pos.z-200.0); // 136.0 is the bottom of the platform footing + short newrot = rot.y + 0xD800; + matrix.applyRotationYXZ(&rot.x, &newrot, &rot.z); + + bodyModel.setDrawMatrix(matrix); + bodyModel.setScale(&(Vec){1.0, 1.0, 1.0}); + bodyModel.calcWorld(false); + + bodyModel.scheduleForDrawing(); + + + matrix.translation(pos.x, pos.y, pos.z); + newrot = rot.y + 0x4000; + matrix.applyRotationYXZ(&rot.x, &newrot, &rot.z); + + shipModel.setDrawMatrix(matrix); + shipModel.setScale(&scale); + shipModel.calcWorld(false); + + shipModel.scheduleForDrawing(); + + return true; +} + + +////////////////// +// State Intro +////////////////// + void daCaptainBowser::beginState_Intro() { + + } + void daCaptainBowser::executeState_Intro() { + + } + void daCaptainBowser::endState_Intro() { } + + +////////////////// +// State Wait +////////////////// + void daCaptainBowser::beginState_Wait() { + if (this->isAngry == 0) { + bindAnimChr_and_setUpdateRate("kp_wait", 1, 0.0, 1.0); + } + else { + bindAnimChr_and_setUpdateRate("kp_wait", 1, 0.0, 1.5); + } + } + void daCaptainBowser::executeState_Wait() { + + if (this->chrAnimation.isAnimationDone()) { + this->chrAnimation.setCurrentFrame(0.0); + + int num = GenerateRandomNumber(4); + + if (num == 0) { + doStateChange(&StateID_Fire); + } + else{ + doStateChange(&StateID_Throw); + } + } + + } + void daCaptainBowser::endState_Wait() { } + + +////////////////// +// State Throw +////////////////// + void daCaptainBowser::beginState_Throw() { + bindAnimChr_and_setUpdateRate("break", 1, 0.0, 1.0); + this->timer = 0; + } + void daCaptainBowser::executeState_Throw() { + + if (this->chrAnimation.getCurrentFrame() == 60.0) { // throw back + int num = GenerateRandomNumber(5); + CreateActor(10, 0x100 + ((num + 1) * 0x10), this->pos, 0, 0); + } + + if (this->chrAnimation.getCurrentFrame() == 126.0) { // throw front + int num = GenerateRandomNumber(4); + CreateActor(10, (num + 1) * 0x10, this->pos, 0, 0); + } + + if (this->chrAnimation.isAnimationDone()) { + this->chrAnimation.setCurrentFrame(0.0); + if (this->isAngry == 1) { + if (this->timer == 1) { + doStateChange(&StateID_Wait); + } + } + else { + doStateChange(&StateID_Wait); + } + + this->timer++; + } + + } + void daCaptainBowser::endState_Throw() { } + + +////////////////// +// State Fire +////////////////// + void daCaptainBowser::beginState_Fire() { + bindAnimChr_and_setUpdateRate("fire1", 1, 0.0, 1.5); + this->timer = 0; + } + void daCaptainBowser::executeState_Fire() { + + if (this->chrAnimation.getCurrentFrame() == 70) { // spit fire + CreateActor(KOOPA_FIRE, 0, this->pos, 0, 0); // Seems like nyb 5 has a setting, 2 bits long, maybe. + } + + if (this->chrAnimation.isAnimationDone()) { + this->chrAnimation.setCurrentFrame(0.0); + if (this->isAngry == 1) { + if (this->timer == 1) { + doStateChange(&StateID_Wait); + } + } + else { + doStateChange(&StateID_Wait); + } + + this->timer++; + } + + } + void daCaptainBowser::endState_Fire() { } + + + +////////////////// +// State Roar +////////////////// + void daCaptainBowser::beginState_Roar() { + bindAnimChr_and_setUpdateRate("kp_roar3", 1, 0.0, 1.0); + this->isInvulnerable = 1; + + } + void daCaptainBowser::executeState_Roar() { + if (this->chrAnimation.getCurrentFrame() == 53.0) { // This is where the smackdown starts + SpawnEffect("Wm_ob_itemget_ring", 0, &this->pos, &(S16Vec){0,0,0}, &(Vec){1.0, 1.0, 1.0}); + } + + if (this->chrAnimation.isAnimationDone()) { + doStateChange(&StateID_Wait); + } + + } + void daCaptainBowser::endState_Roar() { + this->isInvulnerable = 0; + this->isAngry = 1; + } + + + +////////////////// +// State Damage +////////////////// + void daCaptainBowser::beginState_Damage() { + bindAnimChr_and_setUpdateRate("grow_big", 1, 0.0, 1.0); + this->isInvulnerable = 1; + this->chrAnimation.setCurrentFrame(9.0); + } + void daCaptainBowser::executeState_Damage() { + + if (this->chrAnimation.getCurrentFrame() == 65.0) { // stop it here before it's too late + doStateChange(&StateID_Wait); + } + + } + void daCaptainBowser::endState_Damage() { this->isInvulnerable = 0; } + + +////////////////// +// State Outro +////////////////// + void daCaptainBowser::beginState_Outro() { + + } + void daCaptainBowser::executeState_Outro() { + + } + void daCaptainBowser::endState_Outro() { } |