From 9455c885f850f0ea728995199026f6765695f524 Mon Sep 17 00:00:00 2001 From: Dragorn421 Date: Sun, 8 Aug 2021 13:28:28 +0200 Subject: [PATCH] EnMb documented (Moblins) (#861) * Document Moblins (EnMb) * Use actual decomp-style function names * Add renamed functions to actorfixer.py * Add general documentation and add EnMbType enum to check moblin subtype * Add fig's doc comment on Actor_TestFloorInDirection * Revert documentation on z_eff_ss_dead.c * remove `gSPFogPosition(?,?)` comments on `gSPFogFactor` uses in z_rcp.c * run formatter --- .../overlays/actors/ovl_En_Wf/func_80B3487C.s | 2 +- .../overlays/actors/ovl_En_Wf/func_80B35024.s | 4 +- .../overlays/actors/ovl_En_Wf/func_80B355BC.s | 2 +- .../overlays/actors/ovl_En_Wf/func_80B36740.s | 4 +- .../overlays/actors/ovl_En_Zf/func_80B45174.s | 4 +- .../overlays/actors/ovl_En_Zf/func_80B462E4.s | 4 +- .../overlays/actors/ovl_En_Zf/func_80B463E4.s | 2 +- .../overlays/actors/ovl_En_Zf/func_80B4781C.s | 4 +- .../overlays/actors/ovl_En_Zf/func_80B483E4.s | 4 +- .../overlays/actors/ovl_En_Zf/func_80B48578.s | 2 +- assets/xml/objects/object_mb.xml | 50 +- include/functions.h | 6 +- src/code/audio_seqplayer.c | 8 +- src/code/z_actor.c | 71 +- src/code/z_rcp.c | 12 +- .../actors/ovl_Boss_Dodongo/z_boss_dodongo.c | 15 +- .../actors/ovl_Boss_Ganon2/z_boss_ganon2.c | 4 +- .../actors/ovl_Boss_Goma/z_boss_goma.c | 12 +- src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c | 2 +- .../actors/ovl_Door_Shutter/z_door_shutter.c | 8 +- src/overlays/actors/ovl_En_Am/z_en_am.c | 2 +- src/overlays/actors/ovl_En_Bb/z_en_bb.c | 4 +- src/overlays/actors/ovl_En_Bw/z_en_bw.c | 21 +- .../actors/ovl_En_Dodongo/z_en_dodongo.c | 8 +- .../actors/ovl_En_Fire_Rock/z_en_fire_rock.c | 8 +- .../actors/ovl_En_Floormas/z_en_floormas.c | 2 +- src/overlays/actors/ovl_En_Fz/z_en_fz.c | 5 +- src/overlays/actors/ovl_En_GeldB/z_en_geldb.c | 20 +- src/overlays/actors/ovl_En_Mb/z_en_mb.c | 1668 +++++++++-------- src/overlays/actors/ovl_En_Mb/z_en_mb.h | 41 +- src/overlays/actors/ovl_En_Reeba/z_en_reeba.c | 8 +- src/overlays/actors/ovl_En_Sw/z_en_sw.c | 2 +- src/overlays/actors/ovl_En_Test/z_en_test.c | 8 +- src/overlays/actors/ovl_En_Tite/z_en_tite.c | 2 +- src/overlays/actors/ovl_En_Trap/z_en_trap.c | 2 +- .../actors/ovl_En_Wallmas/z_en_wallmas.c | 2 +- .../actors/ovl_player_actor/z_player.c | 4 +- tools/actorfixer.py | 4 +- 38 files changed, 1061 insertions(+), 970 deletions(-) diff --git a/asm/non_matchings/overlays/actors/ovl_En_Wf/func_80B3487C.s b/asm/non_matchings/overlays/actors/ovl_En_Wf/func_80B3487C.s index 58b1de969d..6102663574 100644 --- a/asm/non_matchings/overlays/actors/ovl_En_Wf/func_80B3487C.s +++ b/asm/non_matchings/overlays/actors/ovl_En_Wf/func_80B3487C.s @@ -320,7 +320,7 @@ glabel func_80B3487C /* 01024 80B34CD4 02002825 */ or $a1, $s0, $zero ## $a1 = 00000000 /* 01028 80B34CD8 26060024 */ addiu $a2, $s0, 0x0024 ## $a2 = 00000024 /* 0102C 80B34CDC 3C0741A0 */ lui $a3, 0x41A0 ## $a3 = 41A00000 -/* 01030 80B34CE0 0C00CC98 */ jal Actor_SpawnFloorDust +/* 01030 80B34CE0 0C00CC98 */ jal Actor_SpawnFloorDustRing /* 01034 80B34CE4 E7A80014 */ swc1 $f8, 0x0014($sp) .L80B34CE8: /* 01038 80B34CE8 8FBF0034 */ lw $ra, 0x0034($sp) diff --git a/asm/non_matchings/overlays/actors/ovl_En_Wf/func_80B35024.s b/asm/non_matchings/overlays/actors/ovl_En_Wf/func_80B35024.s index a49bba962f..4508d5406c 100644 --- a/asm/non_matchings/overlays/actors/ovl_En_Wf/func_80B35024.s +++ b/asm/non_matchings/overlays/actors/ovl_En_Wf/func_80B35024.s @@ -53,7 +53,7 @@ glabel func_80B35024 /* 01418 80B350C8 14400008 */ bne $v0, $zero, .L80B350EC /* 0141C 80B350CC 02002025 */ or $a0, $s0, $zero ## $a0 = 00000000 /* 01420 80B350D0 8FA5005C */ lw $a1, 0x005C($sp) -/* 01424 80B350D4 0C00CE6E */ jal func_800339B8 +/* 01424 80B350D4 0C00CE6E */ jal Actor_TestFloorInDirection /* 01428 80B350D8 8E060068 */ lw $a2, 0x0068($s0) ## 00000068 /* 0142C 80B350DC 54400019 */ bnel $v0, $zero, .L80B35144 /* 01430 80B350E0 8FA4005C */ lw $a0, 0x005C($sp) @@ -281,7 +281,7 @@ glabel func_80B35024 /* 01744 80B353F4 02002825 */ or $a1, $s0, $zero ## $a1 = 00000000 /* 01748 80B353F8 26060024 */ addiu $a2, $s0, 0x0024 ## $a2 = 00000024 /* 0174C 80B353FC 3C0741A0 */ lui $a3, 0x41A0 ## $a3 = 41A00000 -/* 01750 80B35400 0C00CC98 */ jal Actor_SpawnFloorDust +/* 01750 80B35400 0C00CC98 */ jal Actor_SpawnFloorDustRing /* 01754 80B35404 E7A80014 */ swc1 $f8, 0x0014($sp) /* 01758 80B35408 8FAB005C */ lw $t3, 0x005C($sp) .L80B3540C: diff --git a/asm/non_matchings/overlays/actors/ovl_En_Wf/func_80B355BC.s b/asm/non_matchings/overlays/actors/ovl_En_Wf/func_80B355BC.s index 01fd1d1b4d..cbb5ca1001 100644 --- a/asm/non_matchings/overlays/actors/ovl_En_Wf/func_80B355BC.s +++ b/asm/non_matchings/overlays/actors/ovl_En_Wf/func_80B355BC.s @@ -135,7 +135,7 @@ glabel func_80B355BC /* 01AC0 80B35770 AFB80018 */ sw $t8, 0x0018($sp) /* 01AC4 80B35774 AFAF0010 */ sw $t7, 0x0010($sp) /* 01AC8 80B35778 8FA4004C */ lw $a0, 0x004C($sp) -/* 01ACC 80B3577C 0C00CC98 */ jal Actor_SpawnFloorDust +/* 01ACC 80B3577C 0C00CC98 */ jal Actor_SpawnFloorDustRing /* 01AD0 80B35780 E7AA0014 */ swc1 $f10, 0x0014($sp) /* 01AD4 80B35784 8E0902E8 */ lw $t1, 0x02E8($s0) ## 000002E8 /* 01AD8 80B35788 252AFFFF */ addiu $t2, $t1, 0xFFFF ## $t2 = FFFFFFFF diff --git a/asm/non_matchings/overlays/actors/ovl_En_Wf/func_80B36740.s b/asm/non_matchings/overlays/actors/ovl_En_Wf/func_80B36740.s index a9e63bba8f..00e5646d79 100644 --- a/asm/non_matchings/overlays/actors/ovl_En_Wf/func_80B36740.s +++ b/asm/non_matchings/overlays/actors/ovl_En_Wf/func_80B36740.s @@ -33,7 +33,7 @@ glabel func_80B36740 /* 02AEC 80B3679C 02002025 */ or $a0, $s0, $zero ## $a0 = 00000000 /* 02AF0 80B367A0 8FA50074 */ lw $a1, 0x0074($sp) /* 02AF4 80B367A4 8E060068 */ lw $a2, 0x0068($s0) ## 00000068 -/* 02AF8 80B367A8 0C00CE6E */ jal func_800339B8 +/* 02AF8 80B367A8 0C00CE6E */ jal Actor_TestFloorInDirection /* 02AFC 80B367AC 860700B6 */ lh $a3, 0x00B6($s0) ## 000000B6 /* 02B00 80B367B0 54400018 */ bnel $v0, $zero, .L80B36814 /* 02B04 80B367B4 860F00B6 */ lh $t7, 0x00B6($s0) ## 000000B6 @@ -365,7 +365,7 @@ glabel func_80B36740 /* 02F94 80B36C44 02002825 */ or $a1, $s0, $zero ## $a1 = 00000000 /* 02F98 80B36C48 26060024 */ addiu $a2, $s0, 0x0024 ## $a2 = 00000024 /* 02F9C 80B36C4C 3C0741A0 */ lui $a3, 0x41A0 ## $a3 = 41A00000 -/* 02FA0 80B36C50 0C00CC98 */ jal Actor_SpawnFloorDust +/* 02FA0 80B36C50 0C00CC98 */ jal Actor_SpawnFloorDustRing /* 02FA4 80B36C54 E7A60014 */ swc1 $f6, 0x0014($sp) /* 02FA8 80B36C58 8FAF003C */ lw $t7, 0x003C($sp) .L80B36C5C: diff --git a/asm/non_matchings/overlays/actors/ovl_En_Zf/func_80B45174.s b/asm/non_matchings/overlays/actors/ovl_En_Zf/func_80B45174.s index f3f0c2f10c..ddd8a00314 100644 --- a/asm/non_matchings/overlays/actors/ovl_En_Zf/func_80B45174.s +++ b/asm/non_matchings/overlays/actors/ovl_En_Zf/func_80B45174.s @@ -105,7 +105,7 @@ glabel func_80B45174 /* 01294 80B452E4 02002825 */ or $a1, $s0, $zero ## $a1 = 00000000 /* 01298 80B452E8 260604F0 */ addiu $a2, $s0, 0x04F0 ## $a2 = 000004F0 /* 0129C 80B452EC 3C074040 */ lui $a3, 0x4040 ## $a3 = 40400000 -/* 012A0 80B452F0 0C00CC98 */ jal Actor_SpawnFloorDust +/* 012A0 80B452F0 0C00CC98 */ jal Actor_SpawnFloorDustRing /* 012A4 80B452F4 E7A80014 */ swc1 $f8, 0x0014($sp) /* 012A8 80B452F8 3C014000 */ lui $at, 0x4000 ## $at = 40000000 /* 012AC 80B452FC 44815000 */ mtc1 $at, $f10 ## $f10 = 2.00 @@ -118,7 +118,7 @@ glabel func_80B45174 /* 012C8 80B45318 AFA00018 */ sw $zero, 0x0018($sp) /* 012CC 80B4531C AFA0001C */ sw $zero, 0x001C($sp) /* 012D0 80B45320 AFA00020 */ sw $zero, 0x0020($sp) -/* 012D4 80B45324 0C00CC98 */ jal Actor_SpawnFloorDust +/* 012D4 80B45324 0C00CC98 */ jal Actor_SpawnFloorDustRing /* 012D8 80B45328 E7AA0014 */ swc1 $f10, 0x0014($sp) .L80B4532C: /* 012DC 80B4532C 0C02927F */ jal SkelAnime_Update diff --git a/asm/non_matchings/overlays/actors/ovl_En_Zf/func_80B462E4.s b/asm/non_matchings/overlays/actors/ovl_En_Zf/func_80B462E4.s index f74c0058f8..362919518e 100644 --- a/asm/non_matchings/overlays/actors/ovl_En_Zf/func_80B462E4.s +++ b/asm/non_matchings/overlays/actors/ovl_En_Zf/func_80B462E4.s @@ -11,7 +11,7 @@ glabel func_80B462E4 /* 022B8 80B46308 3C064220 */ lui $a2, 0x4220 ## $a2 = 42200000 /* 022BC 80B4630C 24E73FFF */ addiu $a3, $a3, 0x3FFF ## $a3 = 00003FFF /* 022C0 80B46310 00073C00 */ sll $a3, $a3, 16 -/* 022C4 80B46314 0C00CE6E */ jal func_800339B8 +/* 022C4 80B46314 0C00CE6E */ jal Actor_TestFloorInDirection /* 022C8 80B46318 00073C03 */ sra $a3, $a3, 16 /* 022CC 80B4631C 1440000A */ bne $v0, $zero, .L80B46348 /* 022D0 80B46320 02002025 */ or $a0, $s0, $zero ## $a0 = 00000000 @@ -20,7 +20,7 @@ glabel func_80B462E4 /* 022DC 80B4632C 3C06C220 */ lui $a2, 0xC220 ## $a2 = C2200000 /* 022E0 80B46330 24E73FFF */ addiu $a3, $a3, 0x3FFF ## $a3 = 00003FFF /* 022E4 80B46334 00073C00 */ sll $a3, $a3, 16 -/* 022E8 80B46338 0C00CE6E */ jal func_800339B8 +/* 022E8 80B46338 0C00CE6E */ jal Actor_TestFloorInDirection /* 022EC 80B4633C 00073C03 */ sra $a3, $a3, 16 /* 022F0 80B46340 10400021 */ beq $v0, $zero, .L80B463C8 /* 022F4 80B46344 02002025 */ or $a0, $s0, $zero ## $a0 = 00000000 diff --git a/asm/non_matchings/overlays/actors/ovl_En_Zf/func_80B463E4.s b/asm/non_matchings/overlays/actors/ovl_En_Zf/func_80B463E4.s index 7d2ecb64a5..9dcfacbdc5 100644 --- a/asm/non_matchings/overlays/actors/ovl_En_Zf/func_80B463E4.s +++ b/asm/non_matchings/overlays/actors/ovl_En_Zf/func_80B463E4.s @@ -126,7 +126,7 @@ glabel func_80B463E4 /* 02538 80B46588 8FA5005C */ lw $a1, 0x005C($sp) /* 0253C 80B4658C 24E73FFF */ addiu $a3, $a3, 0x3FFF ## $a3 = 00003FFF /* 02540 80B46590 00073C00 */ sll $a3, $a3, 16 -/* 02544 80B46594 0C00CE6E */ jal func_800339B8 +/* 02544 80B46594 0C00CE6E */ jal Actor_TestFloorInDirection /* 02548 80B46598 00073C03 */ sra $a3, $a3, 16 /* 0254C 80B4659C 5440003B */ bnel $v0, $zero, .L80B4668C /* 02550 80B465A0 8FA4005C */ lw $a0, 0x005C($sp) diff --git a/asm/non_matchings/overlays/actors/ovl_En_Zf/func_80B4781C.s b/asm/non_matchings/overlays/actors/ovl_En_Zf/func_80B4781C.s index 84ef1a3680..0ad557f02a 100644 --- a/asm/non_matchings/overlays/actors/ovl_En_Zf/func_80B4781C.s +++ b/asm/non_matchings/overlays/actors/ovl_En_Zf/func_80B4781C.s @@ -210,7 +210,7 @@ glabel func_80B4781C /* 03AA8 80B47AF8 02002825 */ or $a1, $s0, $zero ## $a1 = 00000000 /* 03AAC 80B47AFC 260604F0 */ addiu $a2, $s0, 0x04F0 ## $a2 = 000004F0 /* 03AB0 80B47B00 3C074040 */ lui $a3, 0x4040 ## $a3 = 40400000 -/* 03AB4 80B47B04 0C00CC98 */ jal Actor_SpawnFloorDust +/* 03AB4 80B47B04 0C00CC98 */ jal Actor_SpawnFloorDustRing /* 03AB8 80B47B08 E7A60014 */ swc1 $f6, 0x0014($sp) /* 03ABC 80B47B0C 3C014000 */ lui $at, 0x4000 ## $at = 40000000 /* 03AC0 80B47B10 44814000 */ mtc1 $at, $f8 ## $f8 = 2.00 @@ -223,7 +223,7 @@ glabel func_80B4781C /* 03ADC 80B47B2C AFA00018 */ sw $zero, 0x0018($sp) /* 03AE0 80B47B30 AFA0001C */ sw $zero, 0x001C($sp) /* 03AE4 80B47B34 AFA00020 */ sw $zero, 0x0020($sp) -/* 03AE8 80B47B38 0C00CC98 */ jal Actor_SpawnFloorDust +/* 03AE8 80B47B38 0C00CC98 */ jal Actor_SpawnFloorDustRing /* 03AEC 80B47B3C E7A80014 */ swc1 $f8, 0x0014($sp) /* 03AF0 80B47B40 C60A0090 */ lwc1 $f10, 0x0090($s0) ## 00000090 /* 03AF4 80B47B44 C7B00074 */ lwc1 $f16, 0x0074($sp) diff --git a/asm/non_matchings/overlays/actors/ovl_En_Zf/func_80B483E4.s b/asm/non_matchings/overlays/actors/ovl_En_Zf/func_80B483E4.s index e00db6a9af..b6608ed9aa 100644 --- a/asm/non_matchings/overlays/actors/ovl_En_Zf/func_80B483E4.s +++ b/asm/non_matchings/overlays/actors/ovl_En_Zf/func_80B483E4.s @@ -11,7 +11,7 @@ glabel func_80B483E4 /* 043B8 80B48408 3C064220 */ lui $a2, 0x4220 ## $a2 = 42200000 /* 043BC 80B4840C 24E73FFF */ addiu $a3, $a3, 0x3FFF ## $a3 = 00003FFF /* 043C0 80B48410 00073C00 */ sll $a3, $a3, 16 -/* 043C4 80B48414 0C00CE6E */ jal func_800339B8 +/* 043C4 80B48414 0C00CE6E */ jal Actor_TestFloorInDirection /* 043C8 80B48418 00073C03 */ sra $a3, $a3, 16 /* 043CC 80B4841C 1440000A */ bne $v0, $zero, .L80B48448 /* 043D0 80B48420 02002025 */ or $a0, $s0, $zero ## $a0 = 00000000 @@ -20,7 +20,7 @@ glabel func_80B483E4 /* 043DC 80B4842C 3C06C220 */ lui $a2, 0xC220 ## $a2 = C2200000 /* 043E0 80B48430 24E73FFF */ addiu $a3, $a3, 0x3FFF ## $a3 = 00003FFF /* 043E4 80B48434 00073C00 */ sll $a3, $a3, 16 -/* 043E8 80B48438 0C00CE6E */ jal func_800339B8 +/* 043E8 80B48438 0C00CE6E */ jal Actor_TestFloorInDirection /* 043EC 80B4843C 00073C03 */ sra $a3, $a3, 16 /* 043F0 80B48440 10400046 */ beq $v0, $zero, .L80B4855C /* 043F4 80B48444 02002025 */ or $a0, $s0, $zero ## $a0 = 00000000 diff --git a/asm/non_matchings/overlays/actors/ovl_En_Zf/func_80B48578.s b/asm/non_matchings/overlays/actors/ovl_En_Zf/func_80B48578.s index 895fd48eca..e5dc093be8 100644 --- a/asm/non_matchings/overlays/actors/ovl_En_Zf/func_80B48578.s +++ b/asm/non_matchings/overlays/actors/ovl_En_Zf/func_80B48578.s @@ -47,7 +47,7 @@ glabel func_80B48578 /* 045B4 80B48604 A7A80056 */ sh $t0, 0x0056($sp) /* 045B8 80B48608 24E73FFF */ addiu $a3, $a3, 0x3FFF ## $a3 = 00003FFF /* 045BC 80B4860C 00073C00 */ sll $a3, $a3, 16 -/* 045C0 80B48610 0C00CE6E */ jal func_800339B8 +/* 045C0 80B48610 0C00CE6E */ jal Actor_TestFloorInDirection /* 045C4 80B48614 00073C03 */ sra $a3, $a3, 16 /* 045C8 80B48618 1440003B */ bne $v0, $zero, .L80B48708 /* 045CC 80B4861C 87A80056 */ lh $t0, 0x0056($sp) diff --git a/assets/xml/objects/object_mb.xml b/assets/xml/objects/object_mb.xml index 35e72fc641..a8471429db 100644 --- a/assets/xml/objects/object_mb.xml +++ b/assets/xml/objects/object_mb.xml @@ -1,30 +1,30 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/include/functions.h b/include/functions.h index 37e5182b6b..017c663c66 100644 --- a/include/functions.h +++ b/include/functions.h @@ -483,15 +483,15 @@ void BodyBreak_Alloc(BodyBreak* bodyBreak, s32 count, GlobalContext* globalCtx); void BodyBreak_SetInfo(BodyBreak* bodyBreak, s32 limbIndex, s32 minLimbIndex, s32 maxLimbIndex, u32 count, Gfx** dList, s16 objectId); s32 BodyBreak_SpawnParts(Actor* actor, BodyBreak* bodyBreak, GlobalContext* globalCtx, s16 type); -void Actor_SpawnFloorDust(GlobalContext* globalCtx, Actor* actor, Vec3f* arg2, f32 arg3, s32 arg4, f32 arg5, s16 arg6, - s16 arg7, u8 arg8); +void Actor_SpawnFloorDustRing(GlobalContext* globalCtx, Actor* actor, Vec3f* posXZ, f32 radius, s32 amountMinusOne, f32 randAccelWeight, + s16 scale, s16 scaleStep, u8 useLighting); void func_80033480(GlobalContext* globalCtx, Vec3f* arg1, f32 arg2, s32 arg3, s16 arg4, s16 arg5, u8 arg6); Actor* Actor_GetCollidedExplosive(GlobalContext* globalCtx, Collider* collider); Actor* func_80033684(GlobalContext* globalCtx, Actor* explosiveActor); Actor* Actor_GetProjectileActor(GlobalContext* globalCtx, Actor* refActor, f32 radius); void Actor_ChangeCategory(GlobalContext* globalCtx, ActorContext* actorCtx, Actor* actor, u8 actorCategory); void Actor_SetTextWithPrefix(GlobalContext* globalCtx, Actor* actor, s16 textIdLower); -s16 func_800339B8(Actor* actor, GlobalContext* globalCtx, f32 arg2, s16 arg3); +s16 Actor_TestFloorInDirection(Actor* actor, GlobalContext* globalCtx, f32 distance, s16 angle); s32 Actor_IsTargeted(GlobalContext* globalCtx, Actor* actor); s32 Actor_OtherIsTargeted(GlobalContext* globalCtx, Actor* actor); f32 func_80033AEC(Vec3f* arg0, Vec3f* arg1, f32 arg2, f32 arg3, f32 arg4, f32 arg5); diff --git a/src/code/audio_seqplayer.c b/src/code/audio_seqplayer.c index 5214ac33ef..7f86f0bc12 100644 --- a/src/code/audio_seqplayer.c +++ b/src/code/audio_seqplayer.c @@ -1410,15 +1410,15 @@ void Audio_SequenceChannelProcessScript(SequenceChannel* channel) { case 0x10: if (lowBits < 8) { channel->soundScriptIO[lowBits] = -1; - if (Audio_SyncLoadSample(channel->bankId, scriptState->value, &channel->soundScriptIO[lowBits]) == - -1) { + if (Audio_SyncLoadSample(channel->bankId, scriptState->value, + &channel->soundScriptIO[lowBits]) == -1) { break; } } else { lowBits -= 8; channel->soundScriptIO[lowBits] = -1; - if (Audio_SyncLoadSample(channel->bankId, channel->unk_22 + 0x100, &channel->soundScriptIO[lowBits]) == - -1) { + if (Audio_SyncLoadSample(channel->bankId, channel->unk_22 + 0x100, + &channel->soundScriptIO[lowBits]) == -1) { break; } } diff --git a/src/code/z_actor.c b/src/code/z_actor.c index 37613baf41..6f275987c4 100644 --- a/src/code/z_actor.c +++ b/src/code/z_actor.c @@ -2212,20 +2212,20 @@ void Actor_Draw(GlobalContext* globalCtx, Actor* actor) { gSPSegment(POLY_XLU_DISP++, 0x06, globalCtx->objectCtx.status[actor->objBankIndex].segment); if (actor->colorFilterTimer != 0) { - Color_RGBA8 sp2C = { 0, 0, 0, 255 }; + Color_RGBA8 color = { 0, 0, 0, 255 }; if (actor->colorFilterParams & 0x8000) { - sp2C.r = sp2C.g = sp2C.b = ((actor->colorFilterParams & 0x1F00) >> 5) | 7; + color.r = color.g = color.b = ((actor->colorFilterParams & 0x1F00) >> 5) | 7; } else if (actor->colorFilterParams & 0x4000) { - sp2C.r = ((actor->colorFilterParams & 0x1F00) >> 5) | 7; + color.r = ((actor->colorFilterParams & 0x1F00) >> 5) | 7; } else { - sp2C.b = ((actor->colorFilterParams & 0x1F00) >> 5) | 7; + color.b = ((actor->colorFilterParams & 0x1F00) >> 5) | 7; } if (actor->colorFilterParams & 0x2000) { - func_80026860(globalCtx, &sp2C, actor->colorFilterTimer, actor->colorFilterParams & 0xFF); + func_80026860(globalCtx, &color, actor->colorFilterTimer, actor->colorFilterParams & 0xFF); } else { - func_80026400(globalCtx, &sp2C, actor->colorFilterTimer, actor->colorFilterParams & 0xFF); + func_80026400(globalCtx, &color, actor->colorFilterTimer, actor->colorFilterParams & 0xFF); } } @@ -3167,33 +3167,35 @@ s32 BodyBreak_SpawnParts(Actor* actor, BodyBreak* bodyBreak, GlobalContext* glob return true; } -void Actor_SpawnFloorDust(GlobalContext* globalCtx, Actor* actor, Vec3f* arg2, f32 arg3, s32 arg4, f32 randAccelWeight, - s16 scale, s16 scaleStep, u8 arg8) { +void Actor_SpawnFloorDustRing(GlobalContext* globalCtx, Actor* actor, Vec3f* posXZ, f32 radius, s32 amountMinusOne, + f32 randAccelWeight, s16 scale, s16 scaleStep, u8 useLighting) { Vec3f pos; Vec3f velocity = { 0.0f, 0.0f, 0.0f }; Vec3f accel = { 0.0f, 0.3f, 0.0f }; - f32 var; + f32 angle; s32 i; - var = (Rand_ZeroOne() - 0.5f) * 6.28f; + angle = (Rand_ZeroOne() - 0.5f) * (2.0f * 3.14f); pos.y = actor->floorHeight; accel.y += (Rand_ZeroOne() - 0.5f) * 0.2f; - for (i = arg4; i >= 0; i--) { - pos.x = (Math_SinF(var) * arg3) + arg2->x; - pos.z = (Math_CosF(var) * arg3) + arg2->z; + for (i = amountMinusOne; i >= 0; i--) { + pos.x = Math_SinF(angle) * radius + posXZ->x; + pos.z = Math_CosF(angle) * radius + posXZ->z; accel.x = (Rand_ZeroOne() - 0.5f) * randAccelWeight; accel.z = (Rand_ZeroOne() - 0.5f) * randAccelWeight; if (scale == 0) { func_8002857C(globalCtx, &pos, &velocity, &accel); - } else if (arg8 != 0) { - func_800286CC(globalCtx, &pos, &velocity, &accel, scale, scaleStep); } else { - func_8002865C(globalCtx, &pos, &velocity, &accel, scale, scaleStep); + if (useLighting) { + func_800286CC(globalCtx, &pos, &velocity, &accel, scale, scaleStep); + } else { + func_8002865C(globalCtx, &pos, &velocity, &accel, scale, scaleStep); + } } - var += 6.28f / (arg4 + 1.0f); + angle += (2.0f * 3.14f) / (amountMinusOne + 1.0f); } } @@ -3388,24 +3390,33 @@ void Actor_SetTextWithPrefix(GlobalContext* globalCtx, Actor* actor, s16 baseTex actor->textId = prefix | baseTextId; } -s16 func_800339B8(Actor* actor, GlobalContext* globalCtx, f32 arg2, s16 arg3) { +/** + * Checks if a given actor will be standing on the ground after being translated + * by the provided distance and angle. + * + * Returns true if the actor will be standing on ground. + */ +s16 Actor_TestFloorInDirection(Actor* actor, GlobalContext* globalCtx, f32 distance, s16 angle) { s16 ret; - s16 sp44; - f32 sp40; - f32 sp3C; - Vec3f sp30; + s16 prevBgCheckFlags; + f32 dx; + f32 dz; + Vec3f prevActorPos; + + Math_Vec3f_Copy(&prevActorPos, &actor->world.pos); + prevBgCheckFlags = actor->bgCheckFlags; + + dx = Math_SinS(angle) * distance; + dz = Math_CosS(angle) * distance; + actor->world.pos.x += dx; + actor->world.pos.z += dz; - Math_Vec3f_Copy(&sp30, &actor->world.pos); - sp44 = actor->bgCheckFlags; - sp40 = Math_SinS(arg3) * arg2; - sp3C = Math_CosS(arg3) * arg2; - actor->world.pos.x += sp40; - actor->world.pos.z += sp3C; Actor_UpdateBgCheckInfo(globalCtx, actor, 0.0f, 0.0f, 0.0f, 4); - Math_Vec3f_Copy(&actor->world.pos, &sp30); + + Math_Vec3f_Copy(&actor->world.pos, &prevActorPos); ret = actor->bgCheckFlags & 1; - actor->bgCheckFlags = sp44; + actor->bgCheckFlags = prevBgCheckFlags; return ret; } diff --git a/src/code/z_rcp.c b/src/code/z_rcp.c index c7385c0f01..53e5e8efc3 100644 --- a/src/code/z_rcp.c +++ b/src/code/z_rcp.c @@ -782,11 +782,11 @@ Gfx* Gfx_SetFog(Gfx* gfx, s32 r, s32 g, s32 b, s32 a, s32 n, s32 f) { gDPSetFogColor(gfx++, r, g, b, a); if (n >= 1000) { - gSPFogFactor(gfx++, 0, 0); // gSPFogPosition(gfx++, ?, ?) + gSPFogFactor(gfx++, 0, 0); } else if (n >= 997) { - gSPFogFactor(gfx++, 0x7FFF, 0x8100); // gSPFogPosition(gfx++, ?, ?) + gSPFogFactor(gfx++, 0x7FFF, 0x8100); } else if (n < 0) { - gSPFogFactor(gfx++, 0, 255); // gSPFogPosition(gfx++, ?, ?) + gSPFogFactor(gfx++, 0, 255); } else { gSPFogPosition(gfx++, n, f); } @@ -804,11 +804,11 @@ Gfx* Gfx_SetFogWithSync(Gfx* gfx, s32 r, s32 g, s32 b, s32 a, s32 n, s32 f) { gDPSetFogColor(gfx++, r, g, b, a); if (n >= 1000) { - gSPFogFactor(gfx++, 0, 0); // gSPFogPosition(gfx++, ?, ?) + gSPFogFactor(gfx++, 0, 0); } else if (n >= 997) { - gSPFogFactor(gfx++, 0x7FFF, 0x8100); // gSPFogPosition(gfx++, ?, ?) + gSPFogFactor(gfx++, 0x7FFF, 0x8100); } else if (n < 0) { - gSPFogFactor(gfx++, 0, 255); // gSPFogPosition(gfx++, ?, ?) + gSPFogFactor(gfx++, 0, 255); } else { gSPFogPosition(gfx++, n, f); } diff --git a/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c b/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c index a87af5adf2..14bb5d6f83 100644 --- a/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c +++ b/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c @@ -692,9 +692,9 @@ void BossDodongo_Walk(BossDodongo* this, GlobalContext* globalCtx) { } else if (this->unk_1BC != 2) { if (((s32)this->skelAnime.curFrame == 1) || ((s32)this->skelAnime.curFrame == 31)) { if ((s32)this->skelAnime.curFrame == 1) { - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->unk_410, 25.0f, 0xA, 8.0f, 0x1F4, 0xA, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->unk_410, 25.0f, 0xA, 8.0f, 0x1F4, 0xA, 0); } else { - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->unk_404, 25.0f, 0xA, 8.0f, 0x1F4, 0xA, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->unk_404, 25.0f, 0xA, 8.0f, 0x1F4, 0xA, 0); } if (this->unk_1BC != 0) { @@ -789,7 +789,8 @@ void BossDodongo_Roll(BossDodongo* this, GlobalContext* globalCtx) { } if (!(this->unk_19E & 1)) { - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, 40.0f, 3, 8.0f, 0x1F4, 0xA, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 40.0f, 3, 8.0f, 0x1F4, 0xA, + 0); } } } @@ -1421,8 +1422,8 @@ void BossDodongo_DeathCutscene(BossDodongo* this, GlobalContext* globalCtx) { Camera_AddQuake(&globalCtx->mainCamera, 2, 1, 8); } if (!(this->unk_19E & 1)) { - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, 40.0f, 3, 8.0f, 0x1F4, 0xA, - 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 40.0f, 3, 8.0f, 0x1F4, + 0xA, 0); } tempSin = cornerPos->x - this->actor.world.pos.x; tempCos = cornerPos->z - this->actor.world.pos.z; @@ -1546,8 +1547,8 @@ void BossDodongo_DeathCutscene(BossDodongo* this, GlobalContext* globalCtx) { } else { Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_K_ROLL - SFX_FLAG); if (!(this->unk_19E & 1)) { - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, 40.0f, 3, 8.0f, 0x1F4, 0xA, - 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 40.0f, 3, 8.0f, 0x1F4, + 0xA, 0); } } Math_SmoothStepToF(&this->actor.speedXZ, 0.0f, 0.2f, 0.1f, 0.0f); diff --git a/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c b/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c index 65e9022de5..8aaa58a005 100644 --- a/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c +++ b/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c @@ -174,11 +174,11 @@ void BossGanon2_Destroy(Actor* thisx, GlobalContext* globalCtx) { void func_808FD4D4(BossGanon2* this, GlobalContext* globalCtx, s16 arg2, s16 arg3) { if ((arg2 == 0) || (arg2 == 1)) { - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->unk_1D0, 25.0f, arg3, 8.0f, 0x1F4, 0xA, 1); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->unk_1D0, 25.0f, arg3, 8.0f, 0x1F4, 0xA, 1); } if ((arg2 == 0) || (arg2 == 2)) { - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->unk_1DC, 25.0f, arg3, 8.0f, 0x1F4, 0xA, 1); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->unk_1DC, 25.0f, arg3, 8.0f, 0x1F4, 0xA, 1); } Audio_PlayActorSound2(&this->actor, NA_SE_EN_MGANON_WALK); diff --git a/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c b/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c index d6f3458361..11ae8ccfa6 100644 --- a/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c +++ b/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c @@ -368,13 +368,13 @@ void BossGoma_Init(Actor* thisx, GlobalContext* globalCtx) { void BossGoma_PlayEffectsAndSfx(BossGoma* this, GlobalContext* globalCtx, s16 arg2, s16 amountMinus1) { if (arg2 == 0 || arg2 == 1 || arg2 == 3) { - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->rightHandBackLimbWorldPos, 25.0f, amountMinus1, 8.0f, 500, - 10, 1); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->rightHandBackLimbWorldPos, 25.0f, amountMinus1, 8.0f, + 500, 10, 1); } if (arg2 == 0 || arg2 == 2 || arg2 == 3) { - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->leftHandBackLimbWorldPos, 25.0f, amountMinus1, 8.0f, 500, - 10, 1); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->leftHandBackLimbWorldPos, 25.0f, amountMinus1, 8.0f, + 500, 10, 1); } if (arg2 == 0) { @@ -1374,7 +1374,7 @@ void BossGoma_FloorLandStruckDown(BossGoma* this, GlobalContext* globalCtx) { this->framesUntilNextAction = 150; } - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, 55.0f, 4, 8.0f, 500, 10, 1); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 55.0f, 4, 8.0f, 500, 10, 1); } /** @@ -1400,7 +1400,7 @@ void BossGoma_FloorStunned(BossGoma* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelanime); if (this->timer == 1) { - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, 55.0f, 4, 8.0f, 500, 10, 1); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 55.0f, 4, 8.0f, 500, 10, 1); } Math_ApproachZeroF(&this->actor.speedXZ, 0.5f, 1.0f); diff --git a/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c b/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c index 69ae8b2416..8bb1b8e9a2 100644 --- a/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c +++ b/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c @@ -2805,7 +2805,7 @@ void BossTw_TwinrovaDeathCS(BossTw* this, GlobalContext* globalCtx) { Vec3f pos; Vec3f velocity; Vec3f accel = { 0.0f, 0.0f, 0.0f }; - + for (i = 0; i < 50; i++) { velocity.x = Rand_CenteredFloat(3.0f); velocity.y = Rand_CenteredFloat(3.0f); diff --git a/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c b/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c index eab5cfeed2..e0a36b266e 100644 --- a/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c +++ b/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c @@ -562,8 +562,8 @@ void func_809973E8(DoorShutter* this, GlobalContext* globalCtx) { if (Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y, this->dyna.actor.velocity.y)) { if (this->dyna.actor.velocity.y > 20.0f) { this->dyna.actor.floorHeight = this->dyna.actor.home.pos.y; - Actor_SpawnFloorDust(globalCtx, &this->dyna.actor, &this->dyna.actor.world.pos, 45.0f, 0xA, 8.0f, 0x1F4, - 0xA, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->dyna.actor, &this->dyna.actor.world.pos, 45.0f, 0xA, 8.0f, 0x1F4, + 0xA, 0); } Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_STONE_BOUND); quakeId = Quake_Add(Gameplay_GetCamera(globalCtx, 0), 3); @@ -599,8 +599,8 @@ void func_809975C0(DoorShutter* this, GlobalContext* globalCtx) { this->unk_164 = 10; Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_STONE_BOUND); func_8099803C(globalCtx, 2, 10, parent->subCameraId); - Actor_SpawnFloorDust(globalCtx, &this->dyna.actor, &this->dyna.actor.world.pos, 70.0f, 20, 8.0f, 500, 10, - 1); + Actor_SpawnFloorDustRing(globalCtx, &this->dyna.actor, &this->dyna.actor.world.pos, 70.0f, 20, 8.0f, 500, + 10, 1); } } } diff --git a/src/overlays/actors/ovl_En_Am/z_en_am.c b/src/overlays/actors/ovl_En_Am/z_en_am.c index 6493611039..27a40c24bf 100644 --- a/src/overlays/actors/ovl_En_Am/z_en_am.c +++ b/src/overlays/actors/ovl_En_Am/z_en_am.c @@ -270,7 +270,7 @@ void EnAm_SpawnEffects(EnAm* this, GlobalContext* globalCtx) { } Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EN_AMOS_WALK); - Actor_SpawnFloorDust(globalCtx, &this->dyna.actor, &this->dyna.actor.world.pos, 4.0f, 3, 8.0f, 0x12C, 0xF, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->dyna.actor, &this->dyna.actor.world.pos, 4.0f, 3, 8.0f, 0x12C, 0xF, 0); } void EnAm_SetupSleep(EnAm* this) { diff --git a/src/overlays/actors/ovl_En_Bb/z_en_bb.c b/src/overlays/actors/ovl_En_Bb/z_en_bb.c index e6ed6d828c..6abc0a0a5c 100644 --- a/src/overlays/actors/ovl_En_Bb/z_en_bb.c +++ b/src/overlays/actors/ovl_En_Bb/z_en_bb.c @@ -715,7 +715,7 @@ void EnBb_Down(EnBb* this, GlobalContext* globalCtx) { this->actor.velocity.y = 10.0f; } this->actor.bgCheckFlags &= ~1; - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, 7.0f, 2, 2.0f, 0, 0, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 7.0f, 2, 2.0f, 0, 0, 0); Math_SmoothStepToS(&this->actor.world.rot.y, -this->actor.yawTowardsPlayer, 1, 0xBB8, 0); } this->actor.shape.rot.y = this->actor.world.rot.y; @@ -1115,7 +1115,7 @@ void EnBb_Stunned(EnBb* this, GlobalContext* globalCtx) { } else { this->actor.velocity.y = 0.0f; } - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, 7.0f, 2, 2.0f, 0, 0, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 7.0f, 2, 2.0f, 0, 0, 0); } if (this->actor.colorFilterTimer == 0) { this->actor.shape.yOffset = 200.0f; diff --git a/src/overlays/actors/ovl_En_Bw/z_en_bw.c b/src/overlays/actors/ovl_En_Bw/z_en_bw.c index 05a946dbb0..de3bc72efa 100644 --- a/src/overlays/actors/ovl_En_Bw/z_en_bw.c +++ b/src/overlays/actors/ovl_En_Bw/z_en_bw.c @@ -326,7 +326,8 @@ void func_809CEA24(EnBw* this, GlobalContext* globalCtx) { if (this->unk_224 != 0) { this->unk_224--; } - if ((this->unk_234 == 0) && !func_800339B8(&this->actor, globalCtx, 50.0f, this->unk_236 + this->unk_238)) { + if ((this->unk_234 == 0) && + !Actor_TestFloorInDirection(&this->actor, globalCtx, 50.0f, this->unk_236 + this->unk_238)) { if (this->unk_238 != 0x4000) { this->unk_238 = 0x4000; } else { @@ -351,7 +352,7 @@ void func_809CEA24(EnBw* this, GlobalContext* globalCtx) { this->actor.speedXZ * 1000.0f, 0); if ((this->actor.xzDistToPlayer < 90.0f) && (this->actor.yDistToPlayer < 50.0f) && Actor_IsFacingPlayer(&this->actor, 0x1554) && - func_800339B8(&this->actor, globalCtx, 71.24802f, this->actor.yawTowardsPlayer)) { + Actor_TestFloorInDirection(&this->actor, globalCtx, 71.24802f, this->actor.yawTowardsPlayer)) { func_809CF8F0(this); } } else { @@ -460,7 +461,7 @@ void func_809CF984(EnBw* this, GlobalContext* globalCtx) { Actor_Kill(&this->actor); return; } - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, 30.0f, 0xB, 4.0f, 0, 0, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 30.0f, 0xB, 4.0f, 0, 0, 0); this->unk_222 = 3000; this->actor.flags &= ~0x01000000; this->actor.speedXZ = 0.0f; @@ -494,7 +495,7 @@ void func_809CFC4C(EnBw* this, GlobalContext* globalCtx) { this->unk_258 += this->unk_25C; Math_SmoothStepToF(&this->unk_260, 0.075f, 1.0f, 0.005f, 0.0f); if (this->actor.bgCheckFlags & 2) { - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, 30.0f, 0xB, 4.0f, 0, 0, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 30.0f, 0xB, 4.0f, 0, 0, 0); Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_M_GND); } if (this->unk_224 != 0) { @@ -544,7 +545,7 @@ void func_809CFF98(EnBw* this, GlobalContext* globalCtx) { Math_SmoothStepToF(&this->unk_248, 0.6f, 1.0f, 0.05f, 0.0f); SkelAnime_Update(&this->skelAnime); if (this->actor.bgCheckFlags & 3) { - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, 30.0f, 0xB, 4.0f, 0, 0, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 30.0f, 0xB, 4.0f, 0, 0, 0); this->unk_222 = 0xBB8; this->unk_250 = 0.0f; Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_M_GND); @@ -667,7 +668,7 @@ void func_809D0424(EnBw* this, GlobalContext* globalCtx) { if (func_800355E4(globalCtx, &this->collider2.base)) { this->unk_230 = 0; this->actor.scale.y -= 0.009f; - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, 30.0f, 0xB, 4.0f, 0, 0, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 30.0f, 0xB, 4.0f, 0, 0, 0); } else { this->unk_230 = 1; } @@ -681,7 +682,7 @@ void func_809D0584(EnBw* this, GlobalContext* globalCtx) { if ((this->actor.bgCheckFlags & 0x10) && (this->actor.bgCheckFlags & 1)) { this->unk_230 = 0; this->actor.scale.y -= 0.009f; - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, 30.0f, 0xB, 4.0f, 0, 0, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 30.0f, 0xB, 4.0f, 0, 0, 0); func_809D00F4(this); } else { if (this->collider2.base.acFlags & AC_HIT) { @@ -709,8 +710,8 @@ void func_809D0584(EnBw* this, GlobalContext* globalCtx) { if (func_800355E4(globalCtx, &this->collider2.base)) { this->unk_230 = 0; this->actor.scale.y -= 0.009f; - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, 30.0f, 0xB, 4.0f, 0, 0, - 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 30.0f, 0xB, 4.0f, 0, + 0, 0); } else { this->unk_230 = 1; } @@ -789,7 +790,7 @@ void EnBw_Update(Actor* thisx, GlobalContext* globalCtx2) { this->collider1.info.toucher.effect = 1; } - this->unk_234 = func_800339B8(thisx, globalCtx, 50.0f, thisx->world.rot.y); + this->unk_234 = Actor_TestFloorInDirection(thisx, globalCtx, 50.0f, thisx->world.rot.y); if ((this->unk_220 == 4) || (this->unk_220 == 6) || (this->unk_220 == 5) || (this->unk_220 == 1) || (this->unk_234 != 0)) { Actor_MoveForward(thisx); diff --git a/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c b/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c index 46d51b2e0a..a6c556afdb 100644 --- a/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c +++ b/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c @@ -551,13 +551,13 @@ void EnDodongo_Walk(EnDodongo* this, GlobalContext* globalCtx) { if ((s32)this->skelAnime.curFrame < 21) { if (!this->rightFootStep) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_J_WALK); - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->leftFootPos, 10.0f, 3, 2.0f, 0xC8, 0xF, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->leftFootPos, 10.0f, 3, 2.0f, 0xC8, 0xF, 0); this->rightFootStep = true; } } else { if (this->rightFootStep) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_J_WALK); - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->rightFootPos, 10.0f, 3, 2.0f, 0xC8, 0xF, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->rightFootPos, 10.0f, 3, 2.0f, 0xC8, 0xF, 0); this->rightFootStep = false; } } @@ -642,11 +642,11 @@ void EnDodongo_SweepTail(EnDodongo* this, GlobalContext* globalCtx) { tailPos.x = this->sphElements[1].dim.worldSphere.center.x; tailPos.y = this->sphElements[1].dim.worldSphere.center.y; tailPos.z = this->sphElements[1].dim.worldSphere.center.z; - Actor_SpawnFloorDust(globalCtx, &this->actor, &tailPos, 5.0f, 2, 2.0f, 100, 15, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &tailPos, 5.0f, 2, 2.0f, 100, 15, 0); tailPos.x = this->sphElements[2].dim.worldSphere.center.x; tailPos.y = this->sphElements[2].dim.worldSphere.center.y; tailPos.z = this->sphElements[2].dim.worldSphere.center.z; - Actor_SpawnFloorDust(globalCtx, &this->actor, &tailPos, 5.0f, 2, 2.0f, 100, 15, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &tailPos, 5.0f, 2, 2.0f, 100, 15, 0); if (this->colliderBody.base.atFlags & AT_HIT) { Player* player = PLAYER; diff --git a/src/overlays/actors/ovl_En_Fire_Rock/z_en_fire_rock.c b/src/overlays/actors/ovl_En_Fire_Rock/z_en_fire_rock.c index ae58d38db8..8b69f84177 100644 --- a/src/overlays/actors/ovl_En_Fire_Rock/z_en_fire_rock.c +++ b/src/overlays/actors/ovl_En_Fire_Rock/z_en_fire_rock.c @@ -201,8 +201,8 @@ void EnFireRock_Fall(EnFireRock* this, GlobalContext* globalCtx) { case FIRE_ROCK_SPAWNED_FALLING2: func_80033E88(&this->actor, globalCtx, 5, 2); case FIRE_ROCK_BROKEN_PIECE1: - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale, 1, - 8.0f, 500, 10, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale, + 1, 8.0f, 500, 10, 0); for (i = 0; i < 5; i++) { flamePos.x = Rand_CenteredFloat(20.0f) + this->actor.world.pos.x; flamePos.y = this->actor.floorHeight; @@ -212,8 +212,8 @@ void EnFireRock_Fall(EnFireRock* this, GlobalContext* globalCtx) { this->actionFunc = EnFireRock_SpawnMoreBrokenPieces; break; default: - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale, 3, - 8.0f, 200, 10, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale, + 3, 8.0f, 200, 10, 0); Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_EXPLOSION); Actor_Kill(&this->actor); break; diff --git a/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c b/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c index 3ef1465cc9..557aecf2cf 100644 --- a/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c +++ b/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c @@ -255,7 +255,7 @@ void EnFloormas_SetupHover(EnFloormas* this, GlobalContext* globalCtx) { this->actor.speedXZ = 0.0f; this->actor.gravity = 0.0f; EnFloormas_MakeInvulnerable(this); - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, 15.0f, 6, 20.0f, 0x12C, 0x64, 1); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 15.0f, 6, 20.0f, 0x12C, 0x64, 1); Audio_PlayActorSound2(&this->actor, NA_SE_EN_FLOORMASTER_ATTACK); this->actionFunc = EnFloormas_Hover; } diff --git a/src/overlays/actors/ovl_En_Fz/z_en_fz.c b/src/overlays/actors/ovl_En_Fz/z_en_fz.c index cf6621c697..9b4f49673b 100644 --- a/src/overlays/actors/ovl_En_Fz/z_en_fz.c +++ b/src/overlays/actors/ovl_En_Fz/z_en_fz.c @@ -323,8 +323,9 @@ void EnFz_SpawnIceSmokeActiveState(EnFz* this) { void EnFz_ApplyDamage(EnFz* this, GlobalContext* globalCtx) { Vec3f vec; - if (this->isMoving && ((this->actor.bgCheckFlags & 8) || - (func_800339B8(&this->actor, globalCtx, 60.0f, this->actor.world.rot.y) == 0))) { + if (this->isMoving && + ((this->actor.bgCheckFlags & 8) || + (Actor_TestFloorInDirection(&this->actor, globalCtx, 60.0f, this->actor.world.rot.y) == 0))) { this->actor.bgCheckFlags &= ~8; this->isMoving = false; this->speedXZ = 0.0f; diff --git a/src/overlays/actors/ovl_En_GeldB/z_en_geldb.c b/src/overlays/actors/ovl_En_GeldB/z_en_geldb.c index 224b106591..85c9837f8f 100644 --- a/src/overlays/actors/ovl_En_GeldB/z_en_geldb.c +++ b/src/overlays/actors/ovl_En_GeldB/z_en_geldb.c @@ -366,8 +366,8 @@ void EnGeldB_Wait(EnGeldB* this, GlobalContext* globalCtx) { this->actor.focus.pos = this->actor.world.pos; this->actor.bgCheckFlags &= ~2; this->actor.velocity.y = 0.0f; - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->leftFootPos, 3.0f, 2, 2.0f, 0, 0, 0); - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->rightFootPos, 3.0f, 2, 2.0f, 0, 0, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->leftFootPos, 3.0f, 2, 2.0f, 0, 0, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->rightFootPos, 3.0f, 2, 2.0f, 0, 0, 0); } if (SkelAnime_Update(&this->skelAnime)) { EnGeldB_SetupReady(this); @@ -391,8 +391,8 @@ void EnGeldB_Flee(EnGeldB* this, GlobalContext* globalCtx) { } if (this->skelAnime.curFrame == 2.0f) { this->actor.gravity = 0.0f; - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->leftFootPos, 3.0f, 2, 2.0f, 0, 0, 0); - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->rightFootPos, 3.0f, 2, 2.0f, 0, 0, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->leftFootPos, 3.0f, 2, 2.0f, 0, 0, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->rightFootPos, 3.0f, 2, 2.0f, 0, 0, 0); } if (SkelAnime_Update(&this->skelAnime)) { Math_SmoothStepToF(&this->actor.world.pos.y, this->actor.floorHeight + 300.0f, 1.0f, 20.5f, 0.0f); @@ -664,8 +664,8 @@ void EnGeldB_Circle(EnGeldB* this, GlobalContext* globalCtx) { this->actor.speedXZ = 8.0f; } } - if ((this->actor.bgCheckFlags & 8) || - !func_800339B8(&this->actor, globalCtx, this->actor.speedXZ, this->actor.shape.rot.y + 0x3E80)) { + if ((this->actor.bgCheckFlags & 8) || !Actor_TestFloorInDirection(&this->actor, globalCtx, this->actor.speedXZ, + this->actor.shape.rot.y + 0x3E80)) { if (this->actor.bgCheckFlags & 8) { if (this->actor.speedXZ >= 0.0f) { phi_v1 = this->actor.shape.rot.y + 0x3E80; @@ -764,7 +764,7 @@ void EnGeldB_SpinDodge(EnGeldB* this, GlobalContext* globalCtx) { this->actor.world.rot.y = this->actor.yawTowardsPlayer + 0x3A98; if ((this->actor.bgCheckFlags & 8) || - !func_800339B8(&this->actor, globalCtx, this->actor.speedXZ, this->actor.shape.rot.y + 0x3E80)) { + !Actor_TestFloorInDirection(&this->actor, globalCtx, this->actor.speedXZ, this->actor.shape.rot.y + 0x3E80)) { if (this->actor.bgCheckFlags & 8) { if (this->actor.speedXZ >= 0.0f) { phi_v1 = this->actor.shape.rot.y + 0x3E80; @@ -923,8 +923,8 @@ void EnGeldB_SpinAttack(EnGeldB* this, GlobalContext* globalCtx) { if ((s32)this->skelAnime.curFrame < 9) { this->actor.shape.rot.y = this->actor.world.rot.y = this->actor.yawTowardsPlayer; } else if ((s32)this->skelAnime.curFrame == 13) { - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->leftFootPos, 3.0f, 2, 2.0f, 0, 0, 0); - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->rightFootPos, 3.0f, 2, 2.0f, 0, 0, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->leftFootPos, 3.0f, 2, 2.0f, 0, 0, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->rightFootPos, 3.0f, 2, 2.0f, 0, 0, 0); this->swordState = 1; this->actor.speedXZ = 10.0f; Audio_PlayActorSound2(&this->actor, NA_SE_EN_GERUDOFT_ATTACK); @@ -1213,7 +1213,7 @@ void EnGeldB_Sidestep(EnGeldB* this, GlobalContext* globalCtx) { } if ((this->actor.bgCheckFlags & 8) || - !func_800339B8(&this->actor, globalCtx, this->actor.speedXZ, this->actor.shape.rot.y + 0x3E80)) { + !Actor_TestFloorInDirection(&this->actor, globalCtx, this->actor.speedXZ, this->actor.shape.rot.y + 0x3E80)) { if (this->actor.bgCheckFlags & 8) { if (this->actor.speedXZ >= 0.0f) { phi_v1 = this->actor.shape.rot.y + 0x3E80; diff --git a/src/overlays/actors/ovl_En_Mb/z_en_mb.c b/src/overlays/actors/ovl_En_Mb/z_en_mb.c index 297c458b02..18b333c206 100644 --- a/src/overlays/actors/ovl_En_Mb/z_en_mb.c +++ b/src/overlays/actors/ovl_En_Mb/z_en_mb.c @@ -7,10 +7,49 @@ #include "z_en_mb.h" #include "objects/object_mb/object_mb.h" +/* + * This actor can have three behaviors: + * - "Spear Guard" (variable -1): uses a spear, walks around home point, charges player if too close + * - "Club" (variable 0): uses a club, stands still and smashes its club on the ground when the player approaches + * - "Spear Patrol" (variable 0xPP00 PP=pathId): uses a spear, patrols following a path, charges + */ + #define FLAGS 0x00000015 #define THIS ((EnMb*)thisx) +typedef enum { + /* -1 */ ENMB_TYPE_SPEAR_GUARD = -1, + /* 0 */ ENMB_TYPE_CLUB, + /* 1 */ ENMB_TYPE_SPEAR_PATROL +} EnMbType; + +#define ENMB_ATTACK_NONE 0 +#define ENMB_ATTACK_SPEAR 1 +#define ENMB_ATTACK_CLUB_RIGHT 1 +#define ENMB_ATTACK_CLUB_MIDDLE 2 +#define ENMB_ATTACK_CLUB_LEFT 3 + +/* Spear and Club moblins use a different skeleton but the limbs are organized the same */ +typedef enum { + /* 1 */ ENMB_LIMB_ROOT = 1, + /* 3 */ ENMB_LIMB_WAIST = 3, + /* 6 */ ENMB_LIMB_CHEST = 6, + /* 7 */ ENMB_LIMB_HEAD, + /* 9 */ ENMB_LIMB_LSHOULDER = 9, + /* 11 */ ENMB_LIMB_LFOREARM = 11, + /* 12 */ ENMB_LIMB_LHAND, + /* 14 */ ENMB_LIMB_RSHOULDER = 14, + /* 16 */ ENMB_LIMB_RFOREARM = 16, + /* 17 */ ENMB_LIMB_RHAND, + /* 20 */ ENMB_LIMB_LTHIGH = 20, + /* 21 */ ENMB_LIMB_LSHIN, + /* 22 */ ENMB_LIMB_LFOOT, + /* 25 */ ENMB_LIMB_RTHIGH = 25, + /* 26 */ ENMB_LIMB_RSHIN, + /* 27 */ ENMB_LIMB_RFOOT +} EnMbLimb; + void EnMb_Init(Actor* thisx, GlobalContext* globalCtx); void EnMb_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnMb_Update(Actor* thisx, GlobalContext* globalCtx); @@ -28,35 +67,31 @@ const ActorInit En_Mb_InitVars = { (ActorFunc)EnMb_Draw, }; -void func_80AA68FC(EnMb* this, GlobalContext* globalCtx); -void func_80AA6898(EnMb* this); -void func_80AA7134(EnMb* this, GlobalContext* globalCtx); -void func_80AA6830(EnMb* this); -void func_80AA8E88(EnMb* this); -void func_80AA87D8(EnMb* this, GlobalContext* globalCtx); -void func_80AA77D0(EnMb* this, GlobalContext* globalCtx); -void func_80AA7CAC(EnMb* this, GlobalContext* globalCtx); -void func_80AA7310(EnMb* this, GlobalContext* globalCtx); -void func_80AA702C(EnMb* this, GlobalContext* globalCtx); -void func_80AA8514(EnMb* this, GlobalContext* globalCtx); -void func_80AA840C(EnMb* this, GlobalContext* globalCtx); -void func_80AA8DD8(EnMb* this, GlobalContext* globalCtx); -void func_80AA7938(EnMb* this, GlobalContext* globalCtx); -void func_80AA90A0(EnMb* this, GlobalContext* globalCtx); -void func_80AA8F50(EnMb* this, GlobalContext* globalCtx); -void func_80AA8FC8(EnMb* this); -void func_80AA71AC(EnMb* this, GlobalContext* globalCtx); -void func_80AA8AEC(EnMb* this, GlobalContext* globalCtx); -void func_80AA74BC(EnMb* this, GlobalContext* globalCtx); -void func_80AA800C(EnMb* this, GlobalContext* globalCtx); -void func_80AA7478(EnMb* this, GlobalContext* globalCtx); -void func_80AA8378(EnMb* this, GlobalContext* globalCtx); - -void EnMb_SetupAction(EnMb* this, EnMbActionFunc actionFunc) { - this->actionFunc = actionFunc; -} - -static ColliderCylinderInit sCylinderInit = { +void EnMb_SetupSpearPatrolTurnTowardsWaypoint(EnMb* this, GlobalContext* globalCtx); +void EnMb_SetupClubWaitPlayerNear(EnMb* this); +void EnMb_SpearGuardLookAround(EnMb* this, GlobalContext* globalCtx); +void EnMb_SetupSpearGuardLookAround(EnMb* this); +void EnMb_SetupSpearDamaged(EnMb* this); +void EnMb_SpearGuardWalk(EnMb* this, GlobalContext* globalCtx); +void EnMb_SpearGuardPrepareAndCharge(EnMb* this, GlobalContext* globalCtx); +void EnMb_SpearPatrolPrepareAndCharge(EnMb* this, GlobalContext* globalCtx); +void EnMb_SpearEndChargeQuick(EnMb* this, GlobalContext* globalCtx); +void EnMb_Stunned(EnMb* this, GlobalContext* globalCtx); +void EnMb_ClubDead(EnMb* this, GlobalContext* globalCtx); +void EnMb_ClubDamagedWhileKneeling(EnMb* this, GlobalContext* globalCtx); +void EnMb_ClubWaitPlayerNear(EnMb* this, GlobalContext* globalCtx); +void EnMb_ClubAttack(EnMb* this, GlobalContext* globalCtx); +void EnMb_SpearDead(EnMb* this, GlobalContext* globalCtx); +void EnMb_SpearDamaged(EnMb* this, GlobalContext* globalCtx); +void EnMb_SetupSpearDead(EnMb* this); +void EnMb_SpearPatrolTurnTowardsWaypoint(EnMb* this, GlobalContext* globalCtx); +void EnMb_SpearPatrolWalkTowardsWaypoint(EnMb* this, GlobalContext* globalCtx); +void EnMb_SpearPatrolEndCharge(EnMb* this, GlobalContext* globalCtx); +void EnMb_SpearPatrolImmediateCharge(EnMb* this, GlobalContext* globalCtx); +void EnMb_ClubWaitAfterAttack(EnMb* this, GlobalContext* globalCtx); +void EnMb_ClubDamaged(EnMb* this, GlobalContext* globalCtx); + +static ColliderCylinderInit sHitboxInit = { { COLTYPE_HIT0, AT_NONE, @@ -76,7 +111,7 @@ static ColliderCylinderInit sCylinderInit = { { 20, 70, 0, { 0, 0, 0 } }, }; -static ColliderTrisElementInit sTrisElementsInit[2] = { +static ColliderTrisElementInit sFrontShieldingTrisInit[2] = { { { ELEMTYPE_UNK2, @@ -101,7 +136,7 @@ static ColliderTrisElementInit sTrisElementsInit[2] = { }, }; -static ColliderTrisInit sTrisInit = { +static ColliderTrisInit sFrontShieldingInit = { { COLTYPE_METAL, AT_NONE, @@ -111,10 +146,10 @@ static ColliderTrisInit sTrisInit = { COLSHAPE_TRIS, }, 2, - sTrisElementsInit, + sFrontShieldingTrisInit, }; -static ColliderQuadInit sQuadInit = { +static ColliderQuadInit sAttackColliderInit = { { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, @@ -134,148 +169,164 @@ static ColliderQuadInit sQuadInit = { { { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } }, }; -static DamageTable sDamageTable = { - /* Deku nut */ DMG_ENTRY(0, 0x5), - /* Deku stick */ DMG_ENTRY(2, 0xF), - /* Slingshot */ DMG_ENTRY(1, 0xF), - /* Explosive */ DMG_ENTRY(2, 0xF), - /* Boomerang */ DMG_ENTRY(0, 0x1), - /* Normal arrow */ DMG_ENTRY(2, 0xF), - /* Hammer swing */ DMG_ENTRY(2, 0xF), - /* Hookshot */ DMG_ENTRY(2, 0xF), - /* Kokiri sword */ DMG_ENTRY(1, 0xF), - /* Master sword */ DMG_ENTRY(2, 0xF), - /* Giant's Knife */ DMG_ENTRY(4, 0xF), - /* Fire arrow */ DMG_ENTRY(2, 0xF), - /* Ice arrow */ DMG_ENTRY(4, 0x6), - /* Light arrow */ DMG_ENTRY(2, 0xF), - /* Unk arrow 1 */ DMG_ENTRY(4, 0xF), - /* Unk arrow 2 */ DMG_ENTRY(2, 0xF), - /* Unk arrow 3 */ DMG_ENTRY(2, 0xF), - /* Fire magic */ DMG_ENTRY(0, 0x5), - /* Ice magic */ DMG_ENTRY(3, 0x6), - /* Light magic */ DMG_ENTRY(0, 0x5), - /* Shield */ DMG_ENTRY(0, 0x0), - /* Mirror Ray */ DMG_ENTRY(0, 0x0), - /* Kokiri spin */ DMG_ENTRY(1, 0xF), - /* Giant spin */ DMG_ENTRY(4, 0xF), - /* Master spin */ DMG_ENTRY(2, 0xF), - /* Kokiri jump */ DMG_ENTRY(2, 0xF), - /* Giant jump */ DMG_ENTRY(8, 0xF), - /* Master jump */ DMG_ENTRY(4, 0xF), - /* Unknown 1 */ DMG_ENTRY(0, 0x5), - /* Unblockable */ DMG_ENTRY(0, 0x0), - /* Hammer jump */ DMG_ENTRY(4, 0xF), - /* Unknown 2 */ DMG_ENTRY(0, 0x0), +typedef enum { + /* 0x0 */ ENMB_DMGEFF_IGNORE, + /* 0x1 */ ENMB_DMGEFF_STUN, + /* 0x5 */ ENMB_DMGEFF_FREEZE = 0x5, + /* 0x6 */ ENMB_DMGEFF_STUN_ICE, + /* 0xF */ ENMB_DMGEFF_DEFAULT = 0xF +} EnMbDamageEffect; + +static DamageTable sSpearMoblinDamageTable = { + /* Deku nut */ DMG_ENTRY(0, ENMB_DMGEFF_FREEZE), + /* Deku stick */ DMG_ENTRY(2, ENMB_DMGEFF_DEFAULT), + /* Slingshot */ DMG_ENTRY(1, ENMB_DMGEFF_DEFAULT), + /* Explosive */ DMG_ENTRY(2, ENMB_DMGEFF_DEFAULT), + /* Boomerang */ DMG_ENTRY(0, ENMB_DMGEFF_STUN), + /* Normal arrow */ DMG_ENTRY(2, ENMB_DMGEFF_DEFAULT), + /* Hammer swing */ DMG_ENTRY(2, ENMB_DMGEFF_DEFAULT), + /* Hookshot */ DMG_ENTRY(2, ENMB_DMGEFF_DEFAULT), + /* Kokiri sword */ DMG_ENTRY(1, ENMB_DMGEFF_DEFAULT), + /* Master sword */ DMG_ENTRY(2, ENMB_DMGEFF_DEFAULT), + /* Giant's Knife */ DMG_ENTRY(4, ENMB_DMGEFF_DEFAULT), + /* Fire arrow */ DMG_ENTRY(2, ENMB_DMGEFF_DEFAULT), + /* Ice arrow */ DMG_ENTRY(4, ENMB_DMGEFF_STUN_ICE), + /* Light arrow */ DMG_ENTRY(2, ENMB_DMGEFF_DEFAULT), + /* Unk arrow 1 */ DMG_ENTRY(4, ENMB_DMGEFF_DEFAULT), + /* Unk arrow 2 */ DMG_ENTRY(2, ENMB_DMGEFF_DEFAULT), + /* Unk arrow 3 */ DMG_ENTRY(2, ENMB_DMGEFF_DEFAULT), + /* Fire magic */ DMG_ENTRY(0, ENMB_DMGEFF_FREEZE), + /* Ice magic */ DMG_ENTRY(3, ENMB_DMGEFF_STUN_ICE), + /* Light magic */ DMG_ENTRY(0, ENMB_DMGEFF_FREEZE), + /* Shield */ DMG_ENTRY(0, ENMB_DMGEFF_IGNORE), + /* Mirror Ray */ DMG_ENTRY(0, ENMB_DMGEFF_IGNORE), + /* Kokiri spin */ DMG_ENTRY(1, ENMB_DMGEFF_DEFAULT), + /* Giant spin */ DMG_ENTRY(4, ENMB_DMGEFF_DEFAULT), + /* Master spin */ DMG_ENTRY(2, ENMB_DMGEFF_DEFAULT), + /* Kokiri jump */ DMG_ENTRY(2, ENMB_DMGEFF_DEFAULT), + /* Giant jump */ DMG_ENTRY(8, ENMB_DMGEFF_DEFAULT), + /* Master jump */ DMG_ENTRY(4, ENMB_DMGEFF_DEFAULT), + /* Unknown 1 */ DMG_ENTRY(0, ENMB_DMGEFF_FREEZE), + /* Unblockable */ DMG_ENTRY(0, ENMB_DMGEFF_IGNORE), + /* Hammer jump */ DMG_ENTRY(4, ENMB_DMGEFF_DEFAULT), + /* Unknown 2 */ DMG_ENTRY(0, ENMB_DMGEFF_IGNORE), }; -static DamageTable sBigMoblinDamageTable = { - /* Deku nut */ DMG_ENTRY(0, 0x5), - /* Deku stick */ DMG_ENTRY(2, 0xF), - /* Slingshot */ DMG_ENTRY(0, 0x0), - /* Explosive */ DMG_ENTRY(2, 0xF), - /* Boomerang */ DMG_ENTRY(0, 0x0), - /* Normal arrow */ DMG_ENTRY(2, 0xF), - /* Hammer swing */ DMG_ENTRY(2, 0xF), - /* Hookshot */ DMG_ENTRY(0, 0x1), - /* Kokiri sword */ DMG_ENTRY(1, 0xF), - /* Master sword */ DMG_ENTRY(2, 0xF), - /* Giant's Knife */ DMG_ENTRY(4, 0xF), - /* Fire arrow */ DMG_ENTRY(2, 0xF), - /* Ice arrow */ DMG_ENTRY(4, 0x6), - /* Light arrow */ DMG_ENTRY(2, 0xF), - /* Unk arrow 1 */ DMG_ENTRY(4, 0xF), - /* Unk arrow 2 */ DMG_ENTRY(2, 0xF), - /* Unk arrow 3 */ DMG_ENTRY(2, 0xF), - /* Fire magic */ DMG_ENTRY(0, 0x5), - /* Ice magic */ DMG_ENTRY(3, 0x6), - /* Light magic */ DMG_ENTRY(0, 0x5), - /* Shield */ DMG_ENTRY(0, 0x0), - /* Mirror Ray */ DMG_ENTRY(0, 0x0), - /* Kokiri spin */ DMG_ENTRY(1, 0xF), - /* Giant spin */ DMG_ENTRY(4, 0xF), - /* Master spin */ DMG_ENTRY(2, 0xF), - /* Kokiri jump */ DMG_ENTRY(2, 0xF), - /* Giant jump */ DMG_ENTRY(8, 0xF), - /* Master jump */ DMG_ENTRY(4, 0xF), - /* Unknown 1 */ DMG_ENTRY(0, 0x5), - /* Unblockable */ DMG_ENTRY(0, 0x0), - /* Hammer jump */ DMG_ENTRY(4, 0xF), - /* Unknown 2 */ DMG_ENTRY(0, 0x0), +static DamageTable sClubMoblinDamageTable = { + /* Deku nut */ DMG_ENTRY(0, ENMB_DMGEFF_FREEZE), + /* Deku stick */ DMG_ENTRY(2, ENMB_DMGEFF_DEFAULT), + /* Slingshot */ DMG_ENTRY(0, ENMB_DMGEFF_IGNORE), + /* Explosive */ DMG_ENTRY(2, ENMB_DMGEFF_DEFAULT), + /* Boomerang */ DMG_ENTRY(0, ENMB_DMGEFF_IGNORE), + /* Normal arrow */ DMG_ENTRY(2, ENMB_DMGEFF_DEFAULT), + /* Hammer swing */ DMG_ENTRY(2, ENMB_DMGEFF_DEFAULT), + /* Hookshot */ DMG_ENTRY(0, ENMB_DMGEFF_STUN), + /* Kokiri sword */ DMG_ENTRY(1, ENMB_DMGEFF_DEFAULT), + /* Master sword */ DMG_ENTRY(2, ENMB_DMGEFF_DEFAULT), + /* Giant's Knife */ DMG_ENTRY(4, ENMB_DMGEFF_DEFAULT), + /* Fire arrow */ DMG_ENTRY(2, ENMB_DMGEFF_DEFAULT), + /* Ice arrow */ DMG_ENTRY(4, ENMB_DMGEFF_STUN_ICE), + /* Light arrow */ DMG_ENTRY(2, ENMB_DMGEFF_DEFAULT), + /* Unk arrow 1 */ DMG_ENTRY(4, ENMB_DMGEFF_DEFAULT), + /* Unk arrow 2 */ DMG_ENTRY(2, ENMB_DMGEFF_DEFAULT), + /* Unk arrow 3 */ DMG_ENTRY(2, ENMB_DMGEFF_DEFAULT), + /* Fire magic */ DMG_ENTRY(0, ENMB_DMGEFF_FREEZE), + /* Ice magic */ DMG_ENTRY(3, ENMB_DMGEFF_STUN_ICE), + /* Light magic */ DMG_ENTRY(0, ENMB_DMGEFF_FREEZE), + /* Shield */ DMG_ENTRY(0, ENMB_DMGEFF_IGNORE), + /* Mirror Ray */ DMG_ENTRY(0, ENMB_DMGEFF_IGNORE), + /* Kokiri spin */ DMG_ENTRY(1, ENMB_DMGEFF_DEFAULT), + /* Giant spin */ DMG_ENTRY(4, ENMB_DMGEFF_DEFAULT), + /* Master spin */ DMG_ENTRY(2, ENMB_DMGEFF_DEFAULT), + /* Kokiri jump */ DMG_ENTRY(2, ENMB_DMGEFF_DEFAULT), + /* Giant jump */ DMG_ENTRY(8, ENMB_DMGEFF_DEFAULT), + /* Master jump */ DMG_ENTRY(4, ENMB_DMGEFF_DEFAULT), + /* Unknown 1 */ DMG_ENTRY(0, ENMB_DMGEFF_FREEZE), + /* Unblockable */ DMG_ENTRY(0, ENMB_DMGEFF_IGNORE), + /* Hammer jump */ DMG_ENTRY(4, ENMB_DMGEFF_DEFAULT), + /* Unknown 2 */ DMG_ENTRY(0, ENMB_DMGEFF_IGNORE), }; static InitChainEntry sInitChain[] = { ICHAIN_S8(naviEnemyId, 74, ICHAIN_CONTINUE), - ICHAIN_F32_DIV1000(gravity, 64536, ICHAIN_CONTINUE), + ICHAIN_F32_DIV1000(gravity, -1000, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 5300, ICHAIN_STOP), }; +void EnMb_SetupAction(EnMb* this, EnMbActionFunc actionFunc) { + this->actionFunc = actionFunc; +} + void EnMb_Init(Actor* thisx, GlobalContext* globalCtx) { EnMb* this = THIS; s32 pad; Player* player = PLAYER; - s16 yawDiff; + s16 relYawFromPlayer; Actor_ProcessInitChain(&this->actor, sInitChain); ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 46.0f); this->actor.colChkInfo.mass = MASS_IMMOVABLE; - this->actor.colChkInfo.damageTable = &sDamageTable; - Collider_InitCylinder(globalCtx, &this->collider1); - Collider_SetCylinder(globalCtx, &this->collider1, &this->actor, &sCylinderInit); - Collider_InitTris(globalCtx, &this->collider3); - Collider_SetTris(globalCtx, &this->collider3, &this->actor, &sTrisInit, this->collider3Items); - Collider_InitQuad(globalCtx, &this->collider2); - Collider_SetQuad(globalCtx, &this->collider2, &this->actor, &sQuadInit); + this->actor.colChkInfo.damageTable = &sSpearMoblinDamageTable; + Collider_InitCylinder(globalCtx, &this->hitbox); + Collider_SetCylinder(globalCtx, &this->hitbox, &this->actor, &sHitboxInit); + Collider_InitTris(globalCtx, &this->frontShielding); + Collider_SetTris(globalCtx, &this->frontShielding, &this->actor, &sFrontShieldingInit, this->frontShieldingTris); + Collider_InitQuad(globalCtx, &this->attackCollider); + Collider_SetQuad(globalCtx, &this->attackCollider, &this->actor, &sAttackColliderInit); switch (this->actor.params) { - case -1: - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gEnMbSkel_008F38, &gEnMbStandStillAnim, this->jointTable, - this->morphTable, 28); + case ENMB_TYPE_SPEAR_GUARD: + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gEnMbSpearSkel, &gEnMbSpearStandStillAnim, + this->jointTable, this->morphTable, 28); this->actor.colChkInfo.health = 2; this->actor.colChkInfo.mass = MASS_HEAVY; - this->unk_360 = 1000.0f; - this->unk_364 = 1750.0f; - func_80AA6830(this); + this->maxHomeDist = 1000.0f; + this->playerDetectionRange = 1750.0f; + EnMb_SetupSpearGuardLookAround(this); break; - case 0: - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gEnMbSkel_014190, &gEnMbAnim_00EBE4, this->jointTable, - this->morphTable, 28); + case ENMB_TYPE_CLUB: + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gEnMbClubSkel, &gEnMbClubStandStillClubDownAnim, + this->jointTable, this->morphTable, 28); + this->actor.colChkInfo.health = 6; this->actor.colChkInfo.mass = MASS_IMMOVABLE; - this->actor.colChkInfo.damageTable = &sBigMoblinDamageTable; + this->actor.colChkInfo.damageTable = &sClubMoblinDamageTable; Actor_SetScale(&this->actor, 0.02f); - this->collider1.dim.height = 170; - this->collider1.dim.radius = 45; + this->hitbox.dim.height = 170; + this->hitbox.dim.radius = 45; this->actor.uncullZoneForward = 4000.0f; this->actor.uncullZoneScale = 800.0f; this->actor.uncullZoneDownward = 1800.0f; - this->unk_364 = 710.0f; - this->collider2.info.toucher.dmgFlags = 0x20000000; - yawDiff = (this->actor.world.rot.y - Math_Vec3f_Yaw(&this->actor.world.pos, &player->actor.world.pos)); + this->playerDetectionRange = 710.0f; + this->attackCollider.info.toucher.dmgFlags = 0x20000000; - if (ABS(yawDiff) > 0x4000) { + relYawFromPlayer = + this->actor.world.rot.y - Math_Vec3f_Yaw(&this->actor.world.pos, &player->actor.world.pos); + if (ABS(relYawFromPlayer) > 0x4000) { this->actor.world.rot.y = thisx->world.rot.y + 0x8000; this->actor.shape.rot.y = thisx->world.rot.y; this->actor.world.pos.z = thisx->world.pos.z + 600.0f; } + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawFeet, 90.0f); this->actor.flags &= ~1; - this->actor.naviEnemyId++; - func_80AA6898(this); + this->actor.naviEnemyId += 1; + EnMb_SetupClubWaitPlayerNear(this); break; - default: - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gEnMbSkel_008F38, &gEnMbStandStillAnim, this->jointTable, - this->morphTable, 28); + default: /* Spear Patrol */ + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gEnMbSpearSkel, &gEnMbSpearStandStillAnim, + this->jointTable, this->morphTable, 28); + Actor_SetScale(&this->actor, 0.014f); this->path = (thisx->params & 0xFF00) >> 8; - this->actor.params = 1; + this->actor.params = ENMB_TYPE_SPEAR_PATROL; this->waypoint = 0; this->actor.colChkInfo.health = 1; this->actor.colChkInfo.mass = MASS_HEAVY; - this->unk_360 = 350.0f; - this->unk_364 = 1750.0f; + this->maxHomeDist = 350.0f; + this->playerDetectionRange = 1750.0f; this->actor.flags &= ~1; - func_80AA68FC(this, globalCtx); + EnMb_SetupSpearPatrolTurnTowardsWaypoint(this, globalCtx); break; } } @@ -283,21 +334,21 @@ void EnMb_Init(Actor* thisx, GlobalContext* globalCtx) { void EnMb_Destroy(Actor* thisx, GlobalContext* globalCtx) { EnMb* this = THIS; - Collider_DestroyTris(globalCtx, &this->collider3); - Collider_DestroyCylinder(globalCtx, &this->collider1); - Collider_DestroyQuad(globalCtx, &this->collider2); + Collider_DestroyTris(globalCtx, &this->frontShielding); + Collider_DestroyCylinder(globalCtx, &this->hitbox); + Collider_DestroyQuad(globalCtx, &this->attackCollider); } -void func_80AA6408(EnMb* this, GlobalContext* globalCtx) { - s16 yaw = Math_Vec3f_Yaw(&this->actor.world.pos, &this->waypointPos); +void EnMb_FaceWaypoint(EnMb* this, GlobalContext* globalCtx) { + s16 yawToWaypoint = Math_Vec3f_Yaw(&this->actor.world.pos, &this->waypointPos); - this->actor.shape.rot.y = yaw; - this->actor.world.rot.y = yaw; + this->actor.shape.rot.y = yawToWaypoint; + this->actor.world.rot.y = yawToWaypoint; } -void func_80AA6444(EnMb* this, GlobalContext* globalCtx) { +void EnMb_NextWaypoint(EnMb* this, GlobalContext* globalCtx) { Path* path; - Vec3s* pathPos; + Vec3s* waypointPos; path = &globalCtx->setupPathList[this->path]; @@ -308,482 +359,481 @@ void func_80AA6444(EnMb* this, GlobalContext* globalCtx) { } this->waypoint += this->direction; - pathPos = &((Vec3s*)SEGMENTED_TO_VIRTUAL(path->points))[this->waypoint]; - this->waypointPos.x = pathPos->x; - this->waypointPos.y = pathPos->y; - this->waypointPos.z = pathPos->z; + waypointPos = (Vec3s*)SEGMENTED_TO_VIRTUAL(path->points) + this->waypoint; + this->waypointPos.x = waypointPos->x; + this->waypointPos.y = waypointPos->y; + this->waypointPos.z = waypointPos->z; } -s32 func_80AA652C(EnMb* this, GlobalContext* globalCtx) { - Player* player; - f32 xDist; - f32 zDist; - f32 cosAngle; - f32 sinAngle; - f32 xDistABS; - f32 zDistABS; - s16 phi_a2; - - player = PLAYER; - phi_a2 = 0; - if ((this->actor.world.rot.y < -0x62A2) || (this->actor.world.rot.y >= 0x62A3)) { - phi_a2 = -0x8000; +/** + * Checks if the player is in a 800*74 units XZ area centered on this actor, + * the area being directed along its line of sight snapped to a cardinal angle. + * Note: the longest corridor in Sacred Forest Meadows is 800 units long, + * and they all are 100 units wide. + */ +s32 EnMb_IsPlayerInCorridor(EnMb* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + f32 xFromPlayer; + f32 zFromPlayer; + f32 cos; + f32 sin; + f32 xFromPlayerAbs; + f32 zFromPlayerAbs; + s16 alignedYaw = 0; + + if ((this->actor.world.rot.y < -0x62A2) || (this->actor.world.rot.y > 0x62A2)) { + alignedYaw = -0x8000; } else if (this->actor.world.rot.y < -0x20E0) { - phi_a2 = -0x4000; - } else { - if (this->actor.world.rot.y >= 0x20E1) { - phi_a2 = 0x4000; - } + alignedYaw = -0x4000; + } else if (this->actor.world.rot.y > 0x20E0) { + alignedYaw = 0x4000; } - cosAngle = Math_CosS(phi_a2); - sinAngle = Math_SinS(phi_a2); - cosAngle = ABS(cosAngle); - sinAngle = ABS(sinAngle); - xDist = this->actor.world.pos.x - player->actor.world.pos.x; - zDist = this->actor.world.pos.z - player->actor.world.pos.z; - xDistABS = ABS(xDist); - if (xDistABS < cosAngle * 37.0f + sinAngle * 400.0f) { - if (0 <= zDist) { - zDistABS = zDist; - } else { - zDistABS = -zDist; - } - if (zDistABS < (sinAngle * 37.0f) + (cosAngle * 400.0f)) { - return 1; + + cos = Math_CosS(alignedYaw); + sin = Math_SinS(alignedYaw); + cos = ABS(cos); + sin = ABS(sin); + xFromPlayer = this->actor.world.pos.x - player->actor.world.pos.x; + zFromPlayer = this->actor.world.pos.z - player->actor.world.pos.z; + xFromPlayerAbs = ABS(xFromPlayer); + if (xFromPlayerAbs < (cos * 37.0f + sin * 400.0f)) { + zFromPlayerAbs = ABS(zFromPlayer); + if (zFromPlayerAbs < (sin * 37.0f + cos * 400.0f)) { + return true; } } - return 0; + return false; } -void func_80AA66A0(EnMb* this, GlobalContext* globalCtx) { - Path* path; - s16 yawToPoints; - Vec3f points; - Vec3s* pointPath; - s16 yawDiff; - s32 pathCount; - s32 pathIndex; - s32 yawDiffABS; - - path = &globalCtx->setupPathList[this->path]; - for (pathIndex = 0, pathCount = path->count - 1; pathCount >= 0; pathCount--, pathIndex++) { - pointPath = &((Vec3s*)SEGMENTED_TO_VIRTUAL(path->points))[pathIndex]; - points.x = pointPath->x; - points.y = pointPath->y; - points.z = pointPath->z; - yawToPoints = Math_Vec3f_Yaw(&this->actor.world.pos, &points); - yawDiff = yawToPoints - this->actor.yawTowardsPlayer; - yawDiffABS = (yawDiff >= 0) ? yawDiff : -yawDiff; - if (yawDiffABS <= 0x1770) { - this->actor.world.rot.y = yawToPoints; - if (pathIndex == this->waypoint) { +void EnMb_FindWaypointTowardsPlayer(EnMb* this, GlobalContext* globalCtx) { + Path* path = &globalCtx->setupPathList[this->path]; + s16 yawToWaypoint; + Vec3f waypointPosF; + Vec3s* waypointPosS; + s16 yawPlayerToWaypoint; + s32 i; + s32 waypoint; + + for (waypoint = 0, i = path->count - 1; i >= 0; i--, waypoint++) { + waypointPosS = (Vec3s*)SEGMENTED_TO_VIRTUAL(path->points) + waypoint; + waypointPosF.x = waypointPosS->x; + waypointPosF.y = waypointPosS->y; + waypointPosF.z = waypointPosS->z; + yawToWaypoint = Math_Vec3f_Yaw(&this->actor.world.pos, &waypointPosF); + yawPlayerToWaypoint = yawToWaypoint - this->actor.yawTowardsPlayer; + if (ABS(yawPlayerToWaypoint) <= 0x1770) { + this->actor.world.rot.y = yawToWaypoint; + if (waypoint == this->waypoint) { this->direction = -this->direction; } - this->waypointPos = points; - this->waypoint = pathIndex; - return; + this->waypointPos = waypointPosF; + this->waypoint = waypoint; + break; } } } -void func_80AA6830(EnMb* this) { - Animation_MorphToLoop(&this->skelAnime, &gEnMbLookLeftAndRightAnim, -4.0f); +void EnMb_SetupSpearGuardLookAround(EnMb* this) { + Animation_MorphToLoop(&this->skelAnime, &gEnMbSpearLookLeftAndRightAnim, -4.0f); this->actor.speedXZ = 0.0f; - this->unk_32A = Rand_S16Offset(30, 50); - this->unk_320 = 6; - EnMb_SetupAction(this, func_80AA7134); + this->timer1 = Rand_S16Offset(30, 50); + this->state = ENMB_STATE_IDLE; + EnMb_SetupAction(this, EnMb_SpearGuardLookAround); } -void func_80AA6898(EnMb* this) { - Animation_PlayLoop(&this->skelAnime, &gEnMbAnim_00EBE4); +void EnMb_SetupClubWaitPlayerNear(EnMb* this) { + Animation_PlayLoop(&this->skelAnime, &gEnMbClubStandStillClubDownAnim); this->actor.speedXZ = 0.0f; - this->unk_32A = Rand_S16Offset(30, 50); - this->unk_320 = 6; - EnMb_SetupAction(this, func_80AA8DD8); + this->timer1 = Rand_S16Offset(30, 50); + this->state = ENMB_STATE_IDLE; + EnMb_SetupAction(this, EnMb_ClubWaitPlayerNear); } -void func_80AA68FC(EnMb* this, GlobalContext* globalCtx) { - Animation_MorphToLoop(&this->skelAnime, &gEnMbLookLeftAndRightAnim, -4.0f); +void EnMb_SetupSpearPatrolTurnTowardsWaypoint(EnMb* this, GlobalContext* globalCtx) { + Animation_MorphToLoop(&this->skelAnime, &gEnMbSpearLookLeftAndRightAnim, -4.0f); this->actor.speedXZ = 0.0f; - this->unk_32A = Rand_S16Offset(40, 80); - this->unk_320 = 6; - func_80AA6444(this, globalCtx); - EnMb_SetupAction(this, func_80AA71AC); + this->timer1 = Rand_S16Offset(40, 80); + this->state = ENMB_STATE_IDLE; + EnMb_NextWaypoint(this, globalCtx); + EnMb_SetupAction(this, EnMb_SpearPatrolTurnTowardsWaypoint); } -void func_80AA6974(EnMb* this) { - Animation_Change(&this->skelAnime, &gEnMbWalkAnim, 0.0f, 0.0f, Animation_GetLastFrame(&gEnMbWalkAnim), +void EnMb_SetupSpearGuardWalk(EnMb* this) { + Animation_Change(&this->skelAnime, &gEnMbSpearWalkAnim, 0.0f, 0.0f, Animation_GetLastFrame(&gEnMbSpearWalkAnim), ANIMMODE_LOOP, -4.0f); this->actor.speedXZ = 0.59999996f; - this->unk_32A = Rand_S16Offset(50, 70); + this->timer1 = Rand_S16Offset(50, 70); this->unk_332 = 1; - this->unk_320 = 9; - EnMb_SetupAction(this, func_80AA87D8); + this->state = ENMB_STATE_WALK; + EnMb_SetupAction(this, EnMb_SpearGuardWalk); } -void func_80AA6A18(EnMb* this) { - f32 frameCount; +void EnMb_SetupSpearPatrolWalkTowardsWaypoint(EnMb* this) { + f32 frameCount = Animation_GetLastFrame(&gEnMbSpearWalkAnim); - frameCount = Animation_GetLastFrame(&gEnMbWalkAnim); this->actor.speedXZ = 0.59999996f; - this->unk_32A = Rand_S16Offset(50, 70); + this->timer1 = Rand_S16Offset(50, 70); this->unk_332 = 1; - this->unk_320 = 9; - Animation_Change(&this->skelAnime, &gEnMbWalkAnim, 0.0f, 0.0f, frameCount, ANIMMODE_LOOP_INTERP, -4.0f); - EnMb_SetupAction(this, func_80AA8AEC); + this->state = ENMB_STATE_WALK; + Animation_Change(&this->skelAnime, &gEnMbSpearWalkAnim, 0.0f, 0.0f, frameCount, ANIMMODE_LOOP_INTERP, -4.0f); + EnMb_SetupAction(this, EnMb_SpearPatrolWalkTowardsWaypoint); } -void func_80AA6AC8(EnMb* this) { - f32 frameCount; +void EnMb_SetupSpearPrepareAndCharge(EnMb* this) { + f32 frameCount = Animation_GetLastFrame(&gEnMbSpearPrepareChargeAnim); - frameCount = Animation_GetLastFrame(&gEnMbReadyAttackAnim); - Animation_MorphToPlayOnce(&this->skelAnime, &gEnMbReadyAttackAnim, -4.0f); - this->unk_320 = 10; + Animation_MorphToPlayOnce(&this->skelAnime, &gEnMbSpearPrepareChargeAnim, -4.0f); + this->state = ENMB_STATE_ATTACK; this->actor.speedXZ = 0.0f; - this->unk_32E = (s16)frameCount + 6; + this->timer3 = (s16)frameCount + 6; Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_SPEAR_AT); - if (this->actor.params == -1) { - EnMb_SetupAction(this, func_80AA77D0); + if (this->actor.params == ENMB_TYPE_SPEAR_GUARD) { + EnMb_SetupAction(this, EnMb_SpearGuardPrepareAndCharge); } else { - EnMb_SetupAction(this, func_80AA7CAC); + EnMb_SetupAction(this, EnMb_SpearPatrolPrepareAndCharge); } } -void func_80AA6B80(EnMb* this) { - Animation_PlayLoop(&this->skelAnime, &gEnMbChargePlayerAnim); +void EnMb_SetupSpearPatrolImmediateCharge(EnMb* this) { + Animation_PlayLoop(&this->skelAnime, &gEnMbSpearChargeAnim); Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_ATTACK); - this->attackParams = 1; - this->unk_320 = 10; - this->unk_32E = 3; + this->attack = ENMB_ATTACK_SPEAR; + this->state = ENMB_STATE_ATTACK; + this->timer3 = 3; this->actor.speedXZ = 10.0f; - EnMb_SetupAction(this, func_80AA800C); + EnMb_SetupAction(this, EnMb_SpearPatrolImmediateCharge); } -void func_80AA6BF0(EnMb* this) { - f32 frames; - s16 yawDiff; - s32 yawDiffABS; +void EnMb_SetupClubAttack(EnMb* this) { + f32 frames = Animation_GetLastFrame(&gEnMbClubLiftClubAnim); + s16 relYawFromPlayer; - frames = Animation_GetLastFrame(&gEnMbAnim_00B4BC); - this->unk_320 = 10; - Animation_Change(&this->skelAnime, &gEnMbAnim_00B4BC, 3.0f, 0.0f, frames, ANIMMODE_ONCE_INTERP, 0.0f); - this->unk_32E = 1; - yawDiff = (this->actor.world.rot.y - this->actor.yawTowardsPlayer); + this->state = ENMB_STATE_ATTACK; + Animation_Change(&this->skelAnime, &gEnMbClubLiftClubAnim, 3.0f, 0.0f, frames, ANIMMODE_ONCE_INTERP, 0.0f); + this->timer3 = 1; + relYawFromPlayer = this->actor.world.rot.y - this->actor.yawTowardsPlayer; - if (yawDiff >= 0) { - yawDiffABS = yawDiff; + if (ABS(relYawFromPlayer) <= 0x258) { + this->attack = ENMB_ATTACK_CLUB_MIDDLE; + } else if (relYawFromPlayer >= 0) { + this->attack = ENMB_ATTACK_CLUB_RIGHT; } else { - yawDiffABS = 0 - yawDiff; + this->attack = ENMB_ATTACK_CLUB_LEFT; } - if (yawDiffABS < 0x259) { - this->attackParams = 2; - } else if (yawDiff >= 0) { - this->attackParams = 1; - } else { - this->attackParams = 3; - } - - EnMb_SetupAction(this, func_80AA7938); + EnMb_SetupAction(this, EnMb_ClubAttack); } -void func_80AA6CC0(EnMb* this) { - Animation_PlayOnce(&this->skelAnime, &gEnMbResumePatrolAnim); - this->unk_320 = 11; - this->unk_32A = 0; - this->unk_32E = 5; +void EnMb_SetupSpearEndChargeQuick(EnMb* this) { + Animation_PlayOnce(&this->skelAnime, &gEnMbSpearSlowDownAnim); + this->state = ENMB_STATE_ATTACK_END; + this->timer1 = 0; + this->timer3 = 5; Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_SLIDE); - EnMb_SetupAction(this, func_80AA7310); + EnMb_SetupAction(this, EnMb_SpearEndChargeQuick); } -void func_80AA6D20(EnMb* this) { - Animation_PlayOnce(&this->skelAnime, &gEnMbResumePatrolAnim); - this->unk_320 = 0xB; +void EnMb_SetupSpearPatrolEndCharge(EnMb* this) { + Animation_PlayOnce(&this->skelAnime, &gEnMbSpearSlowDownAnim); + this->state = ENMB_STATE_ATTACK_END; this->actor.bgCheckFlags &= ~1; - this->unk_32A = 0; - this->unk_32E = 50; + this->timer1 = 0; + this->timer3 = 50; this->actor.speedXZ = -8.0f; this->actor.velocity.y = 6.0f; Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_SLIDE); - EnMb_SetupAction(this, func_80AA74BC); + EnMb_SetupAction(this, EnMb_SpearPatrolEndCharge); } -void func_80AA6DA4(EnMb* this) { - f32 frameCount; +void EnMb_SetupClubWaitAfterAttack(EnMb* this) { + f32 frameCount = Animation_GetLastFrame(&gEnMbClubStandStillClubDownAnim); - frameCount = Animation_GetLastFrame(&gEnMbAnim_00EBE4); - this->unk_320 = 11; - Animation_Change(&this->skelAnime, &gEnMbAnim_00EBE4, 5.0f, 0.0f, frameCount, ANIMMODE_ONCE_INTERP, 0.0f); - EnMb_SetupAction(this, func_80AA7478); + this->state = ENMB_STATE_ATTACK_END; + Animation_Change(&this->skelAnime, &gEnMbClubStandStillClubDownAnim, 5.0f, 0.0f, frameCount, ANIMMODE_ONCE_INTERP, + 0.0f); + EnMb_SetupAction(this, EnMb_ClubWaitAfterAttack); } -void func_80AA6E1C(EnMb* this) { - Animation_PlayOnce(&this->skelAnime, &gEnMbAnim_00C44C); - this->unk_320 = 3; - this->unk_32A = 0; - this->unk_32E = 20; +void EnMb_SetupClubDamaged(EnMb* this) { + Animation_PlayOnce(&this->skelAnime, &gEnMbClubDamagedKneelAnim); + this->state = ENMB_STATE_CLUB_KNEELING; + this->timer1 = 0; + this->timer3 = 20; Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_DEAD); - EnMb_SetupAction(this, func_80AA8378); + EnMb_SetupAction(this, EnMb_ClubDamaged); } -void func_80AA6E7C(EnMb* this) { - f32 frames; +void EnMb_SetupClubDamagedWhileKneeling(EnMb* this) { + f32 frames = Animation_GetLastFrame(&gEnMbClubBeatenKneelingAnim); - frames = Animation_GetLastFrame(&gEnMbAnim_00D5D4); - this->unk_320 = 2; - this->unk_32A = 0; - this->unk_32E = 6; - Animation_Change(&this->skelAnime, &gEnMbAnim_00D5D4, 1.0f, 4.0f, frames, ANIMMODE_ONCE_INTERP, 0.0f); - EnMb_SetupAction(this, func_80AA840C); + this->state = ENMB_STATE_CLUB_KNEELING_DAMAGED; + this->timer1 = 0; + this->timer3 = 6; + Animation_Change(&this->skelAnime, &gEnMbClubBeatenKneelingAnim, 1.0f, 4.0f, frames, ANIMMODE_ONCE_INTERP, 0.0f); + EnMb_SetupAction(this, EnMb_ClubDamagedWhileKneeling); } -void func_80AA6F04(EnMb* this) { - Animation_MorphToPlayOnce(&this->skelAnime, &gEnMbAnim_00BE58, -4.0f); - this->unk_320 = 1; +void EnMb_SetupClubDead(EnMb* this) { + Animation_MorphToPlayOnce(&this->skelAnime, &gEnMbClubFallOnItsBackAnim, -4.0f); + this->state = ENMB_STATE_CLUB_DEAD; this->actor.flags &= ~1; - this->collider1.dim.height = 80; - this->collider1.dim.radius = 95; - this->unk_32A = 30; + this->hitbox.dim.height = 80; + this->hitbox.dim.radius = 95; + this->timer1 = 30; this->actor.speedXZ = 0.0f; Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_DEAD); - EnMb_SetupAction(this, func_80AA8514); + EnMb_SetupAction(this, EnMb_ClubDead); } -void func_80AA6F8C(EnMb* this) { - this->unk_320 = 5; +void EnMb_SetupStunned(EnMb* this) { + this->state = ENMB_STATE_STUNNED; this->actor.speedXZ = 0.0f; Actor_SetColorFilter(&this->actor, 0, 0x78, 0, 0x50); - if (this->unk_188 == 6) { - this->unk_328 = 40; + if (this->damageEffect == ENMB_DMGEFF_STUN_ICE) { + this->iceEffectTimer = 40; } else { - if (this->actor.params != 0) { - Animation_PlayOnceSetSpeed(&this->skelAnime, &gEnMbAnim_001950, 0.0f); + if (this->actor.params != ENMB_TYPE_CLUB) { + Animation_PlayOnceSetSpeed(&this->skelAnime, &gEnMbSpearDamagedFromFrontAnim, 0.0f); } Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOMA_JR_FREEZE); } - EnMb_SetupAction(this, func_80AA702C); + EnMb_SetupAction(this, EnMb_Stunned); } -void func_80AA702C(EnMb* this, GlobalContext* globalCtx) { +void EnMb_Stunned(EnMb* this, GlobalContext* globalCtx) { Player* player = PLAYER; - if ((player->stateFlags2 & 0x80) && (&this->actor == player->actor.parent)) { + if ((player->stateFlags2 & 0x80) && player->actor.parent == &this->actor) { player->stateFlags2 &= ~0x80; player->actor.parent = NULL; player->unk_850 = 200; func_8002F71C(globalCtx, &this->actor, 4.0f, this->actor.world.rot.y, 4.0f); - this->attackParams = 0; + this->attack = ENMB_ATTACK_NONE; } + if (this->actor.colorFilterTimer == 0) { - if (this->actor.params == 0) { + if (this->actor.params == ENMB_TYPE_CLUB) { if (this->actor.colChkInfo.health == 0) { - func_80AA6F04(this); - } else if (this->unk_320 == 3) { - func_80AA6E7C(this); + EnMb_SetupClubDead(this); + } else if (this->state == ENMB_STATE_CLUB_KNEELING) { + /* dead code: the setup for this action sets state to something else */ + EnMb_SetupClubDamagedWhileKneeling(this); } else { - func_80AA6898(this); + EnMb_SetupClubWaitPlayerNear(this); } - } else if (this->actor.colChkInfo.health == 0) { - func_80AA8FC8(this); } else { - func_80AA8E88(this); + if (this->actor.colChkInfo.health == 0) { + EnMb_SetupSpearDead(this); + } else { + EnMb_SetupSpearDamaged(this); + } } } } -void func_80AA7134(EnMb* this, GlobalContext* globalCtx) { - s16 phi_v0; +void EnMb_SpearGuardLookAround(EnMb* this, GlobalContext* globalCtx) { + s16 timer1; SkelAnime_Update(&this->skelAnime); - if (this->unk_32A == 0) { - phi_v0 = 0; + if (this->timer1 == 0) { + timer1 = 0; } else { - this->unk_32A--; - phi_v0 = this->unk_32A; + this->timer1--; + timer1 = this->timer1; } - if (phi_v0 == 0) { - if (Animation_OnFrame(&this->skelAnime, 0.0f) != 0) { - func_80AA6974(this); - } + if (timer1 == 0 && Animation_OnFrame(&this->skelAnime, 0.0f)) { + EnMb_SetupSpearGuardWalk(this); } } -void func_80AA71AC(EnMb* this, GlobalContext* globalCtx) { - f32 yDist; - s16 yawDiff; - f32 yDistAbs; - s32 yawDiffAbs; +void EnMb_SpearPatrolTurnTowardsWaypoint(EnMb* this, GlobalContext* globalCtx) { + s16 relYawFromPlayer; SkelAnime_Update(&this->skelAnime); - if (this->unk_32A == 0) { - this->unk_330 = Math_Vec3f_Yaw(&this->actor.world.pos, &this->waypointPos); - if (Math_SmoothStepToS(&this->actor.shape.rot.y, this->unk_330, 1, 0x3E8, 0) == 0) { + + if (this->timer1 == 0) { + this->yawToWaypoint = Math_Vec3f_Yaw(&this->actor.world.pos, &this->waypointPos); + if (Math_SmoothStepToS(&this->actor.shape.rot.y, this->yawToWaypoint, 1, 0x3E8, 0) == 0) { this->actor.world.rot.y = this->actor.shape.rot.y; - func_80AA6A18(this); + EnMb_SetupSpearPatrolWalkTowardsWaypoint(this); } } else { - this->unk_32A--; + this->timer1--; Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 1, 0x3E8, 0); } - yDist = this->actor.yDistToPlayer; - yDistAbs = ABS(yDist); - if ((yDistAbs <= 20.0f) && func_80AA652C(this, globalCtx)) { - yawDiff = this->actor.shape.rot.y - this->actor.yawTowardsPlayer; - yawDiffAbs = ABS(yawDiff); - if ((yawDiffAbs <= 0x4000) || (func_8002DDE4(globalCtx) && (this->actor.xzDistToPlayer < 160.0f))) { - func_80AA66A0(this, globalCtx); + + if (ABS(this->actor.yDistToPlayer) <= 20.0f && EnMb_IsPlayerInCorridor(this, globalCtx)) { + relYawFromPlayer = this->actor.shape.rot.y - this->actor.yawTowardsPlayer; + if (ABS(relYawFromPlayer) <= 0x4000 || (func_8002DDE4(globalCtx) && this->actor.xzDistToPlayer < 160.0f)) { + EnMb_FindWaypointTowardsPlayer(this, globalCtx); Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_VOICE); - func_80AA6AC8(this); + EnMb_SetupSpearPrepareAndCharge(this); } } } -void func_80AA7310(EnMb* this, GlobalContext* globalCtx) { +/** + * Slow down and resume walking. + */ +void EnMb_SpearEndChargeQuick(EnMb* this, GlobalContext* globalCtx) { s32 pad; Math_SmoothStepToF(&this->actor.speedXZ, 0.0f, 0.5f, 1.0f, 0.0f); if (this->actor.speedXZ > 1.0f) { - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, 5.0f, 3, 4.0f, 0x64, 0xF, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 5.0f, 3, 4.0f, 100, 15, false); } - if (SkelAnime_Update(&this->skelAnime) != 0) { - if (this->unk_32A == 0) { - this->unk_32E--; - if (this->unk_32E == 0) { - Animation_Change(&this->skelAnime, &gEnMbReadyAttackAnim, -1.0f, - Animation_GetLastFrame(&gEnMbReadyAttackAnim), 0.0f, ANIMMODE_ONCE, 0.0f); - this->unk_32A = 1; + if (SkelAnime_Update(&this->skelAnime)) { + if (this->timer1 == 0) { + this->timer3--; + if (this->timer3 == 0) { + /* Play the charge animation in reverse: let go of the spear and stand normally */ + Animation_Change(&this->skelAnime, &gEnMbSpearPrepareChargeAnim, -1.0f, + Animation_GetLastFrame(&gEnMbSpearPrepareChargeAnim), 0.0f, ANIMMODE_ONCE, 0.0f); + this->timer1 = 1; this->actor.speedXZ = 0.0f; Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_SPEAR_NORM); } } else { - if (this->actor.params < 0) { - func_80AA6974(this); - this->unk_32A = this->soundTimer = this->unk_32E = 80; + if (this->actor.params <= ENMB_TYPE_SPEAR_GUARD) { + EnMb_SetupSpearGuardWalk(this); + this->timer1 = this->timer2 = this->timer3 = 80; } else { - func_80AA68FC(this, globalCtx); + EnMb_SetupSpearPatrolTurnTowardsWaypoint(this, globalCtx); } } } } -void func_80AA7478(EnMb* this, GlobalContext* globalCtx) { - this->attackParams = 0; - if (SkelAnime_Update(&this->skelAnime) != 0) { - func_80AA6898(this); +void EnMb_ClubWaitAfterAttack(EnMb* this, GlobalContext* globalCtx) { + this->attack = ENMB_ATTACK_NONE; + if (SkelAnime_Update(&this->skelAnime)) { + EnMb_SetupClubWaitPlayerNear(this); } } -void func_80AA74BC(EnMb* this, GlobalContext* globalCtx) { +/** + * Slow down, charge again if the player is near, or resume walking. + */ +void EnMb_SpearPatrolEndCharge(EnMb* this, GlobalContext* globalCtx) { Player* player = PLAYER; - f32 endFrame; - s16 yawDiff; + f32 lastFrame; + s16 relYawFromPlayer; + s16 yawPlayerToWaypoint; - if ((player->stateFlags2 & 0x80) && (&this->actor == player->actor.parent)) { + if ((player->stateFlags2 & 0x80) && player->actor.parent == &this->actor) { player->stateFlags2 &= ~0x80; player->actor.parent = NULL; player->unk_850 = 200; func_8002F71C(globalCtx, &this->actor, 4.0f, this->actor.world.rot.y, 4.0f); } + if (this->actor.bgCheckFlags & 1) { Math_SmoothStepToF(&this->actor.speedXZ, 0.0f, 1.0f, 1.5f, 0.0f); - if (1.0f < this->actor.speedXZ) { - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, 5.0f, 3, 4.0f, 0x64, 0xF, 0); + + if (this->actor.speedXZ > 1.0f) { + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 5.0f, 3, 4.0f, 100, 15, false); } - if (this->unk_32A != 0) { - this->unk_32E--; - if (this->unk_32E == 0) { - yawDiff = this->actor.shape.rot.y - this->actor.yawTowardsPlayer; - - if ((ABS(this->actor.yDistToPlayer) <= 20.0f) && (func_80AA652C(this, globalCtx) != 0) && - (ABS(yawDiff) <= 0x4000) && (this->actor.xzDistToPlayer <= 200.0f)) { - func_80AA6AC8(this); + + if (this->timer1 != 0) { + this->timer3--; + if (this->timer3 == 0) { + relYawFromPlayer = this->actor.shape.rot.y - this->actor.yawTowardsPlayer; + + if (ABS(this->actor.yDistToPlayer) <= 20.0f && EnMb_IsPlayerInCorridor(this, globalCtx) && + ABS(relYawFromPlayer) <= 0x4000 && this->actor.xzDistToPlayer <= 200.0f) { + EnMb_SetupSpearPrepareAndCharge(this); } else { - endFrame = Animation_GetLastFrame(&gEnMbReadyAttackAnim); - Animation_Change(&this->skelAnime, &gEnMbReadyAttackAnim, -1.0f, endFrame, 0.0f, ANIMMODE_ONCE, - 0.0f); + lastFrame = Animation_GetLastFrame(&gEnMbSpearPrepareChargeAnim); + /* Play the charge animation in reverse: let go of the spear and stand normally */ + Animation_Change(&this->skelAnime, &gEnMbSpearPrepareChargeAnim, -1.0f, lastFrame, 0.0f, + ANIMMODE_ONCE, 0.0f); this->actor.speedXZ = 0.0f; Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_SPEAR_NORM); } - - } else if (this->actor.xzDistToPlayer <= 160.0f) { - this->actor.speedXZ = -5.0f; } else { - this->actor.speedXZ = 0.0f; + if (this->actor.xzDistToPlayer <= 160.0f) { + this->actor.speedXZ = -5.0f; + } else { + this->actor.speedXZ = 0.0f; + } } } - if (SkelAnime_Update(&this->skelAnime) != 0) { - if (this->unk_32A == 0) { - endFrame = Animation_GetLastFrame(&gEnMbChargePlayerAnim); - Animation_Change(&this->skelAnime, &gEnMbChargePlayerAnim, 0.5f, 0.0f, endFrame, ANIMMODE_LOOP_INTERP, + + if (SkelAnime_Update(&this->skelAnime)) { + if (this->timer1 == 0) { + lastFrame = Animation_GetLastFrame(&gEnMbSpearChargeAnim); + Animation_Change(&this->skelAnime, &gEnMbSpearChargeAnim, 0.5f, 0.0f, lastFrame, ANIMMODE_LOOP_INTERP, 0.0f); - this->unk_32A = 1; + this->timer1 = 1; } else { - yawDiff = Math_Vec3f_Yaw(&this->actor.world.pos, &this->waypointPos) - this->actor.yawTowardsPlayer; + yawPlayerToWaypoint = + Math_Vec3f_Yaw(&this->actor.world.pos, &this->waypointPos) - this->actor.yawTowardsPlayer; - if (ABS(yawDiff) <= 0x4000) { - func_80AA68FC(this, globalCtx); + if (ABS(yawPlayerToWaypoint) <= 0x4000) { + EnMb_SetupSpearPatrolTurnTowardsWaypoint(this, globalCtx); } else { - func_80AA6A18(this); + EnMb_SetupSpearPatrolWalkTowardsWaypoint(this); } } } } } -void func_80AA77D0(EnMb* this, GlobalContext* globalCtx) { - s32 currentFrame; - s16 yawDiff; - - yawDiff = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; +/** + * Prepare charge (animation), then charge until the player isn't in front. + */ +void EnMb_SpearGuardPrepareAndCharge(EnMb* this, GlobalContext* globalCtx) { + s32 prevFrame; + s16 relYawTowardsPlayerAbs = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; - if (yawDiff < 0) { - yawDiff = -yawDiff; + if (relYawTowardsPlayerAbs < 0) { + relYawTowardsPlayerAbs = -relYawTowardsPlayerAbs; } - currentFrame = this->skelAnime.curFrame; + prevFrame = this->skelAnime.curFrame; if (SkelAnime_Update(&this->skelAnime)) { - Animation_PlayLoop(&this->skelAnime, &gEnMbChargePlayerAnim); + Animation_PlayLoop(&this->skelAnime, &gEnMbSpearChargeAnim); Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_ATTACK); } - if (this->unk_32E != 0) { - this->unk_32E--; - Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 1, 3000, 0); + if (this->timer3 != 0) { + this->timer3--; + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 1, 0xBB8, 0); } else { this->actor.speedXZ = 10.0f; - this->attackParams = 1; - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, 5.0f, 3, 4.0f, 0x64, 0xF, 0); - if ((currentFrame != (s32)this->skelAnime.curFrame) && - (((s32)this->skelAnime.curFrame == 2) || ((s32)this->skelAnime.curFrame == 6))) { + this->attack = ENMB_ATTACK_SPEAR; + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 5.0f, 3, 4.0f, 100, 15, false); + if (prevFrame != (s32)this->skelAnime.curFrame && + ((s32)this->skelAnime.curFrame == 2 || (s32)this->skelAnime.curFrame == 6)) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_DASH); } } - if (yawDiff > 5000) { - this->attackParams = 0; - func_80AA6CC0(this); + if (relYawTowardsPlayerAbs > 0x1388) { + this->attack = ENMB_ATTACK_NONE; + EnMb_SetupSpearEndChargeQuick(this); } } -void func_80AA7938(EnMb* this, GlobalContext* globalCtx) { +void EnMb_ClubAttack(EnMb* this, GlobalContext* globalCtx) { Player* player = PLAYER; s32 pad; - Vec3f sp74; - Vec3f sp68 = { 0.0f, 0.0f, 0.0f }; - f32 sp5C[] = { 18.0f, 18.0f, 0.0f }; - s16 sp54[] = { 20, 40, 0 }; - s16 sp4C[] = { -2500, 0, 3500 }; + Vec3f effSpawnPos; + Vec3f effWhiteShockwaveDynamics = { 0.0f, 0.0f, 0.0f }; + f32 flamesParams[] = { 18.0f, 18.0f, 0.0f }; + s16 flamesUnused[] = { 20, 40, 0 }; + s16 relYawTarget[] = { -0x9C4, 0, 0xDAC }; - Math_SmoothStepToS(&this->actor.shape.rot.y, sp4C[this->attackParams - 1] + this->actor.world.rot.y, 1, 0x2EE, 0); + Math_SmoothStepToS(&this->actor.shape.rot.y, relYawTarget[this->attack - 1] + this->actor.world.rot.y, 1, 0x2EE, 0); - if (this->collider2.base.atFlags & AT_HIT) { - this->collider2.base.atFlags &= ~AT_HIT; - if (this->collider2.base.at == &player->actor) { - u8 oldInvincibilityTimer = player->invincibilityTimer; + if (this->attackCollider.base.atFlags & AT_HIT) { + this->attackCollider.base.atFlags &= ~AT_HIT; + if (this->attackCollider.base.at == &player->actor) { + u8 prevPlayerInvincibilityTimer = player->invincibilityTimer; if (player->invincibilityTimer < 0) { - if (player->invincibilityTimer < -39) { + if (player->invincibilityTimer <= -40) { player->invincibilityTimer = 0; } else { player->invincibilityTimer = 0; @@ -791,71 +841,76 @@ void func_80AA7938(EnMb* this, GlobalContext* globalCtx) { } } - func_8002F71C(globalCtx, &this->actor, ((650.0f - this->actor.xzDistToPlayer) * 0.04f) + 4.0f, + func_8002F71C(globalCtx, &this->actor, (650.0f - this->actor.xzDistToPlayer) * 0.04f + 4.0f, this->actor.world.rot.y, 8.0f); - player->invincibilityTimer = oldInvincibilityTimer; + player->invincibilityTimer = prevPlayerInvincibilityTimer; } } + if (SkelAnime_Update(&this->skelAnime)) { - if (this->unk_32E != 0) { - this->unk_32E--; - if (this->unk_32E == 0) { - f32 pad1 = Animation_GetLastFrame(&gEnMbAnim_00ABE0); - Animation_Change(&this->skelAnime, &gEnMbAnim_00ABE0, 1.5f, 0.0f, pad1, ANIMMODE_ONCE_INTERP, 0.0f); + if (this->timer3 != 0) { + this->timer3--; + if (this->timer3 == 0) { + f32 lastAnimFrame = Animation_GetLastFrame(&gEnMbClubStrikeDownAnim); + Animation_Change(&this->skelAnime, &gEnMbClubStrikeDownAnim, 1.5f, 0.0f, lastAnimFrame, + ANIMMODE_ONCE_INTERP, 0.0f); } } else { - sp74 = this->effSpawnPos; - sp74.y = this->actor.floorHeight; + effSpawnPos = this->effSpawnPos; + effSpawnPos.y = this->actor.floorHeight; Audio_PlayActorSound2(&this->actor, NA_SE_EN_MONBLIN_HAM_LAND); func_800AA000(this->actor.xzDistToPlayer, 0xFF, 0x14, 0x96); - EffectSsBlast_SpawnWhiteShockwave(globalCtx, &sp74, &sp68, &sp68); - func_80033480(globalCtx, &sp74, 2.0f, 3, 0x12C, 0xB4, 1); + EffectSsBlast_SpawnWhiteShockwave(globalCtx, &effSpawnPos, &effWhiteShockwaveDynamics, + &effWhiteShockwaveDynamics); + func_80033480(globalCtx, &effSpawnPos, 2.0f, 3, 0x12C, 0xB4, 1); Camera_AddQuake(&globalCtx->mainCamera, 2, 0x19, 5); - func_800358DC(&this->actor, &sp74, &this->actor.world.rot, sp5C, 20, sp54, globalCtx, -1, 0); - func_80AA6DA4(this); + func_800358DC(&this->actor, &effSpawnPos, &this->actor.world.rot, flamesParams, 20, flamesUnused, globalCtx, + -1, 0); + EnMb_SetupClubWaitAfterAttack(this); } } else { - if ((this->unk_32E != 0) && (this->skelAnime.curFrame == 6.0f)) { + if (this->timer3 != 0 && this->skelAnime.curFrame == 6.0f) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_MONBLIN_HAM_UP); - } else if ((this->unk_32E == 0) && (this->skelAnime.curFrame == 3.0f)) { + } else if (this->timer3 == 0 && this->skelAnime.curFrame == 3.0f) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_MONBLIN_HAM_DOWN); } } } -void func_80AA7CAC(EnMb* this, GlobalContext* globalCtx) { - Player* player; - s32 currentFrame; - s32 sp4C; - s32 sp48; - - player = PLAYER; - sp4C = 0; - sp48 = !func_800339B8(&this->actor, globalCtx, 110.0f, this->actor.world.rot.y); - currentFrame = (s32)this->skelAnime.curFrame; - if (SkelAnime_Update(&this->skelAnime) != 0) { - Animation_PlayLoop(&this->skelAnime, &gEnMbChargePlayerAnim); +/** + * Prepare charge (animation), then charge to the end of the floor collision. + */ +void EnMb_SpearPatrolPrepareAndCharge(EnMb* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + s32 prevFrame; + s32 hasHitPlayer = false; + s32 endCharge = !Actor_TestFloorInDirection(&this->actor, globalCtx, 110.0f, this->actor.world.rot.y); + + prevFrame = (s32)this->skelAnime.curFrame; + if (SkelAnime_Update(&this->skelAnime)) { + Animation_PlayLoop(&this->skelAnime, &gEnMbSpearChargeAnim); Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_ATTACK); } - if (this->unk_32E != 0) { - this->unk_32E--; + + if (this->timer3 != 0) { + this->timer3--; Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.world.rot.y, 1, 0x1F40, 0); - sp48 = 0; + endCharge = false; } else { this->actor.speedXZ = 10.0f; - this->attackParams = 1; - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, 5.0f, 3, 4.0f, 0x64, 0xF, 0); - if (currentFrame != (s32)this->skelAnime.curFrame) { - if (((s32)this->skelAnime.curFrame == 2 || (s32)this->skelAnime.curFrame == 6)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_DASH); - } + this->attack = ENMB_ATTACK_SPEAR; + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 5.0f, 3, 4.0f, 100, 15, false); + if (prevFrame != (s32)this->skelAnime.curFrame && + ((s32)this->skelAnime.curFrame == 2 || (s32)this->skelAnime.curFrame == 6)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_DASH); } } - if (this->collider2.base.atFlags & AT_HIT) { - if (this->collider2.base.at == &player->actor) { - if ((sp48 == 0) && !(player->stateFlags2 & 0x80)) { + + if (this->attackCollider.base.atFlags & AT_HIT) { + if (this->attackCollider.base.at == &player->actor) { + if (!endCharge && !(player->stateFlags2 & 0x80)) { if (player->invincibilityTimer < 0) { if (player->invincibilityTimer < -39) { player->invincibilityTimer = 0; @@ -864,31 +919,33 @@ void func_80AA7CAC(EnMb* this, GlobalContext* globalCtx) { globalCtx->damagePlayer(globalCtx, -8); } } - if (!(this->collider2.base.atFlags & AT_BOUNCED)) { + if (!(this->attackCollider.base.atFlags & AT_BOUNCED)) { Audio_PlayActorSound2(&player->actor, NA_SE_PL_BODY_HIT); } - if (globalCtx->grabPlayer(globalCtx, player) != 0) { + if (globalCtx->grabPlayer(globalCtx, player)) { player->actor.parent = &this->actor; } } - sp4C = 1; + hasHitPlayer = true; } else { - this->collider2.base.atFlags &= ~AT_HIT; + this->attackCollider.base.atFlags &= ~AT_HIT; } } - if ((player->stateFlags2 & 0x80) && (&this->actor == player->actor.parent)) { - player->actor.world.pos.x = this->actor.world.pos.x + (Math_CosS(this->actor.shape.rot.y) * 10.0f) + - (Math_SinS(this->actor.shape.rot.y) * 89.0f); - sp4C = 1; - player->actor.world.pos.z = this->actor.world.pos.z + (Math_SinS(this->actor.shape.rot.y) * 10.0f) + - (Math_CosS(this->actor.shape.rot.y) * 89.0f); + + if ((player->stateFlags2 & 0x80) && player->actor.parent == &this->actor) { + player->actor.world.pos.x = this->actor.world.pos.x + Math_CosS(this->actor.shape.rot.y) * 10.0f + + Math_SinS(this->actor.shape.rot.y) * 89.0f; + hasHitPlayer = true; + player->actor.world.pos.z = this->actor.world.pos.z + Math_SinS(this->actor.shape.rot.y) * 10.0f + + Math_CosS(this->actor.shape.rot.y) * 89.0f; player->unk_850 = 0; player->actor.speedXZ = 0.0f; player->actor.velocity.y = 0.0f; } - if (sp48 != 0) { - if ((sp4C != 0) || (player->stateFlags2 & 0x80)) { - this->collider2.base.atFlags &= ~AT_HIT; + + if (endCharge) { + if (hasHitPlayer || (player->stateFlags2 & 0x80)) { + this->attackCollider.base.atFlags &= ~AT_HIT; if (player->stateFlags2 & 0x80) { player->stateFlags2 &= ~0x80; player->actor.parent = NULL; @@ -896,371 +953,373 @@ void func_80AA7CAC(EnMb* this, GlobalContext* globalCtx) { func_8002F71C(globalCtx, &this->actor, 4.0f, this->actor.world.rot.y, 4.0f); } } - this->attackParams = 0; + this->attack = ENMB_ATTACK_NONE; this->actor.speedXZ = -10.0f; - func_80AA6D20(this); + EnMb_SetupSpearPatrolEndCharge(this); } } -void func_80AA800C(EnMb* this, GlobalContext* globalCtx) { - Player* player; - s32 currentFrame; - s32 sp54; - s32 sp50; +/** + * Charge and follow the path, until hitting the player or, after some time, reaching home. + */ +void EnMb_SpearPatrolImmediateCharge(EnMb* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + s32 prevFrame; + s32 hasHitPlayer = false; + s32 endCharge = !Actor_TestFloorInDirection(&this->actor, globalCtx, 110.0f, this->actor.world.rot.y); - player = PLAYER; - sp54 = 0; - sp50 = !func_800339B8(&this->actor, globalCtx, 110.0f, this->actor.world.rot.y); - currentFrame = (s32)this->skelAnime.curFrame; + prevFrame = (s32)this->skelAnime.curFrame; SkelAnime_Update(&this->skelAnime); - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, 5.0f, 3, 4.0f, 0x64, 0xF, 0); - if (currentFrame != (s32)this->skelAnime.curFrame) { - if (((s32)this->skelAnime.curFrame == 2) || ((s32)this->skelAnime.curFrame == 6)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_DASH); - } + + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 5.0f, 3, 4.0f, 100, 15, false); + if (prevFrame != (s32)this->skelAnime.curFrame && + ((s32)this->skelAnime.curFrame == 2 || (s32)this->skelAnime.curFrame == 6)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_DASH); } - if (this->collider2.base.atFlags & AT_HIT) { - if (this->collider2.base.at == &player->actor) { - if ((sp50 == 0) && !(player->stateFlags2 & 0x80)) { + + if (this->attackCollider.base.atFlags & AT_HIT) { + if (this->attackCollider.base.at == &player->actor) { + if (!endCharge && !(player->stateFlags2 & 0x80)) { if (player->invincibilityTimer < 0) { - if (player->invincibilityTimer < -39) { + if (player->invincibilityTimer <= -40) { player->invincibilityTimer = 0; } else { player->invincibilityTimer = 0; globalCtx->damagePlayer(globalCtx, -8); } } - if (!(this->collider2.base.atFlags & AT_BOUNCED)) { + if (!(this->attackCollider.base.atFlags & AT_BOUNCED)) { Audio_PlayActorSound2(&player->actor, NA_SE_PL_BODY_HIT); } - if (globalCtx->grabPlayer(globalCtx, player) != 0) { + if (globalCtx->grabPlayer(globalCtx, player)) { player->actor.parent = &this->actor; } } - sp54 = 1; + hasHitPlayer = true; } else { - this->collider2.base.atFlags &= ~AT_HIT; + this->attackCollider.base.atFlags &= ~AT_HIT; } } - if ((player->stateFlags2 & 0x80) && (&this->actor == player->actor.parent)) { - player->actor.world.pos.x = this->actor.world.pos.x + (Math_CosS(this->actor.shape.rot.y) * 10.0f) + - (Math_SinS(this->actor.shape.rot.y) * 89.0f); - sp54 = 1; - player->actor.world.pos.z = this->actor.world.pos.z + (Math_SinS(this->actor.shape.rot.y) * 10.0f) + - (Math_CosS(this->actor.shape.rot.y) * 89.0f); + + if ((player->stateFlags2 & 0x80) && player->actor.parent == &this->actor) { + player->actor.world.pos.x = this->actor.world.pos.x + Math_CosS(this->actor.shape.rot.y) * 10.0f + + Math_SinS(this->actor.shape.rot.y) * 89.0f; + hasHitPlayer = true; + player->actor.world.pos.z = this->actor.world.pos.z + Math_SinS(this->actor.shape.rot.y) * 10.0f + + Math_CosS(this->actor.shape.rot.y) * 89.0f; player->unk_850 = 0; player->actor.speedXZ = 0.0f; player->actor.velocity.y = 0.0f; } - if (sp50 != 0) { - if ((sp54 != 0) || (player->stateFlags2 & 0x80)) { - this->collider2.base.atFlags &= ~AT_HIT; + + if (endCharge) { + if (hasHitPlayer || (player->stateFlags2 & 0x80)) { + this->attackCollider.base.atFlags &= ~AT_HIT; if (player->stateFlags2 & 0x80) { player->stateFlags2 &= ~0x80; player->actor.parent = NULL; player->unk_850 = 200; func_8002F71C(globalCtx, &this->actor, 4.0f, this->actor.world.rot.y, 4.0f); } - this->attackParams = 0; + this->attack = ENMB_ATTACK_NONE; this->actor.speedXZ = -10.0f; - func_80AA6D20(this); - this->unk_32E = 1; + EnMb_SetupSpearPatrolEndCharge(this); + this->timer3 = 1; } else { - this->unk_32E--; - func_80AA6444(this, globalCtx); + this->timer3--; + EnMb_NextWaypoint(this, globalCtx); } } - func_80AA6408(this, globalCtx); + + EnMb_FaceWaypoint(this, globalCtx); this->actor.shape.rot.y = this->actor.world.rot.y; - if ((this->unk_32E == 0) && Math_Vec3f_DistXZ(&this->actor.home.pos, &this->actor.world.pos) < 80.0f) { - this->attackParams = 0; - func_80AA6CC0(this); + + if (this->timer3 == 0 && Math_Vec3f_DistXZ(&this->actor.home.pos, &this->actor.world.pos) < 80.0f) { + this->attack = ENMB_ATTACK_NONE; + EnMb_SetupSpearEndChargeQuick(this); } } -void func_80AA8378(EnMb* this, GlobalContext* globalCtx) { +void EnMb_ClubDamaged(EnMb* this, GlobalContext* globalCtx) { if (SkelAnime_Update(&this->skelAnime)) { - if (this->unk_32E != 0) { - Animation_PlayOnce(&this->skelAnime, &gEnMbAnim_00E18C); - this->unk_32E = 0; + if (this->timer3 != 0) { + Animation_PlayOnce(&this->skelAnime, &gEnMbClubStandUpAnim); + this->timer3 = 0; func_800AA000(this->actor.xzDistToPlayer, 0xFF, 0x14, 0x96); Camera_AddQuake(&globalCtx->mainCamera, 2, 25, 5); } else { - func_80AA6898(this); + EnMb_SetupClubWaitPlayerNear(this); } } } -void func_80AA840C(EnMb* this, GlobalContext* globalCtx) { +void EnMb_ClubDamagedWhileKneeling(EnMb* this, GlobalContext* globalCtx) { s32 pad; if (SkelAnime_Update(&this->skelAnime)) { - if (this->unk_32E != 0) { - this->unk_32E--; - if (this->unk_32E == 0) { - if (this->unk_32A == 0) { - Animation_Change(&this->skelAnime, &gEnMbAnim_00E18C, 3.0f, 0.0f, - Animation_GetLastFrame(&gEnMbAnim_00E18C), ANIMMODE_ONCE_INTERP, 0.0f); - this->unk_32A = 1; - this->unk_32E = 6; + if (this->timer3 != 0) { + this->timer3--; + if (this->timer3 == 0) { + if (this->timer1 == 0) { + Animation_Change(&this->skelAnime, &gEnMbClubStandUpAnim, 3.0f, 0.0f, + Animation_GetLastFrame(&gEnMbClubStandUpAnim), ANIMMODE_ONCE_INTERP, 0.0f); + this->timer1 = 1; + this->timer3 = 6; } else { - Animation_Change(&this->skelAnime, &gEnMbAnim_00E18C, 3.0f, 0.0f, - Animation_GetLastFrame(&gEnMbAnim_00E18C), ANIMMODE_ONCE_INTERP, 0.0f); + Animation_Change(&this->skelAnime, &gEnMbClubStandUpAnim, 3.0f, 0.0f, + Animation_GetLastFrame(&gEnMbClubStandUpAnim), ANIMMODE_ONCE_INTERP, 0.0f); } } } else { - func_80AA6898(this); + EnMb_SetupClubWaitPlayerNear(this); } } } -void func_80AA8514(EnMb* this, GlobalContext* globalCtx) { - static Vec3f D_80AA9D78 = { 0.0f, 0.0f, 0.0f }; - Vec3f effPosition; - Vec3f temp; - Vec3f effZeroVector; - s32 effectsPerFrame; +void EnMb_ClubDead(EnMb* this, GlobalContext* globalCtx) { + Vec3f effPos; + Vec3f effPosBase; - effPosition = this->actor.world.pos; - effPosition.x += Math_SinS(this->actor.shape.rot.y) * -70.0f; - effPosition.z += Math_CosS(this->actor.shape.rot.y) * -70.0f; + effPos = this->actor.world.pos; + effPos.x += Math_SinS(this->actor.shape.rot.y) * -70.0f; + effPos.z += Math_CosS(this->actor.shape.rot.y) * -70.0f; Math_SmoothStepToF(&this->actor.speedXZ, 0.0f, 1.0f, 0.5f, 0.0f); - temp = effPosition; - if (SkelAnime_Update(&this->skelAnime) != 0) { - if (this->unk_32A > 0) { - effZeroVector = D_80AA9D78; - this->unk_32A--; - for (effectsPerFrame = 4; effectsPerFrame >= 0; effectsPerFrame--) { - effPosition.x = Rand_CenteredFloat(240.0f) + temp.x; - effPosition.y = Rand_CenteredFloat(15.0f) + (temp.y + 20.0f); - effPosition.z = Rand_CenteredFloat(240.0f) + temp.z; - EffectSsDeadDb_Spawn(globalCtx, &effPosition, &effZeroVector, &effZeroVector, 0xE6, 7, 0xFF, 0xFF, 0xFF, - 0xFF, 0, 0xFF, 0, 1, 9, 1); + effPosBase = effPos; + + if (SkelAnime_Update(&this->skelAnime)) { + if (this->timer1 > 0) { + Vec3f effZeroVec = { 0.0f, 0.0f, 0.0f }; + s32 i; + + this->timer1--; + for (i = 4; i >= 0; i--) { + effPos.x = Rand_CenteredFloat(240.0f) + effPosBase.x; + effPos.y = Rand_CenteredFloat(15.0f) + (effPosBase.y + 20.0f); + effPos.z = Rand_CenteredFloat(240.0f) + effPosBase.z; + EffectSsDeadDb_Spawn(globalCtx, &effPos, &effZeroVec, &effZeroVec, 230, 7, 255, 255, 255, 255, 0, 255, + 0, 1, 9, true); } } else { - Item_DropCollectibleRandom(globalCtx, &this->actor, &effPosition, 0xC0); + Item_DropCollectibleRandom(globalCtx, &this->actor, &effPos, 0xC0); Actor_Kill(&this->actor); } - } else if (((s32)this->skelAnime.curFrame == 15) || ((s32)this->skelAnime.curFrame == 22)) { + } else if ((s32)this->skelAnime.curFrame == 15 || (s32)this->skelAnime.curFrame == 22) { func_800AA000(this->actor.xzDistToPlayer, 0xFF, 0x14, 0x96); - Actor_SpawnFloorDust(globalCtx, &this->actor, &effPosition, 50.0f, 0xA, 3.0f, 0x190, 0x3C, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &effPos, 50.0f, 10, 3.0f, 400, 60, false); Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIZA_DOWN); - Camera_AddQuake(&globalCtx->mainCamera, 2, 0x19, 5); + Camera_AddQuake(&globalCtx->mainCamera, 2, 25, 5); } } -void func_80AA87D8(EnMb* this, GlobalContext* globalCtx) { - s32 currentFrame; - s32 sp48; +/** + * Walk around the home point, face and charge the player if close. + */ +void EnMb_SpearGuardWalk(EnMb* this, GlobalContext* globalCtx) { + s32 prevFrame; + s32 beforeCurFrame; + s32 pad1; s32 pad2; - s32 pad; Player* player = PLAYER; - s16 yawDiff; - s16 yaw; - f32 playSpeedABS; + s16 relYawTowardsPlayer = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; + s16 yawTowardsHome; + f32 playSpeedAbs; - yawDiff = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; - yawDiff = ABS(yawDiff); + relYawTowardsPlayer = ABS(relYawTowardsPlayer); Math_SmoothStepToF(&this->actor.speedXZ, 0.59999996f, 0.1f, 1.0f, 0.0f); this->skelAnime.playSpeed = this->actor.speedXZ; - currentFrame = this->skelAnime.curFrame; + prevFrame = this->skelAnime.curFrame; SkelAnime_Update(&this->skelAnime); - playSpeedABS = ABS(this->skelAnime.playSpeed); - sp48 = this->skelAnime.curFrame - playSpeedABS; - playSpeedABS = ABS(this->skelAnime.playSpeed); - if ((this->unk_32E == 0) && (Math_Vec3f_DistXZ(&this->actor.home.pos, &player->actor.world.pos) < this->unk_364)) { - Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 1, 750, 0); + playSpeedAbs = ABS(this->skelAnime.playSpeed); + beforeCurFrame = this->skelAnime.curFrame - playSpeedAbs; + playSpeedAbs = ABS(this->skelAnime.playSpeed); + if (this->timer3 == 0 && + Math_Vec3f_DistXZ(&this->actor.home.pos, &player->actor.world.pos) < this->playerDetectionRange) { + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 1, 0x2EE, 0); this->actor.flags |= 1; - if ((this->actor.xzDistToPlayer < 500.0f) && (yawDiff <= 0x1387)) { - func_80AA6AC8(this); + if (this->actor.xzDistToPlayer < 500.0f && relYawTowardsPlayer < 0x1388) { + EnMb_SetupSpearPrepareAndCharge(this); } } else { this->actor.flags &= ~1; - if ((this->unk_360 < Math_Vec3f_DistXZ(&this->actor.world.pos, &this->actor.home.pos)) || - (this->soundTimer != 0)) { - yaw = Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.home.pos); - Math_SmoothStepToS(&this->actor.world.rot.y, yaw, 1, 750, 0); + if (Math_Vec3f_DistXZ(&this->actor.world.pos, &this->actor.home.pos) > this->maxHomeDist || this->timer2 != 0) { + yawTowardsHome = Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.home.pos); + Math_SmoothStepToS(&this->actor.world.rot.y, yawTowardsHome, 1, 0x2EE, 0); } - if (this->soundTimer != 0) { - this->soundTimer--; + if (this->timer2 != 0) { + this->timer2--; } - if (this->unk_32E != 0) { - this->unk_32E--; + if (this->timer3 != 0) { + this->timer3--; } - if (this->soundTimer == 0) { + if (this->timer2 == 0) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_VOICE); } - this->unk_32A--; - if (this->unk_32A == 0) { + this->timer1--; + if (this->timer1 == 0) { if (Rand_ZeroOne() > 0.7f) { - this->unk_32A = Rand_S16Offset(50, 70); - this->soundTimer = Rand_S16Offset(15, 40); + this->timer1 = Rand_S16Offset(50, 70); + this->timer2 = Rand_S16Offset(15, 40); } else { - func_80AA6830(this); + EnMb_SetupSpearGuardLookAround(this); } } } - if (currentFrame != (s32)this->skelAnime.curFrame) { - if (((sp48 <= 1) && (currentFrame + (s32)playSpeedABS >= 1)) || - ((sp48 <= 20) && (currentFrame + (s32)playSpeedABS >= 20))) { + if (prevFrame != (s32)this->skelAnime.curFrame) { + if ((beforeCurFrame <= 1 && prevFrame + (s32)playSpeedAbs >= 1) || + (beforeCurFrame <= 20 && prevFrame + (s32)playSpeedAbs >= 20)) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_WALK); } } + this->actor.shape.rot.y = this->actor.world.rot.y; } -void func_80AA8AEC(EnMb* this, GlobalContext* globalCtx) { - s32 currentFrame; - s32 temp_f6; - s16 yawDiff; - f32 yDistAbs; - s32 yawDiffAbs; +void EnMb_SpearPatrolWalkTowardsWaypoint(EnMb* this, GlobalContext* globalCtx) { + s32 prevFrame; + s32 beforeCurFrame; + s16 relYawTowardsPlayer; + f32 yDistToPlayerAbs; f32 playSpeedABS; if (Math_Vec3f_DistXZ(&this->waypointPos, &this->actor.world.pos) <= 8.0f || (Rand_ZeroOne() < 0.1f && Math_Vec3f_DistXZ(&this->actor.home.pos, &this->actor.world.pos) <= 4.0f)) { - func_80AA68FC(this, globalCtx); + EnMb_SetupSpearPatrolTurnTowardsWaypoint(this, globalCtx); } else { Math_SmoothStepToF(&this->actor.speedXZ, 0.59999996f, 0.1f, 1.0f, 0.0f); - this->skelAnime.playSpeed = (this->actor.speedXZ + this->actor.speedXZ); + this->skelAnime.playSpeed = 2.0f * this->actor.speedXZ; } - this->unk_330 = Math_Vec3f_Yaw(&this->actor.world.pos, &this->waypointPos); - Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_330, 1, 0x5DC, 0); - yDistAbs = (this->actor.yDistToPlayer >= 0.0f) ? this->actor.yDistToPlayer : -this->actor.yDistToPlayer; - if (yDistAbs <= 20.0f && func_80AA652C(this, globalCtx) != 0) { - yawDiff = (this->actor.shape.rot.y - this->actor.yawTowardsPlayer); - yawDiffAbs = ABS(yawDiff); - if (yawDiffAbs <= 0x4000 || (func_8002DDE4(globalCtx) && this->actor.xzDistToPlayer < 160.0f)) { - func_80AA66A0(this, globalCtx); + + this->yawToWaypoint = Math_Vec3f_Yaw(&this->actor.world.pos, &this->waypointPos); + Math_SmoothStepToS(&this->actor.world.rot.y, this->yawToWaypoint, 1, 0x5DC, 0); + + yDistToPlayerAbs = (this->actor.yDistToPlayer >= 0.0f) ? this->actor.yDistToPlayer : -this->actor.yDistToPlayer; + if (yDistToPlayerAbs <= 20.0f && EnMb_IsPlayerInCorridor(this, globalCtx)) { + relYawTowardsPlayer = (this->actor.shape.rot.y - this->actor.yawTowardsPlayer); + if (ABS(relYawTowardsPlayer) <= 0x4000 || (func_8002DDE4(globalCtx) && this->actor.xzDistToPlayer < 160.0f)) { + EnMb_FindWaypointTowardsPlayer(this, globalCtx); Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_VOICE); - func_80AA6AC8(this); + EnMb_SetupSpearPrepareAndCharge(this); return; } } - if (this->soundTimer != 0) { - this->soundTimer--; + + if (this->timer2 != 0) { + this->timer2--; } - if (this->unk_32E != 0) { - this->unk_32E--; + if (this->timer3 != 0) { + this->timer3--; } - if (this->soundTimer == 0) { + if (this->timer2 == 0) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_VOICE); - this->soundTimer = Rand_S16Offset(30, 70); + this->timer2 = Rand_S16Offset(30, 70); } - currentFrame = this->skelAnime.curFrame; + + prevFrame = this->skelAnime.curFrame; SkelAnime_Update(&this->skelAnime); + playSpeedABS = ABS(this->skelAnime.playSpeed); + beforeCurFrame = this->skelAnime.curFrame - playSpeedABS; playSpeedABS = (this->skelAnime.playSpeed >= 0.0f) ? this->skelAnime.playSpeed : -this->skelAnime.playSpeed; - temp_f6 = this->skelAnime.curFrame - playSpeedABS; - playSpeedABS = (this->skelAnime.playSpeed >= 0.0f) ? this->skelAnime.playSpeed : -this->skelAnime.playSpeed; - if (currentFrame != (s32)this->skelAnime.curFrame) { - if (!(temp_f6 >= 2 || (s32)playSpeedABS + currentFrame <= 0) || - (temp_f6 <= 20 && (s32)playSpeedABS + currentFrame >= 20)) { + if (prevFrame != (s32)this->skelAnime.curFrame) { + if ((beforeCurFrame <= 1 && (s32)playSpeedABS + prevFrame >= 1) || + (beforeCurFrame <= 20 && (s32)playSpeedABS + prevFrame >= 20)) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_WALK); } } + this->actor.shape.rot.y = this->actor.world.rot.y; } -void func_80AA8DD8(EnMb* this, GlobalContext* globalCtx) { +void EnMb_ClubWaitPlayerNear(EnMb* this, GlobalContext* globalCtx) { Player* player = PLAYER; s32 pad; - s16 yawDiff; - s32 yawDiffAbs; + s16 relYawFromPlayer = this->actor.world.rot.y - this->actor.yawTowardsPlayer; - yawDiff = (this->actor.world.rot.y - this->actor.yawTowardsPlayer); SkelAnime_Update(&this->skelAnime); - if (Math_Vec3f_DistXZ(&this->actor.home.pos, &player->actor.world.pos) < this->unk_364) { - if (!(player->stateFlags1 & 0x4000000)) { - yawDiffAbs = ABS(yawDiff); - if (yawDiffAbs < 0x3E80) { - func_80AA6BF0(this); - } - } + if (Math_Vec3f_DistXZ(&this->actor.home.pos, &player->actor.world.pos) < this->playerDetectionRange && + !(player->stateFlags1 & 0x4000000) && ABS(relYawFromPlayer) < 0x3E80) { + EnMb_SetupClubAttack(this); } } -void func_80AA8E88(EnMb* this) { - s16 yawDiff; - s32 yawDiffABS; +void EnMb_SetupSpearDamaged(EnMb* this) { + s16 relYawTowardsPlayer = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; - yawDiff = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; - yawDiffABS = ABS(yawDiff); - if (yawDiffABS <= 0x4000) { - Animation_MorphToPlayOnce(&this->skelAnime, &gEnMbAnim_001950, -4.0f); + if (ABS(relYawTowardsPlayer) <= 0x4000) { + Animation_MorphToPlayOnce(&this->skelAnime, &gEnMbSpearDamagedFromFrontAnim, -4.0f); this->actor.speedXZ = -8.0f; } else { - Animation_MorphToPlayOnce(&this->skelAnime, &gEnMbAnim_00095C, -4.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &gEnMbSpearDamagedFromBehindAnim, -4.0f); this->actor.speedXZ = 8.0f; } - this->unk_32A = 30; - this->unk_320 = 0; + + this->timer1 = 30; + this->state = ENMB_STATE_SPEAR_SPEARPATH_DAMAGED; this->actor.shape.rot.y = this->actor.world.rot.y; Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_DEAD); - EnMb_SetupAction(this, func_80AA8F50); + EnMb_SetupAction(this, EnMb_SpearDamaged); } -void func_80AA8F50(EnMb* this, GlobalContext* globalCtx) { +void EnMb_SpearDamaged(EnMb* this, GlobalContext* globalCtx) { Math_SmoothStepToF(&this->actor.speedXZ, 0.0f, 1.0f, 0.5f, 0.0f); - if (SkelAnime_Update(&this->skelAnime) != 0) { - if (this->actor.params < 0) { - func_80AA6830(this); + if (SkelAnime_Update(&this->skelAnime)) { + if (this->actor.params <= ENMB_TYPE_SPEAR_GUARD) { + EnMb_SetupSpearGuardLookAround(this); } else { - func_80AA6B80(this); + EnMb_SetupSpearPatrolImmediateCharge(this); } } } -void func_80AA8FC8(EnMb* this) { - s16 yawDiff; - s32 yawDiffAbs; +void EnMb_SetupSpearDead(EnMb* this) { + s16 relYawTowardsPlayer = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; - yawDiff = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; - yawDiffAbs = ABS(yawDiff); - if (yawDiffAbs <= 0x4000) { - Animation_MorphToPlayOnce(&this->skelAnime, &gEnMbFallBackAnim, -4.0f); + if (ABS(relYawTowardsPlayer) <= 0x4000) { + Animation_MorphToPlayOnce(&this->skelAnime, &gEnMbSpearFallOnItsBackAnim, -4.0f); this->actor.speedXZ = -8.0f; } else { - Animation_MorphToPlayOnce(&this->skelAnime, &gEnMbFallBackAnim, -4.0f); + /* The gEnMbSpearFallFaceDownAnim animation was probably meant to be used here */ + Animation_MorphToPlayOnce(&this->skelAnime, &gEnMbSpearFallOnItsBackAnim, -4.0f); this->actor.speedXZ = 8.0f; } + this->actor.world.rot.y = this->actor.shape.rot.y; - this->unk_32A = 30; - this->unk_320 = 0; + this->timer1 = 30; + this->state = ENMB_STATE_SPEAR_SPEARPATH_DAMAGED; Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_DEAD); this->actor.flags &= ~1; - EnMb_SetupAction(this, func_80AA90A0); + EnMb_SetupAction(this, EnMb_SpearDead); } -void func_80AA90A0(EnMb* this, GlobalContext* globalCtx) { +void EnMb_SpearDead(EnMb* this, GlobalContext* globalCtx) { Player* player = PLAYER; Math_SmoothStepToF(&this->actor.speedXZ, 0.0f, 1.0f, 0.5f, 0.0f); - if (player->stateFlags2 & 0x80) { - if (&this->actor == player->actor.parent) { - player->stateFlags2 &= ~0x80; - player->actor.parent = NULL; - player->unk_850 = 200; - func_8002F71C(globalCtx, &this->actor, 4.0f, this->actor.world.rot.y, 4.0f); - this->attackParams = 0; - } + + if ((player->stateFlags2 & 0x80) && player->actor.parent == &this->actor) { + player->stateFlags2 &= ~0x80; + player->actor.parent = NULL; + player->unk_850 = 200; + func_8002F71C(globalCtx, &this->actor, 4.0f, this->actor.world.rot.y, 4.0f); + this->attack = ENMB_ATTACK_NONE; } - if (SkelAnime_Update(&this->skelAnime) != 0) { - if (this->unk_32A > 0) { + + if (SkelAnime_Update(&this->skelAnime)) { + if (this->timer1 > 0) { Vec3f zeroVec = { 0.0f, 0.0f, 0.0f }; s32 i; Vec3f effPos; this->actor.shape.shadowScale = 0.0f; - this->unk_32A--; + this->timer1--; for (i = 4; i >= 0; i--) { effPos.x = Rand_CenteredFloat(110.0f) + this->actor.world.pos.x; effPos.y = Rand_CenteredFloat(15.0f) + (this->actor.world.pos.y + 20.0f); effPos.z = Rand_CenteredFloat(110.0f) + this->actor.world.pos.z; - EffectSsDeadDb_Spawn(globalCtx, &effPos, &zeroVec, &zeroVec, 0x64, 7, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0xFF, - 0, 1, 9, 1); + EffectSsDeadDb_Spawn(globalCtx, &effPos, &zeroVec, &zeroVec, 100, 7, 255, 255, 255, 255, 0, 255, 0, 1, + 9, true); } } else { Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0xE0); @@ -1269,85 +1328,88 @@ void func_80AA90A0(EnMb* this, GlobalContext* globalCtx) { } } -void func_80AA92B8(Actor* thisx, GlobalContext* globalCtx) { - Vec3f D_80AA9D90 = { 1000.0f, 1500.0f, 0.0f }; - Vec3f D_80AA9D9C = { -1000.0f, 1500.0f, 0.0f }; - Vec3f D_80AA9DA8 = { 1000.0f, 1500.0f, 4500.0f }; - Vec3f D_80AA9DB4 = { -1000.0f, 1500.0f, 4500.0f }; +void EnMb_SpearUpdateAttackCollider(Actor* thisx, GlobalContext* globalCtx) { + Vec3f quadModel0 = { 1000.0f, 1500.0f, 0.0f }; + Vec3f quadModel1 = { -1000.0f, 1500.0f, 0.0f }; + Vec3f quadModel2 = { 1000.0f, 1500.0f, 4500.0f }; + Vec3f quadModel3 = { -1000.0f, 1500.0f, 4500.0f }; EnMb* this = THIS; - if (this->actor.params > 0) { - D_80AA9D90.x += 2000.0f; - D_80AA9D90.z = -4000.0f; - D_80AA9D9C.z = -4000.0f; - D_80AA9DA8.x += 2000.0f; - D_80AA9D9C.x -= 2000.0f; - D_80AA9DB4.x -= 2000.0f; - D_80AA9DA8.z += 4000.0f; - D_80AA9DB4.z += 4000.0f; + if (this->actor.params >= ENMB_TYPE_SPEAR_PATROL) { + quadModel0.x += 2000.0f; + quadModel0.z = -4000.0f; + quadModel1.z = -4000.0f; + quadModel2.x += 2000.0f; + quadModel1.x -= 2000.0f; + quadModel3.x -= 2000.0f; + quadModel2.z += 4000.0f; + quadModel3.z += 4000.0f; } - Matrix_MultVec3f(&D_80AA9D90, &this->collider2.dim.quad[1]); - Matrix_MultVec3f(&D_80AA9D9C, &this->collider2.dim.quad[0]); - Matrix_MultVec3f(&D_80AA9DA8, &this->collider2.dim.quad[3]); - Matrix_MultVec3f(&D_80AA9DB4, &this->collider2.dim.quad[2]); - Collider_SetQuadVertices(&this->collider2, &this->collider2.dim.quad[0], &this->collider2.dim.quad[1], - &this->collider2.dim.quad[2], &this->collider2.dim.quad[3]); + Matrix_MultVec3f(&quadModel0, &this->attackCollider.dim.quad[1]); + Matrix_MultVec3f(&quadModel1, &this->attackCollider.dim.quad[0]); + Matrix_MultVec3f(&quadModel2, &this->attackCollider.dim.quad[3]); + Matrix_MultVec3f(&quadModel3, &this->attackCollider.dim.quad[2]); + Collider_SetQuadVertices(&this->attackCollider, &this->attackCollider.dim.quad[0], + &this->attackCollider.dim.quad[1], &this->attackCollider.dim.quad[2], + &this->attackCollider.dim.quad[3]); } -void func_80AA9440(Actor* thisx, GlobalContext* globalCtx) { - static Vec3f D_80AA9DC0 = { 1000.0f, 0.0f, 0.0f }; - static Vec3f D_80AA9DCC = { 1000.0f, 0.0f, 0.0f }; - static Vec3f D_80AA9DD8 = { 1000.0f, -8000.0f, -1500.0f }; - static Vec3f D_80AA9DE4 = { 1000.0f, -9000.0f, 2000.0f }; +void EnMb_ClubUpdateAttackCollider(Actor* thisx, GlobalContext* globalCtx) { + static Vec3f quadModel[] = { { 1000.0f, 0.0f, 0.0f }, + { 1000.0f, 0.0f, 0.0f }, + { 1000.0f, -8000.0f, -1500.0f }, + { 1000.0f, -9000.0f, 2000.0f } }; EnMb* this = THIS; - Matrix_MultVec3f(&D_80AA9DC0, &this->collider2.dim.quad[1]); - Matrix_MultVec3f(&D_80AA9DCC, &this->collider2.dim.quad[0]); - Matrix_MultVec3f(&D_80AA9DD8, &this->collider2.dim.quad[3]); - Matrix_MultVec3f(&D_80AA9DE4, &this->collider2.dim.quad[2]); - Collider_SetQuadVertices(&this->collider2, &this->collider2.dim.quad[0], &this->collider2.dim.quad[1], - &this->collider2.dim.quad[2], &this->collider2.dim.quad[3]); + Matrix_MultVec3f(&quadModel[0], &this->attackCollider.dim.quad[1]); + Matrix_MultVec3f(&quadModel[1], &this->attackCollider.dim.quad[0]); + Matrix_MultVec3f(&quadModel[2], &this->attackCollider.dim.quad[3]); + Matrix_MultVec3f(&quadModel[3], &this->attackCollider.dim.quad[2]); + Collider_SetQuadVertices(&this->attackCollider, &this->attackCollider.dim.quad[0], + &this->attackCollider.dim.quad[1], &this->attackCollider.dim.quad[2], + &this->attackCollider.dim.quad[3]); } -void func_80AA94D8(EnMb* this, GlobalContext* globalCtx) { +void EnMb_CheckColliding(EnMb* this, GlobalContext* globalCtx) { Player* player = PLAYER; - if (this->collider3.base.acFlags & AC_HIT) { - this->collider3.base.acFlags &= ~(AC_HIT | AC_BOUNCED); - this->collider1.base.acFlags &= ~AC_HIT; - return; - } - if ((this->collider1.base.acFlags & AC_HIT) && (this->unk_320 >= 5)) { - this->collider1.base.acFlags &= ~AC_HIT; - if ((this->actor.colChkInfo.damageEffect != 0) && (this->actor.colChkInfo.damageEffect != 5)) { - if ((player->stateFlags2 & 0x80) && &this->actor == player->actor.parent) { + if (this->frontShielding.base.acFlags & AC_HIT) { + this->frontShielding.base.acFlags &= ~(AC_HIT | AC_BOUNCED); + this->hitbox.base.acFlags &= ~AC_HIT; + } else if ((this->hitbox.base.acFlags & AC_HIT) && this->state >= ENMB_STATE_STUNNED) { + this->hitbox.base.acFlags &= ~AC_HIT; + if (this->actor.colChkInfo.damageEffect != ENMB_DMGEFF_IGNORE && + this->actor.colChkInfo.damageEffect != ENMB_DMGEFF_FREEZE) { + if ((player->stateFlags2 & 0x80) && player->actor.parent == &this->actor) { player->stateFlags2 &= ~0x80; player->actor.parent = NULL; player->unk_850 = 200; func_8002F71C(globalCtx, &this->actor, 6.0f, this->actor.world.rot.y, 6.0f); } - this->unk_188 = this->actor.colChkInfo.damageEffect; - this->attackParams = 0; - Actor_SetDropFlag(&this->actor, &this->collider1.info, 0); - if ((this->actor.colChkInfo.damageEffect == 1) || (this->actor.colChkInfo.damageEffect == 6)) { - if (this->unk_320 != 5) { + this->damageEffect = this->actor.colChkInfo.damageEffect; + this->attack = ENMB_ATTACK_NONE; + Actor_SetDropFlag(&this->actor, &this->hitbox.info, false); + if (this->actor.colChkInfo.damageEffect == ENMB_DMGEFF_STUN || + this->actor.colChkInfo.damageEffect == ENMB_DMGEFF_STUN_ICE) { + if (this->state != ENMB_STATE_STUNNED) { Actor_ApplyDamage(&this->actor); - func_80AA6F8C(this); - return; + EnMb_SetupStunned(this); } } else { Actor_ApplyDamage(&this->actor); Actor_SetColorFilter(&this->actor, 0x4000, 0xFA, 0, 0xC); - if (this->actor.params == 0) { + if (this->actor.params == ENMB_TYPE_CLUB) { if (this->actor.colChkInfo.health == 0) { - func_80AA6F04(this); - } else if (this->unk_320 != 3) { - func_80AA6E1C(this); + EnMb_SetupClubDead(this); + } else if (this->state != ENMB_STATE_CLUB_KNEELING) { + EnMb_SetupClubDamaged(this); } - } else if (this->actor.colChkInfo.health == 0) { - func_80AA8FC8(this); } else { - func_80AA8E88(this); + if (this->actor.colChkInfo.health == 0) { + EnMb_SetupSpearDead(this); + } else { + EnMb_SetupSpearDamaged(this); + } } } } @@ -1358,139 +1420,141 @@ void EnMb_Update(Actor* thisx, GlobalContext* globalCtx) { EnMb* this = THIS; s32 pad; - func_80AA94D8(this, globalCtx); - if (thisx->colChkInfo.damageEffect != 5) { + EnMb_CheckColliding(this, globalCtx); + if (thisx->colChkInfo.damageEffect != ENMB_DMGEFF_FREEZE) { this->actionFunc(this, globalCtx); Actor_MoveForward(thisx); Actor_UpdateBgCheckInfo(globalCtx, thisx, 40.0f, 40.0f, 70.0f, 0x1D); Actor_SetFocus(thisx, thisx->scale.x * 4500.0f); - Collider_UpdateCylinder(thisx, &this->collider1); + Collider_UpdateCylinder(thisx, &this->hitbox); if (thisx->colChkInfo.health <= 0) { - this->collider1.dim.pos.x += (Math_SinS(thisx->shape.rot.y) * (-4400.0f * thisx->scale.y)); - this->collider1.dim.pos.z += (Math_CosS(thisx->shape.rot.y) * (-4400.0f * thisx->scale.y)); + this->hitbox.dim.pos.x += Math_SinS(thisx->shape.rot.y) * (-4400.0f * thisx->scale.y); + this->hitbox.dim.pos.z += Math_CosS(thisx->shape.rot.y) * (-4400.0f * thisx->scale.y); } - CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); - if (this->unk_320 >= 5) { - if ((thisx->params == 0) || (this->unk_320 != 10)) { - CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); - } + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->hitbox.base); + if (this->state >= ENMB_STATE_STUNNED && + (thisx->params == ENMB_TYPE_CLUB || this->state != ENMB_STATE_ATTACK)) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->hitbox.base); } - if (this->unk_320 >= 6) { - CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider3.base); + if (this->state >= ENMB_STATE_IDLE) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->frontShielding.base); } - if (this->attackParams > 0) { - CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); + if (this->attack > ENMB_ATTACK_NONE) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->attackCollider.base); } } } void EnMb_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) { - static Vec3f D_80AA9DF0 = { 1100.0f, -700.0f, 0.0f }; - static Vec3f D_80AA9DFC = { 0.0f, 0.0f, 0.0f }; - static Vec3f D_80AA9E08 = { 0.0f, -8000.0f, 0.0f }; - static Vec3f D_80AA9E14 = { 0.0f, 0.0f, 0.0f }; - s32 bodyPart; + static Vec3f unused = { 1100.0f, -700.0f, 0.0f }; + static Vec3f feetPos = { 0.0f, 0.0f, 0.0f }; + static Vec3f effSpawnPosModel = { 0.0f, -8000.0f, 0.0f }; + static Vec3f zeroVec = { 0.0f, 0.0f, 0.0f }; + s32 bodyPart = -1; EnMb* this = THIS; - Vec3f sp24; - s32 sp34; - - bodyPart = -1; - if (this->actor.params == 0) { - if (limbIndex == 12) { - Matrix_MultVec3f(&D_80AA9E08, &this->effSpawnPos); - if (this->attackParams > 0) { - func_80AA9440(&this->actor, globalCtx); + Vec3f bodyPartPos; + + if (this->actor.params == ENMB_TYPE_CLUB) { + if (limbIndex == ENMB_LIMB_LHAND) { + Matrix_MultVec3f(&effSpawnPosModel, &this->effSpawnPos); + if (this->attack > ENMB_ATTACK_NONE) { + EnMb_ClubUpdateAttackCollider(&this->actor, globalCtx); } } - Actor_SetFeetPos(&this->actor, limbIndex, 22, &D_80AA9DFC, 27, &D_80AA9DFC); + Actor_SetFeetPos(&this->actor, limbIndex, ENMB_LIMB_LFOOT, &feetPos, ENMB_LIMB_RFOOT, &feetPos); } - if (this->unk_328 != 0) { + + if (this->iceEffectTimer != 0) { switch (limbIndex) { - case 7: + case ENMB_LIMB_HEAD: bodyPart = 0; break; - case 12: + case ENMB_LIMB_LHAND: bodyPart = 1; break; - case 17: + case ENMB_LIMB_RHAND: bodyPart = 2; break; - case 9: + case ENMB_LIMB_LSHOULDER: bodyPart = 3; break; - case 14: + case ENMB_LIMB_RSHOULDER: bodyPart = 4; break; - case 6: + case ENMB_LIMB_CHEST: bodyPart = 5; break; - case 20: + case ENMB_LIMB_LTHIGH: bodyPart = 6; break; - case 25: + case ENMB_LIMB_RTHIGH: bodyPart = 7; break; - case 22: + case ENMB_LIMB_LFOOT: bodyPart = 8; break; - case 27: + case ENMB_LIMB_RFOOT: bodyPart = 9; break; } if (bodyPart >= 0) { - Matrix_MultVec3f(&D_80AA9E14, &sp24); - this->bodyPartsPos[bodyPart].x = sp24.x; - this->bodyPartsPos[bodyPart].y = sp24.y; - this->bodyPartsPos[bodyPart].z = sp24.z; + Matrix_MultVec3f(&zeroVec, &bodyPartPos); + this->bodyPartsPos[bodyPart].x = bodyPartPos.x; + this->bodyPartsPos[bodyPart].y = bodyPartPos.y; + this->bodyPartsPos[bodyPart].z = bodyPartPos.z; } } } void EnMb_Draw(Actor* thisx, GlobalContext* globalCtx) { - static Vec3f D_80AA9E20[] = { + static Vec3f frontShieldingTriModel0[] = { { 4000.0f, 7000.0f, 3500.0f }, { 4000.0f, 0.0f, 3500.0f }, { -4000.0f, 7000.0f, 3500.0f }, }; - static Vec3f D_80AA9E44[] = { + static Vec3f frontShieldingTriModel1[] = { { -4000.0f, 7000.0f, 3500.0f }, { -4000.0f, 0.0f, 3500.0f }, { 4000.0f, 0.0f, 3500.0f }, }; s32 i; f32 scale; - Vec3f phi_s2[3]; - Vec3f phi_s0[3]; - s32 tempPosIndex; + Vec3f frontShieldingTri0[3]; + Vec3f frontShieldingTri1[3]; + s32 bodyPartIdx; EnMb* this = THIS; func_80093D18(globalCtx->state.gfxCtx); SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, NULL, EnMb_PostLimbDraw, thisx); - if (thisx->params != 0) { - if (this->attackParams > 0) { - func_80AA92B8(thisx, globalCtx); + + if (thisx->params != ENMB_TYPE_CLUB) { + if (this->attack > ENMB_ATTACK_NONE) { + EnMb_SpearUpdateAttackCollider(thisx, globalCtx); } for (i = 0; i < 3; i++) { - Matrix_MultVec3f(&D_80AA9E20[i], &phi_s2[i]); - Matrix_MultVec3f(&D_80AA9E44[i], &phi_s0[i]); + Matrix_MultVec3f(&frontShieldingTriModel0[i], &frontShieldingTri0[i]); + Matrix_MultVec3f(&frontShieldingTriModel1[i], &frontShieldingTri1[i]); } - Collider_SetTrisVertices(&this->collider3, 0, &phi_s2[0], &phi_s2[1], &phi_s2[2]); - Collider_SetTrisVertices(&this->collider3, 1, &phi_s0[0], &phi_s0[1], &phi_s0[2]); + Collider_SetTrisVertices(&this->frontShielding, 0, &frontShieldingTri0[0], &frontShieldingTri0[1], + &frontShieldingTri0[2]); + Collider_SetTrisVertices(&this->frontShielding, 1, &frontShieldingTri1[0], &frontShieldingTri1[1], + &frontShieldingTri1[2]); } - if (this->unk_328 != 0) { + + if (this->iceEffectTimer != 0) { thisx->colorFilterTimer++; - if (this->unk_328 >= 0) { - this->unk_328--; + if (this->iceEffectTimer >= 0) { + this->iceEffectTimer--; } - if ((this->unk_328 & 3) == 0) { + if ((this->iceEffectTimer % 4) == 0) { scale = 2.5f; - if (thisx->params == 0) { + if (thisx->params == ENMB_TYPE_CLUB) { scale = 4.0f; } - tempPosIndex = this->unk_328 >> 2; - EffectSsEnIce_SpawnFlyingVec3s(globalCtx, thisx, &this->bodyPartsPos[tempPosIndex], 0x96, 0x96, 0x96, 0xFA, - 0xEB, 0xF5, 0xFF, scale); + bodyPartIdx = this->iceEffectTimer >> 2; + EffectSsEnIce_SpawnFlyingVec3s(globalCtx, thisx, &this->bodyPartsPos[bodyPartIdx], 150, 150, 150, 250, 235, + 245, 255, scale); } } } diff --git a/src/overlays/actors/ovl_En_Mb/z_en_mb.h b/src/overlays/actors/ovl_En_Mb/z_en_mb.h index 3f692ae262..51446f616a 100644 --- a/src/overlays/actors/ovl_En_Mb/z_en_mb.h +++ b/src/overlays/actors/ovl_En_Mb/z_en_mb.h @@ -8,35 +8,46 @@ struct EnMb; typedef void (*EnMbActionFunc)(struct EnMb*, GlobalContext*); +typedef enum { + /* 0 */ ENMB_STATE_SPEAR_SPEARPATH_DAMAGED, + /* 1 */ ENMB_STATE_CLUB_DEAD, + /* 2 */ ENMB_STATE_CLUB_KNEELING_DAMAGED, + /* 3 */ ENMB_STATE_CLUB_KNEELING, + /* 5 */ ENMB_STATE_STUNNED = 5, + /* 6 */ ENMB_STATE_IDLE, + /* 9 */ ENMB_STATE_WALK = 9, + /* 10 */ ENMB_STATE_ATTACK, + /* 11 */ ENMB_STATE_ATTACK_END +} EnMbState; + typedef struct EnMb { /* 0x0000 */ Actor actor; /* 0x014C */ Vec3s bodyPartsPos[10]; - /* 0x0188 */ u8 unk_188; + /* 0x0188 */ u8 damageEffect; /* 0x018C */ SkelAnime skelAnime; /* 0x01D0 */ Vec3s jointTable[28]; /* 0x0278 */ Vec3s morphTable[28]; - /* 0x0320 */ s32 unk_320; + /* 0x0320 */ EnMbState state; /* 0x0324 */ EnMbActionFunc actionFunc; - /* 0x0328 */ s16 unk_328; - /* 0x032A */ s16 unk_32A; - /* 0x032C */ s16 soundTimer; - /* 0x032E */ s16 unk_32E; - /* 0x0330 */ s16 unk_330; + /* 0x0328 */ s16 iceEffectTimer; + /* 0x032A */ s16 timer1; + /* 0x032C */ s16 timer2; + /* 0x032E */ s16 timer3; + /* 0x0330 */ s16 yawToWaypoint; /* 0x0332 */ s16 unk_332; - /* 0x0334 */ s16 attackParams; + /* 0x0334 */ s16 attack; /* 0x0338 */ Vec3f effSpawnPos; /* 0x0344 */ Vec3f waypointPos; /* 0x0350 */ char unk_34A[0xC]; /* 0x035C */ s8 waypoint; /* 0x035D */ s8 path; /* 0x035E */ s8 direction; - /* 0x035F */ s8 unk_35F; - /* 0x0360 */ f32 unk_360; - /* 0x0364 */ f32 unk_364; - /* 0x0368 */ ColliderCylinder collider1; - /* 0x03B4 */ ColliderQuad collider2; - /* 0x0434 */ ColliderTris collider3; - /* 0x0454 */ ColliderTrisElement collider3Items[2]; + /* 0x0360 */ f32 maxHomeDist; + /* 0x0364 */ f32 playerDetectionRange; + /* 0x0368 */ ColliderCylinder hitbox; + /* 0x03B4 */ ColliderQuad attackCollider; // for attacking the player + /* 0x0434 */ ColliderTris frontShielding; // Moblins don't have shields, but this acts as one + /* 0x0454 */ ColliderTrisElement frontShieldingTris[2]; } EnMb; // size = 0x050C extern const ActorInit En_Mb_InitVars; diff --git a/src/overlays/actors/ovl_En_Reeba/z_en_reeba.c b/src/overlays/actors/ovl_En_Reeba/z_en_reeba.c index 5bb8fd75ec..46d5f1bbbe 100644 --- a/src/overlays/actors/ovl_En_Reeba/z_en_reeba.c +++ b/src/overlays/actors/ovl_En_Reeba/z_en_reeba.c @@ -200,8 +200,8 @@ void func_80AE5054(EnReeba* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelanime); if ((globalCtx->gameplayFrames % 4) == 0) { - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale, 1, 8.0f, - 500, 10, 1); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale, 1, + 8.0f, 500, 10, 1); } if (this->unk_278 == 0) { @@ -341,8 +341,8 @@ void func_80AE56E0(EnReeba* this, GlobalContext* globalCtx) { if ((this->unk_284 + 10.0f) <= this->actor.shape.yOffset) { if ((globalCtx->gameplayFrames % 4) == 0) { - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale, 1, - 8.0f, 500, 10, 1); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale, 1, + 8.0f, 500, 10, 1); } Math_ApproachF(&this->actor.shape.yOffset, this->unk_284, 1.0f, this->unk_288); diff --git a/src/overlays/actors/ovl_En_Sw/z_en_sw.c b/src/overlays/actors/ovl_En_Sw/z_en_sw.c index d7dc6ff113..7d72e57bcd 100644 --- a/src/overlays/actors/ovl_En_Sw/z_en_sw.c +++ b/src/overlays/actors/ovl_En_Sw/z_en_sw.c @@ -662,7 +662,7 @@ void func_80B0DB00(EnSw* this, GlobalContext* globalCtx) { } Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_M_GND); - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, 16.0f, 0xC, 2.0f, 0x78, 0xA, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 16.0f, 0xC, 2.0f, 0x78, 0xA, 0); } } diff --git a/src/overlays/actors/ovl_En_Test/z_en_test.c b/src/overlays/actors/ovl_En_Test/z_en_test.c index 89876ee760..b12923b686 100644 --- a/src/overlays/actors/ovl_En_Test/z_en_test.c +++ b/src/overlays/actors/ovl_En_Test/z_en_test.c @@ -597,7 +597,7 @@ void EnTest_WalkAndBlock(EnTest* this, GlobalContext* globalCtx) { } if ((this->actor.params == STALFOS_TYPE_CEILING) && - !func_800339B8(&this->actor, globalCtx, this->actor.speedXZ, this->actor.world.rot.y)) { + !Actor_TestFloorInDirection(&this->actor, globalCtx, this->actor.speedXZ, this->actor.world.rot.y)) { this->actor.speedXZ *= -1.0f; } @@ -826,7 +826,7 @@ void func_80860F84(EnTest* this, GlobalContext* globalCtx) { if ((this->actor.bgCheckFlags & 8) || ((this->actor.params == STALFOS_TYPE_CEILING) && - !func_800339B8(&this->actor, globalCtx, this->actor.speedXZ, this->actor.world.rot.y))) { + !Actor_TestFloorInDirection(&this->actor, globalCtx, this->actor.speedXZ, this->actor.world.rot.y))) { if (this->actor.bgCheckFlags & 8) { if (this->actor.speedXZ >= 0.0f) { newYaw = this->actor.shape.rot.y + 0x3FFF; @@ -1398,7 +1398,7 @@ void func_808628C8(EnTest* this, GlobalContext* globalCtx) { if ((this->actor.bgCheckFlags & 8) || ((this->actor.params == STALFOS_TYPE_CEILING) && - !func_800339B8(&this->actor, globalCtx, this->actor.speedXZ, this->actor.shape.rot.y + 0x3FFF))) { + !Actor_TestFloorInDirection(&this->actor, globalCtx, this->actor.speedXZ, this->actor.shape.rot.y + 0x3FFF))) { if (this->actor.bgCheckFlags & 8) { if (this->actor.speedXZ >= 0.0f) { newYaw = (this->actor.shape.rot.y + 0x3FFF); @@ -1905,7 +1905,7 @@ void EnTest_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, V if ((this->unk_7C8 == 0x15) || (this->unk_7C8 == 0x16)) { if (this->actor.speedXZ != 0.0f) { Matrix_MultVec3f(&D_80864658, &sp64); - Actor_SpawnFloorDust(globalCtx, &this->actor, &sp64, 10.0f, 1, 8.0f, 0x64, 0xF, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &sp64, 10.0f, 1, 8.0f, 0x64, 0xF, 0); } } } diff --git a/src/overlays/actors/ovl_En_Tite/z_en_tite.c b/src/overlays/actors/ovl_En_Tite/z_en_tite.c index 8e63ebd07a..99fefb67df 100644 --- a/src/overlays/actors/ovl_En_Tite/z_en_tite.c +++ b/src/overlays/actors/ovl_En_Tite/z_en_tite.c @@ -814,7 +814,7 @@ void EnTite_FlipOnBack(EnTite* this, GlobalContext* globalCtx) { if (this->actor.bgCheckFlags & 3) { // Upon landing, spawn dust and make noise if (this->actor.bgCheckFlags & 2) { - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, 20.0f, 0xB, 4.0f, 0, 0, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 20.0f, 0xB, 4.0f, 0, 0, 0); Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_M_GND); } this->vOnBackTimer--; diff --git a/src/overlays/actors/ovl_En_Trap/z_en_trap.c b/src/overlays/actors/ovl_En_Trap/z_en_trap.c index afb35a7e8e..c65605347e 100644 --- a/src/overlays/actors/ovl_En_Trap/z_en_trap.c +++ b/src/overlays/actors/ovl_En_Trap/z_en_trap.c @@ -308,7 +308,7 @@ void EnTrap_Update(Actor* thisx, GlobalContext* globalCtx) { } break; } - if (!func_800339B8(thisx, globalCtx, 50.0f, this->vClosestDirection)) { + if (!Actor_TestFloorInDirection(thisx, globalCtx, 50.0f, this->vClosestDirection)) { this->vMovementMetric = 0.0f; } // if in initial position: diff --git a/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c b/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c index 362583aa95..15bf24000b 100644 --- a/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c +++ b/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c @@ -187,7 +187,7 @@ void EnWallmas_SetupLand(EnWallmas* this, GlobalContext* globalCtx) { Animation_Change(&this->skelAnime, objSegChangee, 1.0f, 41.0f, Animation_GetLastFrame(objSegFrameCount), ANIMMODE_ONCE, -3.0f); - Actor_SpawnFloorDust(globalCtx, &this->actor, &this->actor.world.pos, 15.0f, 6, 20.0f, 0x12C, 0x64, 1); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 15.0f, 6, 20.0f, 0x12C, 0x64, 1); Audio_PlayActorSound2(&this->actor, NA_SE_EN_FALL_LAND); this->actionFunc = EnWallmas_Land; } diff --git a/src/overlays/actors/ovl_player_actor/z_player.c b/src/overlays/actors/ovl_player_actor/z_player.c index fa5cb6aa40..de29704001 100644 --- a/src/overlays/actors/ovl_player_actor/z_player.c +++ b/src/overlays/actors/ovl_player_actor/z_player.c @@ -14041,10 +14041,10 @@ s32 func_80852F38(GlobalContext* globalCtx, Player* this) { this->stateFlags2 |= 0x80; func_80832224(this); func_80832698(this, NA_SE_VO_LI_HELD); - return 1; + return true; } - return 0; + return false; } // Sets up player cutscene diff --git a/tools/actorfixer.py b/tools/actorfixer.py index f3586ab939..7e9f6342f4 100755 --- a/tools/actorfixer.py +++ b/tools/actorfixer.py @@ -86,9 +86,11 @@ animdict ={ "func_80035650": "Actor_SetDropFlag", "func_8003573C": "Actor_SetDropFlagJntSph", "func_80033780": "Actor_GetProjectileActor", - "func_80033260": "Actor_SpawnFloorDust", + "func_80033260": "Actor_SpawnFloorDustRing", + "Actor_SpawnFloorDust": "Actor_SpawnFloorDustRing", "func_80032C7C": "Enemy_StartFinishingBlow", "actorCtx.unk_00": "actorCtx.freezeFlashTimer", + "func_800339B8": "Actor_TestFloorInDirection", } def replace_anim(file):