summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/boss.cpp12
-rw-r--r--src/bossCaptainBowser.cpp399
-rw-r--r--src/bossFlameThrower.cpp313
-rw-r--r--src/bossKoopaThrow.cpp338
-rw-r--r--src/bossWrenchThrow.cpp6
-rwxr-xr-xsrc/spriteswapper.cpp86
6 files changed, 1095 insertions, 59 deletions
diff --git a/src/boss.cpp b/src/boss.cpp
index b484171..e5be583 100644
--- a/src/boss.cpp
+++ b/src/boss.cpp
@@ -12,8 +12,15 @@ void DamagePlayer(dEn_c *actor, ActivePhysics *apThis, ActivePhysics *apOther) {
// fix multiple player collisions via megazig
actor->isDead = 0;
actor->flags_4FC |= (1<<(31-7));
- actor->counter_504[apOther->owner->which_player] = 0;
- OSReport("Player is good and hurt\n");
+ if (apOther->owner->which_player == 255 ) {
+ actor->counter_504[0] = 0;
+ actor->counter_504[1] = 0;
+ actor->counter_504[2] = 0;
+ actor->counter_504[3] = 0;
+ }
+ else {
+ actor->counter_504[apOther->owner->which_player] = 0;
+ }
}
@@ -68,7 +75,6 @@ bool GrowBoss(daBoss *actor, daKameckDemo *Kameck, float initialScale, float end
if (timer == 150) { PlaySound(actor, SE_BOSS_IGGY_WANWAN_TO_L); OSReport("Timer = 150\n"); }
if ((timer > 150) && (timer < 230)) {
- OSReport("Timer = %d\n", timer);
scaleSpeed = (endScale -initialScale) / 80.0;
float modifier;
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() { }
diff --git a/src/bossFlameThrower.cpp b/src/bossFlameThrower.cpp
new file mode 100644
index 0000000..70583fd
--- /dev/null
+++ b/src/bossFlameThrower.cpp
@@ -0,0 +1,313 @@
+#include <common.h>
+#include <game.h>
+#include <g3dhax.h>
+#include <sfx.h>
+#include "boss.h"
+
+class daKoopaBreath : public dEn_c {
+ int onCreate();
+ int onExecute();
+ int onDelete();
+ int onDraw();
+
+ mHeapAllocator_c allocator;
+ m3d::mdl_c bodyModel;
+
+ int timer;
+ char Kaboom;
+ char direction;
+ char front;
+ float ymod;
+ int lifespan;
+ u32 cmgr_returnValue;
+
+ static daKoopaBreath *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(daKoopaBreath);
+ DECLARE_STATE(Straight);
+ DECLARE_STATE(Kaboom);
+
+};
+
+CREATE_STATE(daKoopaBreath, Straight);
+CREATE_STATE(daKoopaBreath, Kaboom);
+
+
+extern "C" void *PlayWrenchSound(dEn_c *);
+
+
+void daKoopaBreath::playerCollision(ActivePhysics *apThis, ActivePhysics *apOther) { DamagePlayer(this, apThis, apOther); }
+
+void daKoopaBreath::collisionCat1_Fireball_E_Explosion(ActivePhysics *apThis, ActivePhysics *apOther) { }
+bool daKoopaBreath::collisionCat2_IceBall_15_YoshiIce(ActivePhysics *apThis, ActivePhysics *apOther) {
+ return false;
+}
+void daKoopaBreath::collisionCat9_RollingObject(ActivePhysics *apThis, ActivePhysics *apOther) {}
+void daKoopaBreath::collisionCat13_Hammer(ActivePhysics *apThis, ActivePhysics *apOther) {
+ SpawnEffect("Wm_ob_cmnboxgrain", 0, &this->pos, &(S16Vec){0,0,0}, &(Vec){0.5, 0.5, 0.5});
+
+ PlaySoundAsync(this, SE_BOSS_JR_FLOOR_BREAK);
+ this->Delete(1);
+}
+void daKoopaBreath::collisionCat14_YoshiFire(ActivePhysics *apThis, ActivePhysics *apOther) {}
+void daKoopaBreath::collisionCat7_WMWaggleWater(ActivePhysics *apThis, ActivePhysics *apOther) {
+ this->_vf220(apOther->owner);
+
+ SpawnEffect("Wm_ob_cmnboxgrain", 0, &this->pos, &(S16Vec){0,0,0}, &(Vec){0.5, 0.5, 0.5});
+
+ PlaySoundAsync(this, SE_BOSS_JR_FLOOR_BREAK);
+ this->Delete(1);
+}
+
+
+
+daKoopaBreath *daKoopaBreath::build() {
+ void *buffer = AllocFromGameHeap1(sizeof(daKoopaBreath));
+ return new(buffer) daKoopaBreath;
+}
+
+
+int daKoopaBreath::onCreate() {
+
+ allocator.link(-1, GameHeaps[0], 0, 0x20);
+
+ nw4r::g3d::ResFile rf(getResource("choropoo", "g3d/choropoo.brres"));
+ bodyModel.setup(rf.GetResMdl("spanner"), &allocator, 0x224, 1, 0);
+ SetupTextures_Enemy(&bodyModel, 0);
+
+ allocator.unlink();
+
+
+ this->direction = this->settings & 0xF;
+ this->Kaboom = (this->settings >> 4) & 0xF;
+ this->front = (this->settings >> 8) & 0xF;
+
+ ActivePhysics::Info HitMeBaby;
+
+ if (this->Kaboom == 0) {
+ HitMeBaby.xDistToCenter = 0.0;
+ HitMeBaby.yDistToCenter = 0.0;
+ HitMeBaby.xDistToEdge = 5.0;
+ HitMeBaby.yDistToEdge = 5.0;
+
+ this->scale.x = 1.25;
+ this->scale.y = 1.25;
+ this->scale.z = 1.25;
+ }
+
+ else {
+ HitMeBaby.xDistToCenter = 0.0;
+ HitMeBaby.yDistToCenter = 0.0;
+ HitMeBaby.xDistToEdge = 8.0;
+ HitMeBaby.yDistToEdge = 8.0;
+
+ this->scale.x = 2.0;
+ this->scale.y = 2.0;
+ this->scale.z = 2.0;
+ }
+
+ HitMeBaby.category1 = 0x3;
+ HitMeBaby.category2 = 0x0;
+ HitMeBaby.bitfield1 = 0x47;
+ HitMeBaby.bitfield2 = 0xFFFFFFFF;
+ HitMeBaby.unkShort1C = 0;
+ HitMeBaby.callback = &dEn_c::collisionCallback;
+
+ this->aPhysics.initWithStruct(this, &HitMeBaby);
+ this->aPhysics.addToList();
+
+
+ spriteSomeRectX = 5.0f;
+ spriteSomeRectY = 5.0f;
+ _320 = 0.0f;
+ _324 = 5.0f;
+
+ // 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 (this->Kaboom) {
+ doStateChange(&StateID_Kaboom); }
+ else {
+ doStateChange(&StateID_Straight); }
+
+ this->onExecute();
+ return true;
+}
+
+
+int daKoopaBreath::onDelete() {
+ return true;
+}
+
+int daKoopaBreath::onDraw() {
+ bodyModel.scheduleForDrawing();
+ return true;
+}
+
+
+void daKoopaBreath::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 daKoopaBreath::onExecute() {
+ acState.execute();
+ updateModelMatrices();
+
+ return true;
+}
+
+
+void daKoopaBreath::beginState_Kaboom() {
+ float rand = (float)GenerateRandomNumber(10) * 0.4;
+
+ if (this->direction == 0) { // directions 1 spins clockwise, fly rightwards
+ speed.x = 1.0 + rand;
+ }
+ else { // directions 0 spins anti-clockwise, fly leftwards
+ speed.x = -1.0 - rand;
+ }
+
+ speed.y = 6.0;
+}
+void daKoopaBreath::executeState_Kaboom() {
+
+ speed.y = speed.y - 0.01875;
+
+ HandleXSpeed();
+ HandleYSpeed();
+ doSpriteMovement();
+
+ cmgr_returnValue = collMgr.CollidedWithTile();
+ collMgr.execute();
+
+ if (collMgr.CollidedWithTile()) {
+ // hit the ground
+ 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);
+ }
+ if (collMgr.bitfield_for_checks & (0x15 << direction)) {
+ // hit the wall
+ PlaySoundAsync(this, SE_BOSS_JR_BOMB_BURST);
+
+ if (this->direction == 0) { // directions 1 spins clockwise, fly rightwards
+ SpawnEffect("Wm_en_burst_s", 0, &this->pos, &(S16Vec){0,0x4000,0}, &(Vec){0.75, 0.75, 0.75});
+ SpawnEffect("Wm_mr_wirehit", 0, &this->pos, &(S16Vec){0,0x4000,0}, &(Vec){1.25, 1.25, 1.25});
+ }
+ else { // directions 0 spins anti-clockwise, fly leftwards
+ SpawnEffect("Wm_en_burst_s", 0, &this->pos, &(S16Vec){0,0xE000,0}, &(Vec){0.75, 0.75, 0.75});
+ SpawnEffect("Wm_mr_wirehit", 0, &this->pos, &(S16Vec){0,0xE000,0}, &(Vec){1.25, 1.25, 1.25});
+ }
+
+ this->Delete(1);
+ }
+
+ if (this->direction == 1) { // directions 1 spins clockwise, fly rightwards
+ this->rot.z -= 0x1000; }
+ else { // directions 0 spins anti-clockwise, fly leftwards
+ this->rot.z += 0x1000; }
+
+ PlayWrenchSound(this);
+
+}
+void daKoopaBreath::endState_Kaboom() { }
+
+
+
+void daKoopaBreath::beginState_Straight() {
+ float rand = (float)GenerateRandomNumber(10) * 0.4;
+
+ if (this->direction == 0) { // directions 1 spins clockwise, fly rightwards
+ speed.x = 1.0 + rand;
+ }
+ else { // directions 0 spins anti-clockwise, fly leftwards
+ speed.x = -1.0 - rand;
+ }
+
+ speed.y = 6.0;
+}
+void daKoopaBreath::executeState_Straight() {
+
+ speed.y = speed.y - 0.01875;
+
+ HandleXSpeed();
+ HandleYSpeed();
+ doSpriteMovement();
+
+ cmgr_returnValue = collMgr.CollidedWithTile();
+ collMgr.execute();
+
+ if (collMgr.CollidedWithTile()) {
+ // hit the ground
+ PlaySoundAsync(this, SE_BOSS_JR_FLOOR_BREAK);
+
+ SpawnEffect("Wm_en_burst_s", 0, &this->pos, &(S16Vec){0,0,0}, &(Vec){0.75, 0.75, 0.75});
+ this->Delete(1);
+ }
+ if (collMgr.bitfield_for_checks & (0x15 << direction)) {
+ // hit the wall
+ PlaySoundAsync(this, SE_BOSS_JR_FLOOR_BREAK);
+
+ SpawnEffect("Wm_en_burst_s", 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.z -= 0x1000; }
+ else { // directions 0 spins anti-clockwise, fly leftwards
+ this->rot.z += 0x1000; }
+
+ PlayWrenchSound(this);
+
+}
+void daKoopaBreath::endState_Straight() { }
+
+
+
+
+
+// Wm_en_explosion_smk
+
+
+
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() { }
+
+
+
+
+
+
+
+
+
diff --git a/src/bossWrenchThrow.cpp b/src/bossWrenchThrow.cpp
index af5e272..5247c62 100644
--- a/src/bossWrenchThrow.cpp
+++ b/src/bossWrenchThrow.cpp
@@ -192,6 +192,12 @@ int daWrench::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;
}
diff --git a/src/spriteswapper.cpp b/src/spriteswapper.cpp
index 2bc03d5..89ead56 100755
--- a/src/spriteswapper.cpp
+++ b/src/spriteswapper.cpp
@@ -1,17 +1,14 @@
#include <common.h>
#include <game.h>
-struct SpriteSpawnerTimed {
- u32 id; // 0x00
- u32 settings; // 0x04
- u16 name; // 0x08
- u8 _0A[6]; // 0x0A
- u8 _10[0x9C]; // 0x10
- float x; // 0xAC
- float y; // 0xB0
- float z; // 0xB4
- u8 _B8[0x318]; // 0xB8
- // Any variables you add to the class go here; starting at offset 0x3D0
+
+class SpriteSpawnerTimed : public dStageActor_c {
+public:
+ int onCreate();
+ int onExecute();
+
+ static SpriteSpawnerTimed *build();
+
u64 eventFlag; // 0x3D0
u16 type; // 0x3D4
u32 inheritSet; // 0x3D6
@@ -24,68 +21,45 @@ struct EventTable_t {
};
-struct VEC {
- float x;
- float y;
- float z;
-};
-
+SpriteSpawnerTimed *SpriteSpawnerTimed::build() {
+ void *buffer = AllocFromGameHeap1(sizeof(SpriteSpawnerTimed));
+ return new(buffer) SpriteSpawnerTimed;
+}
extern EventTable_t *EventTable;
-extern "C" dStageActor_c *CreateActor(u16 classID, int settings, VEC pos, char rot, char layer);
-extern "C" dStageActor_c *Actor_SearchByID(u32 actorID);
-
-void SpriteSpawnerTimed_Update(SpriteSpawnerTimed *self);
-
-#define ACTIVATE 1
-#define DEACTIVATE 0
-
+extern "C" dStageActor_c *CreateActor(u16 classID, int settings, Vec pos, char rot, char layer);
-bool SpriteSpawnerTimed_Create(SpriteSpawnerTimed *self) {
+int SpriteSpawnerTimed::onCreate() {
- char eventNum = (self->settings >> 28) & 0xF;
+ char eventNum = (this->settings >> 28) & 0xF;
- self->eventFlag = (u64)1 << (eventNum - 1);
- self->type = (self->settings >> 16) & 0xFFF;
+ this->eventFlag = (u64)1 << (eventNum - 1);
+ this->type = (this->settings >> 16) & 0xFFF;
- short tempSet = self->settings & 0xFFFF;
- self->inheritSet = (tempSet & 3) | ((tempSet & 0xC) << 2) | ((tempSet & 0x30) << 4) | ((tempSet & 0xC0) << 6) | ((tempSet & 0x300) << 8) | ((tempSet & 0xC00) << 10) | ((tempSet & 0x3000) << 12) | ((tempSet & 0xC000) << 14);
+ short tempSet = this->settings & 0xFFFF;
+ this->inheritSet = (tempSet & 3) | ((tempSet & 0xC) << 2) | ((tempSet & 0x30) << 4) | ((tempSet & 0xC0) << 6) | ((tempSet & 0x300) << 8) | ((tempSet & 0xC00) << 10) | ((tempSet & 0x3000) << 12) | ((tempSet & 0xC000) << 14);
- self->timer = 0;
- SpriteSpawnerTimed_Update(self);
+ this->timer = 0;
return true;
}
-bool SpriteSpawnerTimed_Execute(SpriteSpawnerTimed *self) {
- SpriteSpawnerTimed_Update(self);
- return true;
-}
+int SpriteSpawnerTimed::onExecute() {
-
-void SpriteSpawnerTimed_Update(SpriteSpawnerTimed *self) {
-
- if (EventTable->events & self->eventFlag)
- {
-
- if (self->timer == 0)
- {
- VEC pos;
- pos.x = self->x;
- pos.y = self->y;
- pos.z = self->z;
-
-
- dStageActor_c *spawned = CreateActor(self->type, self->inheritSet, pos, 0, 0);
- self->timer = 120;
+ if (EventTable->events & this->eventFlag) { // If the event is on
+ if (this->timer < 1) { // If the timer is empty
+ CreateActor(this->type, this->inheritSet, this->pos, 0, 0);
+ this->timer = 120;
}
+ this->timer--;
}
+
else {
- self->timer = 0;
+ this->timer = 0;
}
- self->timer--;
-}
+ return true;
+} \ No newline at end of file