Add audio cues to assist with ranged aiming

pull/1949/head
Ryan Conrad 2022-04-12 23:51:31 -05:00
parent d4af085a3f
commit 6a7d503c77
4 changed files with 222 additions and 18 deletions
soh
src
overlays/actors/ovl_player_actor

View File

@ -269,7 +269,8 @@ typedef enum {
/* 4 */ ELEMTYPE_UNK4,
/* 5 */ ELEMTYPE_UNK5,
/* 6 */ ELEMTYPE_UNK6,
/* 7 */ ELEMTYPE_UNK7
/* 7 */ ELEMTYPE_UNK7,
/* 8 */ ELEMTYPE_SENSING
} ElementType;
#define AT_NONE 0 // No flags set. Cannot have AT collisions when set as AT

View File

@ -1702,23 +1702,25 @@ s32 CollisionCheck_SetATvsAC(GlobalContext* globalCtx, Collider* at, ColliderInf
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 {
CollisionCheck_HitEffects(globalCtx, at, atInfo, ac, acInfo, hitPos);
atInfo->toucherFlags |= TOUCH_DREW_HITMARK;
if (atInfo->elemType != ELEMTYPE_SENSING) {
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 {
CollisionCheck_HitEffects(globalCtx, at, atInfo, ac, acInfo, hitPos);
atInfo->toucherFlags |= TOUCH_DREW_HITMARK;
}
}
return 1;
}

View File

@ -1260,6 +1260,193 @@ Vec3f D_801261E0[] = {
{ 200.0f, 200.0f, 0.0f },
};
#define AIMCUE_COLLIDER_COUNT 5
static ColliderQuad sAimCueCollider[AIMCUE_COLLIDER_COUNT];
static s32 sAimSurfaceHookshotable;
static s32 sAimLastHookshotableState;
static ColliderQuadInit sSensingColliderInit = {
{
COLTYPE_NONE,
AT_ON | AT_TYPE_PLAYER,
AC_NONE,
OC1_ON | OC1_TYPE_ALL,
OC2_TYPE_2 | OC2_TYPE_1,
COLSHAPE_QUAD,
},
{
ELEMTYPE_SENSING,
{ 0xFFFFFFFF, 0x00, 0x00 },
{ 0xFFFFFFFF, 0x00, 0x00 },
TOUCH_ON | TOUCH_NEAREST | TOUCH_SFX_NONE,
BUMP_NONE,
OCELEM_NONE,
},
{ { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } },
};
void Player_InitAimCueCollision(Player* this, GlobalContext* globalCtx) {
for (int i = 0; i < AIMCUE_COLLIDER_COUNT; i++) {
Collider_InitQuad(globalCtx, &sAimCueCollider[i]);
Collider_SetQuad(globalCtx, &sAimCueCollider[i], NULL, &sSensingColliderInit);
}
}
void Player_UpdateAimCue(Player* this, GlobalContext* globalCtx) {
Actor* hitActor = NULL;
for (int i = 0; i < AIMCUE_COLLIDER_COUNT; i++) {
if (sAimCueCollider[i].base.atFlags & AT_HIT) {
sAimCueCollider[i].base.atFlags &= ~AC_HIT;
if (hitActor == NULL && sAimCueCollider[i].base.at != NULL) {
hitActor = sAimCueCollider[i].base.at;
} else {
continue;
}
if (i != 0 && (globalCtx->gameplayFrames % 1) != 0) {
continue;
}
u16 soundEffect = (i == 0) ? NA_SE_SY_HITPOINT_ALARM : NA_SE_SY_FSEL_CURSOR;
if (hitActor->category == ACTORCAT_ENEMY || hitActor->category == ACTORCAT_BOSS) {
Audio_PlaySoundGeneral(soundEffect, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
} else if (hitActor->category == ACTORCAT_SWITCH) {
Audio_PlaySoundGeneral(soundEffect, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
} else if (hitActor->category == ACTORCAT_NPC) {
Audio_PlaySoundGeneral(soundEffect, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
} else if (hitActor->category == ACTORCAT_PROP &&
(hitActor->id == ACTOR_EN_DNT_NOMAL && hitActor->params == 0) ||
hitActor->id == ACTOR_EN_G_SWITCH) {
// lost woods slingshot target, shooting gallery rupees
Audio_PlaySoundGeneral(soundEffect, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
}
}
}
if (sAimSurfaceHookshotable != sAimLastHookshotableState) {
if (sAimSurfaceHookshotable) {
Audio_PlaySoundGeneral(NA_SE_SY_LOCK_ON_HUMAN, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
} else {
Audio_PlaySoundGeneral(NA_SE_SY_LOCK_OFF, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
}
sAimLastHookshotableState = sAimSurfaceHookshotable;
}
}
void Player_ComputeAimCue(Player* this, GlobalContext* globalCtx, s32 limbIndex) {
if (this->heldItemId == 0) {
return;
}
bool isHoldingHookshotType = Player_HoldsHookshot(this);
if (!isHoldingHookshotType && limbIndex != PLAYER_LIMB_L_HAND ||
isHoldingHookshotType && limbIndex != PLAYER_LIMB_R_HAND) {
return;
}
sAimSurfaceHookshotable = 0;
bool isCharged = (this->stateFlags1 & 0x200) && (this->unk_834 <= 10) && (this->unk_860 >= 0);
bool isAiming = !!func_8002DD78(this);
if (!isAiming || !(isCharged || isHoldingHookshotType)) {
return;
}
CollisionPoly* polyResult;
s32 bgId;
Matrix_Push();
f32 distance;
Vec3f vecCenter;
Vec3f vecCenterFar;
Vec3f vecA;
Vec3f vecB;
Vec3f vecC;
Vec3f vecD;
Vec3f vecResult;
Vec3f vecZero = { 0.0f, 0.0f, 0.0f };
Vec3f vecLeft = { 0.0f, 50.0f, 0.0f };
Vec3f vecRight = { 0.0f, -50.0f, 0.0f };
if (isHoldingHookshotType) {
if (this->heldItemActionParam == PLAYER_AP_HOOKSHOT) {
distance = 38600.0f;
} else {
distance = 77600.0f;
}
Matrix_Translate(0.0f, 150.0f, -100.0f, MTXMODE_APPLY);
} else {
distance = 200000.0f;
Matrix_Translate(-550.0f, -50.0f, -100.0f, MTXMODE_APPLY);
}
Matrix_MultVec3f(&vecZero, &vecCenter);
vecZero.z = distance;
Matrix_MultVec3f(&vecZero, &vecCenterFar);
if (BgCheck_AnyLineTest3(&globalCtx->colCtx, &vecCenter, &vecCenterFar, &vecResult, &polyResult, 1, 1, 1, 1,
&bgId)) {
sAimSurfaceHookshotable =
isHoldingHookshotType && SurfaceType_IsHookshotSurface(&globalCtx->colCtx, polyResult, bgId);
distance *= Math_Vec3f_DistXYZ(&vecCenter, &vecResult) / Math_Vec3f_DistXYZ(&vecCenter, &vecCenterFar);
}
if (!isCharged) {
Matrix_Pop();
return;
}
Matrix_MultVec3f(&vecLeft, &vecA);
Matrix_MultVec3f(&vecRight, &vecB);
vecLeft.z = distance;
vecRight.z = distance;
Matrix_MultVec3f(&vecLeft, &vecC);
Matrix_MultVec3f(&vecRight, &vecD);
Collider_SetQuadVertices(&sAimCueCollider[0], &vecA, &vecB, &vecC, &vecD);
CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &sAimCueCollider[0].base);
Matrix_Scale(500.0f, 500.0f, 1.0f, MTXMODE_APPLY);
f32 rotateOffset = (globalCtx->gameplayFrames % 4) * M_PI / 16;
Matrix_RotateZ(rotateOffset, MTXMODE_APPLY);
for (int i = 1; i < AIMCUE_COLLIDER_COUNT; i++) {
if (i > 1) {
Matrix_RotateZ(M_PI / 4, MTXMODE_APPLY);
}
vecLeft.z = 0;
vecLeft.y = 0.5;
vecRight.z = 0;
vecRight.y = -0.5;
Matrix_MultVec3f(&vecLeft, &vecA);
Matrix_MultVec3f(&vecRight, &vecB);
vecLeft.z = distance * 1.2;
vecLeft.y = sqrtf(distance) * 0.2f;
vecRight.z = distance * 1.2;
vecRight.y = sqrtf(distance) * -0.2f;
Matrix_MultVec3f(&vecLeft, &vecC);
Matrix_MultVec3f(&vecRight, &vecD);
Collider_SetQuadVertices(&sAimCueCollider[i], &vecA, &vecB, &vecC, &vecD);
CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &sAimCueCollider[i].base);
}
Matrix_Pop();
}
void func_80090D20(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) {
Player* this = (Player*)thisx;
@ -1413,9 +1600,11 @@ void func_80090D20(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s*
heldActor->shape.rot = heldActor->world.rot;
if (func_8002DD78(this) != 0) {
Matrix_Push();
Matrix_Translate(500.0f, 300.0f, 0.0f, MTXMODE_APPLY);
Player_DrawHookshotReticle(
globalCtx, this, (this->heldItemActionParam == PLAYER_AP_HOOKSHOT) ? 38600.0f : 77600.0f);
Matrix_Pop();
}
}
}
@ -1452,6 +1641,10 @@ void func_80090D20(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s*
Actor_SetFeetPos(&this->actor, limbIndex, PLAYER_LIMB_L_FOOT, vec, PLAYER_LIMB_R_FOOT, vec);
}
}
if (CVar_GetS32("gAimAudioCues", 0)) {
Player_ComputeAimCue(this, globalCtx, limbIndex);
}
}
u32 func_80091738(GlobalContext* globalCtx, u8* segment, SkelAnime* skelAnime) {

View File

@ -9363,6 +9363,10 @@ void Player_InitCommon(Player* this, GlobalContext* globalCtx, FlexSkeletonHeade
Collider_SetQuad(globalCtx, &this->swordQuads[1], &this->actor, &D_80854650);
Collider_InitQuad(globalCtx, &this->shieldQuad);
Collider_SetQuad(globalCtx, &this->shieldQuad, &this->actor, &D_808546A0);
if (CVar_GetS32("gAimAudioCues", 0)) {
Player_InitAimCueCollision(this, globalCtx);
}
}
static void (*D_80854738[])(GlobalContext* globalCtx, Player* this) = {
@ -10723,6 +10727,10 @@ void Player_UpdateCommon(Player* this, GlobalContext* globalCtx, Input* input) {
Collider_ResetQuadAC(globalCtx, &this->shieldQuad.base);
Collider_ResetQuadAT(globalCtx, &this->shieldQuad.base);
if (CVar_GetS32("gAimAudioCues", 0)) {
Player_UpdateAimCue(this, globalCtx);
}
}
static Vec3f D_80854838 = { 0.0f, 0.0f, -30.0f };