summaryrefslogtreecommitdiff
path: root/src/bossCaptainBowser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/bossCaptainBowser.cpp')
-rw-r--r--src/bossCaptainBowser.cpp399
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() { }