summaryrefslogtreecommitdiff
path: root/src/bossKoopaThrow.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/bossKoopaThrow.cpp338
1 files changed, 338 insertions, 0 deletions
diff --git a/src/bossKoopaThrow.cpp b/src/bossKoopaThrow.cpp
new file mode 100644
index 0000000..8c6d4ee
--- /dev/null
+++ b/src/bossKoopaThrow.cpp
@@ -0,0 +1,338 @@
+#include <common.h>
+#include <game.h>
+#include <g3dhax.h>
+#include <sfx.h>
+#include "boss.h"
+
+struct TypeInfo {
+ const char *arcName;
+ const char *brresName;
+ const char *modelName;
+ const char *deathEffect;
+ int launchSound;
+ int breakSound;
+ int flySound;
+ float size;
+ float scale;
+ u16 xrot;
+ u16 yrot;
+ u16 zrot;
+};
+
+static const TypeInfo types[6] = {
+ {"choropoo", "g3d/choropoo.brres", "spanner", "Wm_en_hit", 0, SE_BOSS_JR_FLOOR_BREAK, 0, 8.0f, 2.0f, 0, 0, 0x1000},
+ {"choropoo", "g3d/choropoo.brres", "spanner", "Wm_en_burst_s", 0, SE_BOSS_JR_BOMB_BURST, 0, 8.0f, 2.0f, 0, 0, 0x1000},
+ {"koopa_clown_bomb", "g3d/koopa_clown_bomb.brres", "koopa_clown_bomb", "Wm_en_burst_s", SE_BOSS_JR_BOMB_BOUND, SE_BOSS_JR_BOMB_BURST, 0, 8.0f, 1.0f, 0x200, 0x800, 0x1000},
+ {"bros", "g3d/t00.brres", "bros_hammer", "Wm_en_hit", 0, SE_OBJ_HAMMER_HIT_BOTH, SE_EMY_MEGA_BROS_HAMMER, 8.0f, 2.0f, 0, 0, 0x1000},
+ {"dossun", "g3d/t00.brres", "dossun", "Wm_en_hit", SE_EMY_DOSSUN, SE_EMY_DOSSUN_DEAD, 0, 8.0f, 1.0f, 0x100, 0x1000, 0x1000},
+ {"KoopaShip", "g3d/present.brres", "PresentBox_penguin", "Wm_dm_presentopen",SE_EMY_DOSSUN, SE_EMY_DOSSUN_DEAD, 0, 8.0f, 1.0f, 0x20, 0x40, 0x200}
+};
+
+
+class daKoopaThrow : public dEn_c {
+ int onCreate();
+ int onExecute();
+ int onDelete();
+ int onDraw();
+
+ mHeapAllocator_c allocator;
+ m3d::mdl_c bodyModel;
+
+ int timer;
+ char Type;
+ char direction;
+ char front;
+ float ymod;
+ int lifespan;
+ u32 cmgr_returnValue;
+
+ const TypeInfo *currentInfo;
+
+ static daKoopaThrow *build();
+
+ void updateModelMatrices();
+ void playerCollision(ActivePhysics *apThis, ActivePhysics *apOther);
+
+ void collisionCat1_Fireball_E_Explosion(ActivePhysics *apThis, ActivePhysics *apOther);
+ bool collisionCat2_IceBall_15_YoshiIce(ActivePhysics *apThis, ActivePhysics *apOther);
+ void collisionCat9_RollingObject(ActivePhysics *apThis, ActivePhysics *apOther);
+ void collisionCat13_Hammer(ActivePhysics *apThis, ActivePhysics *apOther);
+ void collisionCat14_YoshiFire(ActivePhysics *apThis, ActivePhysics *apOther);
+ void collisionCat7_WMWaggleWater(ActivePhysics *apThis, ActivePhysics *apOther);
+
+
+ USING_STATES(daKoopaThrow);
+ DECLARE_STATE(Straight);
+
+};
+
+CREATE_STATE(daKoopaThrow, Straight);
+
+
+// Types:
+//
+// 0 - Wrench
+// 1 - Exploding Wrench
+// 2 - Bomb
+// 3 - Hammer
+// 4 - Thwomp
+// 5 - Present
+//
+
+
+extern "C" void *PlayWrenchSound(dEn_c *);
+
+
+void daKoopaThrow::playerCollision(ActivePhysics *apThis, ActivePhysics *apOther) {
+ if (Type == 5) {
+ PlaySoundAsync(this, currentInfo->breakSound);
+ SpawnEffect(currentInfo->deathEffect, 0, &this->pos, &(S16Vec){0,0,0}, &(Vec){1.0, 1.0, 1.0});
+ CreateActor(EN_HATENA_BALLOON, 0x100, this->pos, 0, 0);
+ this->Delete(1);
+ }
+
+ DamagePlayer(this, apThis, apOther);
+
+ if (Type == 1 || Type == 2) {
+ PlaySoundAsync(this, SE_BOSS_JR_BOMB_BURST);
+
+ SpawnEffect("Wm_en_burst_s", 0, &this->pos, &(S16Vec){0,0,0}, &(Vec){0.75, 0.75, 0.75});
+ SpawnEffect("Wm_mr_wirehit", 0, &this->pos, &(S16Vec){0,0,0}, &(Vec){1.25, 1.25, 1.25});
+ this->Delete(1);
+ }
+}
+
+void daKoopaThrow::collisionCat1_Fireball_E_Explosion(ActivePhysics *apThis, ActivePhysics *apOther) { }
+bool daKoopaThrow::collisionCat2_IceBall_15_YoshiIce(ActivePhysics *apThis, ActivePhysics *apOther) {
+ return false;
+}
+void daKoopaThrow::collisionCat9_RollingObject(ActivePhysics *apThis, ActivePhysics *apOther) {}
+void daKoopaThrow::collisionCat13_Hammer(ActivePhysics *apThis, ActivePhysics *apOther) {
+ if (Type == 1 || Type == 2) {
+ SpawnEffect("Wm_en_burst_s", 0, &this->pos, &(S16Vec){0,0,0}, &(Vec){0.75, 0.75, 0.75});
+ SpawnEffect("Wm_mr_wirehit", 0, &this->pos, &(S16Vec){0,0,0}, &(Vec){1.25, 1.25, 1.25});
+ }
+ else {
+ SpawnEffect("Wm_ob_cmnboxgrain", 0, &this->pos, &(S16Vec){0,0,0}, &(Vec){0.5, 0.5, 0.5});
+ }
+
+ PlaySoundAsync(this, currentInfo->breakSound);
+ this->Delete(1);
+}
+void daKoopaThrow::collisionCat14_YoshiFire(ActivePhysics *apThis, ActivePhysics *apOther) {}
+void daKoopaThrow::collisionCat7_WMWaggleWater(ActivePhysics *apThis, ActivePhysics *apOther) {
+ DamagePlayer(this, apThis, apOther);
+
+ if (Type == 1 || Type == 2) {
+ PlaySoundAsync(this, SE_BOSS_JR_BOMB_BURST);
+
+ SpawnEffect("Wm_en_burst_s", 0, &this->pos, &(S16Vec){0,0,0}, &(Vec){0.75, 0.75, 0.75});
+ SpawnEffect("Wm_mr_wirehit", 0, &this->pos, &(S16Vec){0,0,0}, &(Vec){1.25, 1.25, 1.25});
+ this->Delete(1);
+ }
+}
+
+
+daKoopaThrow *daKoopaThrow::build() {
+ OSReport("Building");
+ void *buffer = AllocFromGameHeap1(sizeof(daKoopaThrow));
+ OSReport("Built");
+ return new(buffer) daKoopaThrow;
+}
+
+
+int daKoopaThrow::onCreate() {
+
+ this->direction = this->settings & 0xF;
+ this->Type = (this->settings >> 4) & 0xF;
+ this->front = (this->settings >> 8) & 0xF;
+
+ OSReport("Type is %d", this->Type);
+
+ currentInfo = &types[Type];
+
+ OSReport("Current Info is: %s, %s, %s", currentInfo->arcName, currentInfo->brresName, currentInfo->modelName);
+
+ allocator.link(-1, GameHeaps[0], 0, 0x20);
+
+ OSReport("Allocated");
+
+ nw4r::g3d::ResFile rf(getResource(currentInfo->arcName, currentInfo->brresName));
+ OSReport("Res File Gotten");
+ bodyModel.setup(rf.GetResMdl(currentInfo->modelName), &allocator, 0x224, 1, 0);
+ OSReport("Body model setup");
+ SetupTextures_Enemy(&bodyModel, 0);
+ OSReport("Textures setup");
+
+ allocator.unlink();
+
+ OSReport("Onwards to Physics");
+
+
+ ActivePhysics::Info KoopaJunk;
+
+ KoopaJunk.xDistToCenter = 0.0;
+ KoopaJunk.yDistToCenter = 0.0;
+ KoopaJunk.xDistToEdge = currentInfo->size;
+ KoopaJunk.yDistToEdge = currentInfo->size;
+
+ this->scale.x = currentInfo->scale;
+ this->scale.y = currentInfo->scale;
+ this->scale.z = currentInfo->scale;
+
+ KoopaJunk.category1 = 0x3;
+ KoopaJunk.category2 = 0x0;
+ KoopaJunk.bitfield1 = 0x47;
+ KoopaJunk.bitfield2 = 0xFFFFFFFF;
+ KoopaJunk.unkShort1C = 0;
+ KoopaJunk.callback = &dEn_c::collisionCallback;
+
+ this->aPhysics.initWithStruct(this, &KoopaJunk);
+ this->aPhysics.addToList();
+
+
+ spriteSomeRectX = currentInfo->size;
+ spriteSomeRectY = currentInfo->size;
+ _320 = 0.0f;
+ _324 = currentInfo->size;
+
+ // These structs tell stupid collider what to collide with - these are from koopa troopa
+ static const u8 one[16] = {0,0,0,1, 0,0,0xC0,0, 0,0,0x40,0, 0,0,0,0};
+ static const u8 two[12] = {0,0,0,0, 0,0,0,0, 0,0,0xC0,0};
+ static const u8 three[16] = {0,0,0,1, 0,0,0x60,0, 0,0,0x90,0, 0,0,0x60,0};
+
+ collMgr.Init(this, one, two, three);
+ collMgr.execute();
+
+ cmgr_returnValue = collMgr.CollidedWithTile();
+
+
+ if (this->direction == 0) { // Ground Facing Left
+ this->pos.x -= 0.0; // -32 to +32
+ this->pos.y += 36.0;
+ // this->rot.z = 0x2000;
+ }
+ else if (this->direction == 1) { // Ground Facing Right
+ this->pos.x += 0.0; // +32 to -32
+ this->pos.y += 36.0;
+ // this->rot.z = 0xE000;
+ }
+ if (this->front == 1) { this->pos.z = -1804.0; }
+ else { this->pos.z = 3300.0; }
+
+
+ if (currentInfo->launchSound != 0) {
+ PlaySound(this, currentInfo->launchSound);
+ }
+
+ doStateChange(&StateID_Straight);
+
+ this->onExecute();
+ return true;
+}
+
+
+int daKoopaThrow::onDelete() {
+ return true;
+}
+
+int daKoopaThrow::onDraw() {
+ bodyModel.scheduleForDrawing();
+ return true;
+}
+
+
+void daKoopaThrow::updateModelMatrices() {
+ 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);
+}
+
+
+int daKoopaThrow::onExecute() {
+ acState.execute();
+ updateModelMatrices();
+
+ float rect[] = {this->_320, this->_324, this->spriteSomeRectX, this->spriteSomeRectY};
+ int ret = this->outOfZone(this->pos, (float*)&rect, this->currentZoneID);
+ if(ret) {
+ this->Delete(1);
+ }
+
+ return true;
+}
+
+
+
+void daKoopaThrow::beginState_Straight() {
+ float rand = (float)GenerateRandomNumber(10) * 0.8;
+
+ if (this->direction == 0) { // directions 1 spins clockwise, fly rightwards
+ speed.x = 3.0 + rand;
+ }
+ else { // directions 0 spins anti-clockwise, fly leftwards
+ speed.x = -3.0 - rand;
+ }
+
+ speed.y = 9.0;
+}
+void daKoopaThrow::executeState_Straight() {
+
+ speed.y = speed.y - 0.01875;
+
+ HandleXSpeed();
+ HandleYSpeed();
+ doSpriteMovement();
+
+ cmgr_returnValue = collMgr.CollidedWithTile();
+ collMgr.execute();
+
+ if (collMgr.CollidedWithTile() || (collMgr.bitfield_for_checks & (0x15 << direction))) {
+ // hit the ground or wall
+ PlaySoundAsync(this, currentInfo->breakSound);
+
+ SpawnEffect(currentInfo->deathEffect, 0, &this->pos, &(S16Vec){0,0,0}, &(Vec){0.75, 0.75, 0.75});
+ this->Delete(1);
+ }
+
+ if (this->direction == 1) { // directions 1 spins clockwise, fly rightwards
+ this->rot.x -= currentInfo->xrot;
+ this->rot.y -= currentInfo->yrot;
+ this->rot.z -= currentInfo->zrot; }
+ else { // directions 0 spins anti-clockwise, fly leftwards
+ this->rot.x -= currentInfo->xrot;
+ this->rot.y -= currentInfo->yrot;
+ this->rot.z += currentInfo->zrot; }
+
+
+ if (Type < 2) {
+ PlayWrenchSound(this);
+ }
+ else if (currentInfo->flySound == 0) { return; }
+ else {
+ PlaySound(this, currentInfo->flySound);
+ }
+
+ if (Type == 5) {
+ if (this->speed.y < 0.0) {
+ PlaySoundAsync(this, currentInfo->breakSound);
+ SpawnEffect(currentInfo->deathEffect, 0, &this->pos, &(S16Vec){0,0,0}, &(Vec){1.0, 1.0, 1.0});
+ CreateActor(EN_HATENA_BALLOON, 0x100, this->pos, 0, 0);
+ this->Delete(1);
+ }
+ }
+
+}
+void daKoopaThrow::endState_Straight() { }
+
+
+
+
+
+
+
+
+