From 9f517b8d695e6d58e28b50dabe73c540735e5848 Mon Sep 17 00:00:00 2001 From: Jonathan Hohle Date: Thu, 15 Aug 2024 12:07:14 -0700 Subject: [PATCH] Decompile Various Weapon Functions * `EntityWeaponAttack` of `w_018` * `EntityWeaponAttack` of `w_041` * `func_ptr_80170004` of `w_043` --- src/weapon/w_018.c | 94 ++++++++++++++++++++++++++++++++++++++++++++-- src/weapon/w_041.c | 73 ++++++++++++++++++++++++++++++++++- src/weapon/w_043.c | 63 +++++++++++++++++++++++++++++-- 3 files changed, 222 insertions(+), 8 deletions(-) diff --git a/src/weapon/w_018.c b/src/weapon/w_018.c index 47fef3b49e..797fc3b0ba 100644 --- a/src/weapon/w_018.c +++ b/src/weapon/w_018.c @@ -32,7 +32,93 @@ static void DebugInputWait(const char* msg) { DebugShowWaitInfo(msg); } -INCLUDE_ASM("weapon/nonmatchings/w_018", EntityWeaponAttack); +extern AnimationFrame D_82000_8017A6A8[]; +extern AnimationFrame D_82000_8017A6E4[]; + +void EntityWeaponAttack(Entity* self) { + self->hitboxState = 0; + switch (self->step) { + // bat appears + case 0: + self->posX.i.hi = PLAYER.posX.i.hi; + self->posY.i.hi = PLAYER.posY.i.hi - 0x38; + SetSpriteBank1(g_Animset); + + self->animSet = ANIMSET_OVL(0x10); + self->palette = PAL_DRA(0x110); + self->unk5A = 0x64; + if (g_HandId != 0) { + self->animSet += 2; + self->palette += 0x18; + self->unk5A += 2; + } + self->facingLeft = 0; + self->flags = FLAG_UNK_04000000 | FLAG_UNK_100000; + self->zPriority = PLAYER.zPriority - 4; + self->unk4C = D_82000_8017A6A8; + SetWeaponProperties(self, 1); + g_api.PlaySfx(SE_WPN_POWER_OF_SIRE); + g_Player.D_80072F00[12] = 4; + self->step++; + break; + // image of dracula appears + case 1: + if (self->animFrameDuration < 0) { + self->drawMode = FLAG_DRAW_UNK20 | FLAG_DRAW_UNK10; + self->unk4C = D_82000_8017A6E4; + self->animFrameIdx = 0; + self->animFrameDuration = 0; + self->ext.weapon.lifetime = 71; + g_api.func_80118C28(5); + g_api.func_80102CD8(3); + g_api.PlaySfx(SFX_TELEPORT_BANG_A); + self->step++; + } + break; + // emit starbursts + case 2: + if (self->ext.weapon.lifetime % 8 == 0 && + self->ext.weapon.lifetime >= 9 && + g_api.CreateEntFactoryFromEntity( + self, ((g_HandId + 1) << 0xC) + FACTORY(0, 0x38), 0)) { + g_api.func_80118C28(6); + SetWeaponProperties(self, 0); + } + + self->ext.weapon.lifetime--; + if ((self->ext.weapon.lifetime) == 0) { + self->drawFlags = 3; + self->rotY = FIX(1.0 / 256.0); + self->rotX = FIX(1.0 / 256.0); + self->ext.weapon.lifetime = 14; + self->step++; + } + break; + // squish and explode + case 3: + self->rotX -= FIX(1.0 / 2048.0); + if (self->rotY < FIX(1.0 / 64.0)) { + self->rotY += FIX(3.0 / 1024.0); + } + if (self->rotX == FIX(1.0 / 1024.0)) { + self->rotPivotX = 1; + g_api.PlaySfx(SFX_TELEPORT_BANG_B); + g_api.CreateEntFactoryFromEntity(self, FACTORY(0xC00, 4), 0); + } + if (self->rotX == FIX(1.0 / 2048.0)) { + self->palette = PAL_OVL(0x15F); + } + if (self->rotX <= 0) { + self->rotX = FIX(3.0 / 32768.0); + } + + self->ext.weapon.lifetime--; + if (self->ext.weapon.lifetime == 0) { + DestroyEntity(self); + } + break; + } +} extern AnimationFrame D_82000_8017A724[]; @@ -77,13 +163,13 @@ s32 func_ptr_80170004(Entity* self) { self->posY.val += (scale + 2) * self->velocityY; g_api.PlaySfx(SFX_UNK_69D); - self->ext.timer.t = 6; + self->ext.weapon.lifetime = 6; self->step++; break; case 1: - self->ext.timer.t--; - if (self->ext.timer.t == 0) { + self->ext.weapon.lifetime--; + if (self->ext.weapon.lifetime == 0) { self->step++; } break; diff --git a/src/weapon/w_041.c b/src/weapon/w_041.c index 293181a71b..64b6e2f796 100644 --- a/src/weapon/w_041.c +++ b/src/weapon/w_041.c @@ -105,7 +105,78 @@ Entity* func_123000_8017A994(Entity* self, s16 angleTarget, s16 tolerance) { return NULL; } -INCLUDE_ASM("weapon/nonmatchings/w_041", EntityWeaponAttack); +extern AnimationFrame D_123000_8017A4DC[]; +extern AnimationFrame D_123000_8017A504[]; +extern s32 D_123000_8017A53C[]; +extern s32 D_123000_8017A54C[]; +extern s32 D_123000_8017B204; +extern s32 D_123000_8017B208; + +void EntityWeaponAttack(Entity* self) { + u8 pad[38]; + s32 speedX; + + switch (self->step) { + case 0: + SetSpriteBank1(g_Animset); + self->animSet = ANIMSET_OVL(0x10); + self->palette = PAL_DRA(0x110); + self->unk5A = 0x64; + if (g_HandId != 0) { + self->palette += 0x18; + self->unk5A += 2; + self->animSet += 2; + } + + self->zPriority = PLAYER.zPriority + 2; + self->facingLeft = PLAYER.facingLeft; + self->flags = FLAG_UNK_08000000 | FLAG_UNK_100000; + self->unk4C = D_123000_8017A504; + self->posY.i.hi -= 4; + + speedX = D_123000_8017B204; + if (D_123000_8017B204 < 0) { + speedX += 3; + } + + D_123000_8017B204 -= (speedX >> 2) * 4; + + SetSpeedX(D_123000_8017A53C[D_123000_8017B204]); + + D_123000_8017B204++; + D_123000_8017B208 = D_123000_8017B204 % 3; + self->velocityY = D_123000_8017A54C[D_123000_8017B208]; + D_123000_8017B208++; + self->ext.weapon.lifetime = (rand() & 0xF) + 24; + g_Player.D_80072F00[10] = 4; + self->step++; + break; + + case 1: + self->posX.val += self->velocityX; + self->posY.val += self->velocityY; + self->velocityY += FIX(5.0 / 32.0); + self->ext.weapon.lifetime--; + if (!self->ext.weapon.lifetime) { + self->unk4C = &D_123000_8017A4DC; + self->animFrameDuration = 0; + self->animFrameIdx = 0; + self->drawMode = DRAW_TPAGE2 | DRAW_TPAGE; + g_api.func_80134714(SFX_GLASS_BREAK_A, 0x50, 0); + g_api.CreateEntFactoryFromEntity( + self, ((g_HandId + 1) << 0xC) + FACTORY(0, 56), 0); + self->step++; + } + break; + + case 2: + if (self->animFrameDuration < 0) { + DestroyEntity(self); + return; + } + break; + } +} s32 func_ptr_80170004(Entity* self) { s16 result; diff --git a/src/weapon/w_043.c b/src/weapon/w_043.c index 4bc308770e..cd140a9572 100644 --- a/src/weapon/w_043.c +++ b/src/weapon/w_043.c @@ -9,17 +9,74 @@ extern s32 g_HandId; #define g_Animset w_043_1 #define g_Animset2 w_043_2 -extern SpriteParts D_131000_8017A040[]; extern AnimationFrame D_131000_8017AF40[]; INCLUDE_ASM("weapon/nonmatchings/w_043", EntityWeaponAttack); -INCLUDE_ASM("weapon/nonmatchings/w_043", func_ptr_80170004); +s32 func_ptr_80170004(Entity* self) { + switch (self->step) { + case 0: + self->palette = PAL_OVL(0x100); + self->zPriority = PLAYER.zPriority; + self->facingLeft = PLAYER.facingLeft; + self->animCurFrame = PLAYER.animCurFrame - 0x8000; + self->animSet = ANIMSET_DRA(1); + self->drawMode = DRAW_TPAGE; + self->flags = FLAG_UNK_04000000 | FLAG_UNK_20000; + self->unk5A = 0; + SetSpeedX(FIX(13.0)); + + self->velocityY = FIX(-1.0 / 8.0); + self->step++; + break; + case 1: + self->animCurFrame = PLAYER.animCurFrame - 0x8000; + self->posX.val += self->velocityX; + self->posY.val += self->velocityY; + DecelerateX(FIX(15.0 / 32.0)); + if (PLAYER.animFrameIdx == 5 && PLAYER.animFrameDuration == 1) { + self->facingLeft++; + self->facingLeft &= 1; + g_api.CreateEntFactoryFromEntity( + self, ((g_HandId + 1) << 0xC) + FACTORY(0, 62), 0); + self->step++; + } + break; + case 2: + self->drawMode = 0; + self->animCurFrame = PLAYER.animCurFrame - 0x8000; + if (PLAYER.animFrameIdx == 0xE) { + self->facingLeft++; + self->facingLeft &= 1; + SetSpeedX(FIX(-13.0)); + + self->velocityY = FIX(1.0 / 8.0); + self->step++; + } + break; + + case 3: + self->drawMode = DRAW_TPAGE; + self->animCurFrame = PLAYER.animCurFrame - 0x8000; + self->posX.val += self->velocityX; + self->posY.val += self->velocityY; + DecelerateX(FIX(15.0 / 32.0)); + if (PLAYER.animFrameIdx == 19) { + DestroyEntity(self); + return; + } + break; + } + + self->drawFlags = PLAYER.drawFlags; + self->rotY = PLAYER.rotY; + self->rotPivotY = PLAYER.rotPivotY; +} static void func_ptr_80170008(Entity* self) { if (self->step == 0) { self->unk4C = D_131000_8017AF40; - SetSpriteBank1(D_131000_8017A040); + SetSpriteBank1(g_Animset); self->animSet = ANIMSET_OVL(0x10); self->palette = 0x110; self->unk5A = 0x64;