diff options
Diffstat (limited to 'src/code')
| -rw-r--r-- | src/code/z_actor.c | 95 | ||||
| -rw-r--r-- | src/code/z_bgcheck.c | 4 | ||||
| -rw-r--r-- | src/code/z_camera.c | 8 | ||||
| -rw-r--r-- | src/code/z_collision_btltbls.c | 818 | ||||
| -rw-r--r-- | src/code/z_collision_check.c | 3801 | ||||
| -rw-r--r-- | src/code/z_en_a_keep.c | 26 | ||||
| -rw-r--r-- | src/code/z_en_item00.c | 4 | ||||
| -rw-r--r-- | src/code/z_play.c | 8 | ||||
| -rw-r--r-- | src/code/z_player_lib.c | 18 |
9 files changed, 2928 insertions, 1854 deletions
diff --git a/src/code/z_actor.c b/src/code/z_actor.c index c5d2f3d4a..40799d352 100644 --- a/src/code/z_actor.c +++ b/src/code/z_actor.c @@ -820,7 +820,7 @@ void Actor_Init(Actor* actor, GlobalContext* globalCtx) { actor->uncullZoneForward = 1000.0f; actor->uncullZoneScale = 350.0f; actor->uncullZoneDownward = 700.0f; - func_80061E48(&actor->colChkInfo); + CollisionCheck_InitInfo(&actor->colChkInfo); actor->floorPolySource = BGCHECK_SCENE; ActorShape_Init(&actor->shape, 0.0f, NULL, 0.0f); if (Object_IsLoaded(&globalCtx->objectCtx, actor->objBankIndex)) { @@ -1432,17 +1432,21 @@ f32 func_8002EFC0(Actor* actor, Player* player, s16 arg2) { } typedef struct { - f32 unk_0, unk_4; -} struct_80115FF8; // size = 0x8 + /* 0x0 */ f32 rangeSq; + /* 0x4 */ f32 leashScale; +} TargetRangeParams; // size = 0x8 -struct_80115FF8 D_80115FF8[] = { - { 4900.0f, 0.5f }, { 28900.0f, 0.6666667f }, { 78400.0f, 0.05f }, { 122500.0f, 0.6666667f }, - { 490000.0f, 0.6666667f }, { 1000000.0f, 0.6666667f }, { 10000.0f, 0.94905096f }, { 19600.0f, 0.85714287f }, - { 57600.0f, 0.41666666f }, { 78400.0f, 0.001f }, +#define TARGET_RANGE(range, leash) \ + { SQ(range), (f32)range / leash } + +TargetRangeParams D_80115FF8[] = { + TARGET_RANGE(70, 140), TARGET_RANGE(170, 255), TARGET_RANGE(280, 5600), TARGET_RANGE(350, 525), + TARGET_RANGE(700, 1050), TARGET_RANGE(1000, 1500), TARGET_RANGE(100, 105.36842), TARGET_RANGE(140, 163.33333), + TARGET_RANGE(240, 576), TARGET_RANGE(280, 280000), }; u32 func_8002F090(Actor* actor, f32 arg1) { - return arg1 < D_80115FF8[actor->unk_1F].unk_0; + return arg1 < D_80115FF8[actor->unk_1F].rangeSq; } s32 func_8002F0C8(Actor* actor, Player* player, s32 flag) { @@ -1464,7 +1468,7 @@ s32 func_8002F0C8(Actor* actor, Player* player, s32 flag) { dist = actor->xyzDistToLinkSq; } - return !func_8002F090(actor, D_80115FF8[actor->unk_1F].unk_4 * dist); + return !func_8002F090(actor, D_80115FF8[actor->unk_1F].leashScale * dist); } return 0; @@ -1722,7 +1726,7 @@ void func_8002F994(Actor* actor, s32 arg1) { s32 func_8002F9EC(GlobalContext* globalCtx, Actor* actor, CollisionPoly* poly, s32 bgId, Vec3f* pos) { if (func_80041D4C(&globalCtx->colCtx, poly, bgId) == 8) { globalCtx->unk_11D30[0] = 1; - func_8005DFAC(globalCtx, NULL, pos); + CollisionCheck_BlueBlood(globalCtx, NULL, pos); Audio_PlayActorSound2(actor, NA_SE_IT_WALL_HIT_BUYO); return true; } @@ -2063,7 +2067,7 @@ void Actor_UpdateAll(GlobalContext* globalCtx, ActorContext* actorCtx) { } else if ((unkFlag && !(actor->flags & unkFlag)) || (!unkFlag && unkCondition && (sp74 != actor) && (actor != player->naviActor) && (actor != player->heldActor) && (&player->actor != actor->parent))) { - func_80061E8C(&actor->colChkInfo); + CollisionCheck_ResetDamage(&actor->colChkInfo); actor = actor->next; } else if (actor->update == NULL) { if (!actor->isDrawn) { @@ -2100,7 +2104,7 @@ void Actor_UpdateAll(GlobalContext* globalCtx, ActorContext* actorCtx) { func_8003F8EC(globalCtx, &globalCtx->colCtx.dyna, actor); } - func_80061E8C(&actor->colChkInfo); + CollisionCheck_ResetDamage(&actor->colChkInfo); actor = actor->next; } @@ -2440,7 +2444,7 @@ void func_800315AC(GlobalContext* globalCtx, ActorContext* actorCtx) { } if ((HREG(64) != 1) || (HREG(76) != 0)) { - CollisionCheck_Draw(globalCtx, &globalCtx->colChkCtx); + CollisionCheck_DrawCollision(globalCtx, &globalCtx->colChkCtx); } CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_actor.c", 6563); @@ -2498,7 +2502,7 @@ void func_80031B14(GlobalContext* globalCtx, ActorContext* actorCtx) { } } - CollisionCheck_InitContext(globalCtx, &globalCtx->colChkCtx); + CollisionCheck_ClearContext(globalCtx, &globalCtx->colChkCtx); actorCtx->flags.tempClear = 0; actorCtx->flags.tempSwch &= 0xFFFFFF; globalCtx->msgCtx.unk_E3F4 = 0; @@ -3198,8 +3202,8 @@ void func_80033480(GlobalContext* globalCtx, Vec3f* arg1, f32 arg2, s32 arg3, s1 } Actor* Actor_GetCollidedExplosive(GlobalContext* globalCtx, Collider* collider) { - if ((collider->acFlags & 0x2) && (collider->ac->type == ACTORTYPE_EXPLOSIVES)) { - collider->acFlags &= ~0x2; + if ((collider->acFlags & AC_HIT) && (collider->ac->type == ACTORTYPE_EXPLOSIVES)) { + collider->acFlags &= ~AC_HIT; return collider->ac; } @@ -3267,8 +3271,9 @@ Actor* func_80033780(GlobalContext* globalCtx, Actor* refActor, f32 arg2) { spA8.y = itemActor->actor.posRot.pos.y + deltaY; spA8.z = itemActor->actor.posRot.pos.z + deltaZ; - if (func_80062ECC(refActor->colChkInfo.unk_10, refActor->colChkInfo.unk_12, 0.0f, &refActor->posRot.pos, - &itemActor->actor.posRot.pos, &spA8, &sp90, &sp84)) { + if (CollisionCheck_CylSideVsLineSeg(refActor->colChkInfo.unk_10, refActor->colChkInfo.unk_12, 0.0f, + &refActor->posRot.pos, &itemActor->actor.posRot.pos, &spA8, &sp90, + &sp84)) { return &itemActor->actor; } else { actor = actor->next; @@ -3555,7 +3560,7 @@ void Actor_DrawDoorLock(GlobalContext* globalCtx, s32 frame, s32 type) { } void func_8003424C(GlobalContext* globalCtx, Vec3f* arg1) { - func_80062D60(globalCtx, arg1); + CollisionCheck_SpawnShieldParticlesMetal(globalCtx, arg1); } void func_8003426C(Actor* actor, s16 arg1, s16 arg2, s16 arg3, s16 arg4) { @@ -3985,7 +3990,7 @@ void func_800355B8(GlobalContext* globalCtx, Vec3f* arg1) { u8 func_800355E4(GlobalContext* globalCtx, Collider* collider) { Player* player = PLAYER; - if ((collider->acFlags & 0x08) && (player->swordState != 0) && (player->swordAnimation == 0x16)) { + if ((collider->acFlags & AC_TYPE_PLAYER) && (player->swordState != 0) && (player->swordAnimation == 0x16)) { return 1; } else { return 0; @@ -4002,27 +4007,27 @@ u8 Actor_ApplyDamage(Actor* actor) { return actor->colChkInfo.health; } -void func_80035650(Actor* actor, ColliderBody* colBody, s32 freezeFlag) { - if (colBody->acHitItem == NULL) { +void func_80035650(Actor* actor, ColliderInfo* colInfo, s32 freezeFlag) { + if (colInfo->acHitInfo == NULL) { actor->unk_116 = 0x00; - } else if (freezeFlag && (colBody->acHitItem->toucher.flags & 0x10060000)) { - actor->freezeTimer = colBody->acHitItem->toucher.damage; + } else if (freezeFlag && (colInfo->acHitInfo->toucher.dmgFlags & 0x10060000)) { + actor->freezeTimer = colInfo->acHitInfo->toucher.damage; actor->unk_116 = 0x00; - } else if (colBody->acHitItem->toucher.flags & 0x0800) { + } else if (colInfo->acHitInfo->toucher.dmgFlags & 0x0800) { actor->unk_116 = 0x01; - } else if (colBody->acHitItem->toucher.flags & 0x1000) { + } else if (colInfo->acHitInfo->toucher.dmgFlags & 0x1000) { actor->unk_116 = 0x02; - } else if (colBody->acHitItem->toucher.flags & 0x4000) { + } else if (colInfo->acHitInfo->toucher.dmgFlags & 0x4000) { actor->unk_116 = 0x04; - } else if (colBody->acHitItem->toucher.flags & 0x8000) { + } else if (colInfo->acHitInfo->toucher.dmgFlags & 0x8000) { actor->unk_116 = 0x08; - } else if (colBody->acHitItem->toucher.flags & 0x10000) { + } else if (colInfo->acHitInfo->toucher.dmgFlags & 0x10000) { actor->unk_116 = 0x10; - } else if (colBody->acHitItem->toucher.flags & 0x2000) { + } else if (colInfo->acHitInfo->toucher.dmgFlags & 0x2000) { actor->unk_116 = 0x20; - } else if (colBody->acHitItem->toucher.flags & 0x80000) { + } else if (colInfo->acHitInfo->toucher.dmgFlags & 0x80000) { if (freezeFlag) { - actor->freezeTimer = colBody->acHitItem->toucher.damage; + actor->freezeTimer = colInfo->acHitInfo->toucher.damage; } actor->unk_116 = 0x40; } else { @@ -4031,34 +4036,34 @@ void func_80035650(Actor* actor, ColliderBody* colBody, s32 freezeFlag) { } void func_8003573C(Actor* actor, ColliderJntSph* jntSph, s32 freezeFlag) { - ColliderBody* curColBody; + ColliderInfo* curColInfo; s32 flag; s32 i; actor->unk_116 = 0x00; for (i = jntSph->count - 1; i >= 0; i--) { - curColBody = &jntSph->list[i].body; - if (curColBody->acHitItem == NULL) { + curColInfo = &jntSph->elements[i].info; + if (curColInfo->acHitInfo == NULL) { flag = 0x00; - } else if (freezeFlag && (curColBody->acHitItem->toucher.flags & 0x10060000)) { - actor->freezeTimer = curColBody->acHitItem->toucher.damage; + } else if (freezeFlag && (curColInfo->acHitInfo->toucher.dmgFlags & 0x10060000)) { + actor->freezeTimer = curColInfo->acHitInfo->toucher.damage; flag = 0x00; - } else if (curColBody->acHitItem->toucher.flags & 0x0800) { + } else if (curColInfo->acHitInfo->toucher.dmgFlags & 0x0800) { flag = 0x01; - } else if (curColBody->acHitItem->toucher.flags & 0x1000) { + } else if (curColInfo->acHitInfo->toucher.dmgFlags & 0x1000) { flag = 0x02; - } else if (curColBody->acHitItem->toucher.flags & 0x4000) { + } else if (curColInfo->acHitInfo->toucher.dmgFlags & 0x4000) { flag = 0x04; - } else if (curColBody->acHitItem->toucher.flags & 0x8000) { + } else if (curColInfo->acHitInfo->toucher.dmgFlags & 0x8000) { flag = 0x08; - } else if (curColBody->acHitItem->toucher.flags & 0x10000) { + } else if (curColInfo->acHitInfo->toucher.dmgFlags & 0x10000) { flag = 0x10; - } else if (curColBody->acHitItem->toucher.flags & 0x2000) { + } else if (curColInfo->acHitInfo->toucher.dmgFlags & 0x2000) { flag = 0x20; - } else if (curColBody->acHitItem->toucher.flags & 0x80000) { + } else if (curColInfo->acHitInfo->toucher.dmgFlags & 0x80000) { if (freezeFlag) { - actor->freezeTimer = curColBody->acHitItem->toucher.damage; + actor->freezeTimer = curColInfo->acHitInfo->toucher.damage; } flag = 0x40; } else { diff --git a/src/code/z_bgcheck.c b/src/code/z_bgcheck.c index 2f6778f50..775db6cde 100644 --- a/src/code/z_bgcheck.c +++ b/src/code/z_bgcheck.c @@ -4390,7 +4390,7 @@ void BgCheck_DrawDynaPolyList(GlobalContext* globalCtx, CollisionContext* colCtx vC.y += AREG(26) * ny; vC.z += AREG(26) * nz; } - func_8005B2AC(globalCtx->state.gfxCtx, &vA, &vB, &vC, r, g, b); + Collider_DrawPoly(globalCtx->state.gfxCtx, &vA, &vB, &vC, r, g, b); if (curNode->next == SS_NULL) { break; } @@ -4461,7 +4461,7 @@ void BgCheck_DrawStaticPoly(GlobalContext* globalCtx, CollisionContext* colCtx, vC.y += AREG(26) * ny; vC.z += AREG(26) * nz; } - func_8005B2AC(globalCtx->state.gfxCtx, &vA, &vB, &vC, r, g, b); + Collider_DrawPoly(globalCtx->state.gfxCtx, &vA, &vB, &vC, r, g, b); } /** diff --git a/src/code/z_camera.c b/src/code/z_camera.c index 4f56fdf80..22b5ff338 100644 --- a/src/code/z_camera.c +++ b/src/code/z_camera.c @@ -3382,8 +3382,8 @@ s32 Camera_KeepOn3(Camera* camera) { Camera_Vec3fVecSphGeoAdd(&lineChkPointB, &anim->atTarget, &atToEyeAdj); if (!(keep3->flags & 0x80)) { while (i < angleCnt) { - if (!func_800626B0(camera->globalCtx, &camera->globalCtx->colChkCtx, &anim->atTarget, &lineChkPointB, - &colChkActors, 2) && + if (!CollisionCheck_LineOCCheck(camera->globalCtx, &camera->globalCtx->colChkCtx, &anim->atTarget, + &lineChkPointB, &colChkActors, 2) && !Camera_BGCheck(camera, &anim->atTarget, &lineChkPointB)) { break; } @@ -3666,8 +3666,8 @@ s32 Camera_KeepOn4(Camera* camera) { if (!(keep4->unk_1C & 1)) { angleCnt = ARRAY_COUNT(D_8011D3B0); for (i = 0; i < angleCnt; i++) { - if (!func_800626B0(camera->globalCtx, &camera->globalCtx->colChkCtx, &D_8015BD50, &D_8015BD70, spCC, - sp9C) && + if (!CollisionCheck_LineOCCheck(camera->globalCtx, &camera->globalCtx->colChkCtx, &D_8015BD50, + &D_8015BD70, spCC, sp9C) && !Camera_BGCheck(camera, &D_8015BD50, &D_8015BD70)) { break; } diff --git a/src/code/z_collision_btltbls.c b/src/code/z_collision_btltbls.c index 1b323dacf..a99f6becb 100644 --- a/src/code/z_collision_btltbls.c +++ b/src/code/z_collision_btltbls.c @@ -1,109 +1,825 @@ #include "global.h" -DamageTable D_8011DB20[] = { +static DamageTable sDamageTablePresets[] = { { { - 0x10, 0x01, 0x01, 0x02, 0xE0, 0x01, 0xF2, 0x10, 0xF1, 0xF2, 0xF2, 0x22, 0x01, 0x01, 0x00, 0x00, - 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0 + /* Deku nut */ DMG_ENTRY(0, 0x1), + /* Deku stick */ DMG_ENTRY(1, 0x0), + /* Slingshot */ DMG_ENTRY(1, 0x0), + /* Explosive */ DMG_ENTRY(2, 0x0), + /* Boomerang */ DMG_ENTRY(0, 0xE), + /* Normal arrow */ DMG_ENTRY(1, 0x0), + /* 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(2, 0xF), + /* Fire arrow */ DMG_ENTRY(2, 0x2), + /* Ice arrow */ DMG_ENTRY(1, 0x0), + /* Light arrow */ DMG_ENTRY(1, 0x0), + /* Unk arrow 1 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 2 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 3 */ DMG_ENTRY(0, 0x0), + /* Fire magic */ DMG_ENTRY(2, 0x2), + /* Ice magic */ DMG_ENTRY(0, 0x0), + /* Light magic */ DMG_ENTRY(0, 0x0), + /* Shield */ DMG_ENTRY(0, 0x0), + /* Mirror Ray */ DMG_ENTRY(0, 0x0), + /* Kokiri spin */ DMG_ENTRY(1, 0x0), + /* Giant spin */ DMG_ENTRY(2, 0x0), + /* Master spin */ DMG_ENTRY(2, 0x0), + /* Kokiri jump */ DMG_ENTRY(0, 0x0), + /* Giant jump */ DMG_ENTRY(0, 0x0), + /* Master jump */ DMG_ENTRY(0, 0x0), + /* Unknown 1 */ DMG_ENTRY(0, 0x0), + /* Unblockable */ DMG_ENTRY(0, 0x0), + /* Hammer jump */ DMG_ENTRY(0, 0x0), + /* Unknown 2 */ DMG_ENTRY(0, 0x0), } }, { { - 0x10, 0x01, 0x01, 0x02, 0xE0, 0x01, 0xF2, 0x10, 0xF1, 0xF2, 0xF2, 0x22, 0x01, 0x01, 0x00, 0x00, - 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 1 Used by En_Karebaba + /* Deku nut */ DMG_ENTRY(0, 0x1), + /* Deku stick */ DMG_ENTRY(1, 0x0), + /* Slingshot */ DMG_ENTRY(1, 0x0), + /* Explosive */ DMG_ENTRY(2, 0x0), + /* Boomerang */ DMG_ENTRY(0, 0xE), + /* Normal arrow */ DMG_ENTRY(1, 0x0), + /* 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(2, 0xF), + /* Fire arrow */ DMG_ENTRY(2, 0x2), + /* Ice arrow */ DMG_ENTRY(1, 0x0), + /* Light arrow */ DMG_ENTRY(1, 0x0), + /* Unk arrow 1 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 2 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 3 */ DMG_ENTRY(0, 0x0), + /* Fire magic */ DMG_ENTRY(2, 0x2), + /* Ice magic */ DMG_ENTRY(0, 0x0), + /* Light magic */ DMG_ENTRY(0, 0x0), + /* Shield */ DMG_ENTRY(0, 0x0), + /* Mirror Ray */ DMG_ENTRY(0, 0x0), + /* Kokiri spin */ DMG_ENTRY(1, 0x0), + /* Giant spin */ DMG_ENTRY(2, 0x0), + /* Master spin */ DMG_ENTRY(2, 0x0), + /* Kokiri jump */ DMG_ENTRY(0, 0x0), + /* Giant jump */ DMG_ENTRY(0, 0x0), + /* Master jump */ DMG_ENTRY(0, 0x0), + /* Unknown 1 */ DMG_ENTRY(0, 0x0), + /* Unblockable */ DMG_ENTRY(0, 0x0), + /* Hammer jump */ DMG_ENTRY(0, 0x0), + /* Unknown 2 */ DMG_ENTRY(0, 0x0), } }, { { - 0x10, 0x02, 0x01, 0x02, 0x10, 0x02, 0x02, 0x02, 0x01, 0x02, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, - 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x02, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, + // 2 Used by En_St, En_Ssh + /* Deku nut */ DMG_ENTRY(0, 0x1), + /* Deku stick */ DMG_ENTRY(2, 0x0), + /* Slingshot */ DMG_ENTRY(1, 0x0), + /* Explosive */ DMG_ENTRY(2, 0x0), + /* Boomerang */ DMG_ENTRY(0, 0x1), + /* Normal arrow */ DMG_ENTRY(2, 0x0), + /* Hammer swing */ DMG_ENTRY(2, 0x0), + /* Hookshot */ DMG_ENTRY(2, 0x0), + /* Kokiri sword */ DMG_ENTRY(1, 0x0), + /* Master sword */ DMG_ENTRY(2, 0x0), + /* Giant's Knife */ DMG_ENTRY(4, 0x0), + /* Fire arrow */ DMG_ENTRY(4, 0x0), + /* Ice arrow */ DMG_ENTRY(4, 0x0), + /* Light arrow */ DMG_ENTRY(4, 0x0), + /* Unk arrow 1 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 2 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 3 */ DMG_ENTRY(0, 0x0), + /* Fire magic */ DMG_ENTRY(4, 0x0), + /* Ice magic */ DMG_ENTRY(3, 0x0), + /* Light magic */ DMG_ENTRY(0, 0x0), + /* Shield */ DMG_ENTRY(0, 0x0), + /* Mirror Ray */ DMG_ENTRY(0, 0x0), + /* Kokiri spin */ DMG_ENTRY(1, 0x0), + /* Giant spin */ DMG_ENTRY(2, 0x0), + /* Master spin */ DMG_ENTRY(4, 0x0), + /* Kokiri jump */ DMG_ENTRY(2, 0x0), + /* Giant jump */ DMG_ENTRY(4, 0x0), + /* Master jump */ DMG_ENTRY(8, 0x0), + /* Unknown 1 */ DMG_ENTRY(0, 0x0), + /* Unblockable */ DMG_ENTRY(0, 0x0), + /* Hammer jump */ DMG_ENTRY(0, 0x0), + /* Unknown 2 */ DMG_ENTRY(0, 0x0), } }, { { - 0x10, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, + // 3 + /* Deku nut */ DMG_ENTRY(0, 0x1), + /* Deku stick */ DMG_ENTRY(1, 0x0), + /* Slingshot */ DMG_ENTRY(1, 0x0), + /* Explosive */ DMG_ENTRY(2, 0x0), + /* Boomerang */ DMG_ENTRY(1, 0x0), + /* Normal arrow */ DMG_ENTRY(1, 0x0), + /* Hammer swing */ DMG_ENTRY(1, 0x0), + /* Hookshot */ DMG_ENTRY(1, 0x0), + /* Kokiri sword */ DMG_ENTRY(1, 0x0), + /* Master sword */ DMG_ENTRY(1, 0x0), + /* Giant's Knife */ DMG_ENTRY(1, 0x0), + /* Fire arrow */ DMG_ENTRY(1, 0x0), + /* Ice arrow */ DMG_ENTRY(1, 0x0), + /* Light arrow */ DMG_ENTRY(1, 0x0), + /* Unk arrow 1 */ DMG_ENTRY(1, 0x0), + /* Unk arrow 2 */ DMG_ENTRY(1, 0x0), + /* Unk arrow 3 */ DMG_ENTRY(1, 0x0), + /* Fire magic */ DMG_ENTRY(1, 0x0), + /* Ice magic */ DMG_ENTRY(1, 0x0), + /* Light magic */ DMG_ENTRY(1, 0x0), + /* Shield */ DMG_ENTRY(0, 0x0), + /* Mirror Ray */ DMG_ENTRY(0, 0x0), + /* Kokiri spin */ DMG_ENTRY(2, 0x0), + /* Giant spin */ DMG_ENTRY(2, 0x0), + /* Master spin */ DMG_ENTRY(2, 0x0), + /* Kokiri jump */ DMG_ENTRY(2, 0x0), + /* Giant jump */ DMG_ENTRY(2, 0x0), + /* Master jump */ DMG_ENTRY(2, 0x0), + /* Unknown 1 */ DMG_ENTRY(0, 0x0), + /* Unblockable */ DMG_ENTRY(0, 0x0), + /* Hammer jump */ DMG_ENTRY(0, 0x0), + /* Unknown 2 */ DMG_ENTRY(0, 0x0), } }, { { - 0x10, 0x02, 0x01, 0x02, 0x01, 0x02, 0x02, 0x02, 0x01, 0x02, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x02, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, + // 4 Used by En_Dodojr + /* Deku nut */ DMG_ENTRY(0, 0x1), + /* Deku stick */ DMG_ENTRY(2, 0x0), + /* Slingshot */ DMG_ENTRY(1, 0x0), + /* Explosive */ DMG_ENTRY(2, 0x0), + /* Boomerang */ DMG_ENTRY(1, 0x0), + /* Normal arrow */ DMG_ENTRY(2, 0x0), + /* Hammer swing */ DMG_ENTRY(2, 0x0), + /* Hookshot */ DMG_ENTRY(2, 0x0), + /* Kokiri sword */ DMG_ENTRY(1, 0x0), + /* Master sword */ DMG_ENTRY(2, 0x0), + /* Giant's Knife */ DMG_ENTRY(4, 0x0), + /* Fire arrow */ DMG_ENTRY(4, 0x0), + /* Ice arrow */ DMG_ENTRY(4, 0x0), + /* Light arrow */ DMG_ENTRY(4, 0x0), + /* Unk arrow 1 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 2 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 3 */ DMG_ENTRY(0, 0x0), + /* Fire magic */ DMG_ENTRY(0, 0x0), + /* Ice magic */ DMG_ENTRY(0, 0x0), + /* Light magic */ DMG_ENTRY(0, 0x0), + /* Shield */ DMG_ENTRY(0, 0x0), + /* Mirror Ray */ DMG_ENTRY(0, 0x0), + /* Kokiri spin */ DMG_ENTRY(1, 0x0), + /* Giant spin */ DMG_ENTRY(2, 0x0), + /* Master spin */ DMG_ENTRY(4, 0x0), + /* Kokiri jump */ DMG_ENTRY(2, 0x0), + /* Giant jump */ DMG_ENTRY(4, 0x0), + /* Master jump */ DMG_ENTRY(8, 0x0), + /* Unknown 1 */ DMG_ENTRY(0, 0x0), + /* Unblockable */ DMG_ENTRY(0, 0x0), + /* Hammer jump */ DMG_ENTRY(0, 0x0), + /* Unknown 2 */ DMG_ENTRY(0, 0x0), } }, { { - 0x10, 0x01, 0x01, 0x00, 0x10, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x31, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 5 + /* Deku nut */ DMG_ENTRY(0, 0x1), + /* Deku stick */ DMG_ENTRY(1, 0x0), + /* Slingshot */ DMG_ENTRY(1, 0x0), + /* Explosive */ DMG_ENTRY(0, 0x0), + /* Boomerang */ DMG_ENTRY(0, 0x1), + /* Normal arrow */ DMG_ENTRY(1, 0x0), + /* Hammer swing */ DMG_ENTRY(1, 0x0), + /* Hookshot */ DMG_ENTRY(0, 0x1), + /* Kokiri sword */ DMG_ENTRY(1, 0x0), + /* Master sword */ DMG_ENTRY(1, 0x0), + /* Giant's Knife */ DMG_ENTRY(1, 0x0), + /* Fire arrow */ DMG_ENTRY(1, 0x0), + /* Ice arrow */ DMG_ENTRY(1, 0x3), + /* Light arrow */ DMG_ENTRY(1, 0x0), + /* Unk arrow 1 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 2 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 3 */ DMG_ENTRY(0, 0x0), + /* Fire magic */ DMG_ENTRY(0, 0x0), + /* Ice magic */ DMG_ENTRY(1, 0x3), + /* Light magic */ DMG_ENTRY(0, 0x0), + /* Shield */ DMG_ENTRY(0, 0x0), + /* Mirror Ray */ DMG_ENTRY(0, 0x0), + /* Kokiri spin */ DMG_ENTRY(1, 0x0), + /* Giant spin */ DMG_ENTRY(1, 0x0), + /* Master spin */ DMG_ENTRY(1, 0x0), + /* Kokiri jump */ DMG_ENTRY(0, 0x0), + /* Giant jump */ DMG_ENTRY(0, 0x0), + /* Master jump */ DMG_ENTRY(0, 0x0), + /* Unknown 1 */ DMG_ENTRY(0, 0x0), + /* Unblockable */ DMG_ENTRY(0, 0x0), + /* Hammer jump */ DMG_ENTRY(0, 0x0), + /* Unknown 2 */ DMG_ENTRY(0, 0x0), } }, { { - 0x00, 0x03, 0x00, 0x06, 0x00, 0x04, 0x04, 0x00, 0x02, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 6 + /* Deku nut */ DMG_ENTRY(0, 0x0), + /* Deku stick */ DMG_ENTRY(3, 0x0), + /* Slingshot */ DMG_ENTRY(0, 0x0), + /* Explosive */ DMG_ENTRY(6, 0x0), + /* Boomerang */ DMG_ENTRY(0, 0x0), + /* Normal arrow */ DMG_ENTRY(4, 0x0), + /* Hammer swing */ DMG_ENTRY(4, 0x0), + /* Hookshot */ DMG_ENTRY(0, 0x0), + /* Kokiri sword */ DMG_ENTRY(2, 0x0), + /* Master sword */ DMG_ENTRY(6, 0x0), + /* Giant's Knife */ DMG_ENTRY(0, 0x0), + /* Fire arrow */ DMG_ENTRY(6, 0x0), + /* Ice arrow */ DMG_ENTRY(0, 0x0), + /* Light arrow */ DMG_ENTRY(0, 0x0), + /* Unk arrow 1 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 2 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 3 */ DMG_ENTRY(0, 0x0), + /* Fire magic */ DMG_ENTRY(4, 0x0), + /* Ice magic */ DMG_ENTRY(0, 0x0), + /* Light magic */ DMG_ENTRY(0, 0x0), + /* Shield */ DMG_ENTRY(0, 0x0), + /* Mirror Ray */ DMG_ENTRY(0, 0x0), + /* Kokiri spin */ DMG_ENTRY(0, 0x0), + /* Giant spin */ DMG_ENTRY(0, 0x0), + /* Master spin */ DMG_ENTRY(0, 0x0), + /* Kokiri jump */ DMG_ENTRY(0, 0x0), + /* Giant jump */ DMG_ENTRY(0, 0x0), + /* Master jump */ DMG_ENTRY(0, 0x0), + /* Unknown 1 */ DMG_ENTRY(0, 0x0), + /* Unblockable */ DMG_ENTRY(0, 0x0), + /* Hammer jump */ DMG_ENTRY(0, 0x0), + /* Unknown 2 */ DMG_ENTRY(0, 0x0), } }, { { - 0x00, 0x03, 0x00, 0x06, 0x00, 0x04, 0x04, 0x00, 0x02, 0x06, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 7 + /* Deku nut */ DMG_ENTRY(0, 0x0), + /* Deku stick */ DMG_ENTRY(3, 0x0), + /* Slingshot */ DMG_ENTRY(0, 0x0), + /* Explosive */ DMG_ENTRY(6, 0x0), + /* Boomerang */ DMG_ENTRY(0, 0x0), + /* Normal arrow */ DMG_ENTRY(4, 0x0), + /* Hammer swing */ DMG_ENTRY(4, 0x0), + /* Hookshot */ DMG_ENTRY(0, 0x0), + /* Kokiri sword */ DMG_ENTRY(2, 0x0), + /* Master sword */ DMG_ENTRY(6, 0x0), + /* Giant's Knife */ DMG_ENTRY(0, 0x0), + /* Fire arrow */ DMG_ENTRY(6, 0x0), + /* Ice arrow */ DMG_ENTRY(6, 0x0), + /* Light arrow */ DMG_ENTRY(0, 0x0), + /* Unk arrow 1 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 2 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 3 */ DMG_ENTRY(0, 0x0), + /* Fire magic */ DMG_ENTRY(4, 0x0), + /* Ice magic */ DMG_ENTRY(4, 0x0), + /* Light magic */ DMG_ENTRY(0, 0x0), + /* Shield */ DMG_ENTRY(0, 0x0), + /* Mirror Ray */ DMG_ENTRY(0, 0x0), + /* Kokiri spin */ DMG_ENTRY(0, 0x0), + /* Giant spin */ DMG_ENTRY(0, 0x0), + /* Master spin */ DMG_ENTRY(0, 0x0), + /* Kokiri jump */ DMG_ENTRY(0, 0x0), + /* Giant jump */ DMG_ENTRY(0, 0x0), + /* Master jump */ DMG_ENTRY(0, 0x0), + /* Unknown 1 */ DMG_ENTRY(0, 0x0), + /* Unblockable */ DMG_ENTRY(0, 0x0), + /* Hammer jump */ DMG_ENTRY(0, 0x0), + /* Unknown 2 */ DMG_ENTRY(0, 0x0), } }, { { - 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 8 + /* Deku nut */ DMG_ENTRY(0, 0x0), + /* Deku stick */ DMG_ENTRY(3, 0x0), + /* Slingshot */ DMG_ENTRY(0, 0x0), + /* Explosive */ DMG_ENTRY(0, 0x0), + /* Boomerang */ DMG_ENTRY(0, 0x0), + /* Normal arrow */ DMG_ENTRY(4, 0x0), + /* Hammer swing */ DMG_ENTRY(4, 0x0), + /* Hookshot */ DMG_ENTRY(0, 0x0), + /* Kokiri sword */ DMG_ENTRY(2, 0x0), + /* Master sword */ DMG_ENTRY(0, 0x0), + /* Giant's Knife */ DMG_ENTRY(0, 0x0), + /* Fire arrow */ DMG_ENTRY(0, 0x0), + /* Ice arrow */ DMG_ENTRY(0, 0x0), + /* Light arrow */ DMG_ENTRY(0, 0x0), + /* Unk arrow 1 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 2 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 3 */ DMG_ENTRY(0, 0x0), + /* Fire magic */ DMG_ENTRY(4, 0x0), + /* Ice magic */ DMG_ENTRY(4, 0x0), + /* Light magic */ DMG_ENTRY(0, 0x0), + /* Shield */ DMG_ENTRY(0, 0x0), + /* Mirror Ray */ DMG_ENTRY(0, 0x0), + /* Kokiri spin */ DMG_ENTRY(0, 0x0), + /* Giant spin */ DMG_ENTRY(0, 0x0), + /* Master spin */ DMG_ENTRY(0, 0x0), + /* Kokiri jump */ DMG_ENTRY(0, 0x0), + /* Giant jump */ DMG_ENTRY(0, 0x0), + /* Master jump */ DMG_ENTRY(0, 0x0), + /* Unknown 1 */ DMG_ENTRY(0, 0x0), + /* Unblockable */ DMG_ENTRY(0, 0x0), + /* Hammer jump */ DMG_ENTRY(0, 0x0), + /* Unknown 2 */ DMG_ENTRY(0, 0x0), } }, { { - 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x01, 0x02, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x02, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, + // 9 Used by En_Bubble + /* Deku nut */ DMG_ENTRY(0, 0x0), + /* Deku stick */ DMG_ENTRY(2, 0x0), + /* Slingshot */ DMG_ENTRY(0, 0x0), + /* Explosive */ DMG_ENTRY(0, 0x0), + /* Boomerang */ DMG_ENTRY(1, 0x0), + /* Normal arrow */ DMG_ENTRY(0, 0x0), + /* Hammer swing */ DMG_ENTRY(2, 0x0), + /* Hookshot */ DMG_ENTRY(2, 0x0), + /* Kokiri sword */ DMG_ENTRY(1, 0x0), + /* Master sword */ DMG_ENTRY(2, 0x0), + /* Giant's Knife */ DMG_ENTRY(4, 0x0), + /* Fire arrow */ DMG_ENTRY(0, 0x0), + /* Ice arrow */ DMG_ENTRY(4, 0x0), + /* Light arrow */ DMG_ENTRY(0, 0x0), + /* Unk arrow 1 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 2 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 3 */ DMG_ENTRY(0, 0x0), + /* Fire magic */ DMG_ENTRY(4, 0x0), + /* Ice magic */ DMG_ENTRY(0, 0x0), + /* Light magic */ DMG_ENTRY(0, 0x0), + /* Shield */ DMG_ENTRY(0, 0x0), + /* Mirror Ray */ DMG_ENTRY(0, 0x0), + /* Kokiri spin */ DMG_ENTRY(1, 0x0), + /* Giant spin */ DMG_ENTRY(2, 0x0), + /* Master spin */ DMG_ENTRY(4, 0x0), + /* Kokiri jump */ DMG_ENTRY(2, 0x0), + /* Giant jump */ DMG_ENTRY(4, 0x0), + /* Master jump */ DMG_ENTRY(8, 0x0), + /* Unknown 1 */ DMG_ENTRY(0, 0x0), + /* Unblockable */ DMG_ENTRY(0, 0x0), + /* Hammer jump */ DMG_ENTRY(0, 0x0), + /* Unknown 2 */ DMG_ENTRY(0, 0x0), } }, { { - 0x10, 0x01, 0x00, 0xE2, 0x10, 0x01, 0x02, 0x10, 0xF1, 0xF2, 0xF2, 0x22, 0x32, 0x01, 0x00, 0x00, - 0x00, 0x22, 0x32, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 10 + /* Deku nut */ DMG_ENTRY(0, 0x1), + /* Deku stick */ DMG_ENTRY(1, 0x0), + /* Slingshot */ DMG_ENTRY(0, 0x0), + /* Explosive */ DMG_ENTRY(2, 0xE), + /* Boomerang */ DMG_ENTRY(0, 0x1), + /* Normal arrow */ DMG_ENTRY(1, 0x0), + /* Hammer swing */ DMG_ENTRY(2, 0x0), + /* Hookshot */ DMG_ENTRY(0, 0x1), + /* Kokiri sword */ DMG_ENTRY(1, 0xF), + /* Master sword */ DMG_ENTRY(2, 0xF), + /* Giant's Knife */ DMG_ENTRY(2, 0xF), + /* Fire arrow */ DMG_ENTRY(2, 0x2), + /* Ice arrow */ DMG_ENTRY(2, 0x3), + /* Light arrow */ DMG_ENTRY(1, 0x0), + /* Unk arrow 1 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 2 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 3 */ DMG_ENTRY(0, 0x0), + /* Fire magic */ DMG_ENTRY(2, 0x2), + /* Ice magic */ DMG_ENTRY(2, 0x3), + /* Light magic */ DMG_ENTRY(0, 0x0), + /* Shield */ DMG_ENTRY(0, 0x0), + /* Mirror Ray */ DMG_ENTRY(0, 0x0), + /* Kokiri spin */ DMG_ENTRY(1, 0x0), + /* Giant spin */ DMG_ENTRY(2, 0x0), + /* Master spin */ DMG_ENTRY(2, 0x0), + /* Kokiri jump */ DMG_ENTRY(0, 0x0), + /* Giant jump */ DMG_ENTRY(0, 0x0), + /* Master jump */ DMG_ENTRY(0, 0x0), + /* Unknown 1 */ DMG_ENTRY(0, 0x0), + /* Unblockable */ DMG_ENTRY(0, 0x0), + /* Hammer jump */ DMG_ENTRY(0, 0x0), + /* Unknown 2 */ DMG_ENTRY(0, 0x0), } }, { { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 11 Used by En_Horse + /* Deku nut */ DMG_ENTRY(0, 0x0), + /* Deku stick */ DMG_ENTRY(0, 0x0), + /* Slingshot */ DMG_ENTRY(0, 0x0), + /* Explosive */ DMG_ENTRY(0, 0x0), + /* Boomerang */ DMG_ENTRY(0, 0x0), + /* Normal arrow */ DMG_ENTRY(0, 0x0), + /* Hammer swing */ DMG_ENTRY(0, 0x0), + /* Hookshot */ DMG_ENTRY(0, 0x0), + /* Kokiri sword */ DMG_ENTRY(9, 0x0), + /* Master sword */ DMG_ENTRY(0, 0x0), + /* Giant's Knife */ DMG_ENTRY(0, 0x0), + /* Fire arrow */ DMG_ENTRY(0, 0x0), + /* Ice arrow */ DMG_ENTRY(0, 0x0), + /* Light arrow */ DMG_ENTRY(0, 0x0), + /* Unk arrow 1 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 2 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 3 */ DMG_ENTRY(0, 0x0), + /* Fire magic */ DMG_ENTRY(0, 0x0), + /* Ice magic */ DMG_ENTRY(0, 0x0), + /* Light magic */ DMG_ENTRY(0, 0x0), + /* Shield */ DMG_ENTRY(0, 0x0), + /* Mirror Ray */ DMG_ENTRY(0, 0x0), + /* Kokiri spin */ DMG_ENTRY(0, 0x0), + /* Giant spin */ DMG_ENTRY(0, 0x0), + /* Master spin */ DMG_ENTRY(0, 0x0), + /* Kokiri jump */ DMG_ENTRY(0, 0x0), + /* Giant jump */ DMG_ENTRY(0, 0x0), + /* Master jump */ DMG_ENTRY(0, 0x0), + /* Unknown 1 */ DMG_ENTRY(0, 0x0), + /* Unblockable */ DMG_ENTRY(0, 0x0), + /* Hammer jump */ DMG_ENTRY(0, 0x0), + /* Unknown 2 */ DMG_ENTRY(0, 0x0), } }, { { - 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 12 + /* Deku nut */ DMG_ENTRY(0, 0x0), + /* Deku stick */ DMG_ENTRY(1, 0x0), + /* Slingshot */ DMG_ENTRY(0, 0x0), + /* Explosive */ DMG_ENTRY(0, 0x0), + /* Boomerang */ DMG_ENTRY(0, 0x0), + /* Normal arrow */ DMG_ENTRY(4, 0x0), + /* Hammer swing */ DMG_ENTRY(4, 0x0), + /* Hookshot */ DMG_ENTRY(0, 0x0), + /* Kokiri sword */ DMG_ENTRY(2, 0x0), + /* Master sword */ DMG_ENTRY(4, 0x0), + /* Giant's Knife */ DMG_ENTRY(4, 0x0), + /* Fire arrow */ DMG_ENTRY(0, 0x0), + /* Ice arrow */ DMG_ENTRY(0, 0x0), + /* Light arrow */ DMG_ENTRY(0, 0x0), + /* Unk arrow 1 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 2 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 3 */ DMG_ENTRY(0, 0x0), + /* Fire magic */ DMG_ENTRY(4, 0x0), + /* Ice magic */ DMG_ENTRY(4, 0x0), + /* Light magic */ DMG_ENTRY(0, 0x0), + /* Shield */ DMG_ENTRY(0, 0x0), + /* Mirror Ray */ DMG_ENTRY(0, 0x0), + /* Kokiri spin */ DMG_ENTRY(0, 0x0), + /* Giant spin */ DMG_ENTRY(0, 0x0), + /* Master spin */ DMG_ENTRY(0, 0x0), + /* Kokiri jump */ DMG_ENTRY(0, 0x0), + /* Giant jump */ DMG_ENTRY(0, 0x0), + /* Master jump */ DMG_ENTRY(0, 0x0), + /* Unknown 1 */ DMG_ENTRY(0, 0x0), + /* Unblockable */ DMG_ENTRY(0, 0x0), + /* Hammer jump */ DMG_ENTRY(0, 0x0), + /* Unknown 2 */ DMG_ENTRY(0, 0x0), } }, { { - 0x10, 0x01, 0x01, 0x02, 0x10, 0x01, 0x02, 0x10, 0x01, 0x02, 0x02, 0x22, 0x01, 0x01, 0x00, 0x00, - 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 13 + /* Deku nut */ DMG_ENTRY(0, 0x1), + /* Deku stick */ DMG_ENTRY(1, 0x0), + /* Slingshot */ DMG_ENTRY(1, 0x0), + /* Explosive */ DMG_ENTRY(2, 0x0), + /* Boomerang */ DMG_ENTRY(0, 0x1), + /* Normal arrow */ DMG_ENTRY(1, 0x0), + /* Hammer swing */ DMG_ENTRY(2, 0x0), + /* Hookshot */ DMG_ENTRY(0, 0x1), + /* Kokiri sword */ DMG_ENTRY(1, 0x0), + /* Master sword */ DMG_ENTRY(2, 0x0), + /* Giant's Knife */ DMG_ENTRY(2, 0x0), + /* Fire arrow */ DMG_ENTRY(2, 0x2), + /* Ice arrow */ DMG_ENTRY(1, 0x0), + /* Light arrow */ DMG_ENTRY(1, 0x0), + /* Unk arrow 1 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 2 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 3 */ DMG_ENTRY(0, 0x0), + /* Fire magic */ DMG_ENTRY(2, 0x2), + /* Ice magic */ DMG_ENTRY(0, 0x0), + /* Light magic */ DMG_ENTRY(0, 0x0), + /* Shield */ DMG_ENTRY(0, 0x0), + /* Mirror Ray */ DMG_ENTRY(0, 0x0), + /* Kokiri spin */ DMG_ENTRY(1, 0x0), + /* Giant spin */ DMG_ENTRY(1, 0x0), + /* Master spin */ DMG_ENTRY(1, 0x0), + /* Kokiri jump */ DMG_ENTRY(0, 0x0), + /* Giant jump */ DMG_ENTRY(0, 0x0), + /* Master jump */ DMG_ENTRY(0, 0x0), + /* Unknown 1 */ DMG_ENTRY(0, 0x0), + /* Unblockable */ DMG_ENTRY(0, 0x0), + /* Hammer jump */ DMG_ENTRY(0, 0x0), + /* Unknown 2 */ DMG_ENTRY(0, 0x0), } }, { { - 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x02, 0x02, 0x01, 0x02, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x02, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, + // 14 Used by En_Sw + /* Deku nut */ DMG_ENTRY(1, 0x0), + /* Deku stick */ DMG_ENTRY(2, 0x0), + /* Slingshot */ DMG_ENTRY(1, 0x0), + /* Explosive */ DMG_ENTRY(2, 0x0), + /* Boomerang */ DMG_ENTRY(1, 0x0), + /* Normal arrow */ DMG_ENTRY(2, 0x0), + /* Hammer swing */ DMG_ENTRY(2, 0x0), + /* Hookshot */ DMG_ENTRY(2, 0x0), + /* Kokiri sword */ DMG_ENTRY(1, 0x0), + /* Master sword */ DMG_ENTRY(2, 0x0), + /* Giant's Knife */ DMG_ENTRY(4, 0x0), + /* Fire arrow */ DMG_ENTRY(4, 0x0), + /* Ice arrow */ DMG_ENTRY(4, 0x0), + /* Light arrow */ DMG_ENTRY(4, 0x0), + /* Unk arrow 1 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 2 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 3 */ DMG_ENTRY(0, 0x0), + /* Fire magic */ DMG_ENTRY(4, 0x0), + /* Ice magic */ DMG_ENTRY(0, 0x0), + /* Light magic */ DMG_ENTRY(0, 0x0), + /* Shield */ DMG_ENTRY(0, 0x0), + /* Mirror Ray */ DMG_ENTRY(0, 0x0), + /* Kokiri spin */ DMG_ENTRY(1, 0x0), + /* Giant spin */ DMG_ENTRY(2, 0x0), + /* Master spin */ DMG_ENTRY(4, 0x0), + /* Kokiri jump */ DMG_ENTRY(2, 0x0), + /* Giant jump */ DMG_ENTRY(4, 0x0), + /* Master jump */ DMG_ENTRY(8, 0x0), + /* Unknown 1 */ DMG_ENTRY(0, 0x0), + /* Unblockable */ DMG_ENTRY(0, 0x0), + /* Hammer jump */ DMG_ENTRY(0, 0x0), + /* Unknown 2 */ DMG_ENTRY(0, 0x0), } }, { { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 15 Used by En_Fd + /* Deku nut */ DMG_ENTRY(0, 0x0), + /* Deku stick */ DMG_ENTRY(0, 0x0), + /* Slingshot */ DMG_ENTRY(0, 0x0), + /* Explosive */ DMG_ENTRY(0, 0x0), + /* Boomerang */ DMG_ENTRY(0, 0x0), + /* Normal arrow */ DMG_ENTRY(0, 0x0), + /* Hammer swing */ DMG_ENTRY(0, 0x0), + /* Hookshot */ DMG_ENTRY(0, 0x0), + /* Kokiri sword */ DMG_ENTRY(0, 0x0), + /* Master sword */ DMG_ENTRY(0, 0x0), + /* Giant's Knife */ DMG_ENTRY(0, 0x0), + /* Fire arrow */ DMG_ENTRY(0, 0x0), + /* Ice arrow */ DMG_ENTRY(0, 0x0), + /* Light arrow */ DMG_ENTRY(0, 0x0), + /* Unk arrow 1 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 2 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 3 */ DMG_ENTRY(0, 0x0), + /* Fire magic */ DMG_ENTRY(0, 0x0), + /* Ice magic */ DMG_ENTRY(0, 0x0), + /* Light magic */ DMG_ENTRY(0, 0x0), + /* Shield */ DMG_ENTRY(0, 0x0), + /* Mirror Ray */ DMG_ENTRY(0, 0x0), + /* Kokiri spin */ DMG_ENTRY(0, 0x0), + /* Giant spin */ DMG_ENTRY(0, 0x0), + /* Master spin */ DMG_ENTRY(0, 0x0), + /* Kokiri jump */ DMG_ENTRY(0, 0x0), + /* Giant jump */ DMG_ENTRY(0, 0x0), + /* Master jump */ DMG_ENTRY(0, 0x0), + /* Unknown 1 */ DMG_ENTRY(0, 0x0), + /* Unblockable */ DMG_ENTRY(0, 0x0), + /* Hammer jump */ DMG_ENTRY(0, 0x0), + /* Unknown 2 */ DMG_ENTRY(0, 0x0), } }, { { - 0x00, 0x02, 0x01, 0x02, 0x01, 0x02, 0x02, 0x02, 0x01, 0x02, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x02, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, + // 16 Used by En_Fw + /* Deku nut */ DMG_ENTRY(0, 0x0), + /* Deku stick */ DMG_ENTRY(2, 0x0), + /* Slingshot */ DMG_ENTRY(1, 0x0), + /* Explosive */ DMG_ENTRY(2, 0x0), + /* Boomerang */ DMG_ENTRY(1, 0x0), + /* Normal arrow */ DMG_ENTRY(2, 0x0), + /* Hammer swing */ DMG_ENTRY(2, 0x0), + /* Hookshot */ DMG_ENTRY(2, 0x0), + /* Kokiri sword */ DMG_ENTRY(1, 0x0), + /* Master sword */ DMG_ENTRY(2, 0x0), + /* Giant's Knife */ DMG_ENTRY(4, 0x0), + /* Fire arrow */ DMG_ENTRY(4, 0x0), + /* Ice arrow */ DMG_ENTRY(4, 0x0), + /* Light arrow */ DMG_ENTRY(4, 0x0), + /* Unk arrow 1 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 2 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 3 */ DMG_ENTRY(0, 0x0), + /* Fire magic */ DMG_ENTRY(4, 0x0), + /* Ice magic */ DMG_ENTRY(0, 0x0), + /* Light magic */ DMG_ENTRY(0, 0x0), + /* Shield */ DMG_ENTRY(0, 0x0), + /* Mirror Ray */ DMG_ENTRY(0, 0x0), + /* Kokiri spin */ DMG_ENTRY(1, 0x0), + /* Giant spin */ DMG_ENTRY(2, 0x0), + /* Master spin */ DMG_ENTRY(4, 0x0), + /* Kokiri jump */ DMG_ENTRY(2, 0x0), + /* Giant jump */ DMG_ENTRY(4, 0x0), + /* Master jump */ DMG_ENTRY(8, 0x0), + /* Unknown 1 */ DMG_ENTRY(0, 0x0), + /* Unblockable */ DMG_ENTRY(0, 0x0), + /* Hammer jump */ DMG_ENTRY(0, 0x0), + /* Unknown 2 */ DMG_ENTRY(0, 0x0), } }, { { - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 17 + /* Deku nut */ DMG_ENTRY(1, 0x0), + /* Deku stick */ DMG_ENTRY(1, 0x0), + /* Slingshot */ DMG_ENTRY(1, 0x0), + /* Explosive */ DMG_ENTRY(1, 0x0), + /* Boomerang */ DMG_ENTRY(1, 0x0), + /* Normal arrow */ DMG_ENTRY(1, 0x0), + /* Hammer swing */ DMG_ENTRY(1, 0x0), + /* Hookshot */ DMG_ENTRY(1, 0x0), + /* Kokiri sword */ DMG_ENTRY(1, 0x0), + /* Master sword */ DMG_ENTRY(1, 0x0), + /* Giant's Knife */ DMG_ENTRY(1, 0x0), + /* Fire arrow */ DMG_ENTRY(1, 0x0), + /* Ice arrow */ DMG_ENTRY(1, 0x0), + /* Light arrow */ DMG_ENTRY(1, 0x0), + /* Unk arrow 1 */ DMG_ENTRY(1, 0x0), + /* Unk arrow 2 */ DMG_ENTRY(1, 0x0), + /* Unk arrow 3 */ DMG_ENTRY(1, 0x0), + /* Fire magic */ DMG_ENTRY(1, 0x0), + /* Ice magic */ DMG_ENTRY(1, 0x0), + /* Light magic */ DMG_ENTRY(1, 0x0), + /* Shield */ DMG_ENTRY(0, 0x0), + /* Mirror Ray */ DMG_ENTRY(0, 0x0), + /* Kokiri spin */ DMG_ENTRY(0, 0x0), + /* Giant spin */ DMG_ENTRY(0, 0x0), + /* Master spin */ DMG_ENTRY(0, 0x0), + /* Kokiri jump */ DMG_ENTRY(0, 0x0), + /* Giant jump */ DMG_ENTRY(0, 0x0), + /* Master jump */ DMG_ENTRY(0, 0x0), + /* Unknown 1 */ DMG_ENTRY(0, 0x0), + /* Unblockable */ DMG_ENTRY(0, 0x0), + /* Hammer jump */ DMG_ENTRY(0, 0x0), + /* Unknown 2 */ DMG_ENTRY(0, 0x0), } }, { { - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 18 + /* Deku nut */ DMG_ENTRY(1, 0x0), + /* Deku stick */ DMG_ENTRY(1, 0x0), + /* Slingshot */ DMG_ENTRY(1, 0x0), + /* Explosive */ DMG_ENTRY(1, 0x0), + /* Boomerang */ DMG_ENTRY(1, 0x0), + /* Normal arrow */ DMG_ENTRY(1, 0x0), + /* Hammer swing */ DMG_ENTRY(1, 0x0), + /* Hookshot */ DMG_ENTRY(1, 0x0), + /* Kokiri sword */ DMG_ENTRY(1, 0x0), + /* Master sword */ DMG_ENTRY(1, 0x0), + /* Giant's Knife */ DMG_ENTRY(1, 0x0), + /* Fire arrow */ DMG_ENTRY(1, 0x0), + /* Ice arrow */ DMG_ENTRY(1, 0x0), + /* Light arrow */ DMG_ENTRY(1, 0x0), + /* Unk arrow 1 */ DMG_ENTRY(1, 0x0), + /* Unk arrow 2 */ DMG_ENTRY(1, 0x0), + /* Unk arrow 3 */ DMG_ENTRY(1, 0x0), + /* Fire magic */ DMG_ENTRY(1, 0x0), + /* Ice magic */ DMG_ENTRY(1, 0x0), + /* Light magic */ DMG_ENTRY(1, 0x0), + /* Shield */ DMG_ENTRY(0, 0x0), + /* Mirror Ray */ DMG_ENTRY(0, 0x0), + /* Kokiri spin */ DMG_ENTRY(0, 0x0), + /* Giant spin */ DMG_ENTRY(0, 0x0), + /* Master spin */ DMG_ENTRY(0, 0x0), + /* Kokiri jump */ DMG_ENTRY(0, 0x0), + /* Giant jump */ DMG_ENTRY(0, 0x0), + /* Master jump */ DMG_ENTRY(0, 0x0), + /* Unknown 1 */ DMG_ENTRY(0, 0x0), + /* Unblockable */ DMG_ENTRY(0, 0x0), + /* Hammer jump */ DMG_ENTRY(0, 0x0), + /* Unknown 2 */ DMG_ENTRY(0, 0x0), } }, { { - 0x10, 0x01, 0x00, 0x02, 0x10, 0x01, 0x02, 0x10, 0xF1, 0xF2, 0xF2, 0x22, 0x32, 0x01, 0x00, 0x00, - 0x00, 0x22, 0x32, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 19 + /* Deku nut */ DMG_ENTRY(0, 0x1), + /* Deku stick */ DMG_ENTRY(1, 0x0), + /* Slingshot */ DMG_ENTRY(0, 0x0), + /* Explosive */ DMG_ENTRY(2, 0x0), + /* Boomerang */ DMG_ENTRY(0, 0x1), + /* Normal arrow */ DMG_ENTRY(1, 0x0), + /* Hammer swing */ DMG_ENTRY(2, 0x0), + /* Hookshot */ DMG_ENTRY(0, 0x1), + /* Kokiri sword */ DMG_ENTRY(1, 0xF), + /* Master sword */ DMG_ENTRY(2, 0xF), + /* Giant's Knife */ DMG_ENTRY(2, 0xF), + /* Fire arrow */ DMG_ENTRY(2, 0x2), + /* Ice arrow */ DMG_ENTRY(2, 0x3), + /* Light arrow */ DMG_ENTRY(1, 0x0), + /* Unk arrow 1 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 2 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 3 */ DMG_ENTRY(0, 0x0), + /* Fire magic */ DMG_ENTRY(2, 0x2), + /* Ice magic */ DMG_ENTRY(2, 0x3), + /* Light magic */ DMG_ENTRY(0, 0x0), + /* Shield */ DMG_ENTRY(0, 0x0), + /* Mirror Ray */ DMG_ENTRY(0, 0x0), + /* Kokiri spin */ DMG_ENTRY(1, 0x0), + /* Giant spin */ DMG_ENTRY(2, 0x0), + /* Master spin */ DMG_ENTRY(2, 0x0), + /* Kokiri jump */ DMG_ENTRY(0, 0x0), + /* Giant jump */ DMG_ENTRY(0, 0x0), + /* Master jump */ DMG_ENTRY(0, 0x0), + /* Unknown 1 */ DMG_ENTRY(0, 0x0), + /* Unblockable */ DMG_ENTRY(0, 0x0), + /* Hammer jump */ DMG_ENTRY(0, 0x0), + /* Unknown 2 */ DMG_ENTRY(0, 0x0), } }, { { - 0x10, 0x01, 0x01, 0xF2, 0xE0, 0x01, 0xD2, 0x10, 0x01, 0x02, 0x02, 0x00, 0x32, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 20 + /* Deku nut */ DMG_ENTRY(0, 0x1), + /* Deku stick */ DMG_ENTRY(1, 0x0), + /* Slingshot */ DMG_ENTRY(1, 0x0), + /* Explosive */ DMG_ENTRY(2, 0xF), + /* Boomerang */ DMG_ENTRY(0, 0xE), + /* Normal arrow */ DMG_ENTRY(1, 0x0), + /* Hammer swing */ DMG_ENTRY(2, 0xD), + /* Hookshot */ DMG_ENTRY(0, 0x1), + /* Kokiri sword */ DMG_ENTRY(1, 0x0), + /* Master sword */ DMG_ENTRY(2, 0x0), + /* Giant's Knife */ DMG_ENTRY(2, 0x0), + /* Fire arrow */ DMG_ENTRY(0, 0x0), + /* Ice arrow */ DMG_ENTRY(2, 0x3), + /* Light arrow */ DMG_ENTRY(0, 0x0), + /* Unk arrow 1 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 2 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 3 */ DMG_ENTRY(0, 0x0), + /* Fire magic */ DMG_ENTRY(0, 0x0), + /* Ice magic */ DMG_ENTRY(2, 0x3), + /* Light magic */ DMG_ENTRY(0, 0x0), + /* Shield */ DMG_ENTRY(0, 0x0), + /* Mirror Ray */ DMG_ENTRY(0, 0x0), + /* Kokiri spin */ DMG_ENTRY(1, 0x0), + /* Giant spin */ DMG_ENTRY(2, 0x0), + /* Master spin */ DMG_ENTRY(2, 0x0), + /* Kokiri jump */ DMG_ENTRY(0, 0x0), + /* Giant jump */ DMG_ENTRY(0, 0x0), + /* Master jump */ DMG_ENTRY(0, 0x0), + /* Unknown 1 */ DMG_ENTRY(0, 0x0), + /* Unblockable */ DMG_ENTRY(0, 0x0), + /* Hammer jump */ DMG_ENTRY(0, 0x0), + /* Unknown 2 */ DMG_ENTRY(0, 0x0), } }, { { - 0x10, 0x01, 0x00, 0xF0, 0x10, 0x01, 0xF0, 0x10, 0x01, 0x02, 0x02, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 21 + /* Deku nut */ DMG_ENTRY(0, 0x1), + /* Deku stick */ DMG_ENTRY(1, 0x0), + /* Slingshot */ DMG_ENTRY(0, 0x0), + /* Explosive */ DMG_ENTRY(0, 0xF), + /* Boomerang */ DMG_ENTRY(0, 0x1), + /* Normal arrow */ DMG_ENTRY(1, 0x0), + /* Hammer swing */ DMG_ENTRY(0, 0xF), + /* Hookshot */ DMG_ENTRY(0, 0x1), + /* Kokiri sword */ DMG_ENTRY(1, 0x0), + /* Master sword */ DMG_ENTRY(2, 0x0), + /* Giant's Knife */ DMG_ENTRY(2, 0x0), + /* Fire arrow */ DMG_ENTRY(0, 0x0), + /* Ice arrow */ DMG_ENTRY(2, 0x1), + /* Light arrow */ DMG_ENTRY(0, 0x0), + /* Unk arrow 1 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 2 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 3 */ DMG_ENTRY(0, 0x0), + /* Fire magic */ DMG_ENTRY(0, 0x0), + /* Ice magic */ DMG_ENTRY(2, 0x1), + /* Light magic */ DMG_ENTRY(0, 0x0), + /* Shield */ DMG_ENTRY(0, 0x0), + /* Mirror Ray */ DMG_ENTRY(0, 0x0), + /* Kokiri spin */ DMG_ENTRY(1, 0x0), + /* Giant spin */ DMG_ENTRY(0, 0x0), + /* Master spin */ DMG_ENTRY(0, 0x0), + /* Kokiri jump */ DMG_ENTRY(0, 0x0), + /* Giant jump */ DMG_ENTRY(0, 0x0), + /* Master jump */ DMG_ENTRY(0, 0x0), + /* Unknown 1 */ DMG_ENTRY(0, 0x0), + /* Unblockable */ DMG_ENTRY(0, 0x0), + /* Hammer jump */ DMG_ENTRY(0, 0x0), + /* Unknown 2 */ DMG_ENTRY(0, 0x0), } }, { { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 22 Used by En_Du, En_Go, En_Ma1, En_Ma2, En_Ma3 + /* Deku nut */ DMG_ENTRY(0, 0x0), + /* Deku stick */ DMG_ENTRY(0, 0x0), + /* Slingshot */ DMG_ENTRY(0, 0x0), + /* Explosive */ DMG_ENTRY(0, 0x0), + /* Boomerang */ DMG_ENTRY(0, 0x0), + /* Normal arrow */ DMG_ENTRY(0, 0x0), + /* Hammer swing */ DMG_ENTRY(0, 0x0), + /* Hookshot */ DMG_ENTRY(0, 0x0), + /* Kokiri sword */ DMG_ENTRY(0, 0x0), + /* Master sword */ DMG_ENTRY(0, 0x0), + /* Giant's Knife */ DMG_ENTRY(0, 0x0), + /* Fire arrow */ DMG_ENTRY(0, 0x0), + /* Ice arrow */ DMG_ENTRY(0, 0x0), + /* Light arrow */ DMG_ENTRY(0, 0x0), + /* Unk arrow 1 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 2 */ DMG_ENTRY(0, 0x0), + /* Unk arrow 3 */ DMG_ENTRY(0, 0x0), + /* Fire magic */ DMG_ENTRY(0, 0x0), + /* Ice magic */ DMG_ENTRY(0, 0x0), + /* Light magic */ DMG_ENTRY(0, 0x0), + /* Shield */ DMG_ENTRY(0, 0x0), + /* Mirror Ray */ DMG_ENTRY(0, 0x0), + /* Kokiri spin */ DMG_ENTRY(0, 0x0), + /* Giant spin */ DMG_ENTRY(0, 0x0), + /* Master spin */ DMG_ENTRY(0, 0x0), + /* Kokiri jump */ DMG_ENTRY(0, 0x0), + /* Giant jump */ DMG_ENTRY(0, 0x0), + /* Master jump */ DMG_ENTRY(0, 0x0), + /* Unknown 1 */ DMG_ENTRY(0, 0x0), + /* Unblockable */ DMG_ENTRY(0, 0x0), + /* Hammer jump */ DMG_ENTRY(0, 0x0), + /* Unknown 2 */ DMG_ENTRY(0, 0x0), } }, }; +// Gets the pointer to one of the 23 preset damage tables. Returns NULL if index is out of range. DamageTable* DamageTable_Get(s32 index) { - if (index < 0 || index >= 23) { + if (!(0 <= index && index < ARRAY_COUNT(sDamageTablePresets))) { + // Index over osSyncPrintf("CollisionBtlTbl_get():インデックスオーバー\n"); - return 0; + return NULL; } - return &D_8011DB20[index]; + return &sDamageTablePresets[index]; } -void func_8005B248(DamageTable* table) { +// Sets all entries in the damage table to 0x00 +void DamageTable_Clear(DamageTable* table) { s32 i; for (i = 0; i < 32; i++) { table->table[i] = 0; diff --git a/src/code/z_collision_check.c b/src/code/z_collision_check.c index fbf8a5eba..be884c444 100644 --- a/src/code/z_collision_check.c +++ b/src/code/z_collision_check.c @@ -1,13 +1,53 @@ #include "global.h" #include "vt.h" +#include "overlays/effects/ovl_Effect_Ss_HitMark/z_eff_ss_hitmark.h" -// draw red poly -void func_8005B280(GraphicsContext* gfxCtx, Vec3f* vA, Vec3f* vB, Vec3f* vC) { - func_8005B2AC(gfxCtx, vA, vB, vC, 255, 0, 0); +typedef s32 (*ColChkResetFunc)(GlobalContext*, Collider*); +typedef void (*ColChkBloodFunc)(GlobalContext*, Collider*, Vec3f*); +typedef void (*ColChkApplyFunc)(GlobalContext*, CollisionCheckContext*, Collider*); +typedef void (*ColChkVsFunc)(GlobalContext*, CollisionCheckContext*, Collider*, Collider*); +typedef s32 (*ColChkLineFunc)(GlobalContext*, CollisionCheckContext*, Collider*, Vec3f*, Vec3f*); + +typedef struct { + /* 0 */ u8 blood; + /* 1 */ u8 effect; +} HitInfo; // size = 0x2 + +typedef enum { + /* 0 */ BLOOD_NONE, + /* 1 */ BLOOD_BLUE, + /* 2 */ BLOOD_GREEN, + /* 3 */ BLOOD_WATER, + /* 4 */ BLOOD_RED, + /* 5 */ BLOOD_RED2 +} ColChkBloodType; + +typedef enum { + /* 0 */ HIT_WHITE, + /* 1 */ HIT_DUST, + /* 2 */ HIT_RED, + /* 3 */ HIT_SOLID, + /* 4 */ HIT_WOOD, + /* 5 */ HIT_NONE +} ColChkHitType; + +typedef enum { + /* 0 */ MASSTYPE_IMMOVABLE, + /* 1 */ MASSTYPE_HEAVY, + /* 2 */ MASSTYPE_NORMAL +} ColChkMassType; + +/** + * Draws a red triangle with vertices vA, vB, and vC. + */ +void Collider_DrawRedPoly(GraphicsContext* gfxCtx, Vec3f* vA, Vec3f* vB, Vec3f* vC) { + Collider_DrawPoly(gfxCtx, vA, vB, vC, 255, 0, 0); } -// draw poly -void func_8005B2AC(GraphicsContext* gfxCtx, Vec3f* vA, Vec3f* vB, Vec3f* vC, u8 r, u8 g, u8 b) { +/** + * Draws the triangle with vertices vA, vB, and vC and with the specified color. + */ +void Collider_DrawPoly(GraphicsContext* gfxCtx, Vec3f* vA, Vec3f* vB, Vec3f* vC, u8 r, u8 g, u8 b) { Vtx* vtxTbl; Vtx* vtx; f32 nx; @@ -63,7 +103,10 @@ void func_8005B2AC(GraphicsContext* gfxCtx, Vec3f* vA, Vec3f* vB, Vec3f* vC, u8 } s32 Collider_InitBase(GlobalContext* globalCtx, Collider* collider) { - static Collider init = { NULL, NULL, NULL, NULL, 0, 0, 0, 0, COLTYPE_UNK3, COLSHAPE_INVALID }; + static Collider init = { + NULL, NULL, NULL, NULL, AT_NONE, AC_NONE, OC1_NONE, OC2_NONE, COLTYPE_HIT3, COLSHAPE_INVALID, + }; + *collider = init; return 1; } @@ -72,58 +115,63 @@ s32 Collider_DestroyBase(GlobalContext* globalCtx, Collider* collider) { return 1; } -s32 Collider_SetBase_Actor(GlobalContext* globalCtx, Collider* collider, ColliderInit_Actor* src) { +/** + * Uses default OC2_TYPE_1 and COLTYPE_HIT0 + */ +s32 Collider_SetBaseToActor(GlobalContext* globalCtx, Collider* collider, ColliderInitToActor* src) { collider->actor = src->actor; collider->atFlags = src->atFlags; collider->acFlags = src->acFlags; - collider->maskA = src->maskA; - collider->maskB = 0x10; + collider->ocFlags1 = src->ocFlags1; + collider->ocFlags2 = OC2_TYPE_1; collider->shape = src->shape; return 1; } -// maskB = 0x10 -s32 Collider_SetBase_Set3(GlobalContext* globalCtx, Collider* collider, Actor* actor, ColliderInit_Set3* src) { +/** + * Uses default OC2_TYPE_1 + */ +s32 Collider_SetBaseType1(GlobalContext* globalCtx, Collider* collider, Actor* actor, ColliderInitType1* src) { collider->actor = actor; - collider->type = src->type; + collider->colType = src->colType; collider->atFlags = src->atFlags; collider->acFlags = src->acFlags; - collider->maskA = src->maskA; - collider->maskB = 0x10; + collider->ocFlags1 = src->ocFlags1; + collider->ocFlags2 = OC2_TYPE_1; collider->shape = src->shape; return 1; } -// maskB = src->maskB s32 Collider_SetBase(GlobalContext* globalCtx, Collider* collider, Actor* actor, ColliderInit* src) { collider->actor = actor; - collider->type = src->type; + collider->colType = src->colType; collider->atFlags = src->atFlags; collider->acFlags = src->acFlags; - collider->maskA = src->maskA; - collider->maskB = src->maskB; + collider->ocFlags1 = src->ocFlags1; + collider->ocFlags2 = src->ocFlags2; collider->shape = src->shape; return 1; } -void Collider_BaseSetAT(GlobalContext* globalCtx, Collider* collider) { +void Collider_ResetATBase(GlobalContext* globalCtx, Collider* collider) { collider->at = NULL; - collider->atFlags &= ~0x6; + collider->atFlags &= ~(AT_HIT | AT_BOUNCED); } -void Collider_BaseSetAC(GlobalContext* globalCtx, Collider* collider) { +void Collider_ResetACBase(GlobalContext* globalCtx, Collider* collider) { collider->ac = NULL; - collider->acFlags &= ~0x82; + collider->acFlags &= ~(AC_HIT | AC_BOUNCED); } -void Collider_BaseSetOC(GlobalContext* globalCtx, Collider* collider) { +void Collider_ResetOCBase(GlobalContext* globalCtx, Collider* collider) { collider->oc = NULL; - collider->maskA &= ~0x2; - collider->maskB &= ~0x1; + collider->ocFlags1 &= ~OC1_HIT; + collider->ocFlags2 &= ~OC2_HIT_PLAYER; } s32 Collider_InitTouch(GlobalContext* globalCtx, ColliderTouch* touch) { - static ColliderTouch init = { 0, 0, 0 }; + static ColliderTouch init = { 0x00000000, 0, 0 }; + *touch = init; return 1; } @@ -132,19 +180,19 @@ s32 Collider_DestroyTouch(GlobalContext* globalCtx, ColliderTouch* touch) { return 1; } -// src might actually be a different type s32 Collider_SetTouch(GlobalContext* globalCtx, ColliderTouch* dest, ColliderTouch* src) { - dest->flags = src->flags; + dest->dmgFlags = src->dmgFlags; dest->effect = src->effect; dest->damage = src->damage; return 1; } -void Collider_BodySetAT_Unk(GlobalContext* globalCtx, ColliderBody* body) { +void Collider_ResetATInfo_Unk(GlobalContext* globalCtx, ColliderInfo* info) { } s32 Collider_InitBump(GlobalContext* globalCtx, ColliderBump* bump) { static ColliderBump init = { 0xFFCFFFFF, 0, 0, { 0, 0, 0 } }; + *bump = init; return 1; } @@ -154,314 +202,321 @@ s32 Collider_DestroyBump(GlobalContext* globalCtx, ColliderBump* bump) { } s32 Collider_SetBump(GlobalContext* globalCtx, ColliderBump* bump, ColliderBumpInit* init) { - bump->flags = init->flags; + bump->dmgFlags = init->dmgFlags; bump->effect = init->effect; bump->defense = init->defense; return 1; } -s32 Collider_InitBody(GlobalContext* globalCtx, ColliderBody* body) { - static ColliderBody init = { - { 0, 0, 0 }, { 0xFFCFFFFF, 0, 0, { 0, 0, 0 } }, 0, 0, 0, 0, NULL, NULL, NULL, NULL, +s32 Collider_InitInfo(GlobalContext* globalCtx, ColliderInfo* info) { + static ColliderInfo init = { + { 0, 0, 0 }, { 0xFFCFFFFF, 0, 0, { 0, 0, 0 } }, + ELEMTYPE_UNK0, TOUCH_NONE, + BUMP_NONE, OCELEM_NONE, + NULL, NULL, + NULL, NULL, }; - *body = init; - Collider_InitTouch(globalCtx, &body->toucher); - Collider_InitBump(globalCtx, &body->bumper); + + *info = init; + Collider_InitTouch(globalCtx, &info->toucher); + Collider_InitBump(globalCtx, &info->bumper); return 1; } -s32 Collider_DestroyBody(GlobalContext* globalCtx, ColliderBody* body) { - Collider_DestroyTouch(globalCtx, &body->toucher); - Collider_DestroyBump(globalCtx, &body->bumper); +s32 Collider_DestroyInfo(GlobalContext* globalCtx, ColliderInfo* info) { + Collider_DestroyTouch(globalCtx, &info->toucher); + Collider_DestroyBump(globalCtx, &info->bumper); return 1; } -s32 Collider_SetBody(GlobalContext* globalCtx, ColliderBody* body, ColliderBodyInit* bodyInit) { - body->flags = bodyInit->bodyFlags; - Collider_SetTouch(globalCtx, &body->toucher, &bodyInit->toucher); - Collider_SetBump(globalCtx, &body->bumper, &bodyInit->bumper); - body->toucherFlags = bodyInit->toucherFlags; - body->bumperFlags = bodyInit->bumperFlags; - body->ocFlags = bodyInit->bodyFlags2; +s32 Collider_SetInfo(GlobalContext* globalCtx, ColliderInfo* info, ColliderInfoInit* infoInit) { + info->elemType = infoInit->elemType; + Collider_SetTouch(globalCtx, &info->toucher, &infoInit->toucher); + Collider_SetBump(globalCtx, &info->bumper, &infoInit->bumper); + info->toucherFlags = infoInit->toucherFlags; + info->bumperFlags = infoInit->bumperFlags; + info->ocElemFlags = infoInit->ocElemFlags; return 1; } -void Collider_BodySetAT(GlobalContext* globalCtx, ColliderBody* body) { - body->atHit = NULL; - body->atHitItem = NULL; - body->toucherFlags &= ~0x2; - body->toucherFlags &= ~0x40; - Collider_BodySetAT_Unk(globalCtx, body); +void Collider_ResetATInfo(GlobalContext* globalCtx, ColliderInfo* info) { + info->atHit = NULL; + info->atHitInfo = NULL; + info->toucherFlags &= ~TOUCH_HIT; + info->toucherFlags &= ~TOUCH_DREW_HITMARK; + Collider_ResetATInfo_Unk(globalCtx, info); } -void Collider_BodySetAC(GlobalContext* globalCtx, ColliderBody* body) { - body->bumper.unk_06.z = 0; - body->bumperFlags &= ~0x2; - body->bumperFlags &= ~0x80; - body->acHit = NULL; - body->acHitItem = NULL; - body->bumper.unk_06.y = body->bumper.unk_06.z; - body->bumper.unk_06.x = body->bumper.unk_06.z; +void Collider_ResetACInfo(GlobalContext* globalCtx, ColliderInfo* info) { + info->bumper.hitPos.x = info->bumper.hitPos.y = info->bumper.hitPos.z = 0; + info->bumperFlags &= ~BUMP_HIT; + info->bumperFlags &= ~BUMP_DRAW_HITMARK; + info->acHit = NULL; + info->acHitInfo = NULL; } -void Collider_BodySetOC(GlobalContext* globalCtx, ColliderBody* body) { - body->ocFlags &= ~0x2; +void Collider_ResetOCInfo(GlobalContext* globalCtx, ColliderInfo* info) { + info->ocElemFlags &= ~OCELEM_HIT; } -s32 Collider_InitJntSphItemDim(GlobalContext* globalCtx, ColliderJntSphItemDim* dim) { - static ColliderJntSphItemDim init = { 0 }; +s32 Collider_InitJntSphElementDim(GlobalContext* globalCtx, ColliderJntSphElementDim* dim) { + static ColliderJntSphElementDim init = { + { { 0, 0, 0 }, 0 }, + { { 0, 0, 0 }, 0 }, + 0.0f, + 0, + }; *dim = init; return 1; } -s32 Collider_DestroyJntSphItemDim(GlobalContext* globalCtx, ColliderJntSphItemDim* item) { +s32 Collider_DestroyJntSphElementDim(GlobalContext* globalCtx, ColliderJntSphElementDim* element) { return 1; } -s32 Collider_SetJntSphItemDim(GlobalContext* globalCtx, ColliderJntSphItemDim* dest, ColliderJntSphItemDimInit* src) { - dest->joint = src->joint; +s32 Collider_SetJntSphElementDim(GlobalContext* globalCtx, ColliderJntSphElementDim* dest, + ColliderJntSphElementDimInit* src) { + dest->limb = src->limb; dest->modelSphere = src->modelSphere; dest->scale = src->scale * 0.01f; return 1; } -s32 Collider_InitJntSphItem(GlobalContext* globalCtx, ColliderJntSphItem* item) { - Collider_InitBody(globalCtx, &item->body); - Collider_InitJntSphItemDim(globalCtx, &item->dim); +s32 Collider_InitJntSphElement(GlobalContext* globalCtx, ColliderJntSphElement* element) { + Collider_InitInfo(globalCtx, &element->info); + Collider_InitJntSphElementDim(globalCtx, &element->dim); return 1; } -s32 Collider_DestroyJntSphItem(GlobalContext* globalCtx, ColliderJntSphItem* item) { - Collider_DestroyBody(globalCtx, &item->body); - Collider_DestroyJntSphItemDim(globalCtx, &item->dim); +s32 Collider_DestroyJntSphElement(GlobalContext* globalCtx, ColliderJntSphElement* element) { + Collider_DestroyInfo(globalCtx, &element->info); + Collider_DestroyJntSphElementDim(globalCtx, &element->dim); return 1; } -s32 Collider_SetJntSphItem(GlobalContext* globalCtx, ColliderJntSphItem* dest, ColliderJntSphItemInit* src) { - Collider_SetBody(globalCtx, &dest->body, &src->body); - Collider_SetJntSphItemDim(globalCtx, &dest->dim, &src->dim); +s32 Collider_SetJntSphElement(GlobalContext* globalCtx, ColliderJntSphElement* dest, ColliderJntSphElementInit* src) { + Collider_SetInfo(globalCtx, &dest->info, &src->info); + Collider_SetJntSphElementDim(globalCtx, &dest->dim, &src->dim); return 1; } -s32 Collider_JntSphItemSetAT(GlobalContext* globalCtx, ColliderJntSphItem* collider) { - Collider_BodySetAT(globalCtx, &collider->body); +s32 Collider_ResetJntSphElementAT(GlobalContext* globalCtx, ColliderJntSphElement* collider) { + Collider_ResetATInfo(globalCtx, &collider->info); return 1; } -s32 Collider_JntSphItemSetAC(GlobalContext* globalCtx, ColliderJntSphItem* collider) { - Collider_BodySetAC(globalCtx, &collider->body); +s32 Collider_ResetJntSphElementAC(GlobalContext* globalCtx, ColliderJntSphElement* collider) { + Collider_ResetACInfo(globalCtx, &collider->info); return 1; } -s32 Collider_JntSphItemSetOC(GlobalContext* globalCtx, ColliderJntSphItem* collider) { - Collider_BodySetOC(globalCtx, &collider->body); +s32 Collider_ResetJntSphElementOC(GlobalContext* globalCtx, ColliderJntSphElement* collider) { + Collider_ResetOCInfo(globalCtx, &collider->info); return 1; } +/** + * Initializes a ColliderJntSph to default values + */ s32 Collider_InitJntSph(GlobalContext* globalCtx, ColliderJntSph* collider) { Collider_InitBase(globalCtx, &collider->base); collider->count = 0; - collider->list = NULL; + collider->elements = NULL; return 1; } -// Destruct ColliderJntSph (malloc) +/** + * Destroys a dynamically allocated ColliderJntSph + */ s32 Collider_FreeJntSph(GlobalContext* globalCtx, ColliderJntSph* collider) { - ColliderJntSphItem* next; + ColliderJntSphElement* element; Collider_DestroyBase(globalCtx, &collider->base); - next = collider->list; - - while (next < collider->list + collider->count) { - Collider_DestroyJntSphItem(globalCtx, next); - next++; + for (element = collider->elements; element < collider->elements + collider->count; element++) { + Collider_DestroyJntSphElement(globalCtx, element); } collider->count = 0; - if (collider->list != NULL) { - ZeldaArena_FreeDebug(collider->list, "../z_collision_check.c", 1393); + if (collider->elements != NULL) { + ZeldaArena_FreeDebug(collider->elements, "../z_collision_check.c", 1393); } - collider->list = NULL; + collider->elements = NULL; return 1; } -// Destruct ColliderJntSph (no malloc) +/** + * Destroys a preallocated ColliderJntSph + */ s32 Collider_DestroyJntSph(GlobalContext* globalCtx, ColliderJntSph* collider) { - ColliderJntSphItem* next; + ColliderJntSphElement* element; Collider_DestroyBase(globalCtx, &collider->base); - next = collider->list; - - while (next < collider->list + collider->count) { - - Collider_DestroyJntSphItem(globalCtx, next); - next++; + for (element = collider->elements; element < collider->elements + collider->count; element++) { + Collider_DestroyJntSphElement(globalCtx, element); } collider->count = 0; - collider->list = NULL; + collider->elements = NULL; return 1; } -// ClObjJntSph -s32 Collider_SetJntSph_Set(GlobalContext* globalCtx, ColliderJntSph* dest, ColliderJntSphInit_Actor* src) { - ColliderJntSphItem* destNext; - ColliderJntSphItemInit* srcNext; +/** + * Sets up the ColliderJntSph using the values in src, sets it to the actor specified in src, and dynamically allocates + * the element array. Uses default OC2_TYPE_1 and COLTYPE_HIT0. Unused. + */ +s32 Collider_SetJntSphToActor(GlobalContext* globalCtx, ColliderJntSph* dest, ColliderJntSphInitToActor* src) { + ColliderJntSphElement* destElem; + ColliderJntSphElementInit* srcElem; - Collider_SetBase_Actor(globalCtx, &dest->base, &src->base); + Collider_SetBaseToActor(globalCtx, &dest->base, &src->base); dest->count = src->count; - dest->list = ZeldaArena_MallocDebug(src->count * sizeof(ColliderJntSphItem), "../z_collision_check.c", 1443); + dest->elements = ZeldaArena_MallocDebug(src->count * sizeof(ColliderJntSphElement), "../z_collision_check.c", 1443); - if (dest->list == NULL) { + if (dest->elements == NULL) { dest->count = 0; osSyncPrintf(VT_FGCOL(RED)); - osSyncPrintf("ClObjJntSph_set():zelda_malloc()出来ません。\n"); // EUC-JP: 出来ません。 | Can not. + // Can not. + osSyncPrintf("ClObjJntSph_set():zelda_malloc()出来ません。\n"); osSyncPrintf(VT_RST); return 0; } - destNext = dest->list; - srcNext = src->list; - - while (destNext < dest->list + dest->count) { - Collider_InitJntSphItem(globalCtx, destNext); - Collider_SetJntSphItem(globalCtx, destNext, srcNext); - destNext++; - srcNext++; + for (destElem = dest->elements, srcElem = src->elements; destElem < dest->elements + dest->count; + destElem++, srcElem++) { + Collider_InitJntSphElement(globalCtx, destElem); + Collider_SetJntSphElement(globalCtx, destElem, srcElem); } return 1; } -// ClObjJntSph_set3 (maskB = 0x10) -// called by En_Nwc -s32 Collider_SetJntSph_Set3(GlobalContext* globalCtx, ColliderJntSph* dest, Actor* actor, - ColliderJntSphInit_Set3* src) { - ColliderJntSphItem* destNext; - ColliderJntSphItemInit* srcNext; +/** + * Sets up the ColliderJntSph using the values in src and dynamically allocates the element array. Uses default + * OC2_TYPE_1. Only used by En_Nwc, an unused and unfinished actor. + */ +s32 Collider_SetJntSphAllocType1(GlobalContext* globalCtx, ColliderJntSph* dest, Actor* actor, + ColliderJntSphInitType1* src) { + ColliderJntSphElement* destElem; + ColliderJntSphElementInit* srcElem; - Collider_SetBase_Set3(globalCtx, &dest->base, actor, &src->base); + Collider_SetBaseType1(globalCtx, &dest->base, actor, &src->base); dest->count = src->count; - dest->list = ZeldaArena_MallocDebug(src->count * sizeof(ColliderJntSphItem), "../z_collision_check.c", 1490); + dest->elements = ZeldaArena_MallocDebug(src->count * sizeof(ColliderJntSphElement), "../z_collision_check.c", 1490); - if (dest->list == NULL) { + if (dest->elements == NULL) { dest->count = 0; osSyncPrintf(VT_FGCOL(RED)); - osSyncPrintf("ClObjJntSph_set3():zelda_malloc_出来ません。\n"); // EUC-JP: 出来ません。 | Can not. + // Can not. + osSyncPrintf("ClObjJntSph_set3():zelda_malloc_出来ません。\n"); osSyncPrintf(VT_RST); return 0; } - destNext = dest->list; - srcNext = src->list; - - while (destNext < dest->list + dest->count) { - Collider_InitJntSphItem(globalCtx, destNext); - Collider_SetJntSphItem(globalCtx, destNext, srcNext); - destNext++; - srcNext++; + for (destElem = dest->elements, srcElem = src->elements; destElem < dest->elements + dest->count; + destElem++, srcElem++) { + Collider_InitJntSphElement(globalCtx, destElem); + Collider_SetJntSphElement(globalCtx, destElem, srcElem); } return 1; } -// ClObjJntSph_set5 (maskB = src->maskB) -s32 Collider_SetJntSph_Set5(GlobalContext* globalCtx, ColliderJntSph* dest, Actor* actor, ColliderJntSphInit* src) { - ColliderJntSphItem* destNext; - ColliderJntSphItemInit* srcNext; +/** + * Sets up the ColliderJntSph using the values in src and dynamically allocates the element array. + * Unused. + */ +s32 Collider_SetJntSphAlloc(GlobalContext* globalCtx, ColliderJntSph* dest, Actor* actor, ColliderJntSphInit* src) { + ColliderJntSphElement* destElem; + ColliderJntSphElementInit* srcElem; Collider_SetBase(globalCtx, &dest->base, actor, &src->base); dest->count = src->count; - dest->list = ZeldaArena_MallocDebug(src->count * sizeof(ColliderJntSphItem), "../z_collision_check.c", 1551); + dest->elements = ZeldaArena_MallocDebug(src->count * sizeof(ColliderJntSphElement), "../z_collision_check.c", 1551); - if (dest->list == NULL) { + if (dest->elements == NULL) { dest->count = 0; osSyncPrintf(VT_FGCOL(RED)); - osSyncPrintf("ClObjJntSph_set5():zelda_malloc出来ません\n"); // EUC-JP: 出来ません。 | Can not. + // Can not. + osSyncPrintf("ClObjJntSph_set5():zelda_malloc出来ません\n"); osSyncPrintf(VT_RST); return 0; } - - destNext = dest->list; - srcNext = src->list; - - while (destNext < dest->list + dest->count) { - Collider_InitJntSphItem(globalCtx, destNext); - Collider_SetJntSphItem(globalCtx, destNext, srcNext); - destNext++; - srcNext++; + for (destElem = dest->elements, srcElem = src->elements; destElem < dest->elements + dest->count; + destElem++, srcElem++) { + Collider_InitJntSphElement(globalCtx, destElem); + Collider_SetJntSphElement(globalCtx, destElem, srcElem); } return 1; } +/** + * Sets up the ColliderJntSph using the values in src, placing the element array in elements. + */ s32 Collider_SetJntSph(GlobalContext* globalCtx, ColliderJntSph* dest, Actor* actor, ColliderJntSphInit* src, - ColliderJntSphItem* list) { - ColliderJntSphItem* destNext; - ColliderJntSphItemInit* srcNext; + ColliderJntSphElement* elements) { + ColliderJntSphElement* destElem; + ColliderJntSphElementInit* srcElem; Collider_SetBase(globalCtx, &dest->base, actor, &src->base); dest->count = src->count; - dest->list = list; + dest->elements = elements; - if (dest->list == NULL) { + if (dest->elements == NULL) { __assert("pclobj_jntsph->elem_tbl != NULL", "../z_collision_check.c", 1603); } - - destNext = dest->list; - srcNext = src->list; - - while (destNext < dest->list + dest->count) { - Collider_InitJntSphItem(globalCtx, destNext); - Collider_SetJntSphItem(globalCtx, destNext, srcNext); - destNext++; - srcNext++; + for (destElem = dest->elements, srcElem = src->elements; destElem < dest->elements + dest->count; + destElem++, srcElem++) { + Collider_InitJntSphElement(globalCtx, destElem); + Collider_SetJntSphElement(globalCtx, destElem, srcElem); } return 1; } -s32 Collider_JntSphSetAT(GlobalContext* globalCtx, Collider* collider) { - ColliderJntSphItem* next; - ColliderJntSph* col = (ColliderJntSph*)collider; - GlobalContext* gctx = globalCtx; +/** + * Resets the collider's AT collision flags. + */ +s32 Collider_ResetJntSphAT(GlobalContext* globalCtx, Collider* collider) { + ColliderJntSphElement* element; + ColliderJntSph* jntSph = (ColliderJntSph*)collider; - Collider_BaseSetAT(gctx, &col->base); - next = col->list; + Collider_ResetATBase(globalCtx, &jntSph->base); - while (next < col->list + col->count) { - Collider_JntSphItemSetAT(gctx, next); - next++; + for (element = jntSph->elements; element < jntSph->elements + jntSph->count; element++) { + Collider_ResetJntSphElementAT(globalCtx, element); } return 1; } -s32 Collider_JntSphSetAC(GlobalContext* globalCtx, Collider* collider) { - ColliderJntSphItem* next; - ColliderJntSph* col = (ColliderJntSph*)collider; - GlobalContext* gctx = globalCtx; +/** + * Resets the collider's AC collision flags. + */ +s32 Collider_ResetJntSphAC(GlobalContext* globalCtx, Collider* collider) { + ColliderJntSphElement* element; + ColliderJntSph* jntSph = (ColliderJntSph*)collider; - Collider_BaseSetAC(gctx, &col->base); - next = col->list; + Collider_ResetACBase(globalCtx, &jntSph->base); - while (next < col->list + col->count) { - Collider_JntSphItemSetAC(gctx, next); - next++; + for (element = jntSph->elements; element < jntSph->elements + jntSph->count; element++) { + Collider_ResetJntSphElementAC(globalCtx, element); } return 1; } -s32 Collider_JntSphSetOC(GlobalContext* globalCtx, Collider* collider) { - ColliderJntSphItem* next; - ColliderJntSph* col = (ColliderJntSph*)collider; - GlobalContext* gctx = globalCtx; +/** + * Resets the collider's OC collision flags. + */ +s32 Collider_ResetJntSphOC(GlobalContext* globalCtx, Collider* collider) { + ColliderJntSphElement* element; + ColliderJntSph* jntSph = (ColliderJntSph*)collider; + + Collider_ResetOCBase(globalCtx, &jntSph->base); - Collider_BaseSetOC(gctx, &col->base); - next = col->list; - while (next < col->list + col->count) { - Collider_JntSphItemSetOC(gctx, next); - next++; + for (element = jntSph->elements; element < jntSph->elements + jntSph->count; element++) { + Collider_ResetJntSphElementOC(globalCtx, element); } return 1; } s32 Collider_InitCylinderDim(GlobalContext* globalCtx, Cylinder16* dim) { - Cylinder16 init = { 0 }; + Cylinder16 init = { 0, 0, 0, { 0, 0, 0 } }; + *dim = init; return 1; } @@ -475,306 +530,337 @@ s32 Collider_SetCylinderDim(GlobalContext* globalCtx, Cylinder16* dest, Cylinder return 1; } +/** + * Initializes a ColliderCylinder to default values + */ s32 Collider_InitCylinder(GlobalContext* globalCtx, ColliderCylinder* collider) { Collider_InitBase(globalCtx, &collider->base); - Collider_InitBody(globalCtx, &collider->body); + Collider_InitInfo(globalCtx, &collider->info); Collider_InitCylinderDim(globalCtx, &collider->dim); return 1; } +/** + * Destroys a ColliderCylinder + */ s32 Collider_DestroyCylinder(GlobalContext* globalCtx, ColliderCylinder* collider) { Collider_DestroyBase(globalCtx, &collider->base); - Collider_DestroyBody(globalCtx, &collider->body); + Collider_DestroyInfo(globalCtx, &collider->info); Collider_DestroyCylinderDim(globalCtx, &collider->dim); return 1; } -// used only by DekuJr, D_80B92A00 -s32 Collider_SetCylinder_Actor(GlobalContext* globalCtx, ColliderCylinder* collider, ColliderCylinderInit_Actor* src) { - Collider_SetBase_Actor(globalCtx, &collider->base, &src->base); - Collider_SetBody(globalCtx, &collider->body, &src->body); +/** + * Sets up the ColliderCylinder using the values in src and sets it to the actor specified in src. Uses default + * OC2_TYPE_1 and COLTYPE_0. Used only by DekuJr, who sets it to himself anyways. + */ +s32 Collider_SetCylinderToActor(GlobalContext* globalCtx, ColliderCylinder* collider, + ColliderCylinderInitToActor* src) { + Collider_SetBaseToActor(globalCtx, &collider->base, &src->base); + Collider_SetInfo(globalCtx, &collider->info, &src->info); Collider_SetCylinderDim(globalCtx, &collider->dim, &src->dim); return 1; } -// maskB = 0x10 -s32 Collider_SetCylinder_Set3(GlobalContext* globalCtx, ColliderCylinder* collider, Actor* actor, - ColliderCylinderInit_Set3* src) { - Collider_SetBase_Set3(globalCtx, &collider->base, actor, &src->base); - Collider_SetBody(globalCtx, &collider->body, &src->body); +/** + * Sets up the ColliderCylinder using the values in src. Uses default OC2_TYPE_1 + */ +s32 Collider_SetCylinderType1(GlobalContext* globalCtx, ColliderCylinder* collider, Actor* actor, + ColliderCylinderInitType1* src) { + Collider_SetBaseType1(globalCtx, &collider->base, actor, &src->base); + Collider_SetInfo(globalCtx, &collider->info, &src->info); Collider_SetCylinderDim(globalCtx, &collider->dim, &src->dim); return 1; } -// maskB = src->maskB +/** + * Sets up the ColliderCylinder using the values in src. + */ s32 Collider_SetCylinder(GlobalContext* globalCtx, ColliderCylinder* collider, Actor* actor, ColliderCylinderInit* src) { Collider_SetBase(globalCtx, &collider->base, actor, &src->base); - Collider_SetBody(globalCtx, &collider->body, &src->body); + Collider_SetInfo(globalCtx, &collider->info, &src->info); Collider_SetCylinderDim(globalCtx, &collider->dim, &src->dim); return 1; } -s32 Collider_CylinderSetAT(GlobalContext* globalCtx, Collider* collider) { - ColliderCylinder* col = (ColliderCylinder*)collider; - Collider_BaseSetAT(globalCtx, &col->base); - Collider_BodySetAT(globalCtx, &col->body); +/** + * Resets the collider's AT collision flags. + */ +s32 Collider_ResetCylinderAT(GlobalContext* globalCtx, Collider* collider) { + ColliderCylinder* cylinder = (ColliderCylinder*)collider; + + Collider_ResetATBase(globalCtx, &cylinder->base); + Collider_ResetATInfo(globalCtx, &cylinder->info); return 1; } -s32 Collider_CylinderSetAC(GlobalContext* globalCtx, Collider* collider) { - ColliderCylinder* col = (ColliderCylinder*)collider; - Collider_BaseSetAC(globalCtx, &col->base); - Collider_BodySetAC(globalCtx, &col->body); +/** + * Resets the collider's AC collision flags. + */ +s32 Collider_ResetCylinderAC(GlobalContext* globalCtx, Collider* collider) { + ColliderCylinder* cylinder = (ColliderCylinder*)collider; + + Collider_ResetACBase(globalCtx, &cylinder->base); + Collider_ResetACInfo(globalCtx, &cylinder->info); return 1; } -s32 Collider_CylinderSetOC(GlobalContext* globalCtx, Collider* collider) { - ColliderCylinder* col = (ColliderCylinder*)collider; - Collider_BaseSetOC(globalCtx, &col->base); - Collider_BodySetOC(globalCtx, &col->body); +/** + * Resets the collider's OC collision flags. + */ +s32 Collider_ResetCylinderOC(GlobalContext* globalCtx, Collider* collider) { + ColliderCylinder* cylinder = (ColliderCylinder*)collider; + + Collider_ResetOCBase(globalCtx, &cylinder->base); + Collider_ResetOCInfo(globalCtx, &cylinder->info); return 1; } -s32 Collider_InitTrisItemDim(GlobalContext* globalCtx, TriNorm* dim) { - static TriNorm init = { 0 }; +s32 Collider_InitTrisElementDim(GlobalContext* globalCtx, TriNorm* dim) { + static TriNorm init = { + { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } }, + { { 0.0f, 0.0f, 0.0f }, 0.0f }, + }; + *dim = init; return 1; } -s32 Collider_DestroyTrisItemDim(GlobalContext* globalCtx, TriNorm* dim) { +s32 Collider_DestroyTrisElementDim(GlobalContext* globalCtx, TriNorm* dim) { return 1; } -s32 Collider_SetTrisItemDim(GlobalContext* globalCtx, TriNorm* dest, ColliderTrisItemDimInit* src) { - Vec3f* d; - Vec3f* s; - f32 nx, ny, nz, nd; +s32 Collider_SetTrisElementDim(GlobalContext* globalCtx, TriNorm* dest, ColliderTrisElementDimInit* src) { + Vec3f* destVtx; + Vec3f* srcVtx; + f32 nx; + f32 ny; + f32 nz; + f32 originDist; - d = dest->vtx; - s = src->vtx; - while (d < dest->vtx + 3) { - *d++ = *s++; + for (destVtx = dest->vtx, srcVtx = src->vtx; destVtx < dest->vtx + 3; destVtx++, srcVtx++) { + *destVtx = *srcVtx; } - Math3D_DefPlane(&src->vtx[0], &src->vtx[1], &src->vtx[2], &nx, &ny, &nz, &nd); + Math3D_DefPlane(&src->vtx[0], &src->vtx[1], &src->vtx[2], &nx, &ny, &nz, &originDist); dest->plane.normal.x = nx; dest->plane.normal.y = ny; dest->plane.normal.z = nz; - dest->plane.originDist = nd; + dest->plane.originDist = originDist; return 1; } -s32 Collider_InitTrisItem(GlobalContext* globalCtx, ColliderTrisItem* collider) { - Collider_InitBody(globalCtx, &collider->body); - Collider_InitTrisItemDim(globalCtx, &collider->dim); +s32 Collider_InitTrisElement(GlobalContext* globalCtx, ColliderTrisElement* collider) { + Collider_InitInfo(globalCtx, &collider->info); + Collider_InitTrisElementDim(globalCtx, &collider->dim); return 1; } -s32 Collider_DestroyTrisItem(GlobalContext* globalCtx, ColliderTrisItem* collider) { - Collider_DestroyBody(globalCtx, &collider->body); - Collider_DestroyTrisItemDim(globalCtx, &collider->dim); +s32 Collider_DestroyTrisElement(GlobalContext* globalCtx, ColliderTrisElement* collider) { + Collider_DestroyInfo(globalCtx, &collider->info); + Collider_DestroyTrisElementDim(globalCtx, &collider->dim); return 1; } -s32 Collider_SetTrisItem(GlobalContext* globalCtx, ColliderTrisItem* dest, ColliderTrisItemInit* src) { - Collider_SetBody(globalCtx, &dest->body, &src->body); - Collider_SetTrisItemDim(globalCtx, &dest->dim, &src->dim); +s32 Collider_SetTrisElement(GlobalContext* globalCtx, ColliderTrisElement* dest, ColliderTrisElementInit* src) { + Collider_SetInfo(globalCtx, &dest->info, &src->info); + Collider_SetTrisElementDim(globalCtx, &dest->dim, &src->dim); return 1; } -s32 Collider_TrisItemSetAT(GlobalContext* globalCtx, ColliderTrisItem* item) { - Collider_BodySetAT(globalCtx, &item->body); +s32 Collider_ResetTrisElementAT(GlobalContext* globalCtx, ColliderTrisElement* element) { + Collider_ResetATInfo(globalCtx, &element->info); return 1; } -s32 Collider_TrisItemSetAC(GlobalContext* globalCtx, ColliderTrisItem* item) { - Collider_BodySetAC(globalCtx, &item->body); +s32 Collider_ResetTrisElementAC(GlobalContext* globalCtx, ColliderTrisElement* element) { + Collider_ResetACInfo(globalCtx, &element->info); return 1; } -s32 Collider_TrisItemSetOC(GlobalContext* globalCtx, ColliderTrisItem* item) { - Collider_BodySetOC(globalCtx, &item->body); +s32 Collider_ResetTrisElementOC(GlobalContext* globalCtx, ColliderTrisElement* element) { + Collider_ResetOCInfo(globalCtx, &element->info); return 1; } +/** + * Initializes a ColliderTris to default values + */ s32 Collider_InitTris(GlobalContext* globalCtx, ColliderTris* tris) { Collider_InitBase(globalCtx, &tris->base); tris->count = 0; - tris->list = 0; + tris->elements = 0; return 1; } -// zelda malloc +/** + * Destroys a dynamically allocated ColliderTris + * Unused + */ s32 Collider_FreeTris(GlobalContext* globalCtx, ColliderTris* tris) { - ColliderTrisItem* next; + ColliderTrisElement* element; Collider_DestroyBase(globalCtx, &tris->base); - next = tris->list; - - while (next < tris->list + tris->count) { - Collider_DestroyTrisItem(globalCtx, next); - next++; + for (element = tris->elements; element < tris->elements + tris->count; element++) { + Collider_DestroyTrisElement(globalCtx, element); } tris->count = 0; - if (tris->list != NULL) { - ZeldaArena_FreeDebug(tris->list, "../z_collision_check.c", 2099); + if (tris->elements != NULL) { + ZeldaArena_FreeDebug(tris->elements, "../z_collision_check.c", 2099); } - tris->list = NULL; + tris->elements = NULL; return 1; } -// no malloc +/** + * Destroys a preallocated ColliderTris + */ s32 Collider_DestroyTris(GlobalContext* globalCtx, ColliderTris* tris) { - ColliderTrisItem* next; + ColliderTrisElement* element; Collider_DestroyBase(globalCtx, &tris->base); - next = tris->list; - - while (next < tris->list + tris->count) { - Collider_DestroyTrisItem(globalCtx, next); - next++; + for (element = tris->elements; element < tris->elements + tris->count; element++) { + Collider_DestroyTrisElement(globalCtx, element); } + tris->count = 0; - tris->list = NULL; + tris->elements = NULL; return 1; } -// ClObjTris_set3 (maskB = 0x10) -s32 Collider_SetTris_Set3(GlobalContext* globalCtx, ColliderTris* dest, Actor* actor, ColliderTrisInit_Set3* src) { - ColliderTrisItem* destNext; - ColliderTrisItemInit* srcNext; +/** + * Sets up the ColliderTris using the values in src and dynamically allocates the element array. Uses default OC2_TYPE_1 + * Unused. + */ +s32 Collider_SetTrisAllocType1(GlobalContext* globalCtx, ColliderTris* dest, Actor* actor, ColliderTrisInitType1* src) { + ColliderTrisElement* destElem; + ColliderTrisElementInit* srcElem; - Collider_SetBase_Set3(globalCtx, &dest->base, actor, &src->base); + Collider_SetBaseType1(globalCtx, &dest->base, actor, &src->base); dest->count = src->count; - dest->list = ZeldaArena_MallocDebug(dest->count * sizeof(ColliderTrisItem), "../z_collision_check.c", 2156); - if (dest->list == NULL) { + dest->elements = ZeldaArena_MallocDebug(dest->count * sizeof(ColliderTrisElement), "../z_collision_check.c", 2156); + if (dest->elements == NULL) { dest->count = 0; osSyncPrintf(VT_FGCOL(RED)); - osSyncPrintf("ClObjTris_set3():zelda_malloc()出来ません\n"); // EUC-JP: 出来ません。 | Can not. + // Can not. + osSyncPrintf("ClObjTris_set3():zelda_malloc()出来ません\n"); osSyncPrintf(VT_RST); return 0; } - destNext = dest->list; - srcNext = src->list; - - while (destNext < dest->list + dest->count) { - Collider_InitTrisItem(globalCtx, destNext); - Collider_SetTrisItem(globalCtx, destNext, srcNext); - destNext++; - srcNext++; + for (destElem = dest->elements, srcElem = src->elements; destElem < dest->elements + dest->count; + destElem++, srcElem++) { + Collider_InitTrisElement(globalCtx, destElem); + Collider_SetTrisElement(globalCtx, destElem, srcElem); } return 1; } -// ClObjTris_set5 (maskB = src->maskB) -s32 Collider_SetTris_Set5(GlobalContext* globalCtx, ColliderTris* dest, Actor* actor, ColliderTrisInit* src) { - ColliderTrisItem* destNext; - ColliderTrisItemInit* srcNext; +/** + * Sets up the ColliderTris using the values in src and dynamically allocates the element array. + * Unused + */ +s32 Collider_SetTrisAlloc(GlobalContext* globalCtx, ColliderTris* dest, Actor* actor, ColliderTrisInit* src) { + ColliderTrisElement* destElem; + ColliderTrisElementInit* srcElem; Collider_SetBase(globalCtx, &dest->base, actor, &src->base); dest->count = src->count; - dest->list = ZeldaArena_MallocDebug(dest->count * sizeof(ColliderTrisItem), "../z_collision_check.c", 2207); + dest->elements = ZeldaArena_MallocDebug(dest->count * sizeof(ColliderTrisElement), "../z_collision_check.c", 2207); - if (dest->list == NULL) { + if (dest->elements == NULL) { osSyncPrintf(VT_FGCOL(RED)); - osSyncPrintf("ClObjTris_set5():zelda_malloc出来ません\n"); // EUC-JP: 出来ません。 | Can not. + // Can not. + osSyncPrintf("ClObjTris_set5():zelda_malloc出来ません\n"); osSyncPrintf(VT_RST); dest->count = 0; return 0; } - destNext = dest->list; - srcNext = src->list; - - while (destNext < dest->list + dest->count) { - Collider_InitTrisItem(globalCtx, destNext); - Collider_SetTrisItem(globalCtx, destNext, srcNext); - destNext++; - srcNext++; + for (destElem = dest->elements, srcElem = src->elements; destElem < dest->elements + dest->count; + destElem++, srcElem++) { + Collider_InitTrisElement(globalCtx, destElem); + Collider_SetTrisElement(globalCtx, destElem, srcElem); } return 1; } +/** + * Sets up the ColliderTris using the values in src, placing the element array in elements. + */ s32 Collider_SetTris(GlobalContext* globalCtx, ColliderTris* dest, Actor* actor, ColliderTrisInit* src, - ColliderTrisItem* list) { - ColliderTrisItem* destNext; - ColliderTrisItemInit* srcNext; + ColliderTrisElement* elements) { + ColliderTrisElement* destElem; + ColliderTrisElementInit* srcElem; Collider_SetBase(globalCtx, &dest->base, actor, &src->base); dest->count = src->count; - dest->list = list; + dest->elements = elements; - if (dest->list == NULL) { + if (dest->elements == NULL) { __assert("pclobj_tris->elem_tbl != NULL", "../z_collision_check.c", 2258); } - destNext = dest->list; - srcNext = src->list; - - while (destNext < dest->list + dest->count) { - Collider_InitTrisItem(globalCtx, destNext); - Collider_SetTrisItem(globalCtx, destNext, srcNext); - destNext++; - srcNext++; + for (destElem = dest->elements, srcElem = src->elements; destElem < dest->elements + dest->count; + destElem++, srcElem++) { + Collider_InitTrisElement(globalCtx, destElem); + Collider_SetTrisElement(globalCtx, destElem, srcElem); } return 1; } -s32 Collider_TrisSetAT(GlobalContext* globalCtx, Collider* collider) { - ColliderTrisItem* next; - ColliderTris* col = (ColliderTris*)collider; - GlobalContext* gctx = globalCtx; - - Collider_BaseSetAT(gctx, &col->base); - next = col->list; +/** + * Resets the collider's AT collision flags. + */ +s32 Collider_ResetTrisAT(GlobalContext* globalCtx, Collider* collider) { + ColliderTrisElement* element; + ColliderTris* tris = (ColliderTris*)collider; - while (next < col->list + col->count) { - Collider_TrisItemSetAT(gctx, next); - next++; + Collider_ResetATBase(globalCtx, &tris->base); + for (element = tris->elements; element < tris->elements + tris->count; element++) { + Collider_ResetTrisElementAT(globalCtx, element); } return 1; } -s32 Collider_TrisSetAC(GlobalContext* globalCtx, Collider* collider) { - ColliderTrisItem* next; - ColliderTris* col = (ColliderTris*)collider; - GlobalContext* gctx = globalCtx; - - Collider_BaseSetAC(gctx, &col->base); - next = col->list; +/** + * Resets the collider's AC collision flags. + */ +s32 Collider_ResetTrisAC(GlobalContext* globalCtx, Collider* collider) { + ColliderTrisElement* element; + ColliderTris* tris = (ColliderTris*)collider; - while (next < col->list + col->count) { - Collider_TrisItemSetAC(gctx, next); - next++; + Collider_ResetACBase(globalCtx, &tris->base); + for (element = tris->elements; element < tris->elements + tris->count; element++) { + Collider_ResetTrisElementAC(globalCtx, element); } return 1; } -s32 Collider_TrisSetOC(GlobalContext* globalCtx, Collider* collider) { - ColliderTrisItem* next; - ColliderTris* col = (ColliderTris*)collider; - GlobalContext* gctx = globalCtx; - - Collider_BaseSetOC(gctx, &col->base); - next = col->list; +/** + * Resets the collider's OC collision flags. + */ +s32 Collider_ResetTrisOC(GlobalContext* globalCtx, Collider* collider) { + ColliderTrisElement* element; + ColliderTris* tris = (ColliderTris*)collider; - while (next < col->list + col->count) { - Collider_TrisItemSetOC(gctx, next); - next++; + Collider_ResetOCBase(globalCtx, &tris->base); + for (element = tris->elements; element < tris->elements + tris->count; element++) { + Collider_ResetTrisElementOC(globalCtx, element); } return 1; } s32 Collider_InitQuadDim(GlobalContext* globalCtx, ColliderQuadDim* dim) { static ColliderQuadDim init = { - { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, + { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } }, { 0, 0, 0 }, { 0, 0, 0 }, 1.0E38f, }; + *dim = init; return 1; } @@ -783,14 +869,12 @@ s32 Collider_DestroyQuadDim(GlobalContext* globalCtx, ColliderQuadDim* dim) { return 1; } -// Set ColliderQuadDim unk_3C -s32 func_8005CEC4(GlobalContext* globalCtx, ColliderQuadDim* dim) { - dim->unk_3C = 1.0E38f; +s32 Collider_ResetQuadACDist(GlobalContext* globalCtx, ColliderQuadDim* dim) { + dim->acDist = 1.0E38f; return 1; } -// ColliderQuadDim compute dc ba midpoints -void func_8005CEDC(ColliderQuadDim* dim) { +void Collider_SetQuadMidpoints(ColliderQuadDim* dim) { dim->dcMid.x = (dim->quad[3].x + dim->quad[2].x) * 0.5f; dim->dcMid.y = (dim->quad[3].y + dim->quad[2].y) * 0.5f; dim->dcMid.z = (dim->quad[3].z + dim->quad[2].z) * 0.5f; @@ -804,170 +888,225 @@ s32 Collider_SetQuadDim(GlobalContext* globalCtx, ColliderQuadDim* dest, Collide dest->quad[1] = src->quad[1]; dest->quad[2] = src->quad[2]; dest->quad[3] = src->quad[3]; - func_8005CEDC(dest); + Collider_SetQuadMidpoints(dest); return 1; } +/** + * Initializes a ColliderQuad to default values. + */ s32 Collider_InitQuad(GlobalContext* globalCtx, ColliderQuad* collider) { Collider_InitBase(globalCtx, &collider->base); - Collider_InitBody(globalCtx, &collider->body); + Collider_InitInfo(globalCtx, &collider->info); Collider_InitQuadDim(globalCtx, &collider->dim); return 1; } +/** + * Destroys a ColliderQuad. + */ s32 Collider_DestroyQuad(GlobalContext* globalCtx, ColliderQuad* collider) { Collider_DestroyBase(globalCtx, &collider->base); - Collider_DestroyBody(globalCtx, &collider->body); + Collider_DestroyInfo(globalCtx, &collider->info); Collider_DestroyQuadDim(globalCtx, &collider->dim); return 1; } -// maskB = 0x10 -s32 Collider_SetQuad_Set3(GlobalContext* globalCtx, ColliderQuad* collider, Actor* actor, ColliderQuadInit_Set3* src) { - Collider_SetBase_Set3(globalCtx, &collider->base, actor, &src->base); - Collider_SetBody(globalCtx, &collider->body, &src->body); +/** + * Sets up the ColliderQuad using the values in src. Uses the default OC2_TYPE_1 + */ +s32 Collider_SetQuadType1(GlobalContext* globalCtx, ColliderQuad* collider, Actor* actor, ColliderQuadInitType1* src) { + Collider_SetBaseType1(globalCtx, &collider->base, actor, &src->base); + Collider_SetInfo(globalCtx, &collider->info, &src->info); Collider_SetQuadDim(globalCtx, &collider->dim, &src->dim); return 1; } -// maskB = src->maskB +/** + * Sets up the ColliderQuad using the values in src. + */ s32 Collider_SetQuad(GlobalContext* globalCtx, ColliderQuad* collider, Actor* actor, ColliderQuadInit* src) { Collider_SetBase(globalCtx, &collider->base, actor, &src->base); - Collider_SetBody(globalCtx, &collider->body, &src->body); + Collider_SetInfo(globalCtx, &collider->info, &src->info); Collider_SetQuadDim(globalCtx, &collider->dim, &src->dim); return 1; } -s32 Collider_QuadSetAT(GlobalContext* globalCtx, Collider* collider) { - ColliderQuad* col = (ColliderQuad*)collider; - Collider_BaseSetAT(globalCtx, &col->base); - Collider_BodySetAT(globalCtx, &col->body); - func_8005CEC4(globalCtx, &col->dim); +/** + * Resets the collider's AT collision flags. + */ +s32 Collider_ResetQuadAT(GlobalContext* globalCtx, Collider* collider) { + ColliderQuad* quad = (ColliderQuad*)collider; + + Collider_ResetATBase(globalCtx, &quad->base); + Collider_ResetATInfo(globalCtx, &quad->info); + Collider_ResetQuadACDist(globalCtx, &quad->dim); return 1; } -s32 Collider_QuadSetAC(GlobalContext* globalCtx, Collider* collider) { - ColliderQuad* col = (ColliderQuad*)collider; - Collider_BaseSetAC(globalCtx, &col->base); - Collider_BodySetAC(globalCtx, &col->body); +/** + * Resets the collider's AC collision flags. + */ +s32 Collider_ResetQuadAC(GlobalContext* globalCtx, Collider* collider) { + ColliderQuad* quad = (ColliderQuad*)collider; + + Collider_ResetACBase(globalCtx, &quad->base); + Collider_ResetACInfo(globalCtx, &quad->info); return 1; } -s32 Collider_QuadSetOC(GlobalContext* globalCtx, Collider* collider) { - ColliderQuad* col = (ColliderQuad*)collider; - Collider_BaseSetOC(globalCtx, &col->base); - Collider_BodySetOC(globalCtx, &col->body); +/** + * Resets the collider's OC collision flags. + */ +s32 Collider_ResetQuadOC(GlobalContext* globalCtx, Collider* collider) { + ColliderQuad* quad = (ColliderQuad*)collider; + + Collider_ResetOCBase(globalCtx, &quad->base); + Collider_ResetOCInfo(globalCtx, &quad->info); return 1; } -s32 func_8005D218(GlobalContext* globalCtx, ColliderQuad* quad, Vec3f* arg2) { - f32 temp; - Vec3f sp20; +/** + * For quad colliders with AT_NEAREST, resets the previous AC collider it hit if the current element is closer, + * otherwise returns false. Used on player AT colliders to prevent multiple collisions from registering. + */ +s32 Collider_QuadSetNearestAC(GlobalContext* globalCtx, ColliderQuad* quad, Vec3f* hitPos) { + f32 acDist; + Vec3f dcMid; - if (!(quad->body.toucherFlags & 4)) { - return 1; + if (!(quad->info.toucherFlags & TOUCH_NEAREST)) { + return true; } - Math_Vec3s_ToVec3f(&sp20, &quad->dim.dcMid); - temp = Math3D_Vec3fDistSq(&sp20, arg2); - if (temp < quad->dim.unk_3C) { - quad->dim.unk_3C = temp; - if (quad->body.atHit != NULL) { - Collider_BaseSetAC(globalCtx, quad->body.atHit); + Math_Vec3s_ToVec3f(&dcMid, &quad->dim.dcMid); + acDist = Math3D_Vec3fDistSq(&dcMid, hitPos); + if (acDist < quad->dim.acDist) { + quad->dim.acDist = acDist; + if (quad->info.atHit != NULL) { + Collider_ResetACBase(globalCtx, quad->info.atHit); } - if (quad->body.atHitItem != NULL) { - Collider_BodySetAC(globalCtx, quad->body.atHitItem); + if (quad->info.atHitInfo != NULL) { + Collider_ResetACInfo(globalCtx, quad->info.atHitInfo); } - return 1; + return true; } - return 0; + return false; } -s32 Collider_InitOcLine(GlobalContext* globalCtx, OcLine* line) { - static Vec3f init = { 0, 0, 0 }; - Vec3f temp; +/** + * Initializes an OcLine to default values + * OcLines are entirely unused. + */ +s32 Collider_InitLine(GlobalContext* globalCtx, OcLine* line) { + Vec3f init = { 0.0f, 0.0f, 0.0f }; - temp = init; - Math_Vec3f_Copy(&line->line.a, &temp); - Math_Vec3f_Copy(&line->line.b, &temp); + Math_Vec3f_Copy(&line->line.a, &init); + Math_Vec3f_Copy(&line->line.b, &init); return 1; } -s32 Collider_DestroyOcLine(GlobalContext* globalCtx, OcLine* line) { +/** + * Destroys an OcLine + * OcLines are entirely unused. + */ +s32 Collider_DestroyLine(GlobalContext* globalCtx, OcLine* line) { return 1; } -s32 func_8005D334(UNK_TYPE arg0, OcLine* arg1, Vec3f* arg2, Vec3f* arg3) { - Math_Vec3f_Copy(&arg1->line.a, arg2); - Math_Vec3f_Copy(&arg1->line.b, arg3); +/** + * Sets up an OcLine with endpoints a and b. + * OcLines are entirely unused. + */ +s32 Collider_SetLinePoints(GlobalContext* GlobalContext, OcLine* ocLine, Vec3f* a, Vec3f* b) { + Math_Vec3f_Copy(&ocLine->line.a, a); + Math_Vec3f_Copy(&ocLine->line.b, b); return 1; } -s32 func_8005D378(UNK_TYPE arg0, OcLine* arg1, OcLine* arg2) { - arg1->unk_18 = arg2->unk_18; - func_8005D334(arg0, arg1, &arg2->line.a, &arg2->line.b); +/** + * Sets up an OcLine using the values in src. + * OcLines are entirely unused. + */ +s32 Collider_SetLine(GlobalContext* globalCtx, OcLine* dest, OcLine* src) { + dest->ocFlags = src->ocFlags; + Collider_SetLinePoints(globalCtx, dest, &src->line.a, &src->line.b); return 1; } -s32 func_8005D3A4(GlobalContext* globalCtx, OcLine* line) { - line->unk_18 &= 0xFFFE; +/** + * Resets the OcLine's collision flags. + * OcLines are entirely unused. + */ +s32 Collider_ResetLineOC(GlobalContext* globalCtx, OcLine* line) { + line->ocFlags &= ~OCLINE_HIT; return 1; } -void func_8005D3BC(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx) { +/** + * Initializes CollisionCheckContext. Clears all collider arrays, disables SAC, and sets flags for drawing colliders. + */ +void CollisionCheck_InitContext(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx) { colChkCtx->sacFlags = 0; - CollisionCheck_InitContext(globalCtx, colChkCtx); - AREG(21) = 1; - AREG(22) = 1; - AREG(23) = 1; + CollisionCheck_ClearContext(globalCtx, colChkCtx); + AREG(21) = true; + AREG(22) = true; + AREG(23) = true; } void CollisionCheck_DestroyContext(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx) { } -// Initialize CollisionCheckContext -void CollisionCheck_InitContext(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx) { - Collider** c; - OcLine** d; +/** + * Clears all collider lists in CollisionCheckContext when not in SAC mode. + */ +void CollisionCheck_ClearContext(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx) { + Collider** col; + OcLine** line; if (!(colChkCtx->sacFlags & 1)) { - colChkCtx->colAtCount = 0; - colChkCtx->colAcCount = 0; - colChkCtx->colOcCount = 0; - colChkCtx->colOcLineCount = 0; - for (c = colChkCtx->colAt; c < colChkCtx->colAt + COLLISION_CHECK_AT_MAX; c++) { - *c = NULL; + colChkCtx->colATCount = 0; + colChkCtx->colACCount = 0; + colChkCtx->colOCCount = 0; + colChkCtx->colLineCount = 0; + for (col = colChkCtx->colAT; col < colChkCtx->colAT + COLLISION_CHECK_AT_MAX; col++) { + *col = NULL; } - for (c = colChkCtx->colAc; c < colChkCtx->colAc + COLLISION_CHECK_AC_MAX; c++) { - *c = NULL; + for (col = colChkCtx->colAC; col < colChkCtx->colAC + COLLISION_CHECK_AC_MAX; col++) { + *col = NULL; } - for (c = colChkCtx->colOc; c < colChkCtx->colOc + COLLISION_CHECK_OC_MAX; c++) { - *c = NULL; + for (col = colChkCtx->colOC; col < colChkCtx->colOC + COLLISION_CHECK_OC_MAX; col++) { + *col = NULL; } - for (d = colChkCtx->colOcLine; d < colChkCtx->colOcLine + COLLISION_CHECK_OC_LINE_MAX; d++) { - *d = NULL; + for (line = colChkCtx->colLine; line < colChkCtx->colLine + COLLISION_CHECK_OC_LINE_MAX; line++) { + *line = NULL; } } } -// Unused +/** + * Enables SAC, an alternate collision check mode that allows direct management of collider lists. Unused. + */ void CollisionCheck_EnableSAC(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx) { - colChkCtx->sacFlags |= 1; + colChkCtx->sacFlags |= AC_ON; } -// Unused +/** + * Disables SAC, an alternate collision check mode that allows direct management of collider lists. Unused. + */ void CollisionCheck_DisableSAC(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx) { - colChkCtx->sacFlags &= ~1; + colChkCtx->sacFlags &= ~AC_ON; } -// Draw Collider -void func_8005D4DC(GlobalContext* globalCtx, Collider* collider) { +/** + * Draws a collider of any shape. + * Math3D_DrawSphere and Math3D_DrawCylinder are noops, so JntSph and Cylinder are not drawn. + */ +void Collider_Draw(GlobalContext* globalCtx, Collider* collider) { ColliderJntSph* jntSph; ColliderCylinder* cylinder; ColliderTris* tris; - ColliderTrisItem* trisItem; ColliderQuad* quad; s32 i; @@ -978,7 +1117,7 @@ void func_8005D4DC(GlobalContext* globalCtx, Collider* collider) { case COLSHAPE_JNTSPH: jntSph = (ColliderJntSph*)collider; for (i = 0; i < jntSph->count; i++) { - Math3D_DrawSphere(globalCtx, &jntSph->list[i].dim.worldSphere); + Math3D_DrawSphere(globalCtx, &jntSph->elements[i].dim.worldSphere); } break; case COLSHAPE_CYLINDER: @@ -988,39 +1127,42 @@ void func_8005D4DC(GlobalContext* globalCtx, Collider* collider) { case COLSHAPE_TRIS: tris = (ColliderTris*)collider; for (i = 0; i < tris->count; i++) { - trisItem = &tris->list[i]; - func_8005B280(globalCtx->state.gfxCtx, &trisItem->dim.vtx[0], &trisItem->dim.vtx[1], - &trisItem->dim.vtx[2]); + Collider_DrawRedPoly(globalCtx->state.gfxCtx, &tris->elements[i].dim.vtx[0], + &tris->elements[i].dim.vtx[1], &tris->elements[i].dim.vtx[2]); } break; case COLSHAPE_QUAD: quad = (ColliderQuad*)collider; - func_8005B280(globalCtx->state.gfxCtx, &quad->dim.quad[2], &quad->dim.quad[3], &quad->dim.quad[1]); - func_8005B280(globalCtx->state.gfxCtx, &quad->dim.quad[1], &quad->dim.quad[0], &quad->dim.quad[2]); + Collider_DrawRedPoly(globalCtx->state.gfxCtx, &quad->dim.quad[2], &quad->dim.quad[3], &quad->dim.quad[1]); + Collider_DrawRedPoly(globalCtx->state.gfxCtx, &quad->dim.quad[1], &quad->dim.quad[0], &quad->dim.quad[2]); break; } } -void CollisionCheck_Draw(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx) { +/** + * Draws collision if AREG(15) and other AREGs are set. AREG(21) draws AT colliders, AREG(22) draws AC colliders, + * AREG(23) draws OC colliders, AREG(24) draws dynapolys, and AREG(25) draws bg polys + */ +void CollisionCheck_DrawCollision(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx) { Collider* collider; s32 i; if (AREG(15)) { if (AREG(21)) { - for (i = 0; i < colChkCtx->colAtCount; i++) { - func_8005D4DC(globalCtx, colChkCtx->colAt[i]); + for (i = 0; i < colChkCtx->colATCount; i++) { + Collider_Draw(globalCtx, colChkCtx->colAT[i]); } } if (AREG(22)) { - for (i = 0; i < colChkCtx->colAcCount; i++) { - func_8005D4DC(globalCtx, colChkCtx->colAc[i]); + for (i = 0; i < colChkCtx->colACCount; i++) { + Collider_Draw(globalCtx, colChkCtx->colAC[i]); } } if (AREG(23)) { - for (i = 0; i < colChkCtx->colOcCount; i++) { - collider = colChkCtx->colOc[i]; - if (collider->maskA & 1) { - func_8005D4DC(globalCtx, collider); + for (i = 0; i < colChkCtx->colOCCount; i++) { + collider = colChkCtx->colOC[i]; + if (collider->ocFlags1 & OC1_ON) { + Collider_Draw(globalCtx, collider); } } } @@ -1033,262 +1175,298 @@ void CollisionCheck_Draw(GlobalContext* globalCtx, CollisionCheckContext* colChk } } -s32 (*D_8011DEF8[])(GlobalContext*, Collider*) = { Collider_JntSphSetAT, Collider_CylinderSetAT, Collider_TrisSetAT, - Collider_QuadSetAT }; +static ColChkResetFunc sATResetFuncs[] = { + Collider_ResetJntSphAT, + Collider_ResetCylinderAT, + Collider_ResetTrisAT, + Collider_ResetQuadAT, +}; -// Sets collider as an AT (attack) for the current frame, which will be checked against ACs (attack colliders) +/** + * Sets collider as an AT (attack) for the current frame, which will be checked against ACs (attack colliders) + * The last argument takes a Collider, so pass collider.base rather than the raw collider. + */ s32 CollisionCheck_SetAT(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider) { s32 index; if (func_800C0D28(globalCtx) == 1) { return -1; } - if (!(collider->shape < COLSHAPE_INVALID)) { + if (!(collider->shape <= COLSHAPE_QUAD)) { __assert("pcl_obj->data_type <= CL_DATA_LBL_SWRD", "../z_collision_check.c", 2997); } - D_8011DEF8[collider->shape](globalCtx, collider); - if (collider->actor != NULL) { - if (collider->actor->update == NULL) { - return -1; - } + sATResetFuncs[collider->shape](globalCtx, collider); + if (collider->actor != NULL && collider->actor->update == NULL) { + return -1; } - if (colChkCtx->colAtCount >= COLLISION_CHECK_AT_MAX) { + if (colChkCtx->colATCount >= COLLISION_CHECK_AT_MAX) { + // Index exceeded and cannot add more osSyncPrintf("CollisionCheck_setAT():インデックスがオーバーして追加不能\n"); - // EUC-JP: インデックスがオーバーして追加不能 | Index exceeded and cannot be added return -1; } if (colChkCtx->sacFlags & 1) { return -1; } - index = colChkCtx->colAtCount; - colChkCtx->colAt[colChkCtx->colAtCount++] = collider; + index = colChkCtx->colATCount; + colChkCtx->colAT[colChkCtx->colATCount++] = collider; return index; } -// Unused. Sets collider as an AT (attack) for the current frame, which will be checked against ACs (attack colliders). -// If CollisionCheck_SAC is enabled, the collider will be inserted into the list at the specified index, otherwise it -// will be inserted into the next slot +/** + * Unused. Sets collider as an AT (attack) for the current frame, which will be checked against ACs (attack colliders). + * If CollisionCheck_SAC is enabled, the collider will be inserted into the list at the specified index, otherwise it + * will be inserted into the next slot + */ s32 CollisionCheck_SetAT_SAC(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider, s32 index) { - if (!(collider->shape < COLSHAPE_INVALID)) { + if (!(collider->shape <= COLSHAPE_QUAD)) { __assert("pcl_obj->data_type <= CL_DATA_LBL_SWRD", "../z_collision_check.c", 3037); } if (func_800C0D28(globalCtx) == 1) { return -1; } - D_8011DEF8[collider->shape](globalCtx, collider); + sATResetFuncs[collider->shape](globalCtx, collider); if (collider->actor != NULL && collider->actor->update == NULL) { return -1; } if (colChkCtx->sacFlags & 1) { - if (!(index < colChkCtx->colAtCount)) { + if (!(index < colChkCtx->colATCount)) { + // You are trying to register a location that is larger than the total number of data. osSyncPrintf("CollisionCheck_setAT_SAC():全データ数より大きいところに登録しようとしている。\n"); - // EUC-JP: 全データ数より大きいところに登録しようとしている。 | You are trying to register a location that - // is larger than the total number of data. return -1; } - colChkCtx->colAt[index] = collider; + colChkCtx->colAT[index] = collider; } else { - if (!(colChkCtx->colAtCount < COLLISION_CHECK_AT_MAX)) { + if (!(colChkCtx->colATCount < COLLISION_CHECK_AT_MAX)) { + // Index exceeded and cannot add more osSyncPrintf("CollisionCheck_setAT():インデックスがオーバーして追加不能\n"); return -1; } - index = colChkCtx->colAtCount; - colChkCtx->colAt[colChkCtx->colAtCount++] = collider; + index = colChkCtx->colATCount; + colChkCtx->colAT[colChkCtx->colATCount++] = collider; } return index; } -s32 (*D_8011DF08[])(GlobalContext*, Collider*) = { Collider_JntSphSetAC, Collider_CylinderSetAC, Collider_TrisSetAC, - Collider_QuadSetAC }; +static ColChkResetFunc sACResetFuncs[] = { + Collider_ResetJntSphAC, + Collider_ResetCylinderAC, + Collider_ResetTrisAC, + Collider_ResetQuadAC, +}; -// Sets collider as an AC (attack collider) for the current frame, allowing it to detect ATs (attacks) +/** + * Sets collider as an AC (attack collider) for the current frame, allowing it to detect ATs (attacks) + * The last argument takes a Collider, so pass collider.base rather than the raw collider. + */ s32 CollisionCheck_SetAC(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider) { s32 index; if (func_800C0D28(globalCtx) == 1) { return -1; } - if (!(collider->shape < COLSHAPE_INVALID)) { + if (!(collider->shape <= COLSHAPE_QUAD)) { __assert("pcl_obj->data_type <= CL_DATA_LBL_SWRD", "../z_collision_check.c", 3114); } - D_8011DF08[collider->shape](globalCtx, collider); - if (collider->actor != NULL) { - if (collider->actor->update == NULL) { - return -1; - } + sACResetFuncs[collider->shape](globalCtx, collider); + if (collider->actor != NULL && collider->actor->update == NULL) { + return -1; } - if (colChkCtx->colAcCount >= COLLISION_CHECK_AC_MAX) { + if (colChkCtx->colACCount >= COLLISION_CHECK_AC_MAX) { + // Index exceeded and cannot add more osSyncPrintf("CollisionCheck_setAC():インデックスがオーバして追加不能\n"); - // EUC-JP: インデックスがオーバして追加不能 | Index exceeded and cannot be added return -1; } if (colChkCtx->sacFlags & 1) { return -1; } - index = colChkCtx->colAcCount; - colChkCtx->colAc[colChkCtx->colAcCount++] = collider; + index = colChkCtx->colACCount; + colChkCtx->colAC[colChkCtx->colACCount++] = collider; return index; } -// Unused. Sets collider as an AC (attack collider) for the current frame, allowing it to detect ATs (attacks). -// If CollisionCheck_SAC is enabled, the collider will be inserted into the list at the specified index, otherwise it -// will be inserted into the next slot +/** + * Unused. Sets collider as an AC (attack collider) for the current frame, allowing it to detect ATs (attacks). + * If CollisionCheck_SAC is enabled, the collider will be inserted into the list at the specified index, otherwise it + * will be inserted into the next slot + */ s32 CollisionCheck_SetAC_SAC(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider, s32 index) { - if (!(collider->shape < COLSHAPE_INVALID)) { + if (!(collider->shape <= COLSHAPE_QUAD)) { __assert("pcl_obj->data_type <= CL_DATA_LBL_SWRD", "../z_collision_check.c", 3153); } if (func_800C0D28(globalCtx) == 1) { return -1; } - D_8011DF08[collider->shape](globalCtx, collider); + sACResetFuncs[collider->shape](globalCtx, collider); if (collider->actor != NULL && collider->actor->update == NULL) { return -1; } if (colChkCtx->sacFlags & 1) { - if (!(index < colChkCtx->colAcCount)) { + if (!(index < colChkCtx->colACCount)) { + // You are trying to register a location that is larger than the total number of data. osSyncPrintf("CollisionCheck_setAC_SAC():全データ数より大きいところに登録しようとしている。\n"); - // EUC-JP: 全データ数より大きいところに登録しようとしている。| You are trying to register a location that is - // larger than the total number of data. return -1; } - colChkCtx->colAc[index] = collider; + colChkCtx->colAC[index] = collider; } else { - if (!(colChkCtx->colAcCount < COLLISION_CHECK_AC_MAX)) { + if (!(colChkCtx->colACCount < COLLISION_CHECK_AC_MAX)) { + // Index exceeded and cannot add more osSyncPrintf("CollisionCheck_setAC():インデックスがオーバして追加不能\n"); - // EUC-JP: インデックスがオーバして追加不能 | Index exceeded and cannot be added return -1; } - index = colChkCtx->colAcCount; - colChkCtx->colAc[colChkCtx->colAcCount++] = collider; + index = colChkCtx->colACCount; + colChkCtx->colAC[colChkCtx->colACCount++] = collider; } return index; } -s32 (*D_8011DF18[])(GlobalContext*, Collider*) = { - Collider_JntSphSetOC, - Collider_CylinderSetOC, - Collider_TrisSetOC, - Collider_QuadSetOC, +static ColChkResetFunc sOCResetFuncs[] = { + Collider_ResetJntSphOC, + Collider_ResetCylinderOC, + Collider_ResetTrisOC, + Collider_ResetQuadOC, }; -// Sets collider as an OC (object collider) for the current frame, allowing it to detect other OCs +/** + * Sets collider as an OC (object collider) for the current frame, allowing it to detect other OCs + * The last argument takes a Collider, so pass collider.base rather than the raw collider. + */ s32 CollisionCheck_SetOC(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider) { s32 index; if (func_800C0D28(globalCtx) == 1) { return -1; } - if (!(collider->shape < COLSHAPE_INVALID)) { + if (!(collider->shape <= COLSHAPE_QUAD)) { __assert("pcl_obj->data_type <= CL_DATA_LBL_SWRD", "../z_collision_check.c", 3229); } - D_8011DF18[collider->shape](globalCtx, collider); - if (collider->actor != NULL) { - if (collider->actor->update == NULL) { - return -1; - } + sOCResetFuncs[collider->shape](globalCtx, collider); + if (collider->actor != NULL && collider->actor->update == NULL) { + return -1; } - if (colChkCtx->colOcCount >= COLLISION_CHECK_OC_MAX) { + if (colChkCtx->colOCCount >= COLLISION_CHECK_OC_MAX) { + // Index exceeded and cannot add more osSyncPrintf("CollisionCheck_setOC():インデックスがオーバして追加不能\n"); - // EUC-JP: インデックスがオーバして追加不能 | Index exceeded and cannot be added return -1; } if (colChkCtx->sacFlags & 1) { return -1; } - index = colChkCtx->colOcCount; - colChkCtx->colOc[colChkCtx->colOcCount++] = collider; + index = colChkCtx->colOCCount; + colChkCtx->colOC[colChkCtx->colOCCount++] = collider; return index; } -// Unused. Sets collider as an OC (object collider) for the current frame, allowing it to detect other OCs -// If CollisionCheck_SAC is enabled, the collider will be inserted into the list at the specified index, otherwise it -// will be inserted into the next slot +/** + * Unused. Sets collider as an OC (object collider) for the current frame, allowing it to detect other OCs + * If CollisionCheck_SAC is enabled, the collider will be inserted into the list at the specified index, otherwise it + * will be inserted into the next slot + */ s32 CollisionCheck_SetOC_SAC(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider, s32 index) { if (func_800C0D28(globalCtx) == 1) { return -1; } - if (!(collider->shape < COLSHAPE_INVALID)) { + if (!(collider->shape <= COLSHAPE_QUAD)) { __assert("pcl_obj->data_type <= CL_DATA_LBL_SWRD", "../z_collision_check.c", 3274); } - D_8011DF18[collider->shape](globalCtx, collider); + sOCResetFuncs[collider->shape](globalCtx, collider); if (collider->actor != NULL && collider->actor->update == NULL) { return -1; } if (colChkCtx->sacFlags & 1) { - if (!(index < colChkCtx->colOcCount)) { + if (!(index < colChkCtx->colOCCount)) { + // You are trying to register a location that is larger than the total number of data. osSyncPrintf("CollisionCheck_setOC_SAC():全データ数より大きいところに登録しようとしている。\n"); - // EUC-JP: 全データ数より大きいところに登録しようとしている。| You are trying to register a location that is - // larger than the total number of data. return -1; } - //! @bug Should be colOc - colChkCtx->colAt[index] = collider; + //! @bug Should be colOC + colChkCtx->colAT[index] = collider; } else { - if (!(colChkCtx->colOcCount < COLLISION_CHECK_OC_MAX)) { + if (!(colChkCtx->colOCCount < COLLISION_CHECK_OC_MAX)) { + // Index exceeded and cannot add more osSyncPrintf("CollisionCheck_setOC():インデックスがオーバして追加不能\n"); - // EUC-JP: インデックスがオーバして追加不能 | Index exceeded and cannot be added return -1; } - index = colChkCtx->colOcCount; - colChkCtx->colOc[colChkCtx->colOcCount++] = collider; + index = colChkCtx->colOCCount; + colChkCtx->colOC[colChkCtx->colOCCount++] = collider; } return index; } +/** + * Sets a line as an OC collider for this frame. + * OC lines are entirely unused, and do not even have collision check functions. + */ s32 CollisionCheck_SetOCLine(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, OcLine* collider) { s32 index; if (func_800C0D28(globalCtx) == 1) { return -1; } - func_8005D3A4(globalCtx, collider); - if (!(colChkCtx->colOcLineCount < COLLISION_CHECK_OC_LINE_MAX)) { + Collider_ResetLineOC(globalCtx, collider); + if (!(colChkCtx->colLineCount < COLLISION_CHECK_OC_LINE_MAX)) { + // Index exceeded and cannot add more osSyncPrintf("CollisionCheck_setOCLine():インデックスがオーバして追加不能\n"); return -1; } - index = colChkCtx->colOcLineCount; - colChkCtx->colOcLine[colChkCtx->colOcLineCount++] = collider; + index = colChkCtx->colLineCount; + colChkCtx->colLine[colChkCtx->colLineCount++] = collider; return index; } -s32 func_8005DF2C(ColliderBody* body) { - if (!(body->toucherFlags & 1)) { +/** + * Skips AT elements that are off. + */ +s32 CollisionCheck_SkipTouch(ColliderInfo* info) { + if (!(info->toucherFlags & TOUCH_ON)) { return 1; } return 0; } -s32 func_8005DF50(ColliderBody* body) { - if (!(body->bumperFlags & 1)) { +/** + * Skips AC elements that are off. + */ +s32 CollisionCheck_SkipBump(ColliderInfo* info) { + if (!(info->bumperFlags & BUMP_ON)) { return 1; } return 0; } -s32 func_8005DF74(ColliderBody* left, ColliderBody* right) { - if (!(left->toucher.flags & right->bumper.flags)) { +/** + * If the AT element has no dmgFlags in common with the AC element, no collision happens. + */ +s32 CollisionCheck_NoSharedFlags(ColliderInfo* atInfo, ColliderInfo* acInfo) { + if (!(atInfo->toucher.dmgFlags & acInfo->bumper.dmgFlags)) { return 1; } return 0; } -void func_8005DF9C(GlobalContext* globalCtx, Collider* collider, Vec3f* v) { +/** + * Spawns no blood drops. + * Used by collider types HIT1, HIT3, HIT5, METAL, NONE, WOOD, HARD, and TREE + */ +void CollisionCheck_NoBlood(GlobalContext* globalCtx, Collider* collider, Vec3f* v) { } -// Blue EffectSpark -void func_8005DFAC(GlobalContext* globalCtx, Collider* collider, Vec3f* pos) { +/** + * Spawns blue blood drops. + * Used by collider types HIT0 and HIT8. + */ +void CollisionCheck_BlueBlood(GlobalContext* globalCtx, Collider* collider, Vec3f* v) { static EffectSparkInit D_8015D8A0; - s32 sp24; + s32 effectIndex; - D_8015D8A0.position.x = (s32)pos->x; - D_8015D8A0.position.y = (s32)pos->y; - D_8015D8A0.position.z = (s32)pos->z; + D_8015D8A0.position.x = v->x; + D_8015D8A0.position.y = v->y; + D_8015D8A0.position.z = v->z; D_8015D8A0.uDiv = 5; D_8015D8A0.vDiv = 5; D_8015D8A0.colorStart[0].r = 10; @@ -1328,17 +1506,20 @@ void func_8005DFAC(GlobalContext* globalCtx, Collider* collider, Vec3f* pos) { D_8015D8A0.speed = 8.0f; D_8015D8A0.gravity = -1.0f; - Effect_Add(globalCtx, &sp24, EFFECT_SPARK, 0, 1, &D_8015D8A0); + Effect_Add(globalCtx, &effectIndex, EFFECT_SPARK, 0, 1, &D_8015D8A0); } -// Green EffectSpark -void func_8005E10C(GlobalContext* globalCtx, Collider* collider, Vec3f* pos) { +/** + * Spawns green blood drops. + * Used by collider types HIT2 and HIT6. No actor has type HIT2. + */ +void CollisionCheck_GreenBlood(GlobalContext* globalCtx, Collider* collider, Vec3f* v) { static EffectSparkInit D_8015DD68; - s32 sp24; + s32 effectIndex; - D_8015DD68.position.x = (s32)pos->x; - D_8015DD68.position.y = (s32)pos->y; - D_8015DD68.position.z = (s32)pos->z; + D_8015DD68.position.x = v->x; + D_8015DD68.position.y = v->y; + D_8015DD68.position.z = v->z; D_8015DD68.uDiv = 5; D_8015DD68.vDiv = 5; D_8015DD68.colorStart[0].r = 10; @@ -1378,410 +1559,440 @@ void func_8005E10C(GlobalContext* globalCtx, Collider* collider, Vec3f* pos) { D_8015DD68.speed = 8.0f; D_8015DD68.gravity = -1.0f; - Effect_Add(globalCtx, &sp24, EFFECT_SPARK, 0, 1, &D_8015DD68); + Effect_Add(globalCtx, &effectIndex, EFFECT_SPARK, 0, 1, &D_8015DD68); } -void func_8005E26C(GlobalContext* globalCtx, Collider* collider, Vec3f* pos) { +/** + * Spawns a burst of water. + * Used by collider type HIT4, which no actor has. + */ +void CollisionCheck_WaterBurst(GlobalContext* globalCtx, Collider* collider, Vec3f* pos) { EffectSsSibuki_SpawnBurst(globalCtx, pos); - func_80062B80(globalCtx, pos); + CollisionCheck_SpawnWaterDroplets(globalCtx, pos); } -void func_8005E2A4(GlobalContext* globalCtx, Collider* collider, Vec3f* v) { - func_80062A28(globalCtx, v); +/** + * Spawns red blood drops. + * Used by collider type HIT7, which no actor has. + */ +void CollisionCheck_RedBlood(GlobalContext* globalCtx, Collider* collider, Vec3f* v) { + CollisionCheck_SpawnRedBlood(globalCtx, v); } -void func_8005E2C8(GlobalContext* globalCtx, Collider* collider, Vec3f* v) { - func_80062A28(globalCtx, v); +/** + * Spawns red blood drops. + * Unused. + */ +void CollisionCheck_RedBloodUnused(GlobalContext* globalCtx, Collider* collider, Vec3f* v) { + CollisionCheck_SpawnRedBlood(globalCtx, v); } -void func_8005E2EC(GlobalContext* globalCtx, ColliderBody* colliderBody, Collider* collider, Vec3f* arg3) { +/** + * Plays sound effects and displays hitmarks for solid-type AC colliders (METAL, WOOD, HARD, and TREE) + */ +void CollisionCheck_HitSolid(GlobalContext* globalCtx, ColliderInfo* info, Collider* collider, Vec3f* hitPos) { s32 flags; - flags = colliderBody->toucherFlags & 0x18; - if (flags == 0 && collider->type != COLTYPE_METAL_SHIELD) { - EffectSsHitMark_SpawnFixedScale(globalCtx, 0, arg3); + flags = info->toucherFlags & TOUCH_SFX_NONE; + if (flags == TOUCH_SFX_NORMAL && collider->colType != COLTYPE_METAL) { + EffectSsHitMark_SpawnFixedScale(globalCtx, EFFECT_HITMARK_WHITE, hitPos); if (collider->actor == NULL) { Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); - return; + } else { + Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &collider->actor->projectedPos, 4, &D_801333E0, &D_801333E0, + &D_801333E8); } - Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &collider->actor->projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); - return; - } - if (flags == 0) { - EffectSsHitMark_SpawnFixedScale(globalCtx, 3, arg3); + } else if (flags == TOUCH_SFX_NORMAL) { // collider->colType == COLTYPE_METAL + EffectSsHitMark_SpawnFixedScale(globalCtx, EFFECT_HITMARK_METAL, hitPos); if (collider->actor == NULL) { - func_80062D60(globalCtx, arg3); - return; + CollisionCheck_SpawnShieldParticlesMetal(globalCtx, hitPos); + } else { + CollisionCheck_SpawnShieldParticlesMetalSound(globalCtx, hitPos, &collider->actor->projectedPos); } - func_80062DAC(globalCtx, arg3, &collider->actor->projectedPos); - return; - } - if (flags == 8) { - EffectSsHitMark_SpawnFixedScale(globalCtx, 0, arg3); + } else if (flags == TOUCH_SFX_HARD) { + EffectSsHitMark_SpawnFixedScale(globalCtx, EFFECT_HITMARK_WHITE, hitPos); if (collider->actor == NULL) { Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); - return; + } else { + Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &collider->actor->projectedPos, 4, &D_801333E0, &D_801333E0, + &D_801333E8); } - Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &collider->actor->projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); - return; - } - if (flags == 0x10) { - EffectSsHitMark_SpawnFixedScale(globalCtx, 1, arg3); + } else if (flags == TOUCH_SFX_WOOD) { + EffectSsHitMark_SpawnFixedScale(globalCtx, EFFECT_HITMARK_DUST, hitPos); if (collider->actor == NULL) { Audio_PlaySoundGeneral(NA_SE_IT_REFLECTION_WOOD, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); - return; + } else { + Audio_PlaySoundGeneral(NA_SE_IT_REFLECTION_WOOD, &collider->actor->projectedPos, 4, &D_801333E0, + &D_801333E0, &D_801333E8); } - Audio_PlaySoundGeneral(NA_SE_IT_REFLECTION_WOOD, &collider->actor->projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); - return; } } -s32 func_8005E4F8(Collider* left, ColliderBody* rightBody) { - if (left->actor != NULL) { - if (ACTORTYPE_PLAYER == left->actor->type) { - if (rightBody->flags == 0) { - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_STRIKE, &left->actor->projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); - } else if (rightBody->flags == 1) { - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_STRIKE_HARD, &left->actor->projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); - } else if (rightBody->flags == 2) { - Audio_PlaySoundGeneral(NA_SE_PL_WALK_GROUND - SFX_FLAG, &left->actor->projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); - } else if (rightBody->flags == 3) { - Audio_PlaySoundGeneral(NA_SE_PL_WALK_GROUND - SFX_FLAG, &left->actor->projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); - } +/** + * Plays a hit sound effect for AT colliders attached to Player based on the AC element's elemType. + */ +s32 CollisionCheck_SwordHitAudio(Collider* at, ColliderInfo* acInfo) { + if (at->actor != NULL && at->actor->type == ACTORTYPE_PLAYER) { + if (acInfo->elemType == ELEMTYPE_UNK0) { + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_STRIKE, &at->actor->projectedPos, 4, &D_801333E0, &D_801333E0, + &D_801333E8); + } else if (acInfo->elemType == ELEMTYPE_UNK1) { + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_STRIKE_HARD, &at->actor->projectedPos, 4, &D_801333E0, &D_801333E0, + &D_801333E8); + } else if (acInfo->elemType == ELEMTYPE_UNK2) { + Audio_PlaySoundGeneral(NA_SE_PL_WALK_GROUND - SFX_FLAG, &at->actor->projectedPos, 4, &D_801333E0, + &D_801333E0, &D_801333E8); + } else if (acInfo->elemType == ELEMTYPE_UNK3) { + Audio_PlaySoundGeneral(NA_SE_PL_WALK_GROUND - SFX_FLAG, &at->actor->projectedPos, 4, &D_801333E0, + &D_801333E0, &D_801333E8); } } return 1; } -typedef struct { - u8 unk00; - u8 unk01; -} D_8011DF40_s; - -void func_8005E604(GlobalContext* globalCtx, Collider* left, ColliderBody* leftBody, Collider* right, - ColliderBody* rightBody, Vec3f* arg5) { - - static void (*D_8011DF28[])(GlobalContext*, Collider*, Vec3f*) = { - func_8005DF9C, func_8005DFAC, func_8005E10C, func_8005E26C, func_8005E2A4, func_8005E2C8, - }; - - static D_8011DF40_s D_8011DF40[] = { - { 1, 0 }, { 0, 1 }, { 2, 1 }, { 0, 0 }, { 3, 5 }, { 0, 2 }, { 2, 0 }, - { 4, 0 }, { 1, 2 }, { 0, 3 }, { 0, 5 }, { 0, 3 }, { 0, 3 }, { 0, 4 }, - }; +static ColChkBloodFunc sBloodFuncs[] = { + CollisionCheck_NoBlood, CollisionCheck_BlueBlood, CollisionCheck_GreenBlood, + CollisionCheck_WaterBurst, CollisionCheck_RedBlood, CollisionCheck_RedBloodUnused, +}; +static HitInfo sHitInfo[] = { + { BLOOD_BLUE, HIT_WHITE }, { BLOOD_NONE, HIT_DUST }, { BLOOD_GREEN, HIT_DUST }, { BLOOD_NONE, HIT_WHITE }, + { BLOOD_WATER, HIT_NONE }, { BLOOD_NONE, HIT_RED }, { BLOOD_GREEN, HIT_WHITE }, { BLOOD_RED, HIT_WHITE }, + { BLOOD_BLUE, HIT_RED }, { BLOOD_NONE, HIT_SOLID }, { BLOOD_NONE, HIT_NONE }, { BLOOD_NONE, HIT_SOLID }, + { BLOOD_NONE, HIT_SOLID }, { BLOOD_NONE, HIT_WOOD }, +}; - if (rightBody->bumperFlags & 0x40) { +/** + * Handles hitmarks, blood, and sound effects for each AC collision, determined by the AC collider's colType + */ +void CollisionCheck_HitEffects(GlobalContext* globalCtx, Collider* at, ColliderInfo* atInfo, Collider* ac, + ColliderInfo* acInfo, Vec3f* hitPos) { + if (acInfo->bumperFlags & BUMP_NO_HITMARK) { return; } - if (!(leftBody->toucherFlags & 0x20) && leftBody->toucherFlags & 0x40) { + if (!(atInfo->toucherFlags & TOUCH_AT_HITMARK) && atInfo->toucherFlags & TOUCH_DREW_HITMARK) { return; } - if (right->actor != NULL) { - (*D_8011DF28[D_8011DF40[right->type].unk00])(globalCtx, right, arg5); + if (ac->actor != NULL) { + sBloodFuncs[sHitInfo[ac->colType].blood](globalCtx, ac, hitPos); } - if (right->actor != NULL) { - if (D_8011DF40[right->type].unk01 == 3) { - func_8005E2EC(globalCtx, leftBody, right, arg5); - } else if (D_8011DF40[right->type].unk01 == 4) { - if (left->actor == NULL) { - func_80062CD4(globalCtx, arg5); + if (ac->actor != NULL) { + if (sHitInfo[ac->colType].effect == HIT_SOLID) { + CollisionCheck_HitSolid(globalCtx, atInfo, ac, hitPos); + } else if (sHitInfo[ac->colType].effect == HIT_WOOD) { + if (at->actor == NULL) { + CollisionCheck_SpawnShieldParticles(globalCtx, hitPos); Audio_PlaySoundGeneral(NA_SE_IT_REFLECTION_WOOD, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); } else { - func_80062E14(globalCtx, arg5, &left->actor->projectedPos); + CollisionCheck_SpawnShieldParticlesWood(globalCtx, hitPos, &at->actor->projectedPos); } - } else if (D_8011DF40[right->type].unk01 != 5) { - EffectSsHitMark_SpawnFixedScale(globalCtx, D_8011DF40[right->type].unk01, arg5); - if ((rightBody->bumperFlags & 0x20) == 0) { - func_8005E4F8(left, rightBody); + } else if (sHitInfo[ac->colType].effect != HIT_NONE) { + EffectSsHitMark_SpawnFixedScale(globalCtx, sHitInfo[ac->colType].effect, hitPos); + if (!(acInfo->bumperFlags & BUMP_NO_SWORD_SFX)) { + CollisionCheck_SwordHitAudio(at, acInfo); } } } else { - EffectSsHitMark_SpawnFixedScale(globalCtx, 0, arg5); - if (right->actor == NULL) { + EffectSsHitMark_SpawnFixedScale(globalCtx, EFFECT_HITMARK_WHITE, hitPos); + if (ac->actor == NULL) { Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); } else { - Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &right->actor->projectedPos, 4, &D_801333E0, &D_801333E0, + Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &ac->actor->projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); } } } -void func_8005E800(Collider* left, Collider* right) { - left->atFlags |= 4; - right->acFlags |= 0x80; +/** + * Sets the flags to indicate an attack bounced off an AC_HARD collider. + */ +void CollisionCheck_SetBounce(Collider* at, Collider* ac) { + at->atFlags |= AT_BOUNCED; + ac->acFlags |= AC_BOUNCED; } -// Set AT to AC collision -s32 func_8005E81C(GlobalContext* globalCtx, Collider* left, ColliderBody* leftBody, Vec3f* leftv, Collider* right, - ColliderBody* rightBody, Vec3f* rightv, Vec3f* arg7) { - - if (right->acFlags & 4 && left->actor != NULL && right->actor != NULL) { - func_8005E800(left, right); - } - if (!(rightBody->bumperFlags & 8)) { - left->atFlags |= 2; - left->at = right->actor; - leftBody->atHit = right; - leftBody->atHitItem = rightBody; - leftBody->toucherFlags |= 2; - if (left->actor != NULL) { - left->actor->colChkInfo.atHitEffect = rightBody->bumper.effect; - } - } - right->acFlags |= 2; - right->ac = left->actor; - rightBody->acHit = left; - rightBody->acHitItem = leftBody; - rightBody->bumperFlags |= 2; - if (right->actor != NULL) { - right->actor->colChkInfo.acHitEffect = leftBody->toucher.effect; - } - rightBody->bumper.unk_06.x = (s16)arg7->x; - rightBody->bumper.unk_06.y = (s16)arg7->y; - rightBody->bumper.unk_06.z = (s16)arg7->z; - if (!(leftBody->toucherFlags & 0x20) && right->type != COLTYPE_METAL_SHIELD && - right->type != COLTYPE_WOODEN_SHIELD && right->type != COLTYPE_UNK12) { - rightBody->bumperFlags |= 0x80; +/** + * Performs the AC collision between the AT element and AC element that collided. + */ +s32 CollisionCheck_SetATvsAC(GlobalContext* globalCtx, Collider* at, ColliderInfo* atInfo, Vec3f* atPos, Collider* ac, + ColliderInfo* acInfo, Vec3f* acPos, Vec3f* hitPos) { + + if (ac->acFlags & AC_HARD && at->actor != NULL && ac->actor != NULL) { + CollisionCheck_SetBounce(at, ac); + } + if (!(acInfo->bumperFlags & BUMP_NO_AT_INFO)) { + at->atFlags |= AT_HIT; + at->at = ac->actor; + atInfo->atHit = ac; + atInfo->atHitInfo = acInfo; + atInfo->toucherFlags |= TOUCH_HIT; + if (at->actor != NULL) { + at->actor->colChkInfo.atHitEffect = acInfo->bumper.effect; + } + } + ac->acFlags |= AC_HIT; + ac->ac = at->actor; + acInfo->acHit = at; + acInfo->acHitInfo = atInfo; + acInfo->bumperFlags |= BUMP_HIT; + if (ac->actor != NULL) { + ac->actor->colChkInfo.acHitEffect = atInfo->toucher.effect; + } + acInfo->bumper.hitPos.x = hitPos->x; + acInfo->bumper.hitPos.y = hitPos->y; + acInfo->bumper.hitPos.z = hitPos->z; + if (!(atInfo->toucherFlags & TOUCH_AT_HITMARK) && ac->colType != COLTYPE_METAL && ac->colType != COLTYPE_WOOD && + ac->colType != COLTYPE_HARD) { + acInfo->bumperFlags |= BUMP_DRAW_HITMARK; } else { - func_8005E604(globalCtx, left, leftBody, right, rightBody, arg7); - leftBody->toucherFlags |= 0x40; + CollisionCheck_HitEffects(globalCtx, at, atInfo, ac, acInfo, hitPos); + atInfo->toucherFlags |= TOUCH_DREW_HITMARK; } return 1; } -void CollisionCheck_AC_JntSphVsJntSph(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* l, - Collider* r) { - ColliderJntSph* left; - ColliderJntSph* right; - ColliderJntSphItem* lItem; - ColliderJntSphItem* rItem; - f32 sp8C; - f32 sp88; - f32 temp_f0; - Vec3f sp78; - Vec3f sp6C; - Vec3f sp60; - - left = (ColliderJntSph*)l; - right = (ColliderJntSph*)r; - if (left->count <= 0 || left->list == NULL || right->count <= 0 || right->list == NULL) { - return; - } - for (lItem = left->list; lItem < left->list + left->count; lItem++) { - if (func_8005DF2C(&lItem->body) == 1) { - continue; - } - for (rItem = right->list; rItem < right->list + right->count; rItem++) { - if (func_8005DF50(&rItem->body) == 1) { - continue; - } - if (func_8005DF74(&lItem->body, &rItem->body) == 1) { +/** + * AC overlap check. Calculates the center of each collider element and the point of contact. + */ +void CollisionCheck_AC_JntSphVsJntSph(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* colAT, + Collider* colAC) { + ColliderJntSph* at = (ColliderJntSph*)colAT; + ColliderJntSphElement* atItem; + ColliderJntSph* ac = (ColliderJntSph*)colAC; + ColliderJntSphElement* acElem; + f32 overlapSize; + f32 centerDist; + + if (at->count > 0 && at->elements != NULL && ac->count > 0 && ac->elements != NULL) { + for (atItem = at->elements; atItem < at->elements + at->count; atItem++) { + if (CollisionCheck_SkipTouch(&atItem->info) == 1) { continue; } - if (Math3D_SphVsSphOverlapCenter(&lItem->dim.worldSphere, &rItem->dim.worldSphere, &sp8C, &sp88) == 1) { - sp6C.x = lItem->dim.worldSphere.center.x; - sp6C.y = lItem->dim.worldSphere.center.y; - sp6C.z = lItem->dim.worldSphere.center.z; - sp60.x = rItem->dim.worldSphere.center.x; - sp60.y = rItem->dim.worldSphere.center.y; - sp60.z = rItem->dim.worldSphere.center.z; - if (!IS_ZERO(sp88)) { - temp_f0 = rItem->dim.worldSphere.radius / sp88; - sp78.x = (((sp6C.x - sp60.x) * temp_f0) + sp60.x); - sp78.y = (((sp6C.y - sp60.y) * temp_f0) + sp60.y); - sp78.z = (((sp6C.z - sp60.z) * temp_f0) + sp60.z); - } else { - Math_Vec3f_Copy(&sp78, &sp6C); + for (acElem = ac->elements; acElem < ac->elements + ac->count; acElem++) { + if (CollisionCheck_SkipBump(&acElem->info) == 1) { + continue; } - func_8005E81C(globalCtx, &left->base, &lItem->body, &sp6C, &right->base, &rItem->body, &sp60, &sp78); - if (!(right->base.maskB & 0x40)) { - return; + if (CollisionCheck_NoSharedFlags(&atItem->info, &acElem->info) == 1) { + continue; + } + if (Math3D_SphVsSphOverlapCenter(&atItem->dim.worldSphere, &acElem->dim.worldSphere, &overlapSize, + ¢erDist) == 1) { + f32 acToHit; + Vec3f hitPos; + Vec3f atPos; + Vec3f acPos; + + atPos.x = atItem->dim.worldSphere.center.x; + atPos.y = atItem->dim.worldSphere.center.y; + atPos.z = atItem->dim.worldSphere.center.z; + acPos.x = acElem->dim.worldSphere.center.x; + acPos.y = acElem->dim.worldSphere.center.y; + acPos.z = acElem->dim.worldSphere.center.z; + if (!IS_ZERO(centerDist)) { + acToHit = acElem->dim.worldSphere.radius / centerDist; + hitPos.x = (((atPos.x - acPos.x) * acToHit) + acPos.x); + hitPos.y = (((atPos.y - acPos.y) * acToHit) + acPos.y); + hitPos.z = (((atPos.z - acPos.z) * acToHit) + acPos.z); + } else { + Math_Vec3f_Copy(&hitPos, &atPos); + } + CollisionCheck_SetATvsAC(globalCtx, &at->base, &atItem->info, &atPos, &ac->base, &acElem->info, + &acPos, &hitPos); + if (!(ac->base.ocFlags2 & OC2_FIRST_ONLY)) { + return; + } } } } } } -void CollisionCheck_AC_JntSphVsCyl(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* l, - Collider* r) { - ColliderJntSph* left = (ColliderJntSph*)l; - ColliderCylinder* right = (ColliderCylinder*)r; - ColliderJntSphItem* lItem; - f32 sp80; - f32 sp7C; - Vec3f sp70; - Vec3f sp64; - Vec3f sp58; - f32 temp_f0; - - if (left->count <= 0 || left->list == NULL || right->dim.radius <= 0 || right->dim.height <= 0) { - return; - } - if (func_8005DF50(&right->body) == 1) { - return; - } - for (lItem = left->list; lItem < left->list + left->count; lItem++) { - if (func_8005DF2C(&lItem->body) == 1) { - continue; - } - if (func_8005DF74(&lItem->body, &right->body) == 1) { - continue; +/** + * AC overlap check. Calculates the center of each collider element and the point of contact. + */ +void CollisionCheck_AC_JntSphVsCyl(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* colAT, + Collider* colAC) { + ColliderJntSph* at = (ColliderJntSph*)colAT; + ColliderJntSphElement* atItem; + ColliderCylinder* ac = (ColliderCylinder*)colAC; + f32 overlapSize; + f32 centerDist; + + if (at->count > 0 && at->elements != NULL && ac->dim.radius > 0 && ac->dim.height > 0) { + if (CollisionCheck_SkipBump(&ac->info) == 1) { + return; } - if (Math3D_SphVsCylOverlapCenterDist(&lItem->dim.worldSphere, &right->dim, &sp80, &sp7C) != 0) { - sp64.x = lItem->dim.worldSphere.center.x; - sp64.y = lItem->dim.worldSphere.center.y; - sp64.z = lItem->dim.worldSphere.center.z; - sp58.x = right->dim.pos.x; - sp58.y = right->dim.pos.y; - sp58.z = right->dim.pos.z; - if (!IS_ZERO(sp7C)) { - temp_f0 = right->dim.radius / sp7C; - if (temp_f0 <= 1.0f) { - sp70.x = ((sp64.x - sp58.x) * temp_f0) + sp58.x; - sp70.y = ((sp64.y - sp58.y) * temp_f0) + sp58.y; - sp70.z = ((sp64.z - sp58.z) * temp_f0) + sp58.z; + for (atItem = at->elements; atItem < at->elements + at->count; atItem++) { + if (CollisionCheck_SkipTouch(&atItem->info) == 1) { + continue; + } + if (CollisionCheck_NoSharedFlags(&atItem->info, &ac->info) == 1) { + continue; + } + if (Math3D_SphVsCylOverlapCenterDist(&atItem->dim.worldSphere, &ac->dim, &overlapSize, ¢erDist)) { + Vec3f hitPos; + Vec3f atPos; + Vec3f acPos; + f32 acToHit; + + atPos.x = atItem->dim.worldSphere.center.x; + atPos.y = atItem->dim.worldSphere.center.y; + atPos.z = atItem->dim.worldSphere.center.z; + acPos.x = ac->dim.pos.x; + acPos.y = ac->dim.pos.y; + acPos.z = ac->dim.pos.z; + if (!IS_ZERO(centerDist)) { + acToHit = ac->dim.radius / centerDist; + if (acToHit <= 1.0f) { + hitPos.x = ((atPos.x - acPos.x) * acToHit) + acPos.x; + hitPos.y = ((atPos.y - acPos.y) * acToHit) + acPos.y; + hitPos.z = ((atPos.z - acPos.z) * acToHit) + acPos.z; + } else { + Math_Vec3f_Copy(&hitPos, &atPos); + } } else { - Math_Vec3f_Copy(&sp70, &sp64); + Math_Vec3f_Copy(&hitPos, &atPos); } - } else { - Math_Vec3f_Copy(&sp70, &sp64); + CollisionCheck_SetATvsAC(globalCtx, &at->base, &atItem->info, &atPos, &ac->base, &ac->info, &acPos, + &hitPos); + return; } - func_8005E81C(globalCtx, &left->base, &lItem->body, &sp64, &right->base, &right->body, &sp58, &sp70); - return; } } } -void CollisionCheck_AC_CylVsJntSph(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* l, - Collider* r) { - ColliderCylinder* left = (ColliderCylinder*)l; - ColliderJntSph* right = (ColliderJntSph*)r; - f32 sp9C; - f32 sp98; - ColliderJntSphItem* rItem; - Vec3f sp88; - Vec3f sp7C; - Vec3f sp70; - f32 temp_f0; - - if (right->count <= 0 || right->list == NULL || left->dim.radius <= 0 || left->dim.height <= 0) { - return; - } - if (func_8005DF2C(&left->body) == 1) { - return; - } - for (rItem = right->list; rItem < right->list + right->count; rItem++) { - if (func_8005DF50(&rItem->body) == 1) { - continue; - } - if (func_8005DF74(&left->body, &rItem->body) == 1) { - continue; +/** + * AC overlap check. Calculates the center of each collider element and the point of contact. + */ +void CollisionCheck_AC_CylVsJntSph(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* colAT, + Collider* colAC) { + ColliderCylinder* at = (ColliderCylinder*)colAT; + ColliderJntSph* ac = (ColliderJntSph*)colAC; + f32 overlapSize; + f32 centerDist; + ColliderJntSphElement* acElem; + + if (ac->count > 0 && ac->elements != NULL && at->dim.radius > 0 && at->dim.height > 0) { + if (CollisionCheck_SkipTouch(&at->info) == 1) { + return; } - if (Math3D_SphVsCylOverlapCenterDist(&rItem->dim.worldSphere, &left->dim, &sp9C, &sp98) != 0) { - sp7C.x = left->dim.pos.x; - sp7C.y = left->dim.pos.y; - sp7C.z = left->dim.pos.z; - sp70.x = rItem->dim.worldSphere.center.x; - sp70.y = rItem->dim.worldSphere.center.y; - sp70.z = rItem->dim.worldSphere.center.z; - if (!IS_ZERO(sp98)) { - temp_f0 = (f32)rItem->dim.worldSphere.radius / sp98; - if (temp_f0 <= 1.0f) { - sp88.x = ((sp7C.x - sp70.x) * temp_f0) + sp70.x; - sp88.y = ((sp7C.y - sp70.y) * temp_f0) + sp70.y; - sp88.z = ((sp7C.z - sp70.z) * temp_f0) + sp70.z; + for (acElem = ac->elements; acElem < ac->elements + ac->count; acElem++) { + if (CollisionCheck_SkipBump(&acElem->info) == 1) { + continue; + } + if (CollisionCheck_NoSharedFlags(&at->info, &acElem->info) == 1) { + continue; + } + if (Math3D_SphVsCylOverlapCenterDist(&acElem->dim.worldSphere, &at->dim, &overlapSize, ¢erDist)) { + Vec3f hitPos; + Vec3f atPos; + Vec3f acPos; + f32 acToHit; + + atPos.x = at->dim.pos.x; + atPos.y = at->dim.pos.y; + atPos.z = at->dim.pos.z; + acPos.x = acElem->dim.worldSphere.center.x; + acPos.y = acElem->dim.worldSphere.center.y; + acPos.z = acElem->dim.worldSphere.center.z; + if (!IS_ZERO(centerDist)) { + acToHit = acElem->dim.worldSphere.radius / centerDist; + if (acToHit <= 1.0f) { + hitPos.x = ((atPos.x - acPos.x) * acToHit) + acPos.x; + hitPos.y = ((atPos.y - acPos.y) * acToHit) + acPos.y; + hitPos.z = ((atPos.z - acPos.z) * acToHit) + acPos.z; + } else { + Math_Vec3f_Copy(&hitPos, &atPos); + } } else { - Math_Vec3f_Copy(&sp88, &sp7C); + Math_Vec3f_Copy(&hitPos, &atPos); + } + CollisionCheck_SetATvsAC(globalCtx, &at->base, &at->info, &atPos, &ac->base, &acElem->info, &acPos, + &hitPos); + if (!(ac->base.ocFlags2 & OC2_FIRST_ONLY)) { + break; } - } else { - Math_Vec3f_Copy(&sp88, &sp7C); - } - func_8005E81C(globalCtx, &left->base, &left->body, &sp7C, &right->base, &rItem->body, &sp70, &sp88); - if (!(right->base.maskB & 0x40)) { - break; } } } } -void CollisionCheck_AC_JntSphVsTris(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* l, - Collider* r) { - ColliderJntSph* left = (ColliderJntSph*)l; - ColliderTris* right = (ColliderTris*)r; - ColliderJntSphItem* lItem; - ColliderTrisItem* rItem; - Vec3f sp6C; - Vec3f sp60; - Vec3f sp54; - - if (left->count <= 0 || left->list == NULL || right->count <= 0 || right->list == NULL) { - return; - } - for (lItem = left->list; lItem < left->list + left->count; lItem++) { - if (func_8005DF2C(&lItem->body) == 1) { - continue; - } - for (rItem = right->list; rItem < right->list + right->count; rItem++) { - if (func_8005DF50(&rItem->body) == 1) { - continue; - } - if (func_8005DF74(&lItem->body, &rItem->body) == 1) { +/** + * AC overlap check. Calculates the center of each collider element and the point of contact. + */ +void CollisionCheck_AC_JntSphVsTris(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* colAT, + Collider* colAC) { + ColliderJntSph* at = (ColliderJntSph*)colAT; + ColliderJntSphElement* atSph; + ColliderTris* ac = (ColliderTris*)colAC; + ColliderTrisElement* acTri; + Vec3f hitPos; + + if (at->count > 0 && at->elements != NULL && ac->count > 0 && ac->elements != NULL) { + for (atSph = at->elements; atSph < at->elements + at->count; atSph++) { + if (CollisionCheck_SkipTouch(&atSph->info) == 1) { continue; } - if (Math3D_TriVsSphIntersect(&lItem->dim.worldSphere, &rItem->dim, &sp6C) == 1) { - sp60.x = lItem->dim.worldSphere.center.x; - sp60.y = lItem->dim.worldSphere.center.y; - sp60.z = lItem->dim.worldSphere.center.z; - sp54.x = (rItem->dim.vtx[0].x + rItem->dim.vtx[1].x + rItem->dim.vtx[2].x) * (1.0f / 3); - sp54.y = (rItem->dim.vtx[0].y + rItem->dim.vtx[1].y + rItem->dim.vtx[2].y) * (1.0f / 3); - sp54.z = (rItem->dim.vtx[0].z + rItem->dim.vtx[1].z + rItem->dim.vtx[2].z) * (1.0f / 3); - func_8005E81C(globalCtx, &left->base, &lItem->body, &sp60, &right->base, &rItem->body, &sp54, &sp6C); - return; + for (acTri = ac->elements; acTri < ac->elements + ac->count; acTri++) { + if (CollisionCheck_SkipBump(&acTri->info) == 1) { + continue; + } + if (CollisionCheck_NoSharedFlags(&atSph->info, &acTri->info) == 1) { + continue; + } + if (Math3D_TriVsSphIntersect(&atSph->dim.worldSphere, &acTri->dim, &hitPos) == 1) { + Vec3f atPos; + Vec3f acPos; + + atPos.x = atSph->dim.worldSphere.center.x; + atPos.y = atSph->dim.worldSphere.center.y; + atPos.z = atSph->dim.worldSphere.center.z; + acPos.x = (acTri->dim.vtx[0].x + acTri->dim.vtx[1].x + acTri->dim.vtx[2].x) * (1.0f / 3); + acPos.y = (acTri->dim.vtx[0].y + acTri->dim.vtx[1].y + acTri->dim.vtx[2].y) * (1.0f / 3); + acPos.z = (acTri->dim.vtx[0].z + acTri->dim.vtx[1].z + acTri->dim.vtx[2].z) * (1.0f / 3); + CollisionCheck_SetATvsAC(globalCtx, &at->base, &atSph->info, &atPos, &ac->base, &acTri->info, + &acPos, &hitPos); + return; + } } } } } -void CollisionCheck_AC_TrisVsJntSph(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* l, - Collider* r) { - ColliderTris* left = (ColliderTris*)l; - ColliderTrisItem* lItem; - ColliderJntSph* right = (ColliderJntSph*)r; - ColliderJntSphItem* rItem; - Vec3f sp7C; - Vec3f sp70; - Vec3f sp64; - - if (right->count > 0 && right->list != NULL) { - if (left->count > 0 && left->list != NULL) { - for (rItem = right->list; rItem < right->list + right->count; rItem++) { - if (func_8005DF50(&rItem->body) == 1) { +/** + * AC overlap check. Calculates the center of each collider element and the point of contact. + */ +void CollisionCheck_AC_TrisVsJntSph(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* colAT, + Collider* colAC) { + ColliderTris* at = (ColliderTris*)colAT; + ColliderTrisElement* atItem; + ColliderJntSph* ac = (ColliderJntSph*)colAC; + ColliderJntSphElement* acElem; + Vec3f hitPos; + + if (ac->count > 0 && ac->elements != NULL && at->count > 0 && at->elements != NULL) { + for (acElem = ac->elements; acElem < ac->elements + ac->count; acElem++) { + if (CollisionCheck_SkipBump(&acElem->info) == 1) { + continue; + } + for (atItem = at->elements; atItem < at->elements + at->count; atItem++) { + if (CollisionCheck_SkipTouch(&atItem->info) == 1) { continue; } - for (lItem = left->list; lItem < left->list + left->count; lItem++) { - if (func_8005DF2C(&lItem->body) == 1) { - continue; - } - if (func_8005DF74(&lItem->body, &rItem->body) == 1) { - continue; - } - if (Math3D_TriVsSphIntersect(&rItem->dim.worldSphere, &lItem->dim, &sp7C) == 1) { - Math_Vec3s_ToVec3f(&sp64, &rItem->dim.worldSphere.center); - sp70.x = (lItem->dim.vtx[0].x + lItem->dim.vtx[1].x + lItem->dim.vtx[2].x) * (1.0f / 3); - sp70.y = (lItem->dim.vtx[0].y + lItem->dim.vtx[1].y + lItem->dim.vtx[2].y) * (1.0f / 3); - sp70.z = (lItem->dim.vtx[0].z + lItem->dim.vtx[1].z + lItem->dim.vtx[2].z) * (1.0f / 3); - func_8005E81C(globalCtx, &left->base, &lItem->body, &sp70, &right->base, &rItem->body, &sp64, - &sp7C); - if (!(right->base.maskB & 0x40)) { - return; - } + if (CollisionCheck_NoSharedFlags(&atItem->info, &acElem->info) == 1) { + continue; + } + if (Math3D_TriVsSphIntersect(&acElem->dim.worldSphere, &atItem->dim, &hitPos) == 1) { + Vec3f atPos; + Vec3f acPos; + + Math_Vec3s_ToVec3f(&acPos, &acElem->dim.worldSphere.center); + atPos.x = (atItem->dim.vtx[0].x + atItem->dim.vtx[1].x + atItem->dim.vtx[2].x) * (1.0f / 3); + atPos.y = (atItem->dim.vtx[0].y + atItem->dim.vtx[1].y + atItem->dim.vtx[2].y) * (1.0f / 3); + atPos.z = (atItem->dim.vtx[0].z + atItem->dim.vtx[1].z + atItem->dim.vtx[2].z) * (1.0f / 3); + CollisionCheck_SetATvsAC(globalCtx, &at->base, &atItem->info, &atPos, &ac->base, &acElem->info, + &acPos, &hitPos); + if (!(ac->base.ocFlags2 & OC2_FIRST_ONLY)) { + return; } } } @@ -1789,94 +2000,94 @@ void CollisionCheck_AC_TrisVsJntSph(GlobalContext* globalCtx, CollisionCheckCont } } -static TriNorm D_8015E230; -static TriNorm D_8015E268; - -void CollisionCheck_AC_JntSphVsQuad(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* l, - Collider* r) { - ColliderJntSph* left = (ColliderJntSph*)l; - ColliderQuad* right = (ColliderQuad*)r; - Vec3f sp7C; - ColliderJntSphItem* lItem; - Vec3f sp6C; - Vec3f sp60; - - if (left->count > 0 && left->list != NULL) { - if (func_8005DF50(&right->body) == 1) { +/** + * AC overlap check. Calculates the center of each collider element and the point of contact. + */ +void CollisionCheck_AC_JntSphVsQuad(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* colAT, + Collider* colAC) { + static TriNorm D_8015E230; + static TriNorm D_8015E268; + ColliderJntSph* at = (ColliderJntSph*)colAT; + ColliderQuad* ac = (ColliderQuad*)colAC; + Vec3f hitPos; + ColliderJntSphElement* atItem; + + if (at->count > 0 && at->elements != NULL) { + if (CollisionCheck_SkipBump(&ac->info) == 1) { return; } - Math3D_TriNorm(&D_8015E230, &right->dim.quad[2], &right->dim.quad[3], &right->dim.quad[1]); - Math3D_TriNorm(&D_8015E268, &right->dim.quad[1], &right->dim.quad[0], &right->dim.quad[2]); - for (lItem = left->list; lItem < left->list + left->count; lItem++) { - if (func_8005DF2C(&lItem->body) == 1) { + Math3D_TriNorm(&D_8015E230, &ac->dim.quad[2], &ac->dim.quad[3], &ac->dim.quad[1]); + Math3D_TriNorm(&D_8015E268, &ac->dim.quad[1], &ac->dim.quad[0], &ac->dim.quad[2]); + for (atItem = at->elements; atItem < at->elements + at->count; atItem++) { + if (CollisionCheck_SkipTouch(&atItem->info) == 1) { continue; } - if (func_8005DF74(&lItem->body, &right->body) == 1) { + if (CollisionCheck_NoSharedFlags(&atItem->info, &ac->info) == 1) { continue; } - if (Math3D_TriVsSphIntersect(&lItem->dim.worldSphere, &D_8015E230, &sp7C) == 1 || - Math3D_TriVsSphIntersect(&lItem->dim.worldSphere, &D_8015E268, &sp7C) == 1) { - Math_Vec3s_ToVec3f(&sp6C, &lItem->dim.worldSphere.center); - - sp60.x = - (right->dim.quad[0].x + (right->dim.quad[1].x + (right->dim.quad[3].x + right->dim.quad[2].x))) * - (1.0f / 4); - sp60.y = - (right->dim.quad[0].y + (right->dim.quad[1].y + (right->dim.quad[3].y + right->dim.quad[2].y))) * - (1.0f / 4); - sp60.z = - (right->dim.quad[0].z + (right->dim.quad[1].z + (right->dim.quad[3].z + right->dim.quad[2].z))) * - (1.0f / 4); - func_8005E81C(globalCtx, &left->base, &lItem->body, &sp6C, &right->base, &right->body, &sp60, &sp7C); + if (Math3D_TriVsSphIntersect(&atItem->dim.worldSphere, &D_8015E230, &hitPos) == 1 || + Math3D_TriVsSphIntersect(&atItem->dim.worldSphere, &D_8015E268, &hitPos) == 1) { + Vec3f atPos; + Vec3f acPos; + + Math_Vec3s_ToVec3f(&atPos, &atItem->dim.worldSphere.center); + + acPos.x = (ac->dim.quad[0].x + (ac->dim.quad[1].x + (ac->dim.quad[3].x + ac->dim.quad[2].x))) / 4.0f; + acPos.y = (ac->dim.quad[0].y + (ac->dim.quad[1].y + (ac->dim.quad[3].y + ac->dim.quad[2].y))) / 4.0f; + acPos.z = (ac->dim.quad[0].z + (ac->dim.quad[1].z + (ac->dim.quad[3].z + ac->dim.quad[2].z))) / 4.0f; + + CollisionCheck_SetATvsAC(globalCtx, &at->base, &atItem->info, &atPos, &ac->base, &ac->info, &acPos, + &hitPos); return; } } } } -static TriNorm D_8015E2A0; -static TriNorm D_8015E2D8; - -void CollisionCheck_AC_QuadVsJntSph(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* l, - Collider* r) { - ColliderJntSph* right = (ColliderJntSph*)r; - Vec3f sp88; - ColliderQuad* left = (ColliderQuad*)l; - ColliderJntSphItem* rItem; - Vec3f sp74; - Vec3f sp68; - - if (right->count > 0 && right->list != NULL) { - if (func_8005DF2C(&left->body) != 1) { - Math3D_TriNorm(&D_8015E2A0, &left->dim.quad[2], &left->dim.quad[3], &left->dim.quad[1]); - Math3D_TriNorm(&D_8015E2D8, &left->dim.quad[2], &left->dim.quad[1], &left->dim.quad[0]); - for (rItem = right->list; rItem < right->list + right->count; rItem++) { - if (func_8005DF50(&rItem->body) == 1) { - continue; - } - if (func_8005DF74(&left->body, &rItem->body) == 1) { - continue; - } - if (Math3D_TriVsSphIntersect(&rItem->dim.worldSphere, &D_8015E2A0, &sp88) != 1 && - Math3D_TriVsSphIntersect(&rItem->dim.worldSphere, &D_8015E2D8, &sp88) != 1) { - continue; - } - if (func_8005D218(globalCtx, left, &sp88) != 0) { - sp68.x = rItem->dim.worldSphere.center.x; - sp68.y = rItem->dim.worldSphere.center.y; - sp68.z = rItem->dim.worldSphere.center.z; - - sp74.x = - (left->dim.quad[0].x + (left->dim.quad[1].x + (left->dim.quad[3].x + left->dim.quad[2].x))) * - (1.0f / 4); - sp74.y = - (left->dim.quad[0].y + (left->dim.quad[1].y + (left->dim.quad[3].y + left->dim.quad[2].y))) * - (1.0f / 4); - sp74.z = - (left->dim.quad[0].z + (left->dim.quad[1].z + (left->dim.quad[3].z + left->dim.quad[2].z))) * - (1.0f / 4); - func_8005E81C(globalCtx, &left->base, &left->body, &sp74, &right->base, &rItem->body, &sp68, &sp88); - if ((right->base.maskB & 0x40) == 0) { +/** + * AC overlap check. Calculates the center of each collider element and the point of contact. + */ +void CollisionCheck_AC_QuadVsJntSph(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* colAT, + Collider* colAC) { + static TriNorm D_8015E2A0; + static TriNorm D_8015E2D8; + ColliderJntSph* ac = (ColliderJntSph*)colAC; + Vec3f hitPos; + ColliderQuad* at = (ColliderQuad*)colAT; + ColliderJntSphElement* acElem; + + if (ac->count > 0 && ac->elements != NULL) { + if (CollisionCheck_SkipTouch(&at->info) == 1) { + return; + } + Math3D_TriNorm(&D_8015E2A0, &at->dim.quad[2], &at->dim.quad[3], &at->dim.quad[1]); + Math3D_TriNorm(&D_8015E2D8, &at->dim.quad[2], &at->dim.quad[1], &at->dim.quad[0]); + for (acElem = ac->elements; acElem < ac->elements + ac->count; acElem++) { + if (CollisionCheck_SkipBump(&acElem->info) == 1) { + continue; + } + if (CollisionCheck_NoSharedFlags(&at->info, &acElem->info) == 1) { + continue; + } + if (Math3D_TriVsSphIntersect(&acElem->dim.worldSphere, &D_8015E2A0, &hitPos) == 1 || + Math3D_TriVsSphIntersect(&acElem->dim.worldSphere, &D_8015E2D8, &hitPos) == 1) { + if (Collider_QuadSetNearestAC(globalCtx, at, &hitPos)) { + Vec3f atPos; + Vec3f acPos; + + acPos.x = acElem->dim.worldSphere.center.x; + acPos.y = acElem->dim.worldSphere.center.y; + acPos.z = acElem->dim.worldSphere.center.z; + + atPos.x = + (at->dim.quad[0].x + (at->dim.quad[1].x + (at->dim.quad[3].x + at->dim.quad[2].x))) / 4.0f; + atPos.y = + (at->dim.quad[0].y + (at->dim.quad[1].y + (at->dim.quad[3].y + at->dim.quad[2].y))) / 4.0f; + atPos.z = + (at->dim.quad[0].z + (at->dim.quad[1].z + (at->dim.quad[3].z + at->dim.quad[2].z))) / 4.0f; + CollisionCheck_SetATvsAC(globalCtx, &at->base, &at->info, &atPos, &ac->base, &acElem->info, &acPos, + &hitPos); + if (!(ac->base.ocFlags2 & OC2_FIRST_ONLY)) { return; } } @@ -1885,152 +2096,163 @@ void CollisionCheck_AC_QuadVsJntSph(GlobalContext* globalCtx, CollisionCheckCont } } -void CollisionCheck_AC_CylVsCyl(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* l, Collider* r) { - ColliderCylinder* left = (ColliderCylinder*)l; - ColliderCylinder* right = (ColliderCylinder*)r; - f32 sp6C; - f32 sp68; - Vec3f sp5C; - Vec3f sp50; - Vec3f sp44; - f32 temp_f0; - - if (left->dim.radius <= 0 || left->dim.height <= 0 || right->dim.radius <= 0 || right->dim.height <= 0) { - return; - } - if (func_8005DF50(&right->body) == 1) { - return; - } - if (func_8005DF2C(&left->body) == 1) { - return; - } - if (func_8005DF74(&left->body, &right->body) == 1) { - return; - } - if (Math3D_CylOutsideCylDist(&left->dim, &right->dim, &sp6C, &sp68) == 1) { - Math_Vec3s_ToVec3f(&sp50, &left->dim.pos); - Math_Vec3s_ToVec3f(&sp44, &right->dim.pos); - if (!IS_ZERO(sp68)) { - temp_f0 = (f32)right->dim.radius / sp68; - sp5C.y = (f32)right->dim.pos.y + (f32)right->dim.yShift + (f32)right->dim.height * 0.5f; - sp5C.x = ((f32)left->dim.pos.x - right->dim.pos.x) * temp_f0 + right->dim.pos.x; - sp5C.z = ((f32)left->dim.pos.z - right->dim.pos.z) * temp_f0 + right->dim.pos.z; - } else { - Math_Vec3s_ToVec3f(&sp5C, &right->dim.pos); +/** + * AC overlap check. Calculates the center of each collider element and the point of contact. + */ +void CollisionCheck_AC_CylVsCyl(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* colAT, + Collider* colAC) { + ColliderCylinder* at = (ColliderCylinder*)colAT; + ColliderCylinder* ac = (ColliderCylinder*)colAC; + f32 deadSpace; + f32 centerDistXZ; + Vec3f hitPos; + + if (at->dim.radius > 0 && at->dim.height > 0 && ac->dim.radius > 0 && ac->dim.height > 0) { + if (CollisionCheck_SkipBump(&ac->info) == 1) { + return; + } + if (CollisionCheck_SkipTouch(&at->info) == 1) { + return; + } + if (CollisionCheck_NoSharedFlags(&at->info, &ac->info) == 1) { + return; + } + if (Math3D_CylOutsideCylDist(&at->dim, &ac->dim, &deadSpace, ¢erDistXZ) == 1) { + Vec3f atPos; + Vec3f acPos; + f32 acToHit; + + Math_Vec3s_ToVec3f(&atPos, &at->dim.pos); + Math_Vec3s_ToVec3f(&acPos, &ac->dim.pos); + if (!IS_ZERO(centerDistXZ)) { + acToHit = ac->dim.radius / centerDistXZ; + hitPos.y = (f32)ac->dim.pos.y + ac->dim.yShift + ac->dim.height * 0.5f; + hitPos.x = ((f32)at->dim.pos.x - ac->dim.pos.x) * acToHit + ac->dim.pos.x; + hitPos.z = ((f32)at->dim.pos.z - ac->dim.pos.z) * acToHit + ac->dim.pos.z; + } else { + Math_Vec3s_ToVec3f(&hitPos, &ac->dim.pos); + } + CollisionCheck_SetATvsAC(globalCtx, &at->base, &at->info, &atPos, &ac->base, &ac->info, &acPos, &hitPos); } - func_8005E81C(globalCtx, &left->base, &left->body, &sp50, &right->base, &right->body, &sp44, &sp5C); } } -void CollisionCheck_AC_CylVsTris(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* l, Collider* r) { - ColliderCylinder* left = (ColliderCylinder*)l; - ColliderTris* right = (ColliderTris*)r; - ColliderTrisItem* rItem; - Vec3f sp68; - Vec3f sp5C; - Vec3f sp50; - - if (left->dim.radius > 0 && left->dim.height > 0 && right->count > 0 && right->list != NULL) { - if (func_8005DF2C(&left->body) == 1) { +/** + * AC overlap check. Calculates the center of each collider element and the point of contact. + */ +void CollisionCheck_AC_CylVsTris(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* colAT, + Collider* colAC) { + ColliderCylinder* at = (ColliderCylinder*)colAT; + ColliderTris* ac = (ColliderTris*)colAC; + ColliderTrisElement* acElem; + Vec3f hitPos; + + if (at->dim.radius > 0 && at->dim.height > 0 && ac->count > 0 && ac->elements != NULL) { + if (CollisionCheck_SkipTouch(&at->info) == 1) { return; } - for (rItem = right->list; rItem < right->list + right->count; rItem++) { - if (func_8005DF50(&rItem->body) == 1) { + for (acElem = ac->elements; acElem < ac->elements + ac->count; acElem++) { + if (CollisionCheck_SkipBump(&acElem->info) == 1) { continue; } - if (func_8005DF74(&left->body, &rItem->body) == 1) { + if (CollisionCheck_NoSharedFlags(&at->info, &acElem->info) == 1) { continue; } - if (Math3D_CylTriVsIntersect(&left->dim, &rItem->dim, &sp68) == 1) { - Math_Vec3s_ToVec3f(&sp5C, &left->dim.pos); + if (Math3D_CylTriVsIntersect(&at->dim, &acElem->dim, &hitPos) == 1) { + Vec3f atpos; + Vec3f acPos; - sp50.x = (rItem->dim.vtx[0].x + rItem->dim.vtx[1].x + rItem->dim.vtx[2].x) * (1.0f / 3); - sp50.y = (rItem->dim.vtx[0].y + rItem->dim.vtx[1].y + rItem->dim.vtx[2].y) * (1.0f / 3); - sp50.z = (rItem->dim.vtx[0].z + rItem->dim.vtx[1].z + rItem->dim.vtx[2].z) * (1.0f / 3); - func_8005E81C(globalCtx, &left->base, &left->body, &sp5C, &right->base, &rItem->body, &sp50, &sp68); + Math_Vec3s_ToVec3f(&atpos, &at->dim.pos); + + acPos.x = (acElem->dim.vtx[0].x + acElem->dim.vtx[1].x + acElem->dim.vtx[2].x) * (1.0f / 3); + acPos.y = (acElem->dim.vtx[0].y + acElem->dim.vtx[1].y + acElem->dim.vtx[2].y) * (1.0f / 3); + acPos.z = (acElem->dim.vtx[0].z + acElem->dim.vtx[1].z + acElem->dim.vtx[2].z) * (1.0f / 3); + CollisionCheck_SetATvsAC(globalCtx, &at->base, &at->info, &atpos, &ac->base, &acElem->info, &acPos, + &hitPos); return; } } } } -static Vec3f D_8015E310; - -void CollisionCheck_AC_TrisVsCyl(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* l, Collider* r) { - ColliderTris* left = (ColliderTris*)l; - ColliderCylinder* right = (ColliderCylinder*)r; - ColliderTrisItem* lItem; - Vec3f sp60; - Vec3f sp54; - - if (right->dim.radius > 0 && right->dim.height > 0 && left->count > 0 && left->list != NULL) { - if (func_8005DF50(&right->body) == 1) { +/** + * AC overlap check. Calculates the center of each collider element and the point of contact. + */ +void CollisionCheck_AC_TrisVsCyl(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* colAT, + Collider* colAC) { + static Vec3f D_8015E310; + ColliderTris* at = (ColliderTris*)colAT; + ColliderTrisElement* atItem; + ColliderCylinder* ac = (ColliderCylinder*)colAC; + Vec3f atPos; + Vec3f acPos; + + if (ac->dim.radius > 0 && ac->dim.height > 0 && at->count > 0 && at->elements != NULL) { + if (CollisionCheck_SkipBump(&ac->info) == 1) { return; } - for (lItem = left->list; lItem < left->list + left->count; lItem++) { - if (func_8005DF2C(&lItem->body) == 1) { + for (atItem = at->elements; atItem < at->elements + at->count; atItem++) { + if (CollisionCheck_SkipTouch(&atItem->info) == 1) { continue; } - if (func_8005DF74(&lItem->body, &right->body) == 1) { + if (CollisionCheck_NoSharedFlags(&atItem->info, &ac->info) == 1) { continue; } - if (Math3D_CylTriVsIntersect(&right->dim, &lItem->dim, &D_8015E310) == 1) { - sp60.x = (lItem->dim.vtx[0].x + lItem->dim.vtx[1].x + lItem->dim.vtx[2].x) * (1.0f / 3); - sp60.y = (lItem->dim.vtx[0].y + lItem->dim.vtx[1].y + lItem->dim.vtx[2].y) * (1.0f / 3); - sp60.z = (lItem->dim.vtx[0].z + lItem->dim.vtx[1].z + lItem->dim.vtx[2].z) * (1.0f / 3); - Math_Vec3s_ToVec3f(&sp54, &right->dim.pos); - func_8005E81C(globalCtx, &left->base, &lItem->body, &sp60, &right->base, &right->body, &sp54, - &D_8015E310); + if (Math3D_CylTriVsIntersect(&ac->dim, &atItem->dim, &D_8015E310) == 1) { + atPos.x = (atItem->dim.vtx[0].x + atItem->dim.vtx[1].x + atItem->dim.vtx[2].x) * (1.0f / 3); + atPos.y = (atItem->dim.vtx[0].y + atItem->dim.vtx[1].y + atItem->dim.vtx[2].y) * (1.0f / 3); + atPos.z = (atItem->dim.vtx[0].z + atItem->dim.vtx[1].z + atItem->dim.vtx[2].z) * (1.0f / 3); + Math_Vec3s_ToVec3f(&acPos, &ac->dim.pos); + CollisionCheck_SetATvsAC(globalCtx, &at->base, &atItem->info, &atPos, &ac->base, &ac->info, &acPos, + &D_8015E310); return; } } } } -static TriNorm D_8015E320; -static TriNorm D_8015E358; -static Vec3f D_8015E390; +/** + * AC overlap check. Calculates the center of each collider element and the point of contact. + */ +void CollisionCheck_AC_CylVsQuad(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* colAT, + Collider* colAC) { + static TriNorm D_8015E320; + static TriNorm D_8015E358; + static Vec3f D_8015E390; + ColliderCylinder* at = (ColliderCylinder*)colAT; + ColliderQuad* ac = (ColliderQuad*)colAC; + + if (at->dim.height > 0 && at->dim.radius > 0) { + if (CollisionCheck_SkipTouch(&at->info) == 1 || CollisionCheck_SkipBump(&ac->info) == 1) { + return; + } + if (CollisionCheck_NoSharedFlags(&at->info, &ac->info) == 1) { + return; + } + Math3D_TriNorm(&D_8015E320, &ac->dim.quad[2], &ac->dim.quad[3], &ac->dim.quad[1]); + Math3D_TriNorm(&D_8015E358, &ac->dim.quad[1], &ac->dim.quad[0], &ac->dim.quad[2]); + if (Math3D_CylTriVsIntersect(&at->dim, &D_8015E320, &D_8015E390) == 1) { + Vec3f atPos1; + Vec3f acPos1; -void CollisionCheck_AC_CylVsQuad(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* l, Collider* r) { - ColliderCylinder* left = (ColliderCylinder*)l; - ColliderQuad* right = (ColliderQuad*)r; - Vec3f sp64; - Vec3f sp58; - Vec3f sp4C; - Vec3f sp40; + Math_Vec3s_ToVec3f(&atPos1, &at->dim.pos); + acPos1.x = (ac->dim.quad[0].x + (ac->dim.quad[1].x + (ac->dim.quad[3].x + ac->dim.quad[2].x))) / 4.0f; + acPos1.y = (ac->dim.quad[0].y + (ac->dim.quad[1].y + (ac->dim.quad[3].y + ac->dim.quad[2].y))) / 4.0f; + acPos1.z = (ac->dim.quad[0].z + (ac->dim.quad[1].z + (ac->dim.quad[3].z + ac->dim.quad[2].z))) / 4.0f; + CollisionCheck_SetATvsAC(globalCtx, &at->base, &at->info, &atPos1, &ac->base, &ac->info, &acPos1, + &D_8015E390); + } else if (Math3D_CylTriVsIntersect(&at->dim, &D_8015E358, &D_8015E390) == 1) { + Vec3f atPos2; + Vec3f acPos2; - if (left->dim.height <= 0 || left->dim.radius <= 0) { - return; - } - if (func_8005DF2C(&left->body) == 1 || func_8005DF50(&right->body) == 1) { - return; - } - if (func_8005DF74(&left->body, &right->body) == 1) { - return; - } - Math3D_TriNorm(&D_8015E320, &right->dim.quad[2], &right->dim.quad[3], &right->dim.quad[1]); - Math3D_TriNorm(&D_8015E358, &right->dim.quad[1], &right->dim.quad[0], &right->dim.quad[2]); - if (Math3D_CylTriVsIntersect(&left->dim, &D_8015E320, &D_8015E390) == 1) { - Math_Vec3s_ToVec3f(&sp64, &left->dim.pos); - sp58.x = - (right->dim.quad[0].x + (right->dim.quad[1].x + (right->dim.quad[3].x + right->dim.quad[2].x))) * 0.25f; - sp58.y = - (right->dim.quad[0].y + (right->dim.quad[1].y + (right->dim.quad[3].y + right->dim.quad[2].y))) * 0.25f; - sp58.z = - (right->dim.quad[0].z + (right->dim.quad[1].z + (right->dim.quad[3].z + right->dim.quad[2].z))) * 0.25f; - func_8005E81C(globalCtx, &left->base, &left->body, &sp64, &right->base, &right->body, &sp58, &D_8015E390); - return; - } - if (Math3D_CylTriVsIntersect(&left->dim, &D_8015E358, &D_8015E390) == 1) { - Math_Vec3s_ToVec3f(&sp4C, &left->dim.pos); - sp40.x = (right->dim.quad[0].x + (right->dim.quad[1].x + (right->dim.quad[3].x + right->dim.quad[2].x))) * - (1.0f / 4); - sp40.y = (right->dim.quad[0].y + (right->dim.quad[1].y + (right->dim.quad[3].y + right->dim.quad[2].y))) * - (1.0f / 4); - sp40.z = (right->dim.quad[0].z + (right->dim.quad[1].z + (right->dim.quad[3].z + right->dim.quad[2].z))) * - (1.0f / 4); - func_8005E81C(globalCtx, &left->base, &left->body, &sp4C, &right->base, &right->body, &sp40, &D_8015E390); + Math_Vec3s_ToVec3f(&atPos2, &at->dim.pos); + acPos2.x = (ac->dim.quad[0].x + (ac->dim.quad[1].x + (ac->dim.quad[3].x + ac->dim.quad[2].x))) / 4.0f; + acPos2.y = (ac->dim.quad[0].y + (ac->dim.quad[1].y + (ac->dim.quad[3].y + ac->dim.quad[2].y))) / 4.0f; + acPos2.z = (ac->dim.quad[0].z + (ac->dim.quad[1].z + (ac->dim.quad[3].z + ac->dim.quad[2].z))) / 4.0f; + CollisionCheck_SetATvsAC(globalCtx, &at->base, &at->info, &atPos2, &ac->base, &ac->info, &acPos2, + &D_8015E390); + } } } @@ -2038,52 +2260,52 @@ static s8 sBssDummy0; static s8 sBssDummy1; static s8 sBssDummy2; -static TriNorm D_8015E3A0; -static TriNorm D_8015E3D8; -static Vec3f D_8015E410; - -void CollisionCheck_AC_QuadVsCyl(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* l, Collider* r) { - ColliderQuad* left = (ColliderQuad*)l; - ColliderCylinder* right = (ColliderCylinder*)r; - Vec3f sp64; - Vec3f sp58; - Vec3f sp4C; - Vec3f sp40; - - if (right->dim.height <= 0 || right->dim.radius <= 0) { - return; - } - if (func_8005DF50(&right->body) == 1 || func_8005DF2C(&left->body) == 1) { - return; - } - if (func_8005DF74(&left->body, &right->body) == 1) { - return; - } - Math3D_TriNorm(&D_8015E3A0, &left->dim.quad[2], &left->dim.quad[3], &left->dim.quad[1]); - Math3D_TriNorm(&D_8015E3D8, &left->dim.quad[2], &left->dim.quad[1], &left->dim.quad[0]); - if (Math3D_CylTriVsIntersect(&right->dim, &D_8015E3A0, &D_8015E410) == 1) { - if (func_8005D218(globalCtx, left, &D_8015E410) != 0) { - sp64.x = (left->dim.quad[0].x + (left->dim.quad[1].x + (left->dim.quad[3].x + left->dim.quad[2].x))) * - (1.0f / 4); - sp64.y = (left->dim.quad[0].y + (left->dim.quad[1].y + (left->dim.quad[3].y + left->dim.quad[2].y))) * - (1.0f / 4); - sp64.z = (left->dim.quad[0].z + (left->dim.quad[1].z + (left->dim.quad[3].z + left->dim.quad[2].z))) * - (1.0f / 4); - Math_Vec3s_ToVec3f(&sp58, &right->dim.pos); - func_8005E81C(globalCtx, &left->base, &left->body, &sp64, &right->base, &right->body, &sp58, &D_8015E410); +/** + * AC overlap check. Calculates the center of each collider element and the point of contact. + */ +void CollisionCheck_AC_QuadVsCyl(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* colAT, + Collider* colAC) { + static TriNorm D_8015E3A0; + static TriNorm D_8015E3D8; + static Vec3f D_8015E410; + ColliderQuad* at = (ColliderQuad*)colAT; + ColliderCylinder* ac = (ColliderCylinder*)colAC; + + if (ac->dim.height > 0 && ac->dim.radius > 0) { + if (CollisionCheck_SkipBump(&ac->info) == 1 || CollisionCheck_SkipTouch(&at->info) == 1) { return; } - } - if (Math3D_CylTriVsIntersect(&right->dim, &D_8015E3D8, &D_8015E410) == 1) { - if (func_8005D218(globalCtx, left, &D_8015E410) != 0) { - sp4C.x = (left->dim.quad[0].x + (left->dim.quad[1].x + (left->dim.quad[3].x + left->dim.quad[2].x))) * - (1.0f / 4); - sp4C.y = (left->dim.quad[0].y + (left->dim.quad[1].y + (left->dim.quad[3].y + left->dim.quad[2].y))) * - (1.0f / 4); - sp4C.z = (left->dim.quad[0].z + (left->dim.quad[1].z + (left->dim.quad[3].z + left->dim.quad[2].z))) * - (1.0f / 4); - Math_Vec3s_ToVec3f(&sp40, &right->dim.pos); - func_8005E81C(globalCtx, &left->base, &left->body, &sp4C, &right->base, &right->body, &sp40, &D_8015E410); + if (CollisionCheck_NoSharedFlags(&at->info, &ac->info) == 1) { + return; + } + Math3D_TriNorm(&D_8015E3A0, &at->dim.quad[2], &at->dim.quad[3], &at->dim.quad[1]); + Math3D_TriNorm(&D_8015E3D8, &at->dim.quad[2], &at->dim.quad[1], &at->dim.quad[0]); + if (Math3D_CylTriVsIntersect(&ac->dim, &D_8015E3A0, &D_8015E410) == 1) { + if (Collider_QuadSetNearestAC(globalCtx, at, &D_8015E410)) { + Vec3f atPos1; + Vec3f acPos1; + + atPos1.x = (at->dim.quad[0].x + (at->dim.quad[1].x + (at->dim.quad[3].x + at->dim.quad[2].x))) / 4.0f; + atPos1.y = (at->dim.quad[0].y + (at->dim.quad[1].y + (at->dim.quad[3].y + at->dim.quad[2].y))) / 4.0f; + atPos1.z = (at->dim.quad[0].z + (at->dim.quad[1].z + (at->dim.quad[3].z + at->dim.quad[2].z))) / 4.0f; + Math_Vec3s_ToVec3f(&acPos1, &ac->dim.pos); + CollisionCheck_SetATvsAC(globalCtx, &at->base, &at->info, &atPos1, &ac->base, &ac->info, &acPos1, + &D_8015E410); + return; + } + } + if (Math3D_CylTriVsIntersect(&ac->dim, &D_8015E3D8, &D_8015E410) == 1) { + if (Collider_QuadSetNearestAC(globalCtx, at, &D_8015E410)) { + Vec3f atPos2; + Vec3f acPos2; + + atPos2.x = (at->dim.quad[0].x + (at->dim.quad[1].x + (at->dim.quad[3].x + at->dim.quad[2].x))) / 4.0f; + atPos2.y = (at->dim.quad[0].y + (at->dim.quad[1].y + (at->dim.quad[3].y + at->dim.quad[2].y))) / 4.0f; + atPos2.z = (at->dim.quad[0].z + (at->dim.quad[1].z + (at->dim.quad[3].z + at->dim.quad[2].z))) / 4.0f; + Math_Vec3s_ToVec3f(&acPos2, &ac->dim.pos); + CollisionCheck_SetATvsAC(globalCtx, &at->base, &at->info, &atPos2, &ac->base, &ac->info, &acPos2, + &D_8015E410); + } } } } @@ -2093,39 +2315,41 @@ static s8 sBssDummy4; static s8 sBssDummy5; static s8 sBssDummy6; -static Vec3f D_8015E420; - -void CollisionCheck_AC_TrisVsTris(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* l, - Collider* r) { - ColliderTris* left = (ColliderTris*)l; - ColliderTris* right = (ColliderTris*)r; - ColliderTrisItem* lItem; - ColliderTrisItem* rItem; - - Vec3f sp5C; - Vec3f sp50; - - if (right->count > 0 && right->list != NULL && left->count > 0 && left->list != NULL) { - for (rItem = right->list; rItem < right->list + right->count; rItem++) { - if (func_8005DF50(&rItem->body) == 1) { +/** + * AC overlap check. Calculates the center of each collider element and the point of contact. + */ +void CollisionCheck_AC_TrisVsTris(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* colAT, + Collider* colAC) { + static Vec3f D_8015E420; + ColliderTris* at = (ColliderTris*)colAT; + ColliderTrisElement* atItem; + ColliderTris* ac = (ColliderTris*)colAC; + ColliderTrisElement* acElem; + + if (ac->count > 0 && ac->elements != NULL && at->count > 0 && at->elements != NULL) { + for (acElem = ac->elements; acElem < ac->elements + ac->count; acElem++) { + if (CollisionCheck_SkipBump(&acElem->info) == 1) { continue; } - for (lItem = left->list; lItem < left->list + left->count; lItem++) { - if (func_8005DF2C(&lItem->body) == 1) { + for (atItem = at->elements; atItem < at->elements + at->count; atItem++) { + if (CollisionCheck_SkipTouch(&atItem->info) == 1) { continue; } - if (func_8005DF74(&lItem->body, &rItem->body) == 1) { + if (CollisionCheck_NoSharedFlags(&atItem->info, &acElem->info) == 1) { continue; } - if (Math3D_TriVsTriIntersect(&lItem->dim, &rItem->dim, &D_8015E420) == 1) { - sp5C.x = (lItem->dim.vtx[0].x + lItem->dim.vtx[1].x + lItem->dim.vtx[2].x) * (1.0f / 3); - sp5C.y = (lItem->dim.vtx[0].y + lItem->dim.vtx[1].y + lItem->dim.vtx[2].y) * (1.0f / 3); - sp5C.z = (lItem->dim.vtx[0].z + lItem->dim.vtx[1].z + lItem->dim.vtx[2].z) * (1.0f / 3); - sp50.x = (rItem->dim.vtx[0].x + rItem->dim.vtx[1].x + rItem->dim.vtx[2].x) * (1.0f / 3); - sp50.y = (rItem->dim.vtx[0].y + rItem->dim.vtx[1].y + rItem->dim.vtx[2].y) * (1.0f / 3); - sp50.z = (rItem->dim.vtx[0].z + rItem->dim.vtx[1].z + rItem->dim.vtx[2].z) * (1.0f / 3); - func_8005E81C(globalCtx, &left->base, &lItem->body, &sp5C, &right->base, &rItem->body, &sp50, - &D_8015E420); + if (Math3D_TriVsTriIntersect(&atItem->dim, &acElem->dim, &D_8015E420) == 1) { + Vec3f atPos; + Vec3f acPos; + + atPos.x = (atItem->dim.vtx[0].x + atItem->dim.vtx[1].x + atItem->dim.vtx[2].x) * (1.0f / 3); + atPos.y = (atItem->dim.vtx[0].y + atItem->dim.vtx[1].y + atItem->dim.vtx[2].y) * (1.0f / 3); + atPos.z = (atItem->dim.vtx[0].z + atItem->dim.vtx[1].z + atItem->dim.vtx[2].z) * (1.0f / 3); + acPos.x = (acElem->dim.vtx[0].x + acElem->dim.vtx[1].x + acElem->dim.vtx[2].x) * (1.0f / 3); + acPos.y = (acElem->dim.vtx[0].y + acElem->dim.vtx[1].y + acElem->dim.vtx[2].y) * (1.0f / 3); + acPos.z = (acElem->dim.vtx[0].z + acElem->dim.vtx[1].z + acElem->dim.vtx[2].z) * (1.0f / 3); + CollisionCheck_SetATvsAC(globalCtx, &at->base, &atItem->info, &atPos, &ac->base, &acElem->info, + &acPos, &D_8015E420); return; } } @@ -2138,150 +2362,146 @@ static s8 sBssDummy8; static s8 sBssDummy9; static s8 sBssDummy10; -static Vec3f D_8015E430; -static TriNorm D_8015E440; -static TriNorm D_8015E478; - -void CollisionCheck_AC_TrisVsQuad(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* l, - Collider* r) { - ColliderTris* left = (ColliderTris*)l; - ColliderQuad* right = (ColliderQuad*)r; - ColliderTrisItem* lItem; - Vec3f sp68; - Vec3f sp5C; - - if (left->count > 0 && left->list != NULL) { - if (func_8005DF50(&right->body) != 1) { - Math3D_TriNorm(&D_8015E440, &right->dim.quad[2], &right->dim.quad[3], &right->dim.quad[1]); - Math3D_TriNorm(&D_8015E478, &right->dim.quad[1], &right->dim.quad[0], &right->dim.quad[2]); - for (lItem = left->list; lItem < left->list + left->count; lItem++) { - if (func_8005DF2C(&lItem->body) == 1) { - continue; - } - if (func_8005DF74(&lItem->body, &right->body) == 1) { - continue; - } - if (Math3D_TriVsTriIntersect(&D_8015E440, &lItem->dim, &D_8015E430) == 1 || - Math3D_TriVsTriIntersect(&D_8015E478, &lItem->dim, &D_8015E430) == 1) { - sp68.x = (lItem->dim.vtx[0].x + lItem->dim.vtx[1].x + lItem->dim.vtx[2].x) * (1.0f / 3); - sp68.y = (lItem->dim.vtx[0].y + lItem->dim.vtx[1].y + lItem->dim.vtx[2].y) * (1.0f / 3); - sp68.z = (lItem->dim.vtx[0].z + lItem->dim.vtx[1].z + lItem->dim.vtx[2].z) * (1.0f / 3); - sp5C.x = (right->dim.quad[0].x + - (right->dim.quad[1].x + (right->dim.quad[3].x + right->dim.quad[2].x))) * - (1.0f / 4); - sp5C.y = (right->dim.quad[0].y + - (right->dim.quad[1].y + (right->dim.quad[3].y + right->dim.quad[2].y))) * - (1.0f / 4); - sp5C.z = (right->dim.quad[0].z + - (right->dim.quad[1].z + (right->dim.quad[3].z + right->dim.quad[2].z))) * - (1.0f / 4); - func_8005E81C(globalCtx, &left->base, &lItem->body, &sp68, &right->base, &right->body, &sp5C, - &D_8015E430); - return; - } +/** + * AC overlap check. Calculates the center of each collider element and the point of contact. + */ +void CollisionCheck_AC_TrisVsQuad(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* colAT, + Collider* colAC) { + static Vec3f D_8015E430; + static TriNorm D_8015E440; + static TriNorm D_8015E478; + ColliderTris* at = (ColliderTris*)colAT; + ColliderTrisElement* atItem; + ColliderQuad* ac = (ColliderQuad*)colAC; + + if (at->count > 0 && at->elements != NULL) { + if (CollisionCheck_SkipBump(&ac->info) == 1) { + return; + } + Math3D_TriNorm(&D_8015E440, &ac->dim.quad[2], &ac->dim.quad[3], &ac->dim.quad[1]); + Math3D_TriNorm(&D_8015E478, &ac->dim.quad[1], &ac->dim.quad[0], &ac->dim.quad[2]); + for (atItem = at->elements; atItem < at->elements + at->count; atItem++) { + if (CollisionCheck_SkipTouch(&atItem->info) == 1) { + continue; + } + if (CollisionCheck_NoSharedFlags(&atItem->info, &ac->info) == 1) { + continue; + } + if (Math3D_TriVsTriIntersect(&D_8015E440, &atItem->dim, &D_8015E430) == 1 || + Math3D_TriVsTriIntersect(&D_8015E478, &atItem->dim, &D_8015E430) == 1) { + Vec3f atPos; + Vec3f acPos; + + atPos.x = (atItem->dim.vtx[0].x + atItem->dim.vtx[1].x + atItem->dim.vtx[2].x) * (1.0f / 3); + atPos.y = (atItem->dim.vtx[0].y + atItem->dim.vtx[1].y + atItem->dim.vtx[2].y) * (1.0f / 3); + atPos.z = (atItem->dim.vtx[0].z + atItem->dim.vtx[1].z + atItem->dim.vtx[2].z) * (1.0f / 3); + acPos.x = (ac->dim.quad[0].x + (ac->dim.quad[1].x + (ac->dim.quad[3].x + ac->dim.quad[2].x))) / 4.0f; + acPos.y = (ac->dim.quad[0].y + (ac->dim.quad[1].y + (ac->dim.quad[3].y + ac->dim.quad[2].y))) / 4.0f; + acPos.z = (ac->dim.quad[0].z + (ac->dim.quad[1].z + (ac->dim.quad[3].z + ac->dim.quad[2].z))) / 4.0f; + CollisionCheck_SetATvsAC(globalCtx, &at->base, &atItem->info, &atPos, &ac->base, &ac->info, &acPos, + &D_8015E430); + return; } } } } -static Vec3f D_8015E4B0; -static TriNorm D_8015E4C0; -static TriNorm D_8015E4F8; - -void CollisionCheck_AC_QuadVsTris(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* l, - Collider* r) { - ColliderQuad* left = (ColliderQuad*)l; - ColliderTris* right = (ColliderTris*)r; - ColliderTrisItem* rItem; - Vec3f sp68; - Vec3f sp5C; - - if (right->count > 0 && right->list != NULL) { - if (func_8005DF2C(&left->body) != 1) { - Math3D_TriNorm(&D_8015E4C0, &left->dim.quad[2], &left->dim.quad[3], &left->dim.quad[1]); - Math3D_TriNorm(&D_8015E4F8, &left->dim.quad[1], &left->dim.quad[0], &left->dim.quad[2]); - for (rItem = right->list; rItem < right->list + right->count; rItem++) { - if (func_8005DF50(&rItem->body) == 1) { - continue; - } - if (func_8005DF74(&left->body, &rItem->body) == 1) { - continue; - } - if (Math3D_TriVsTriIntersect(&D_8015E4C0, &rItem->dim, &D_8015E4B0) == 1 || - Math3D_TriVsTriIntersect(&D_8015E4F8, &rItem->dim, &D_8015E4B0) == 1) { - if (func_8005D218(globalCtx, left, &D_8015E4B0) != 0) { - sp5C.x = (rItem->dim.vtx[0].x + rItem->dim.vtx[1].x + rItem->dim.vtx[2].x) * (1.0f / 3); - sp5C.y = (rItem->dim.vtx[0].y + rItem->dim.vtx[1].y + rItem->dim.vtx[2].y) * (1.0f / 3); - sp5C.z = (rItem->dim.vtx[0].z + rItem->dim.vtx[1].z + rItem->dim.vtx[2].z) * (1.0f / 3); - sp68.x = (left->dim.quad[0].x + - (left->dim.quad[1].x + (left->dim.quad[3].x + left->dim.quad[2].x))) * - (1.0f / 4); - sp68.y = (left->dim.quad[0].y + - (left->dim.quad[1].y + (left->dim.quad[3].y + left->dim.quad[2].y))) * - (1.0f / 4); - sp68.z = (left->dim.quad[0].z + - (left->dim.quad[1].z + (left->dim.quad[3].z + left->dim.quad[2].z))) * - (1.0f / 4); - func_8005E81C(globalCtx, &left->base, &left->body, &sp68, &right->base, &rItem->body, &sp5C, - &D_8015E4B0); - return; - } +/** + * AC overlap check. Calculates the center of each collider element and the point of contact. + */ +void CollisionCheck_AC_QuadVsTris(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* colAT, + Collider* colAC) { + static Vec3f D_8015E4B0; + static TriNorm D_8015E4C0; + static TriNorm D_8015E4F8; + ColliderQuad* at = (ColliderQuad*)colAT; + ColliderTris* ac = (ColliderTris*)colAC; + ColliderTrisElement* acElem; + + if (ac->count > 0 && ac->elements != NULL) { + if (CollisionCheck_SkipTouch(&at->info) == 1) { + return; + } + Math3D_TriNorm(&D_8015E4C0, &at->dim.quad[2], &at->dim.quad[3], &at->dim.quad[1]); + Math3D_TriNorm(&D_8015E4F8, &at->dim.quad[1], &at->dim.quad[0], &at->dim.quad[2]); + for (acElem = ac->elements; acElem < ac->elements + ac->count; acElem++) { + if (CollisionCheck_SkipBump(&acElem->info) == 1) { + continue; + } + if (CollisionCheck_NoSharedFlags(&at->info, &acElem->info) == 1) { + continue; + } + if (Math3D_TriVsTriIntersect(&D_8015E4C0, &acElem->dim, &D_8015E4B0) == 1 || + Math3D_TriVsTriIntersect(&D_8015E4F8, &acElem->dim, &D_8015E4B0) == 1) { + if (Collider_QuadSetNearestAC(globalCtx, at, &D_8015E4B0)) { + Vec3f atPos; + Vec3f acPos; + + acPos.x = (acElem->dim.vtx[0].x + acElem->dim.vtx[1].x + acElem->dim.vtx[2].x) * (1.0f / 3); + acPos.y = (acElem->dim.vtx[0].y + acElem->dim.vtx[1].y + acElem->dim.vtx[2].y) * (1.0f / 3); + acPos.z = (acElem->dim.vtx[0].z + acElem->dim.vtx[1].z + acElem->dim.vtx[2].z) * (1.0f / 3); + atPos.x = + (at->dim.quad[0].x + (at->dim.quad[1].x + (at->dim.quad[3].x + at->dim.quad[2].x))) / 4.0f; + atPos.y = + (at->dim.quad[0].y + (at->dim.quad[1].y + (at->dim.quad[3].y + at->dim.quad[2].y))) / 4.0f; + atPos.z = + (at->dim.quad[0].z + (at->dim.quad[1].z + (at->dim.quad[3].z + at->dim.quad[2].z))) / 4.0f; + CollisionCheck_SetATvsAC(globalCtx, &at->base, &at->info, &atPos, &ac->base, &acElem->info, &acPos, + &D_8015E4B0); + return; } } } } } -static TriNorm D_8015E530[2]; -static Vec3f D_8015E598; -static TriNorm D_8015E5A8[2]; - -void CollisionCheck_AC_QuadVsQuad(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* l, - Collider* r) { - ColliderQuad* left = (ColliderQuad*)l; - ColliderQuad* right = (ColliderQuad*)r; +/** + * AC overlap check. Calculates the center of each collider element and the point of contact. + */ +void CollisionCheck_AC_QuadVsQuad(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* colAT, + Collider* colAC) { + static TriNorm D_8015E530[2]; + static Vec3f D_8015E598; + static TriNorm D_8015E5A8[2]; + ColliderQuad* at = (ColliderQuad*)colAT; + ColliderQuad* ac = (ColliderQuad*)colAC; s32 i; s32 j; - Vec3f sp6C; - Vec3f sp60; - if (func_8005DF2C(&left->body) == 1) { + if (CollisionCheck_SkipTouch(&at->info) == 1) { return; } - if (func_8005DF50(&right->body) == 1) { + if (CollisionCheck_SkipBump(&ac->info) == 1) { return; } - if (func_8005DF74(&left->body, &right->body) == 1) { + if (CollisionCheck_NoSharedFlags(&at->info, &ac->info) == 1) { return; } - Math3D_TriNorm(&D_8015E5A8[0], &left->dim.quad[2], &left->dim.quad[3], &left->dim.quad[1]); - Math3D_TriNorm(&D_8015E5A8[1], &left->dim.quad[2], &left->dim.quad[1], &left->dim.quad[0]); - Math3D_TriNorm(&D_8015E530[0], &right->dim.quad[2], &right->dim.quad[3], &right->dim.quad[1]); - Math3D_TriNorm(&D_8015E530[1], &right->dim.quad[2], &right->dim.quad[1], &right->dim.quad[0]); + Math3D_TriNorm(&D_8015E5A8[0], &at->dim.quad[2], &at->dim.quad[3], &at->dim.quad[1]); + Math3D_TriNorm(&D_8015E5A8[1], &at->dim.quad[2], &at->dim.quad[1], &at->dim.quad[0]); + Math3D_TriNorm(&D_8015E530[0], &ac->dim.quad[2], &ac->dim.quad[3], &ac->dim.quad[1]); + Math3D_TriNorm(&D_8015E530[1], &ac->dim.quad[2], &ac->dim.quad[1], &ac->dim.quad[0]); for (i = 0; i < 2; i++) { for (j = 0; j < 2; j++) { if (Math3D_TriVsTriIntersect(&D_8015E5A8[j], &D_8015E530[i], &D_8015E598) == 1) { - if (func_8005D218(globalCtx, left, &D_8015E598) != 0) { - sp6C.x = - (left->dim.quad[0].x + (left->dim.quad[1].x + (left->dim.quad[3].x + left->dim.quad[2].x))) * - (1.0f / 4); - sp6C.y = - (left->dim.quad[0].y + (left->dim.quad[1].y + (left->dim.quad[3].y + left->dim.quad[2].y))) * - (1.0f / 4); - sp6C.z = - (left->dim.quad[0].z + (left->dim.quad[1].z + (left->dim.quad[3].z + left->dim.quad[2].z))) * - (1.0f / 4); - sp60.x = (right->dim.quad[0].x + - (right->dim.quad[1].x + (right->dim.quad[3].x + right->dim.quad[2].x))) * - (1.0f / 4); - sp60.y = (right->dim.quad[0].y + - (right->dim.quad[1].y + (right->dim.quad[3].y + right->dim.quad[2].y))) * - (1.0f / 4); - sp60.z = (right->dim.quad[0].z + - (right->dim.quad[1].z + (right->dim.quad[3].z + right->dim.quad[2].z))) * - (1.0f / 4); - func_8005E81C(globalCtx, &left->base, &left->body, &sp6C, &right->base, &right->body, &sp60, - &D_8015E598); + if (Collider_QuadSetNearestAC(globalCtx, at, &D_8015E598)) { + Vec3f atPos; + Vec3f acPos; + + atPos.x = + (at->dim.quad[0].x + (at->dim.quad[1].x + (at->dim.quad[3].x + at->dim.quad[2].x))) / 4.0f; + atPos.y = + (at->dim.quad[0].y + (at->dim.quad[1].y + (at->dim.quad[3].y + at->dim.quad[2].y))) / 4.0f; + atPos.z = + (at->dim.quad[0].z + (at->dim.quad[1].z + (at->dim.quad[3].z + at->dim.quad[2].z))) / 4.0f; + acPos.x = + (ac->dim.quad[0].x + (ac->dim.quad[1].x + (ac->dim.quad[3].x + ac->dim.quad[2].x))) / 4.0f; + acPos.y = + (ac->dim.quad[0].y + (ac->dim.quad[1].y + (ac->dim.quad[3].y + ac->dim.quad[2].y))) / 4.0f; + acPos.z = + (ac->dim.quad[0].z + (ac->dim.quad[1].z + (ac->dim.quad[3].z + ac->dim.quad[2].z))) / 4.0f; + CollisionCheck_SetATvsAC(globalCtx, &at->base, &at->info, &atPos, &ac->base, &ac->info, &acPos, + &D_8015E598); return; } } @@ -2289,174 +2509,184 @@ void CollisionCheck_AC_QuadVsQuad(GlobalContext* globalCtx, CollisionCheckContex } } -// D_8011DF5C ColliderJntSph -void func_80060EBC(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider) { - ColliderJntSph* col = (ColliderJntSph*)collider; - ColliderJntSphItem* item; - Vec3f sp24; - - for (item = col->list; item < col->list + col->count; item++) { - if (item->body.bumperFlags & 0x80) { - if (item->body.acHitItem != NULL) { - if (!(item->body.acHitItem->toucherFlags & 0x40)) { - Math_Vec3s_ToVec3f(&sp24, &item->body.bumper.unk_06); - func_8005E604(globalCtx, item->body.acHit, item->body.acHitItem, &col->base, &item->body, &sp24); - item->body.acHitItem->toucherFlags |= 0x40; - return; - } - } +/** + * Sets a ColliderJntSph's hit effects + */ +void CollisionCheck_SetJntSphHitFX(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider) { + ColliderJntSph* jntSph = (ColliderJntSph*)collider; + ColliderJntSphElement* element; + Vec3f hitPos; + + for (element = jntSph->elements; element < jntSph->elements + jntSph->count; element++) { + if ((element->info.bumperFlags & BUMP_DRAW_HITMARK) && (element->info.acHitInfo != NULL) && + !(element->info.acHitInfo->toucherFlags & TOUCH_DREW_HITMARK)) { + Math_Vec3s_ToVec3f(&hitPos, &element->info.bumper.hitPos); + CollisionCheck_HitEffects(globalCtx, element->info.acHit, element->info.acHitInfo, &jntSph->base, + &element->info, &hitPos); + element->info.acHitInfo->toucherFlags |= TOUCH_DREW_HITMARK; + return; } } } -// D_8011DF5C ColliderCylinder -void func_80060F94(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider) { - ColliderCylinder* item = (ColliderCylinder*)collider; - Vec3f sp28; +/** + * Sets a ColliderCylinder's hit effects + */ +void CollisionCheck_SetCylHitFX(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider) { + ColliderCylinder* cylinder = (ColliderCylinder*)collider; + Vec3f hitPos; - if (item->body.bumperFlags & 0x80) { - if (item->body.acHitItem != NULL) { - if (!(item->body.acHitItem->toucherFlags & 0x40)) { - Math_Vec3s_ToVec3f(&sp28, &item->body.bumper.unk_06); - func_8005E604(globalCtx, item->body.acHit, item->body.acHitItem, &item->base, &item->body, &sp28); - item->body.acHitItem->toucherFlags |= 0x40; - } + if ((cylinder->info.bumperFlags & BUMP_DRAW_HITMARK) && (cylinder->info.acHitInfo != NULL) && + !(cylinder->info.acHitInfo->toucherFlags & TOUCH_DREW_HITMARK)) { + Math_Vec3s_ToVec3f(&hitPos, &cylinder->info.bumper.hitPos); + CollisionCheck_HitEffects(globalCtx, cylinder->info.acHit, cylinder->info.acHitInfo, &cylinder->base, + &cylinder->info, &hitPos); + cylinder->info.acHitInfo->toucherFlags |= TOUCH_DREW_HITMARK; + } +} + +/** + * Sets a ColliderTris's hit effects + */ +void CollisionCheck_SetTrisHitFX(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider) { + ColliderTris* tris = (ColliderTris*)collider; + ColliderTrisElement* element; + Vec3f hitPos; + + for (element = tris->elements; element < tris->elements + tris->count; element++) { + if ((element->info.bumperFlags & BUMP_DRAW_HITMARK) && (element->info.acHitInfo != NULL) && + !(element->info.acHitInfo->toucherFlags & TOUCH_DREW_HITMARK)) { + Math_Vec3s_ToVec3f(&hitPos, &element->info.bumper.hitPos); + CollisionCheck_HitEffects(globalCtx, element->info.acHit, element->info.acHitInfo, &tris->base, + &element->info, &hitPos); + element->info.acHitInfo->toucherFlags |= TOUCH_DREW_HITMARK; + return; } } } -// D_8011DF5C ColliderTris -void func_80061028(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider) { - ColliderTris* col = (ColliderTris*)collider; - ColliderTrisItem* item; - Vec3f sp24; +/** + * Sets a ColliderQuad's hit effects + */ +void CollisionCheck_SetQuadHitFX(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider) { + ColliderQuad* quad = (ColliderQuad*)collider; + Vec3f hitPos; - for (item = col->list; item < col->list + col->count; item++) { - if (item->body.bumperFlags & 0x80) { - if (item->body.acHitItem != NULL) { - if (!(item->body.acHitItem->toucherFlags & 0x40)) { - Math_Vec3s_ToVec3f(&sp24, &item->body.bumper.unk_06); - func_8005E604(globalCtx, item->body.acHit, item->body.acHitItem, &col->base, &item->body, &sp24); - item->body.acHitItem->toucherFlags |= 0x40; - return; - } - } - } + if ((quad->info.bumperFlags & BUMP_DRAW_HITMARK) && (quad->info.acHitInfo != NULL) && + !(quad->info.acHitInfo->toucherFlags & TOUCH_DREW_HITMARK)) { + Math_Vec3s_ToVec3f(&hitPos, &quad->info.bumper.hitPos); + CollisionCheck_HitEffects(globalCtx, quad->info.acHit, quad->info.acHitInfo, &quad->base, &quad->info, &hitPos); + quad->info.acHitInfo->toucherFlags |= TOUCH_DREW_HITMARK; } } -// D_8011DF5C ColliderQuad -void func_8006110C(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider) { - ColliderQuad* item = (ColliderQuad*)collider; - Vec3f sp28; +static ColChkApplyFunc sColChkApplyFuncs[] = { + CollisionCheck_SetJntSphHitFX, + CollisionCheck_SetCylHitFX, + CollisionCheck_SetTrisHitFX, + CollisionCheck_SetQuadHitFX, +}; + +/** + * Handles hit effects for each AC collider that had an AC collision. Spawns hitmarks and plays sound effects. + */ +void CollisionCheck_SetHitEffects(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx) { + Collider** col; - if (item->body.bumperFlags & 0x80) { - if (item->body.acHitItem != NULL) { - if (!(item->body.acHitItem->toucherFlags & 0x40)) { - Math_Vec3s_ToVec3f(&sp28, &item->body.bumper.unk_06); - func_8005E604(globalCtx, item->body.acHit, item->body.acHitItem, &item->base, &item->body, &sp28); - item->body.acHitItem->toucherFlags |= 0x40; + for (col = colChkCtx->colAC; col < colChkCtx->colAC + colChkCtx->colACCount; col++) { + Collider* colAC = *col; + + if (colAC != NULL && colAC->acFlags & AC_ON) { + if (colAC->actor != NULL && colAC->actor->update == NULL) { + continue; } + sColChkApplyFuncs[colAC->shape](globalCtx, colChkCtx, colAC); } } } -void func_800611A0(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx) { +static ColChkVsFunc sACVsFuncs[4][4] = { + { CollisionCheck_AC_JntSphVsJntSph, CollisionCheck_AC_JntSphVsCyl, CollisionCheck_AC_JntSphVsTris, + CollisionCheck_AC_JntSphVsQuad }, + { CollisionCheck_AC_CylVsJntSph, CollisionCheck_AC_CylVsCyl, CollisionCheck_AC_CylVsTris, + CollisionCheck_AC_CylVsQuad }, + { CollisionCheck_AC_TrisVsJntSph, CollisionCheck_AC_TrisVsCyl, CollisionCheck_AC_TrisVsTris, + CollisionCheck_AC_TrisVsQuad }, + { CollisionCheck_AC_QuadVsJntSph, CollisionCheck_AC_QuadVsCyl, CollisionCheck_AC_QuadVsTris, + CollisionCheck_AC_QuadVsQuad }, +}; + +/** + * Iterates through all AC colliders, performing AC collisions with the AT collider. + */ +void CollisionCheck_AC(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* colAT) { Collider** col; - Collider* temp; - static void (*D_8011DF5C[4])(GlobalContext*, CollisionCheckContext*, Collider*) = { - func_80060EBC, - func_80060F94, - func_80061028, - func_8006110C, - }; + for (col = colChkCtx->colAC; col < colChkCtx->colAC + colChkCtx->colACCount; col++) { + Collider* colAC = *col; - for (col = colChkCtx->colAc; col < colChkCtx->colAc + colChkCtx->colAcCount; col++) { - temp = *col; - if (temp != NULL) { - if (temp->acFlags & 1) { - if (temp->actor == NULL || temp->actor->update != NULL) { - (*D_8011DF5C[temp->shape])(globalCtx, colChkCtx, temp); + if (colAC != NULL && colAC->acFlags & AC_ON) { + if (colAC->actor != NULL && colAC->actor->update == NULL) { + continue; + } + if ((colAC->acFlags & colAT->atFlags & AC_TYPE_ALL) && (colAT != colAC)) { + if (!(colAT->atFlags & AT_SELF) && colAT->actor != NULL && colAC->actor == colAT->actor) { + continue; } + sACVsFuncs[colAT->shape][colAC->shape](globalCtx, colChkCtx, colAT, colAC); } } } } -void CollisionCheck_AC(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider) { +/** + * Iterates through all AT colliders, testing them for AC collisions with each AC collider, setting the info regarding + * the collision for each AC and AT collider that collided. Then spawns hitmarks and plays sound effects for each + * successful collision. To collide, an AT collider must share a type (PLAYER, ENEMY, or BOMB) with the AC collider and + * the toucher and bumper elements that overlapped must share a dmgFlag. + */ +void CollisionCheck_AT(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx) { Collider** col; - Collider* temp; - - static void (*D_8011DF6C[4][4])(GlobalContext*, CollisionCheckContext*, Collider*, Collider*) = { - { CollisionCheck_AC_JntSphVsJntSph, CollisionCheck_AC_JntSphVsCyl, CollisionCheck_AC_JntSphVsTris, - CollisionCheck_AC_JntSphVsQuad }, - { CollisionCheck_AC_CylVsJntSph, CollisionCheck_AC_CylVsCyl, CollisionCheck_AC_CylVsTris, - CollisionCheck_AC_CylVsQuad }, - { CollisionCheck_AC_TrisVsJntSph, CollisionCheck_AC_TrisVsCyl, CollisionCheck_AC_TrisVsTris, - CollisionCheck_AC_TrisVsQuad }, - { CollisionCheck_AC_QuadVsJntSph, CollisionCheck_AC_QuadVsCyl, CollisionCheck_AC_QuadVsTris, - CollisionCheck_AC_QuadVsQuad }, - }; - for (col = colChkCtx->colAc; col < colChkCtx->colAc + colChkCtx->colAcCount; col++) { - temp = *col; - if (temp == NULL) { - continue; - } else if (!(temp->acFlags & 1)) { - continue; - } else if (temp->actor != NULL && temp->actor->update == NULL) { - continue; - } else if (!((temp->acFlags & collider->atFlags) & 0x38)) { - continue; - } else if (collider == temp) { - continue; - } - else if ((collider->atFlags & 0x40) || collider->actor == NULL || temp->actor != collider->actor) { - D_8011DF6C[collider->shape][temp->shape](globalCtx, colChkCtx, collider, temp); - } + if (colChkCtx->colATCount == 0 || colChkCtx->colACCount == 0) { + return; } -} - -// Test Attack Collisions -void func_8006139C(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx) { - Collider** colAt; - Collider* colliderAt; + for (col = colChkCtx->colAT; col < colChkCtx->colAT + colChkCtx->colATCount; col++) { + Collider* colAT = *col; - if (colChkCtx->colAtCount != 0) { - if (colChkCtx->colAcCount != 0) { - for (colAt = colChkCtx->colAt; colAt < colChkCtx->colAt + colChkCtx->colAtCount; colAt++) { - colliderAt = *colAt; - if (colliderAt != NULL) { - if (colliderAt->atFlags & 1) { - if ((colliderAt->actor == NULL) || (colliderAt->actor->update != NULL)) { - CollisionCheck_AC(globalCtx, colChkCtx, colliderAt); - } - } - } + if (colAT != NULL && colAT->atFlags & AT_ON) { + if (colAT->actor != NULL && colAT->actor->update == NULL) { + continue; } - func_800611A0(globalCtx, colChkCtx); + CollisionCheck_AC(globalCtx, colChkCtx, colAT); } } + CollisionCheck_SetHitEffects(globalCtx, colChkCtx); } -// Get mass type -s32 func_8006146C(u8 mass) { - if (mass == 0xFF) { - return 0; +/** + * Get mass type. Immobile colliders cannot be pushed, while heavy colliders can only be pushed by heavy and immobile + * colliders. + */ +s32 CollisionCheck_GetMassType(u8 mass) { + if (mass == MASS_IMMOVABLE) { + return MASSTYPE_IMMOVABLE; } - if (mass == 0xFE) { - return 1; + if (mass == MASS_HEAVY) { + return MASSTYPE_HEAVY; } - return 2; + return MASSTYPE_NORMAL; } -// SetOC collision, perform elastic collision -void func_800614A4(Collider* left, ColliderBody* leftBody, Vec3f* leftv, Collider* right, ColliderBody* rightBody, - Vec3f* rightv, f32 arg6) { - f32 temp_f0; - f32 leftDisplacementFactor; - f32 rightDisplacementFactor; +/** + * Sets OC collision flags for OC collider overlaps. If both colliders are attached to actors and can push, + * also performs an elastic collision where both colliders are moved apart in proportion to their masses. + */ +void CollisionCheck_SetOCvsOC(Collider* left, ColliderInfo* leftInfo, Vec3f* leftPos, Collider* right, + ColliderInfo* rightInfo, Vec3f* rightPos, f32 overlap) { + f32 pad; + f32 leftDispRatio; + f32 rightDispRatio; f32 xzDist; f32 leftMass; f32 rightMass; @@ -2464,248 +2694,283 @@ void func_800614A4(Collider* left, ColliderBody* leftBody, Vec3f* leftv, Collide f32 inverseTotalMass; f32 xDelta; f32 zDelta; - Actor* leftActor; - Actor* rightActor; - s32 rightMassType; + Actor* leftActor = left->actor; + Actor* rightActor = right->actor; s32 leftMassType; + s32 rightMassType; - leftActor = left->actor; - rightActor = right->actor; - left->maskA |= 2; + left->ocFlags1 |= OC1_HIT; left->oc = rightActor; - leftBody->ocFlags |= 2; - if ((right->maskB & 8) != 0) { - left->maskB |= 1; + leftInfo->ocElemFlags |= OCELEM_HIT; + if (right->ocFlags2 & OC2_TYPE_PLAYER) { + left->ocFlags2 |= OC2_HIT_PLAYER; } right->oc = leftActor; - right->maskA |= 2; - rightBody->ocFlags |= 2; - if ((left->maskB & 8) != 0) { - right->maskB |= 1; + right->ocFlags1 |= OC1_HIT; + rightInfo->ocElemFlags |= OCELEM_HIT; + if (left->ocFlags2 & OC2_TYPE_PLAYER) { + right->ocFlags2 |= OC2_HIT_PLAYER; } - if (leftActor == NULL || rightActor == NULL || (left->maskA & 4) || (right->maskA & 4)) { + if (leftActor == NULL || rightActor == NULL || left->ocFlags1 & OC1_NO_PUSH || right->ocFlags1 & OC1_NO_PUSH) { return; } - leftMassType = func_8006146C(leftActor->colChkInfo.mass); - rightMassType = func_8006146C(rightActor->colChkInfo.mass); + rightMassType = CollisionCheck_GetMassType(leftActor->colChkInfo.mass); + leftMassType = CollisionCheck_GetMassType(rightActor->colChkInfo.mass); leftMass = leftActor->colChkInfo.mass; rightMass = rightActor->colChkInfo.mass; totalMass = leftMass + rightMass; if (IS_ZERO(totalMass)) { - totalMass = (leftMass = rightMass = 1.0f) * 2; + leftMass = rightMass = 1.0f; + totalMass = 2.0f; } - xDelta = rightv->x - leftv->x; - zDelta = rightv->z - leftv->z; + xDelta = rightPos->x - leftPos->x; + zDelta = rightPos->z - leftPos->z; xzDist = sqrtf(SQ(xDelta) + SQ(zDelta)); - if (leftMassType == 0) { - if (rightMassType == 0) { + if (rightMassType == MASSTYPE_IMMOVABLE) { + if (leftMassType == MASSTYPE_IMMOVABLE) { return; - } else { - leftDisplacementFactor = 0; - rightDisplacementFactor = 1; - } - } else if (leftMassType == 1) { - if (rightMassType == 0) { - leftDisplacementFactor = 1; - rightDisplacementFactor = 0; - } else if (rightMassType == 1) { - leftDisplacementFactor = 0.5f; - rightDisplacementFactor = 0.5f; - } else { - leftDisplacementFactor = 0; - rightDisplacementFactor = 1; - } - } else { - if (rightMassType == 2) { + } else { // leftMassType == MASS_HEAVY | MASS_NORMAL + leftDispRatio = 0; + rightDispRatio = 1; + } + } else if (rightMassType == MASSTYPE_HEAVY) { + if (leftMassType == MASSTYPE_IMMOVABLE) { + leftDispRatio = 1; + rightDispRatio = 0; + } else if (leftMassType == MASSTYPE_HEAVY) { + leftDispRatio = 0.5f; + rightDispRatio = 0.5f; + } else { // leftMassType == MASS_NORMAL + leftDispRatio = 0; + rightDispRatio = 1; + } + } else { // rightMassType == MASS_NORMAL + if (leftMassType == MASSTYPE_NORMAL) { inverseTotalMass = 1 / totalMass; - leftDisplacementFactor = rightMass * inverseTotalMass; - rightDisplacementFactor = leftMass * inverseTotalMass; - } else { - leftDisplacementFactor = 1; - rightDisplacementFactor = 0; + leftDispRatio = rightMass * inverseTotalMass; + rightDispRatio = leftMass * inverseTotalMass; + } else { // leftMassType == MASS_HEAVY | MASS_IMMOVABLE + leftDispRatio = 1; + rightDispRatio = 0; } } if (!IS_ZERO(xzDist)) { - temp_f0 = arg6 / xzDist; - xDelta *= temp_f0; - zDelta *= temp_f0; - leftActor->colChkInfo.displacement.x += -xDelta * leftDisplacementFactor; - leftActor->colChkInfo.displacement.z += -zDelta * leftDisplacementFactor; - rightActor->colChkInfo.displacement.x += xDelta * rightDisplacementFactor; - rightActor->colChkInfo.displacement.z += zDelta * rightDisplacementFactor; - } else if (!(arg6 == 0.0f)) { - leftActor->colChkInfo.displacement.x += -arg6 * leftDisplacementFactor; - rightActor->colChkInfo.displacement.x += arg6 * rightDisplacementFactor; + xDelta *= overlap / xzDist; + zDelta *= overlap / xzDist; + leftActor->colChkInfo.displacement.x += -xDelta * leftDispRatio; + leftActor->colChkInfo.displacement.z += -zDelta * leftDispRatio; + rightActor->colChkInfo.displacement.x += xDelta * rightDispRatio; + rightActor->colChkInfo.displacement.z += zDelta * rightDispRatio; + } else if (!(overlap == 0.0f)) { + leftActor->colChkInfo.displacement.x += -overlap * leftDispRatio; + rightActor->colChkInfo.displacement.x += overlap * rightDispRatio; } else { - leftActor->colChkInfo.displacement.x -= leftDisplacementFactor; - rightActor->colChkInfo.displacement.x += rightDisplacementFactor; + leftActor->colChkInfo.displacement.x -= leftDispRatio; + rightActor->colChkInfo.displacement.x += rightDispRatio; } } +/** + * OC overlap check for two JntSphs + */ void CollisionCheck_OC_JntSphVsJntSph(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* l, Collider* r) { ColliderJntSph* left = (ColliderJntSph*)l; + ColliderJntSphElement* leftElem; ColliderJntSph* right = (ColliderJntSph*)r; - ColliderJntSphItem* lItem; - ColliderJntSphItem* rItem; - f32 sp74; - Vec3f sp68; - Vec3f sp5C; - - if (left->count > 0 && left->list != NULL && right->count > 0 && right->list != NULL) { - for (lItem = left->list; lItem < left->list + left->count; lItem++) { - if (!(lItem->body.ocFlags & 1)) { + ColliderJntSphElement* rightElem; + f32 overlap; + + if (left->count > 0 && left->elements != NULL && right->count > 0 && right->elements != NULL) { + for (leftElem = left->elements; leftElem < left->elements + left->count; leftElem++) { + if (!(leftElem->info.ocElemFlags & OCELEM_ON)) { continue; } - for (rItem = right->list; rItem < right->list + right->count; rItem++) { - if (!(rItem->body.ocFlags & 1)) { + for (rightElem = right->elements; rightElem < right->elements + right->count; rightElem++) { + if (!(rightElem->info.ocElemFlags & OCELEM_ON)) { continue; } - if (Math3D_SphVsSphOverlap(&lItem->dim.worldSphere, &rItem->dim.worldSphere, &sp74) == 1) { - Math_Vec3s_ToVec3f(&sp68, &lItem->dim.worldSphere.center); - Math_Vec3s_ToVec3f(&sp5C, &rItem->dim.worldSphere.center); - func_800614A4(&left->base, &lItem->body, &sp68, &right->base, &rItem->body, &sp5C, sp74); + if (Math3D_SphVsSphOverlap(&leftElem->dim.worldSphere, &rightElem->dim.worldSphere, &overlap) == 1) { + Vec3f leftPos; + Vec3f rightPos; + + Math_Vec3s_ToVec3f(&leftPos, &leftElem->dim.worldSphere.center); + Math_Vec3s_ToVec3f(&rightPos, &rightElem->dim.worldSphere.center); + CollisionCheck_SetOCvsOC(&left->base, &leftElem->info, &leftPos, &right->base, &rightElem->info, + &rightPos, overlap); } } } } } +/** + * OC overlap check for a JntSph and Cylinder + */ void CollisionCheck_OC_JntSphVsCyl(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* l, Collider* r) { ColliderJntSph* left = (ColliderJntSph*)l; + ColliderJntSphElement* leftElem; ColliderCylinder* right = (ColliderCylinder*)r; - ColliderJntSphItem* lItem; - f32 sp78; - Vec3f sp6C; - Vec3f sp60; + f32 overlap; - if (left->count > 0 && left->list != NULL) { - if (!(right->base.maskA & 1)) { - return; - } - if (!(right->body.ocFlags & 1)) { - return; - } - for (lItem = left->list; lItem < left->list + left->count; lItem++) { - if (!(lItem->body.ocFlags & 1)) { - continue; - } - if (Math3D_SphVsCylOverlapDist(&lItem->dim.worldSphere, &right->dim, &sp78) == 1) { - Math_Vec3s_ToVec3f(&sp6C, &lItem->dim.worldSphere.center); - Math_Vec3s_ToVec3f(&sp60, &right->dim.pos); - func_800614A4(&left->base, &lItem->body, &sp6C, &right->base, &right->body, &sp60, sp78); + if (left->count > 0 && left->elements != NULL) { + if ((right->base.ocFlags1 & OC1_ON) && (right->info.ocElemFlags & OCELEM_ON)) { + for (leftElem = left->elements; leftElem < left->elements + left->count; leftElem++) { + if (!(leftElem->info.ocElemFlags & OCELEM_ON)) { + continue; + } + if (Math3D_SphVsCylOverlapDist(&leftElem->dim.worldSphere, &right->dim, &overlap) == 1) { + Vec3f leftPos; + Vec3f rightPos; + + Math_Vec3s_ToVec3f(&leftPos, &leftElem->dim.worldSphere.center); + Math_Vec3s_ToVec3f(&rightPos, &right->dim.pos); + CollisionCheck_SetOCvsOC(&left->base, &leftElem->info, &leftPos, &right->base, &right->info, + &rightPos, overlap); + } } } } } +/** + * OC overlap check for a Cylinder and JntSph + */ void CollisionCheck_OC_CylVsJntSph(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* l, Collider* r) { CollisionCheck_OC_JntSphVsCyl(globalCtx, colChkCtx, r, l); } +/** + * OC overlap check for two Cylinders + */ void CollisionCheck_OC_CylVsCyl(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* l, Collider* r) { ColliderCylinder* left = (ColliderCylinder*)l; ColliderCylinder* right = (ColliderCylinder*)r; - f32 sp4C; - Vec3f sp40; - Vec3f sp34; - - if (!(left->base.maskA & 1) || !(right->base.maskA & 1)) { - return; - } - if (!(left->body.ocFlags & 1) || !(right->body.ocFlags & 1)) { - return; - } - if (Math3D_CylOutsideCyl(&left->dim, &right->dim, &sp4C) == 1) { - Math_Vec3s_ToVec3f(&sp40, &left->dim.pos); - Math_Vec3s_ToVec3f(&sp34, &right->dim.pos); - func_800614A4(&left->base, &left->body, &sp40, &right->base, &right->body, &sp34, sp4C); + f32 deadSpace; + + if ((left->base.ocFlags1 & OC1_ON) && (right->base.ocFlags1 & OC1_ON)) { + if ((left->info.ocElemFlags & OCELEM_ON) && (right->info.ocElemFlags & OCELEM_ON)) { + if (Math3D_CylOutsideCyl(&left->dim, &right->dim, &deadSpace) == 1) { + Vec3f leftPos; + Vec3f rightPos; + + Math_Vec3s_ToVec3f(&leftPos, &left->dim.pos); + Math_Vec3s_ToVec3f(&rightPos, &right->dim.pos); + CollisionCheck_SetOCvsOC(&left->base, &left->info, &leftPos, &right->base, &right->info, &rightPos, + deadSpace); + } + } } } -// CollisionCheck_OC test ? -s32 func_80061BF4(Collider* collider) { - if (!(collider->maskA & 1)) { +/** + * Skip any OC colliders that are off + */ +s32 CollisionCheck_SkipOC(Collider* collider) { + if (!(collider->ocFlags1 & OC1_ON)) { return 1; } return 0; } -// CollisionCheck_OC test ? -s32 func_80061C18(Collider* arg0, Collider* arg1) { - if (!((arg0->maskA & arg1->maskB) & 0x38) || !((arg0->maskB & arg1->maskA) & 0x38) || - ((arg0->maskB & 2) && (arg1->maskB & 4)) || ((arg1->maskB & 2) && (arg0->maskB & 4))) { +/** + * Checks for OC compatibility. There are three conditions: + * First, each collider must have an OC flag corresponding to the other's OC type. + * Second, OC2_UNK1 and OC2_UNK2 can't collide with each other (has something to do with horses?) + * Third, the colliders can't collide if they belong to the same actor + */ +s32 CollisionCheck_Incompatible(Collider* left, Collider* right) { + if (!(left->ocFlags1 & right->ocFlags2 & OC1_TYPE_ALL) || !(left->ocFlags2 & right->ocFlags1 & OC1_TYPE_ALL) || + ((left->ocFlags2 & OC2_UNK1) && (right->ocFlags2 & OC2_UNK2)) || + ((right->ocFlags2 & OC2_UNK1) && (left->ocFlags2 & OC2_UNK2))) { return 1; } - if (arg0->actor == arg1->actor) { + if (left->actor == right->actor) { return 1; } return 0; } +static ColChkVsFunc sOCVsFuncs[4][4] = { + { CollisionCheck_OC_JntSphVsJntSph, CollisionCheck_OC_JntSphVsCyl, NULL, NULL }, + { CollisionCheck_OC_CylVsJntSph, CollisionCheck_OC_CylVsCyl, NULL, NULL }, + { NULL, NULL, NULL, NULL }, + { NULL, NULL, NULL, NULL }, +}; + +/** + * Iterates through all OC colliders and collides them with all subsequent OC colliders on the list. During an OC + * collision, colliders with overlapping elements move away from each other so that their elements no longer overlap. + * The relative amount each collider is pushed is determined by the collider's mass. Only JntSph and Cylinder colliders + * can collide, and each collider must have the OC flag corresponding to the other's OC type. Additionally, OC2_UNK1 + * cannot collide with OC2_UNK2, nor can two colliders that share an actor. + */ void CollisionCheck_OC(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx) { - Collider** phi_s2; - Collider** phi_s0; - Collider** new_var; - Collider** new_var2; - void (*test)(GlobalContext*, CollisionCheckContext*, Collider*, Collider*); - - static void (*D_8011DFAC[4][4])(GlobalContext*, CollisionCheckContext*, Collider*, Collider*) = { - { CollisionCheck_OC_JntSphVsJntSph, CollisionCheck_OC_JntSphVsCyl, NULL, NULL }, - { CollisionCheck_OC_CylVsJntSph, CollisionCheck_OC_CylVsCyl, NULL, NULL }, - { NULL, NULL, NULL, NULL }, - { NULL, NULL, NULL, NULL }, - }; + Collider** left; + Collider** right; + ColChkVsFunc vsFunc; - for (phi_s2 = colChkCtx->colOc; phi_s2 < colChkCtx->colOc + colChkCtx->colOcCount; phi_s2++) { - if (*phi_s2 == NULL || func_80061BF4(*phi_s2) == 1) { + for (left = colChkCtx->colOC; left < colChkCtx->colOC + colChkCtx->colOCCount; left++) { + if (*left == NULL || CollisionCheck_SkipOC(*left) == 1) { continue; } - for (phi_s0 = phi_s2 + 1; phi_s0 < colChkCtx->colOc + colChkCtx->colOcCount; phi_s0++) { - if (*phi_s0 == NULL || func_80061BF4(*phi_s0) == 1 || func_80061C18(*phi_s2, *phi_s0) == 1) { + for (right = left + 1; right < colChkCtx->colOC + colChkCtx->colOCCount; right++) { + if (*right == NULL || CollisionCheck_SkipOC(*right) == 1 || + CollisionCheck_Incompatible(*left, *right) == 1) { continue; } - new_var2 = phi_s0; - new_var = phi_s2; - test = D_8011DFAC[(*new_var)->shape][(*new_var2)->shape]; - if (test == NULL) { - osSyncPrintf("CollisionCheck_OC():未対応 %d, %d\n", (*new_var)->shape, (*new_var2)->shape); - // EUC-JP: 未対応 | Not compatible + vsFunc = sOCVsFuncs[(*left)->shape][(*right)->shape]; + if (vsFunc == NULL) { + // Not compatible + osSyncPrintf("CollisionCheck_OC():未対応 %d, %d\n", (*left)->shape, (*right)->shape); continue; } - (*test)(globalCtx, colChkCtx, *new_var, *new_var2); + vsFunc(globalCtx, colChkCtx, *left, *right); } } } -// Initialize CollisionCheckInfo -void func_80061E48(CollisionCheckInfo* info) { - static CollisionCheckInfo init = { NULL, { 0, 0, 0 }, 10, 10, 0, 50, 8, 0, 0, 0, 0 }; +/** + * Initializes CollisionCheckInfo to default values + */ +void CollisionCheck_InitInfo(CollisionCheckInfo* info) { + static CollisionCheckInfo init = { + NULL, { 0.0f, 0.0f, 0.0f }, 10, 10, 0, 50, 8, 0, 0, 0, 0, + }; + *info = init; } -void func_80061E8C(CollisionCheckInfo* info) { +/** + * Resets ColisionCheckInfo fields other than DamageTable, mass, and dim. + */ +void CollisionCheck_ResetDamage(CollisionCheckInfo* info) { info->damage = 0; info->damageEffect = 0; info->atHitEffect = 0; info->acHitEffect = 0; - info->displacement.z = 0.0f; - info->displacement.y = 0.0f; - info->displacement.x = 0.0f; + info->displacement.x = info->displacement.y = info->displacement.z = 0.0f; } -void func_80061EB0(CollisionCheckInfo* info, CollisionCheckInfoInit* init) { +/** + * Sets up CollisionCheckInfo using the values in init. Does not set a damage table or the unused unk_14. + * Unused, as all actors that don't set a damage table set their CollisionCheckInfo manually + */ +void CollisionCheck_SetInfoNoDamageTable(CollisionCheckInfo* info, CollisionCheckInfoInit* init) { info->health = init->health; info->unk_10 = init->unk_02; info->unk_12 = init->unk_04; info->mass = init->mass; } -void func_80061ED4(CollisionCheckInfo* info, DamageTable* damageTable, CollisionCheckInfoInit* init) { +/** + * Sets up CollisionCheckInfo using the values in init. Does not set the unused unk_14 + */ +void CollisionCheck_SetInfo(CollisionCheckInfo* info, DamageTable* damageTable, CollisionCheckInfoInit* init) { info->health = init->health; info->damageTable = damageTable; info->unk_10 = init->unk_02; @@ -2713,7 +2978,10 @@ void func_80061ED4(CollisionCheckInfo* info, DamageTable* damageTable, Collision info->mass = init->mass; } -void func_80061EFC(CollisionCheckInfo* info, DamageTable* damageTable, CollisionCheckInfoInit2* init) { +/** + * Sets up CollisionCheckInfo using the values in init. Sets the unused unk_14 + */ +void CollisionCheck_SetInfo2(CollisionCheckInfo* info, DamageTable* damageTable, CollisionCheckInfoInit2* init) { info->health = init->health; info->damageTable = damageTable; info->unk_10 = init->unk_02; @@ -2722,183 +2990,206 @@ void func_80061EFC(CollisionCheckInfo* info, DamageTable* damageTable, Collision info->mass = init->mass; } -void func_80061F2C(CollisionCheckInfo* info, s32 index, CollisionCheckInfoInit2* init) { - func_80061EFC(info, DamageTable_Get(index), init); +/** + * Sets up CollisionCheckInfo using the values in Init and a preset damage table. Sets the unused unk_14. + * Unused, as all actors that use a preset damage table set their CollisionCheckInfo manually. + */ +void CollisionCheck_SetInfoGetDamageTable(CollisionCheckInfo* info, s32 index, CollisionCheckInfoInit2* init) { + CollisionCheck_SetInfo2(info, DamageTable_Get(index), init); } -// Apply AC damage effect -void func_80061F64(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider, ColliderBody* body) { +/** + * Apply AC damage effect + */ +void CollisionCheck_ApplyDamage(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider, + ColliderInfo* info) { DamageTable* tbl; - u32 flags; - s32 i; f32 damage; - s32 tblLookup; - if (collider->actor == NULL || !(collider->acFlags & 2)) { + if (collider->actor == NULL || !(collider->acFlags & AC_HIT)) { return; } - if (!(body->bumperFlags & 2) || (body->bumperFlags & 0x10)) { + if (!(info->bumperFlags & BUMP_HIT) || info->bumperFlags & BUMP_NO_DAMAGE) { return; } - if (body->acHitItem == NULL) { + if (info->acHitInfo == NULL) { __assert("pclobj_elem->ac_hit_elem != NULL", "../z_collision_check.c", 6493); } tbl = collider->actor->colChkInfo.damageTable; if (tbl == NULL) { - damage = (f32)body->acHitItem->toucher.damage - (f32)body->bumper.defense; + damage = (f32)info->acHitInfo->toucher.damage - info->bumper.defense; if (damage < 0) { damage = 0; } } else { - for (i = 0, flags = body->acHitItem->toucher.flags; i < 0x20; i++, flags >>= 1) { + s32 i; + u32 flags = info->acHitInfo->toucher.dmgFlags; + + for (i = 0; i < 0x20; i++, flags >>= 1) { if (flags == 1) { break; } } - tblLookup = tbl->table[i]; - damage = tblLookup & 0xF; - collider->actor->colChkInfo.damageEffect = tblLookup >> 4 & 0xF; + damage = tbl->table[i] & 0xF; + collider->actor->colChkInfo.damageEffect = tbl->table[i] >> 4 & 0xF; } - if (!(collider->acFlags & 4)) { - collider->actor->colChkInfo.damage = (u32)(collider->actor->colChkInfo.damage + damage); + if (!(collider->acFlags & AC_HARD)) { + collider->actor->colChkInfo.damage += damage; } } -// Apply ColliderJntSph AC damage effect -void func_8006216C(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider) { +/** + * Apply ColliderJntSph AC damage effect + */ +void CollisionCheck_ApplyDamageJntSph(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider) { ColliderJntSph* jntSph = (ColliderJntSph*)collider; s32 i; - if (!(jntSph->count > 0) || jntSph->list == NULL) { - return; - } - for (i = 0; i < jntSph->count; i++) { - func_80061F64(globalCtx, colChkCtx, &jntSph->base, &jntSph->list[i].body); + if (jntSph->count > 0 && jntSph->elements != NULL) { + for (i = 0; i < jntSph->count; i++) { + CollisionCheck_ApplyDamage(globalCtx, colChkCtx, &jntSph->base, &jntSph->elements[i].info); + } } } -// Apply ColliderCylinder AC damage effect -void func_80062210(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider) { +/** + * Apply ColliderCylinder AC damage effect + */ +void CollisionCheck_ApplyDamageCyl(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider) { ColliderCylinder* cylinder = (ColliderCylinder*)collider; - func_80061F64(globalCtx, colChkCtx, &cylinder->base, &cylinder->body); + CollisionCheck_ApplyDamage(globalCtx, colChkCtx, &cylinder->base, &cylinder->info); } -// Apply ColliderTris AC damage effect -void func_80062230(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider) { +/** + * Apply ColliderTris AC damage effect + */ +void CollisionCheck_ApplyDamageTris(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider) { ColliderTris* tris = (ColliderTris*)collider; s32 i; for (i = 0; i < tris->count; i++) { - func_80061F64(globalCtx, colChkCtx, collider, &tris->list[i].body); + CollisionCheck_ApplyDamage(globalCtx, colChkCtx, collider, &tris->elements[i].info); } } -// Apply ColliderQuad AC damage effect -void func_800622C4(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider) { +/** + * Apply ColliderQuad AC damage effect + */ +void CollisionCheck_ApplyDamageQuad(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider) { ColliderQuad* quad = (ColliderQuad*)collider; - func_80061F64(globalCtx, colChkCtx, &quad->base, &quad->body); + CollisionCheck_ApplyDamage(globalCtx, colChkCtx, &quad->base, &quad->info); } -// Apply all AC damage effects -void func_800622E4(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx) { - Collider* collider; +static ColChkApplyFunc sApplyDamageFuncs[4] = { + CollisionCheck_ApplyDamageJntSph, + CollisionCheck_ApplyDamageCyl, + CollisionCheck_ApplyDamageTris, + CollisionCheck_ApplyDamageQuad, +}; + +/** + * For all AC colliders, sets any damage effects from collisions with AT colliders to their corresponding actor's + * CollisionCheckInfo. + */ +void CollisionCheck_Damage(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx) { s32 i; - static void (*D_8011E008[4])(GlobalContext*, CollisionCheckContext*, Collider*) = { - func_8006216C, - func_80062210, - func_80062230, - func_800622C4, - }; + for (i = 0; i < colChkCtx->colACCount; i++) { + Collider* collider = colChkCtx->colAC[i]; - for (i = 0; i < colChkCtx->colAcCount; i++) { - collider = colChkCtx->colAc[i]; - if (collider == 0) { + if (collider == NULL) { continue; } - if ((collider->acFlags & 0x40)) { + if (collider->acFlags & AC_NO_DAMAGE) { continue; } - D_8011E008[collider->shape](globalCtx, colChkCtx, collider); + sApplyDamageFuncs[collider->shape](globalCtx, colChkCtx, collider); } } -static Linef D_8015E610; - -s32 CollisionCheck_generalLineOcCheck_JntSph(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, - Collider* collider, Vec3f* arg3, Vec3f* arg4) { +/** + * Checks if the line ab intersects any of the ColliderJntSph's elements + */ +s32 CollisionCheck_LineOC_JntSph(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider, + Vec3f* a, Vec3f* b) { + static Linef D_8015E610; ColliderJntSph* jntSph = (ColliderJntSph*)collider; - ColliderJntSphItem* item; - s32 phi_s0; - for (phi_s0 = 0; phi_s0 < jntSph->count; phi_s0++) { - item = &jntSph->list[phi_s0]; - if (!(item->body.ocFlags & 1)) { + s32 i; + + for (i = 0; i < jntSph->count; i++) { + ColliderJntSphElement* element = &jntSph->elements[i]; + + if (!(element->info.ocElemFlags & OCELEM_ON)) { continue; } - D_8015E610.a = *arg3; - D_8015E610.b = *arg4; - if (Math3D_LineVsSph(&item->dim.worldSphere, &D_8015E610) == 1) { - return 1; + D_8015E610.a = *a; + D_8015E610.b = *b; + if (Math3D_LineVsSph(&element->dim.worldSphere, &D_8015E610) == 1) { + return true; } } - return 0; + return false; } -static Vec3f D_8015E628; -static Vec3f D_8015E638; - -s32 CollisionCheck_generalLineOcCheck_Cyl(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, - Collider* collider, Vec3f* arg3, Vec3f* arg4) { +/** + * Checks if the line segment ab intersects the ColliderCylinder + */ +s32 CollisionCheck_LineOC_Cyl(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Collider* collider, Vec3f* a, + Vec3f* b) { + static Vec3f D_8015E628; + static Vec3f D_8015E638; ColliderCylinder* cylinder = (ColliderCylinder*)collider; - if (!(cylinder->body.ocFlags & 1)) { - return 0; + + if (!(cylinder->info.ocElemFlags & OCELEM_ON)) { + return false; } - if (Math3D_CylVsLineSeg(&cylinder->dim, arg3, arg4, &D_8015E628, &D_8015E638) != 0) { - return 1; + if (Math3D_CylVsLineSeg(&cylinder->dim, a, b, &D_8015E628, &D_8015E638) != 0) { + return true; } - return 0; + return false; } -s32 CollisionCheck_GeneralLineOcCheck(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Vec3f* camera_3C, - Vec3f* arg3, Actor** arg4, s32 arg5) { - Collider* collider; - s32 (*t)(GlobalContext*, CollisionCheckContext*, Collider*, Vec3f*, Vec3f*); - Collider** c; +static ColChkLineFunc sOCLineCheckFuncs[4] = { + CollisionCheck_LineOC_JntSph, + CollisionCheck_LineOC_Cyl, + NULL, + NULL, +}; + +/** + * Checks if the line segment ab intersects any OC colliders, excluding those attached to actors + * on the exclusion list. Returns true if there are any intersections and false otherwise. + */ +s32 CollisionCheck_LineOC(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Vec3f* a, Vec3f* b, + Actor** exclusions, s32 numExclusions) { + ColChkLineFunc lineCheck; + Collider** col; s32 i; - s32 test; - s32 result; - - static s32 (*D_8011E018[4])(GlobalContext*, CollisionCheckContext*, Collider*, Vec3f*, Vec3f*) = { - CollisionCheck_generalLineOcCheck_JntSph, - CollisionCheck_generalLineOcCheck_Cyl, - NULL, - NULL, - }; + s32 exclude; + s32 result = 0; - result = 0; - for (c = colChkCtx->colOc; c < colChkCtx->colOc + colChkCtx->colOcCount; c++) { - if (func_80061BF4(*c) == 1) { + for (col = colChkCtx->colOC; col < colChkCtx->colOC + colChkCtx->colOCCount; col++) { + if (CollisionCheck_SkipOC(*col) == 1) { continue; } - test = 0; - for (i = 0; i < arg5; i++) { - if ((*c)->actor == arg4[i]) { - test = 1; + exclude = 0; + for (i = 0; i < numExclusions; i++) { + if ((*col)->actor == exclusions[i]) { + exclude = 1; break; } } - if (test == 1) { + if (exclude == 1) { continue; } - collider = *c; - t = D_8011E018[collider->shape]; - if (t == NULL) { - osSyncPrintf("CollisionCheck_generalLineOcCheck():未対応 %dタイプ\n", collider->shape); - // EUC-JP: 未対応 %dタイプ | %d's type is not supported + lineCheck = sOCLineCheckFuncs[(*col)->shape]; + if (lineCheck == NULL) { + // type %d not supported + osSyncPrintf("CollisionCheck_generalLineOcCheck():未対応 %dタイプ\n", (*col)->shape); } else { - result = (*t)(globalCtx, colChkCtx, collider, camera_3C, arg3); - if (result != 0) { + result = lineCheck(globalCtx, colChkCtx, (*col), a, b); + if (result) { break; } } @@ -2906,60 +3197,79 @@ s32 CollisionCheck_GeneralLineOcCheck(GlobalContext* globalCtx, CollisionCheckCo return result; } -s32 func_8006268C(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Vec3f* arg2, Vec3f* arg3) { - CollisionCheck_GeneralLineOcCheck(globalCtx, colChkCtx, arg2, arg3, NULL, 0); +/** + * Checks if the line segment ab intersects any OC colliders. Returns true if there are any intersections and false + * otherwise. Unused. + */ +s32 CollisionCheck_LineOCCheckAll(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Vec3f* a, Vec3f* b) { + CollisionCheck_LineOC(globalCtx, colChkCtx, a, b, NULL, 0); } -s32 func_800626B0(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Vec3f* camera_3C, Vec3f* arg3, - Actor** arg4, s32 arg5) { - CollisionCheck_GeneralLineOcCheck(globalCtx, colChkCtx, camera_3C, arg3, arg4, arg5); +/** + * Checks if the line segment ab intersects any OC colliders, excluding those attached to actors on the exclusion list. + * Returns true if there are any intersections and false otherwise. + */ +s32 CollisionCheck_LineOCCheck(GlobalContext* globalCtx, CollisionCheckContext* colChkCtx, Vec3f* a, Vec3f* b, + Actor** exclusions, s32 numExclusions) { + CollisionCheck_LineOC(globalCtx, colChkCtx, a, b, exclusions, numExclusions); } -void Collider_CylinderUpdate(Actor* actor, ColliderCylinder* collider) { - collider->dim.pos.x = (s32)actor->posRot.pos.x; - collider->dim.pos.y = (s32)actor->posRot.pos.y; - collider->dim.pos.z = (s32)actor->posRot.pos.z; +/** + * Moves the ColliderCylinder's position to the actor's position + */ +void Collider_UpdateCylinder(Actor* actor, ColliderCylinder* collider) { + collider->dim.pos.x = actor->posRot.pos.x; + collider->dim.pos.y = actor->posRot.pos.y; + collider->dim.pos.z = actor->posRot.pos.z; } -// Set ColliderCylinder position -void func_80062718(ColliderCylinder* collider, Vec3s* pos) { +/** + * Sets the ColliderCylinder's position + */ +void Collider_SetCylinderPosition(ColliderCylinder* collider, Vec3s* pos) { collider->dim.pos.x = pos->x; collider->dim.pos.y = pos->y; collider->dim.pos.z = pos->z; } -// Set ColliderQuad vertices -void func_80062734(ColliderQuad* collider, Vec3f* a, Vec3f* b, Vec3f* c, Vec3f* d) { +/** + * Sets the ColliderQuad's vertices + */ +void Collider_SetQuadVertices(ColliderQuad* collider, Vec3f* a, Vec3f* b, Vec3f* c, Vec3f* d) { Math_Vec3f_Copy(&collider->dim.quad[2], c); Math_Vec3f_Copy(&collider->dim.quad[3], d); Math_Vec3f_Copy(&collider->dim.quad[0], a); Math_Vec3f_Copy(&collider->dim.quad[1], b); - func_8005CEDC(&collider->dim); + Collider_SetQuadMidpoints(&collider->dim); } -// Set ColliderTrisItem at index -void func_800627A0(ColliderTris* collider, s32 index, Vec3f* a, Vec3f* b, Vec3f* c) { - ColliderTrisItem* item; - f32 sp40; - f32 sp3C; - f32 sp38; - f32 sp34; +/** + * Sets the specified ColliderTrisElement's vertices + */ +void Collider_SetTrisVertices(ColliderTris* collider, s32 index, Vec3f* a, Vec3f* b, Vec3f* c) { + ColliderTrisElement* element = &collider->elements[index]; + f32 nx; + f32 ny; + f32 nz; + f32 originDist; - item = &collider->list[index]; - Math_Vec3f_Copy(&item->dim.vtx[0], a); - Math_Vec3f_Copy(&item->dim.vtx[1], b); - Math_Vec3f_Copy(&item->dim.vtx[2], c); - Math3D_DefPlane(a, b, c, &sp40, &sp3C, &sp38, &sp34); - item->dim.plane.normal.x = sp40; - item->dim.plane.normal.y = sp3C; - item->dim.plane.normal.z = sp38; - item->dim.plane.originDist = sp34; + Math_Vec3f_Copy(&element->dim.vtx[0], a); + Math_Vec3f_Copy(&element->dim.vtx[1], b); + Math_Vec3f_Copy(&element->dim.vtx[2], c); + Math3D_DefPlane(a, b, c, &nx, &ny, &nz, &originDist); + element->dim.plane.normal.x = nx; + element->dim.plane.normal.y = ny; + element->dim.plane.normal.z = nz; + element->dim.plane.originDist = originDist; } -// Set ColliderTrisItem at index -void func_8006285C(GlobalContext* globalCtx, ColliderTris* collider, s32 index, ColliderTrisItemDimInit* init) { - ColliderTrisItem* item = &collider->list[index]; - Collider_SetTrisItemDim(globalCtx, &item->dim, init); +/** + * Sets the specified ColliderTrisElement's dim using the values in src + */ +void Collider_SetTrisDim(GlobalContext* globalCtx, ColliderTris* collider, s32 index, ColliderTrisElementDimInit* src) { + ColliderTrisElement* element = &collider->elements[index]; + + Collider_SetTrisElementDim(globalCtx, &element->dim, src); } // Due to an unknown reason, bss ordering changed between the 2 static Vec3f variables in the function below. @@ -2971,33 +3281,40 @@ static s8 sBssDummy12; static s8 sBssDummy13; static s8 sBssDummy14; -void func_800628A4(s32 arg0, ColliderJntSph* collider) { +/** + * Updates the world spheres for all of the collider's JntSph elements attached to the specified limb + */ +void Collider_UpdateSpheres(s32 limb, ColliderJntSph* collider) { static Vec3f D_8015E648; static Vec3f D_8015CF00; // bss ordering changes here s32 i; for (i = 0; i < collider->count; i++) { - if (arg0 == collider->list[i].dim.joint) { - D_8015E648.x = collider->list[i].dim.modelSphere.center.x; - D_8015E648.y = collider->list[i].dim.modelSphere.center.y; - D_8015E648.z = collider->list[i].dim.modelSphere.center.z; + if (limb == collider->elements[i].dim.limb) { + D_8015E648.x = collider->elements[i].dim.modelSphere.center.x; + D_8015E648.y = collider->elements[i].dim.modelSphere.center.y; + D_8015E648.z = collider->elements[i].dim.modelSphere.center.z; Matrix_MultVec3f(&D_8015E648, &D_8015CF00); - collider->list[i].dim.worldSphere.center.x = (s32)D_8015CF00.x; - collider->list[i].dim.worldSphere.center.y = (s32)D_8015CF00.y; - collider->list[i].dim.worldSphere.center.z = (s32)D_8015CF00.z; - collider->list[i].dim.worldSphere.radius = - (s32)((f32)collider->list[i].dim.modelSphere.radius * collider->list[i].dim.scale); + collider->elements[i].dim.worldSphere.center.x = D_8015CF00.x; + collider->elements[i].dim.worldSphere.center.y = D_8015CF00.y; + collider->elements[i].dim.worldSphere.center.z = D_8015CF00.z; + collider->elements[i].dim.worldSphere.radius = + collider->elements[i].dim.modelSphere.radius * collider->elements[i].dim.scale; } } } -void func_80062A28(GlobalContext* globalCtx, Vec3f* v) { +/** + * Spawns red blood droplets. + * No actor has a collision type that spawns red blood. + */ +void CollisionCheck_SpawnRedBlood(GlobalContext* globalCtx, Vec3f* v) { static EffectSparkInit D_8015CF10; - s32 sp24; + s32 effectIndex; - D_8015CF10.position.x = (s32)v->x; - D_8015CF10.position.y = (s32)v->y; - D_8015CF10.position.z = (s32)v->z; + D_8015CF10.position.x = v->x; + D_8015CF10.position.y = v->y; + D_8015CF10.position.z = v->z; D_8015CF10.uDiv = 5; D_8015CF10.vDiv = 5; D_8015CF10.colorStart[0].r = 128; @@ -3037,16 +3354,20 @@ void func_80062A28(GlobalContext* globalCtx, Vec3f* v) { D_8015CF10.speed = 8.0f; D_8015CF10.gravity = -1.0f; - Effect_Add(globalCtx, &sp24, EFFECT_SPARK, 0, 1, &D_8015CF10); + Effect_Add(globalCtx, &effectIndex, EFFECT_SPARK, 0, 1, &D_8015CF10); } -void func_80062B80(GlobalContext* globalCtx, Vec3f* v) { +/** + * Spawns water droplets. + * No actor has a collision type that spawns water droplets. + */ +void CollisionCheck_SpawnWaterDroplets(GlobalContext* globalCtx, Vec3f* v) { static EffectSparkInit D_8015D3D8; - s32 sp24; + s32 effectIndex; - D_8015D3D8.position.x = (s32)v->x; - D_8015D3D8.position.y = (s32)v->y; - D_8015D3D8.position.z = (s32)v->z; + D_8015D3D8.position.x = v->x; + D_8015D3D8.position.y = v->y; + D_8015D3D8.position.z = v->z; D_8015D3D8.uDiv = 5; D_8015D3D8.vDiv = 5; D_8015D3D8.colorStart[0].r = 255; @@ -3086,90 +3407,105 @@ void func_80062B80(GlobalContext* globalCtx, Vec3f* v) { D_8015D3D8.speed = 8.0f; D_8015D3D8.gravity = -1.0f; - Effect_Add(globalCtx, &sp24, EFFECT_SPARK, 0, 1, &D_8015D3D8); + Effect_Add(globalCtx, &effectIndex, EFFECT_SPARK, 0, 1, &D_8015D3D8); } -void func_80062CD4(GlobalContext* globalCtx, Vec3f* v) { - static EffectShieldParticleInit init = { +/** + * Spawns streaks of light from hits against solid objects + */ +void CollisionCheck_SpawnShieldParticles(GlobalContext* globalCtx, Vec3f* v) { + static EffectShieldParticleInit initMetal = { 16, - { 0.0f, 0.0f, 0.0f }, - { 0x00, 0xC8, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0x80, 0xFF }, - { 0xFF, 0xFF, 0x00, 0xFF }, - { 0xFF, 0x40, 0x00, 0xC8 }, - { 0xFF, 0x00, 0x00, 0xFF }, + { 0, 0, 0 }, + { 0, 200, 255, 255 }, + { 255, 255, 255, 255 }, + { 255, 255, 128, 255 }, + { 255, 255, 0, 255 }, + { 255, 64, 0, 200 }, + { 255, 0, 0, 255 }, 2.1f, 35.0f, 30.0f, 8, - { 0, 0, 0, 0x00, 0x80, 0xFF, 0x00, 300 }, - 1, + { 0, 0, 0, { 0, 128, 255 }, false, 300 }, + true, }; - s32 sp24; + s32 effectIndex; - init.position.x = (s32)v->x; - init.position.y = (s32)v->y; - init.position.z = (s32)v->z; - init.lightPoint.x = init.position.x; - init.lightPoint.y = init.position.y; - init.lightPoint.z = init.position.z; + initMetal.position.x = v->x; + initMetal.position.y = v->y; + initMetal.position.z = v->z; + initMetal.lightPoint.x = initMetal.position.x; + initMetal.lightPoint.y = initMetal.position.y; + initMetal.lightPoint.z = initMetal.position.z; - Effect_Add(globalCtx, &sp24, EFFECT_SHIELD_PARTICLE, 0, 1, &init); + Effect_Add(globalCtx, &effectIndex, EFFECT_SHIELD_PARTICLE, 0, 1, &initMetal); } -void func_80062D60(GlobalContext* globalCtx, Vec3f* v) { - func_80062CD4(globalCtx, v); +/** + * Spawns streaks of light and makes a metallic sound + */ +void CollisionCheck_SpawnShieldParticlesMetal(GlobalContext* globalCtx, Vec3f* v) { + CollisionCheck_SpawnShieldParticles(globalCtx, v); Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_REFLECT_SW, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); } -void func_80062DAC(GlobalContext* globalCtx, Vec3f* v, Vec3f* arg2) { - func_80062CD4(globalCtx, v); - Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_REFLECT_SW, arg2, 4, &D_801333E0, &D_801333E0, &D_801333E8); +/** + * Spawns streaks of light and makes a metallic sound at the specified position + */ +void CollisionCheck_SpawnShieldParticlesMetalSound(GlobalContext* globalCtx, Vec3f* v, Vec3f* pos) { + CollisionCheck_SpawnShieldParticles(globalCtx, v); + Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_REFLECT_SW, pos, 4, &D_801333E0, &D_801333E0, &D_801333E8); } -void func_80062DF4(GlobalContext* globalCtx, Vec3f* v) { - func_80062D60(globalCtx, v); +/** + * Spawns streaks of light and makes a metallic sound + */ +void CollisionCheck_SpawnShieldParticlesMetal2(GlobalContext* globalCtx, Vec3f* v) { + CollisionCheck_SpawnShieldParticlesMetal(globalCtx, v); } -void func_80062E14(GlobalContext* globalCtx, Vec3f* v, Vec3f* arg2) { - static EffectShieldParticleInit init = { +/** + * Spawns streaks of light and makes a wooden sound + */ +void CollisionCheck_SpawnShieldParticlesWood(GlobalContext* globalCtx, Vec3f* v, Vec3f* actorPos) { + static EffectShieldParticleInit initWood = { 16, - { 0.0f, 0.0f, 0.0f }, - { 0x00, 0xC8, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0x80, 0xFF }, - { 0xFF, 0xFF, 0x00, 0xFF }, - { 0xFF, 0x40, 0x00, 0xC8 }, - { 0xFF, 0x00, 0x00, 0xFF }, + { 0, 0, 0 }, + { 0, 200, 255, 255 }, + { 255, 255, 255, 255 }, + { 255, 255, 128, 255 }, + { 255, 255, 0, 255 }, + { 255, 64, 0, 200 }, + { 255, 0, 0, 255 }, 2.1f, 35.0f, 30.0f, 8, - { 0, 0, 0, 0x00, 0x80, 0xFF, 0x00, 300 }, - 0, + { 0, 0, 0, { 0, 128, 255 }, false, 300 }, + false, }; - s32 sp24; + s32 effectIndex; - init.position.x = (s32)v->x; - init.position.y = (s32)v->y; - init.position.z = (s32)v->z; - init.lightPoint.x = init.position.x; - init.lightPoint.y = init.position.y; - init.lightPoint.z = init.position.z; + initWood.position.x = v->x; + initWood.position.y = v->y; + initWood.position.z = v->z; + initWood.lightPoint.x = initWood.position.x; + initWood.lightPoint.y = initWood.position.y; + initWood.lightPoint.z = initWood.position.z; - Effect_Add(globalCtx, &sp24, EFFECT_SHIELD_PARTICLE, 0, 1, &init); - Audio_PlaySoundGeneral(NA_SE_IT_REFLECTION_WOOD, arg2, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Effect_Add(globalCtx, &effectIndex, EFFECT_SHIELD_PARTICLE, 0, 1, &initWood); + Audio_PlaySoundGeneral(NA_SE_IT_REFLECTION_WOOD, actorPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); } -/* +/** * Determines if the line segment connecting itemPos and itemProjPos intersects the side of a cylinder with the given * radius, height, and offset at actorPos. Returns 3 if either endpoint is inside the cylinder, otherwise returns the * number of points of intersection with the side of the cylinder. The locations of those points are put in out1 and * out2, with out1 being closer to itemPos. Line segments that pass through both bases of the cylinder are not detected. */ -s32 func_80062ECC(f32 radius, f32 height, f32 offset, Vec3f* actorPos, Vec3f* itemPos, Vec3f* itemProjPos, Vec3f* out1, - Vec3f* out2) { +s32 CollisionCheck_CylSideVsLineSeg(f32 radius, f32 height, f32 offset, Vec3f* actorPos, Vec3f* itemPos, + Vec3f* itemProjPos, Vec3f* out1, Vec3f* out2) { Vec3f actorToItem; Vec3f actorToItemProj; Vec3f itemStep; @@ -3301,20 +3637,23 @@ s32 func_80062ECC(f32 radius, f32 height, f32 offset, Vec3f* actorPos, Vec3f* it return 1; } -s32 func_800635D0(s32 arg0) { - s32 result; +/** + * Gets damage from a sword strike using generic values, and returns 0 if the attack is + * not sword-type. Used by bosses to require that a sword attack deal the killing blow. + */ +u8 CollisionCheck_GetSwordDamage(s32 dmgFlags) { + u8 damage = 0; - result = 0; - if (arg0 & 0x00400100) { - result = 1; - } else if (arg0 & 0x03000242) { - result = 2; - } else if (arg0 & 0x48800400) { - result = 4; - } else if (arg0 & 0x04000000) { - result = 8; + if (dmgFlags & 0x00400100) { + damage = 1; + } else if (dmgFlags & 0x03000242) { + damage = 2; + } else if (dmgFlags & 0x48800400) { + damage = 4; + } else if (dmgFlags & 0x04000000) { + damage = 8; } - KREG(7) = result; - return result; + KREG(7) = damage; + return damage; } diff --git a/src/code/z_en_a_keep.c b/src/code/z_en_a_keep.c index 64b18aea3..3e62d46cb 100644 --- a/src/code/z_en_a_keep.c +++ b/src/code/z_en_a_keep.c @@ -34,8 +34,22 @@ const ActorInit En_A_Obj_InitVars = { }; static ColliderCylinderInit sCylinderInit = { - { COLTYPE_UNK10, 0x00, 0x39, 0x39, 0x20, COLSHAPE_CYLINDER }, - { 0x02, { 0x00000000, 0x00, 0x00 }, { 0xFFCFFFFF, 0x00, 0x00 }, 0x00, 0x01, 0x01 }, + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_ALL, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK2, + { 0x00000000, 0x00, 0x00 }, + { 0xFFCFFFFF, 0x00, 0x00 }, + TOUCH_NONE, + BUMP_ON, + OCELEM_ON, + }, { 25, 60, 0, { 0, 0, 0 } }, }; @@ -138,7 +152,7 @@ void EnAObj_Init(Actor* thisx, GlobalContext* globalCtx) { func_8001D234(this, thisx->params); Collider_InitCylinder(globalCtx, &this->collider); Collider_SetCylinder(globalCtx, &this->collider, thisx, &sCylinderInit); - thisx->colChkInfo.mass = 0xFF; + thisx->colChkInfo.mass = MASS_IMMOVABLE; thisx->unk_1F = 0; break; case A_OBJ_KNOB: @@ -152,7 +166,7 @@ void EnAObj_Init(Actor* thisx, GlobalContext* globalCtx) { } if (thisx->params < 5) { - thisx->colChkInfo.mass = 0xFF; + thisx->colChkInfo.mass = MASS_IMMOVABLE; } if (this->dyna.bgId != BGACTOR_NEG_ONE) { @@ -315,8 +329,8 @@ void EnAObj_Update(Actor* thisx, GlobalContext* globalCtx) { switch (this->dyna.actor.params) { case A_OBJ_SIGNPOST_OBLONG: case A_OBJ_SIGNPOST_ARROW: - Collider_CylinderUpdate(&this->dyna.actor, &this->collider); - CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider); + Collider_UpdateCylinder(&this->dyna.actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); } } diff --git a/src/code/z_en_item00.c b/src/code/z_en_item00.c index 4a67a7172..af464beeb 100644 --- a/src/code/z_en_item00.c +++ b/src/code/z_en_item00.c @@ -499,8 +499,8 @@ void EnItem00_Update(Actor* thisx, GlobalContext* globalCtx) { } } - Collider_CylinderUpdate(&this->actor, &this->collider); - CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider); + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); if ((this->actor.params == ITEM00_SHIELD_DEKU) || (this->actor.params == ITEM00_SHIELD_HYLIAN) || (this->actor.params == ITEM00_TUNIC_ZORA) || (this->actor.params == ITEM00_TUNIC_GORON)) { diff --git a/src/code/z_play.c b/src/code/z_play.c index 12d1b07bd..fba0e5a4c 100644 --- a/src/code/z_play.c +++ b/src/code/z_play.c @@ -237,7 +237,7 @@ void Gameplay_Init(GameState* thisx) { func_8006BA00(globalCtx); Effect_InitContext(globalCtx); EffectSs_InitInfo(globalCtx, 0x55); - func_8005D3BC(globalCtx, &globalCtx->colChkCtx); + CollisionCheck_InitContext(globalCtx, &globalCtx->colChkCtx); AnimationContext_Reset(&globalCtx->animationCtx); func_8006450C(globalCtx, &globalCtx->csCtx); @@ -835,7 +835,7 @@ void Gameplay_Update(GlobalContext* globalCtx) { LOG_NUM("1", 1, "../z_play.c", 3612); } - func_8006139C(globalCtx, &globalCtx->colChkCtx); + CollisionCheck_AT(globalCtx, &globalCtx->colChkCtx); if (1 && HREG(63)) { LOG_NUM("1", 1, "../z_play.c", 3618); @@ -847,13 +847,13 @@ void Gameplay_Update(GlobalContext* globalCtx) { LOG_NUM("1", 1, "../z_play.c", 3624); } - func_800622E4(globalCtx, &globalCtx->colChkCtx); + CollisionCheck_Damage(globalCtx, &globalCtx->colChkCtx); if (1 && HREG(63)) { LOG_NUM("1", 1, "../z_play.c", 3631); } - CollisionCheck_InitContext(globalCtx, &globalCtx->colChkCtx); + CollisionCheck_ClearContext(globalCtx, &globalCtx->colChkCtx); if (1 && HREG(63)) { LOG_NUM("1", 1, "../z_play.c", 3637); diff --git a/src/code/z_player_lib.c b/src/code/z_player_lib.c index db619db67..248998e21 100644 --- a/src/code/z_player_lib.c +++ b/src/code/z_player_lib.c @@ -945,7 +945,7 @@ u8 func_80090480(GlobalContext* globalCtx, ColliderQuad* collider, WeaponInfo* w Vec3f* newBase) { if (weaponInfo->active == 0) { if (collider != NULL) { - Collider_QuadSetAT(globalCtx, &collider->base); + Collider_ResetQuadAT(globalCtx, &collider->base); } Math_Vec3f_Copy(&weaponInfo->tip, newTip); Math_Vec3f_Copy(&weaponInfo->base, newBase); @@ -955,12 +955,12 @@ u8 func_80090480(GlobalContext* globalCtx, ColliderQuad* collider, WeaponInfo* w (weaponInfo->tip.z == newTip->z) && (weaponInfo->base.x == newBase->x) && (weaponInfo->base.y == newBase->y) && (weaponInfo->base.z == newBase->z)) { if (collider != NULL) { - Collider_QuadSetAT(globalCtx, &collider->base); + Collider_ResetQuadAT(globalCtx, &collider->base); } return 0; } else { if (collider != NULL) { - func_80062734(collider, newBase, newTip, &weaponInfo->base, &weaponInfo->tip); + Collider_SetQuadVertices(collider, newBase, newTip, &weaponInfo->base, &weaponInfo->tip); CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &collider->base); } Math_Vec3f_Copy(&weaponInfo->base, newBase); @@ -972,22 +972,22 @@ u8 func_80090480(GlobalContext* globalCtx, ColliderQuad* collider, WeaponInfo* w void func_80090604(GlobalContext* globalCtx, Player* this, ColliderQuad* collider, Vec3f* quadSrc) { static u8 shieldColTypes[PLAYER_SHIELD_MAX] = { - COLTYPE_METAL_SHIELD, - COLTYPE_WOODEN_SHIELD, - COLTYPE_METAL_SHIELD, - COLTYPE_METAL_SHIELD, + COLTYPE_METAL, + COLTYPE_WOOD, + COLTYPE_METAL, + COLTYPE_METAL, }; if (this->stateFlags1 & 0x400000) { Vec3f quadDest[4]; - this->shieldQuad.base.type = shieldColTypes[this->currentShield]; + this->shieldQuad.base.colType = shieldColTypes[this->currentShield]; Matrix_MultVec3f(&quadSrc[0], &quadDest[0]); Matrix_MultVec3f(&quadSrc[1], &quadDest[1]); Matrix_MultVec3f(&quadSrc[2], &quadDest[2]); Matrix_MultVec3f(&quadSrc[3], &quadDest[3]); - func_80062734(collider, &quadDest[0], &quadDest[1], &quadDest[2], &quadDest[3]); + Collider_SetQuadVertices(collider, &quadDest[0], &quadDest[1], &quadDest[2], &quadDest[3]); CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &collider->base); CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &collider->base); |
