diff options
Diffstat (limited to 'src/bossKoopaThrow.cpp')
-rw-r--r-- | src/bossKoopaThrow.cpp | 338 |
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() { } + + + + + + + + + |