/** * d_cc_s.cpp * */ #include "d/dolzel.h" // IWYU pragma: keep #include "d/d_cc_s.h" #include "d/d_com_inf_game.h" #include "d/d_jnt_col.h" #include "f_op/f_op_actor_mng.h" #if TARGET_PC #include "dusk/settings.h" #endif class dCcS_HIO : public JORReflexible { public: enum flags_e { FLAG_CAM_COL_DISP_e = 0x1, FLAG_AT_ON_e = 0x2, FLAG_TG_ON_e = 0x4, FLAG_CO_ON_e = 0x8, FLAG_DRAW_CLEAR_OFF_e = 0x10, FLAG_COUNTER_e = 0x20, FLAG_MOVE_OFF_e = 0x40, FLAG_MASS_OFF_e = 0x80, FLAG_MOVE_TIMER_e = 0x100, FLAG_MASS_TIMER_e = 0x200, FLAG_MASS_COUNTER_e = 0x400, FLAG_ALL_MASS_TIMER_e = 0x800, }; dCcS_HIO() { m_flags = 0; m_shield_range = 0x4000; } virtual ~dCcS_HIO(); void genMessage(JORMContext*); BOOL ChkMoveTimer() { return m_flags & FLAG_MOVE_TIMER_e; } BOOL ChkMoveOff() { return m_flags & FLAG_MOVE_OFF_e; } BOOL ChkAllMassTimer() { return m_flags & FLAG_ALL_MASS_TIMER_e; } BOOL ChkDrawClearOff() { return m_flags & FLAG_DRAW_CLEAR_OFF_e; } BOOL ChkCounter() { return m_flags & FLAG_COUNTER_e; } BOOL ChkCamColDisp() { return m_flags & FLAG_CAM_COL_DISP_e; } BOOL CheckCoOn() { return m_flags & FLAG_CO_ON_e; } BOOL CheckTgOn() { return m_flags & FLAG_TG_ON_e; } BOOL CheckAtOn() { return m_flags & FLAG_AT_ON_e; } BOOL ChkMassCounter() { return m_flags & FLAG_MASS_COUNTER_e; } BOOL ChkMassOff() { return m_flags & FLAG_MASS_OFF_e; } BOOL ChkMassTimer() { return m_flags & FLAG_MASS_TIMER_e; } /* 0x4 */ s8 id; /* 0x6 */ u16 m_flags; /* 0x8 */ s16 m_shield_range; }; dCcS_HIO::~dCcS_HIO() {} void dCcS_HIO::genMessage(JORMContext* mctx) { #if DEBUG mctx->genLabel("処理関係 -----", 0); mctx->genCheckBox("処理Off", &m_flags, 0x40); mctx->genCheckBox("多数ヒットチェック(草木花)Off", &m_flags, 0x80); mctx->genCheckBox("多数ヒット 1回時間", &m_flags, 0x200); mctx->genCheckBox("多数ヒット 通しの処理時間(->terminal)", &m_flags, 0x800); mctx->genCheckBox("多数ヒット チェックカウンタ", &m_flags, 0x400); mctx->genCheckBox("処理時間(->terminal)", &m_flags, 0x100); mctx->genLabel("描画関係 -----", 0); mctx->genCheckBox("At 描画", &m_flags, 2); mctx->genCheckBox("Tg 描画", &m_flags, 4); mctx->genCheckBox("Co 描画", &m_flags, 8); mctx->genCheckBox("カメラCo描画", &m_flags, 1); mctx->genCheckBox("クリアOff", &m_flags, 0x10); mctx->genLabel("情報(->terminal) -----", 0); mctx->genCheckBox("個数", &m_flags, 0x20); mctx->genLabel("特殊-----", 0); mctx->genSlider("盾範囲(max=360度)", &m_shield_range, 0, 0x7FFF); #endif } #if DEBUG static OSStopwatch s_move_timer; static OSStopwatch s_mass_timer; int g_mass_counter; #endif static dCcS_HIO s_Hio; void dCcS::Ct() { cCcS::Ct(); #if DEBUG m_is_mass_all_timer = 0; s_Hio.id = mDoHIO_CREATE_CHILD("zelda コリジョンシステム", &s_Hio); OSInitStopwatch(&s_move_timer, "CollsionCheckMove"); OSResetStopwatch(&s_move_timer); OSInitStopwatch(&s_mass_timer, "MassCheck"); OSResetStopwatch(&s_mass_timer); g_mass_counter = 0; #endif mMass_Mng.Ct(); #if DEBUG dJntCol_setDebugHIO(); #endif } void dCcS::Dt() { cCcS::Dt(); #if DEBUG mDoHIO_DELETE_CHILD(s_Hio.id); dJntCol_deleteDebugHIO(); #endif } bool dCcS::ChkShieldFrontRange(cCcD_Obj* i_atObj, cCcD_Obj* i_tgObj, int param_2, cXyz const* i_hitPos) { dCcD_GObjInf* atObj = (dCcD_GObjInf*)i_atObj->GetGObjInf(); if (atObj == NULL) { return false; } dCcD_GObjInf* tgObj = (dCcD_GObjInf*)i_tgObj->GetGObjInf(); if (tgObj == NULL) { return false; } fopAc_ac_c* tgActor = tgObj->GetAc(); if (tgActor == NULL) { return false; } csXyz sp10; CalcParticleAngle(atObj, i_atObj->GetStts(), i_tgObj->GetStts(), &sp10); if (param_2 != 0) { dJntCol_c* jntcol = fopAcM_GetJntCol(tgActor); if (jntcol != NULL) { cXyz pos; csXyz angle; int temp_r3 = jntcol->getHitmarkPosAndAngle(i_hitPos, &sp10, &pos, &angle, 0); if (temp_r3 >= 0 && jntcol->checkShieldType(temp_r3)) { cXyz sp18; mDoMtx_stack_c::ZXYrotS(sp10); mDoMtx_stack_c::multVecSR(&cXyz::BaseZ, &sp18); mDoMtx_stack_c::ZXYrotS(angle); mDoMtx_stack_c::multVecSR(&cXyz::BaseZ, &pos); if (pos.inprod(sp18) > 0.0f) { return true; } else { return false; } } return false; } } s16 var_r4; if (tgObj->GetTgShieldFrontRangeYAngle() != NULL) { var_r4 = *tgObj->GetTgShieldFrontRangeYAngle(); } else { var_r4 = fopAcM_GetShapeAngle_p(tgActor)->y; } s16 shield_range = tgObj->GetTgShieldRange(); if (param_2 != 0) { shield_range >>= 1; } if (cLib_distanceAngleS(sp10.y - -0x8000, var_r4) > shield_range) { return false; } return true; } bool dCcS::ChkShield(cCcD_Obj* i_atObj, cCcD_Obj* i_tgObj, dCcD_GObjInf* i_atObjInf, dCcD_GObjInf* i_tgObjInf, cXyz const* i_hitPos) { if (i_atObjInf->ChkAtNoGuard()) { return false; } if (i_tgObjInf->ChkTgShield() || i_tgObjInf->ChkTgSpShield() || (i_tgObjInf->ChkTgSmallShield() && i_atObjInf->GetAtSpl() == 8)) { if (i_tgObjInf->ChkTgShieldFrontRange()) { return ChkShieldFrontRange(i_atObj, i_tgObj, !i_tgObjInf->ChkTgShield(), i_hitPos); } return true; } return false; } void dCcS::CalcTgPlusDmg(cCcD_Obj* i_atObj, cCcD_Obj* i_tgObj, cCcD_Stts* i_atStts, cCcD_Stts* i_tgStts) {} bool dCcS::ChkAtTgHitAfterCross(bool i_setAt, bool i_setTg, cCcD_GObjInf const* i_atObjInf, cCcD_GObjInf const* i_tgObjInf, cCcD_Stts* i_atStts, cCcD_Stts* i_tgStts, cCcD_GStts* i_atGStts, cCcD_GStts* i_tgGStts) { fpc_ProcID tgApid = i_atStts->GetApid(); fpc_ProcID atApid = i_tgStts->GetApid(); dCcD_GObjInf* atObjInf = (dCcD_GObjInf*)i_atObjInf; dCcD_GObjInf* tgObjInf = (dCcD_GObjInf*)i_tgObjInf; if (i_setAt) { static_cast(i_atGStts)->SetAtApid(atApid); if (atObjInf->ChkAtNoConHit() && !tgObjInf->ChkTgStopNoConHit()) { if (static_cast(i_atGStts)->GetAtOldApid() == i_tgStts->GetApid()) { return true; } } } if (i_setTg) { static_cast(i_tgGStts)->SetTgApid(tgApid); if (tgObjInf->ChkTgNoConHit() && !atObjInf->ChkAtStopNoConHit()) { if (static_cast(i_tgGStts)->GetTgOldApid() == i_atStts->GetApid()) { return true; } } } return false; } void dCcS::SetCoGObjInf(bool i_co1Set, bool i_co2Set, cCcD_GObjInf* i_co1Obj, cCcD_GObjInf* i_co2Obj, cCcD_Stts* i_co1Stts, cCcD_Stts* i_co2Stts, cCcD_GStts* i_co1GStts, cCcD_GStts* i_co2GStts) { dCcD_GObjInf* co1Obj = (dCcD_GObjInf*)i_co1Obj; dCcD_GObjInf* co2Obj = (dCcD_GObjInf*)i_co2Obj; dCcD_GStts* co1GStts = (dCcD_GStts*)i_co1GStts; dCcD_GStts* co2GStts = (dCcD_GStts*)i_co2GStts; if (i_co1Set) { co1Obj->SetCoHitApid(i_co2Stts->GetApid()); if (co2GStts->ChkNoActor()) { co1Obj->OnCoHitNoActor(); } } if (i_co2Set) { co2Obj->SetCoHitApid(i_co1Stts->GetApid()); if (co1GStts->ChkNoActor()) { co2Obj->OnCoHitNoActor(); } } if (i_co1Set) { dCcD_HitCallback cb = co1Obj->GetCoHitCallback(); if (cb != NULL) { cb(co1Obj->GetAc(), co1Obj, co2Obj->GetAc(), co2Obj); } } if (i_co2Set) { dCcD_HitCallback cb = co2Obj->GetCoHitCallback(); if (cb != NULL) { cb(co2Obj->GetAc(), co2Obj, co1Obj->GetAc(), co1Obj); } } } int dCcS::GetRank(u8 weight) { if (weight == 255) { return 10; } if (weight == 254) { return 9; } if (weight >= 217) { return 8; } if (weight >= 181) { return 7; } if (weight >= 145) { return 6; } if (weight >= 109) { return 5; } if (weight >= 73) { return 4; } if (weight >= 37) { return 3; } if (weight >= 2) { return 2; } if (weight == 1) { return 1; } return 0; } bool dCcS::ChkNoHitGCo(cCcD_Obj* i_co1Obj, cCcD_Obj* i_co2Obj) { return false; } static u8 rank_tbl[11][11] = { 0x00, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x00, 0x32, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x00, 0x00, 0x32, 0x4B, 0x5A, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x00, 0x00, 0x19, 0x32, 0x4B, 0x5A, 0x64, 0x64, 0x64, 0x64, 0x64, 0x00, 0x00, 0x0A, 0x19, 0x32, 0x4B, 0x5A, 0x64, 0x64, 0x64, 0x64, 0x00, 0x00, 0x00, 0x0A, 0x19, 0x32, 0x4B, 0x5A, 0x64, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x19, 0x32, 0x4B, 0x5A, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x19, 0x32, 0x4B, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x19, 0x32, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; void dCcS::SetPosCorrect(cCcD_Obj* i_co1Obj, cXyz* i_pos1, cCcD_Obj* i_co2Obj, cXyz* i_pos2, f32 i_cross_len) { if (i_co1Obj->ChkCoNoCrr() || i_co2Obj->ChkCoNoCrr()) { return; } if (i_co1Obj->GetStts() == NULL || i_co2Obj->GetStts() == NULL) { return; } if (cM3d_IsZero(i_cross_len)) { return; } SetCoGCorrectProc(i_co1Obj, i_co2Obj); bool bvar2 = false; if (i_co1Obj->ChkCoSph3DCrr() && i_co2Obj->ChkCoSph3DCrr()) { bvar2 = true; } if ((i_co1Obj->GetStts()->GetWeightUc() == 0 && i_co2Obj->GetStts()->GetWeightUc() == 0) || (i_co1Obj->GetStts()->GetWeightUc() == 0xFF && i_co2Obj->GetStts()->GetWeightUc() == 0xFF)) { return; } int co1_rank = GetRank(i_co1Obj->GetStts()->GetWeightUc()); int co2_rank = GetRank(i_co2Obj->GetStts()->GetWeightUc()); u8 rank = rank_tbl[co1_rank][co2_rank]; u8 var_r22 = 100 - rank; f32 fvar1 = rank * 0.01f; f32 fvar2 = var_r22 * 0.01f; cXyz co1_move; cXyz co2_move; Vec local_c8; f32 fvar14; if (bvar2) { PSVECSubtract(i_pos2, i_pos1, &local_c8); fvar14 = PSVECMag(&local_c8); } else { local_c8.x = i_pos2->x - i_pos1->x; local_c8.y = 0.0f; local_c8.z = i_pos2->z - i_pos1->z; fvar14 = JMAFastSqrt((local_c8.x * local_c8.x) + (local_c8.z * local_c8.z)); } if (!cM3d_IsZero(fvar14)) { if (bvar2) { f32 var_f26 = i_cross_len / fvar14; PSVECScale(&local_c8, &local_c8, var_f26); fvar1 *= -1.0f; PSVECScale(&local_c8, &co1_move, fvar1); PSVECScale(&local_c8, &co2_move, fvar2); } else { f32 var_f27 = i_cross_len / fvar14; local_c8.x *= var_f27; local_c8.z *= var_f27; co1_move.x = -local_c8.x * fvar1; co1_move.y = 0.0f; co1_move.z = -local_c8.z * fvar1; co2_move.x = local_c8.x * fvar2; co2_move.y = 0.0f; co2_move.z = local_c8.z * fvar2; } } else { co1_move.y = 0.0f; co1_move.z = 0.0f; co2_move.y = 0.0f; co2_move.z = 0.0f; if (!cM3d_IsZero(i_cross_len)) { co1_move.x = -i_cross_len * fvar1; co2_move.x = i_cross_len * fvar2; } else { co1_move.x = -fvar1; co2_move.x = fvar2; } } i_co1Obj->GetStts()->PlusCcMove(co1_move.x, co1_move.y, co1_move.z); i_co2Obj->GetStts()->PlusCcMove(co2_move.x, co2_move.y, co2_move.z); *i_pos1 += co1_move; *i_pos2 += co2_move; } void dCcS::CalcParticleAngle(dCcD_GObjInf* i_atObjInf, cCcD_Stts* i_atStts, cCcD_Stts* i_tgStts, csXyz* o_angle) { cXyz vec(*i_atObjInf->GetAtVecP()); if (cM3d_IsZero(PSVECMag(&vec))) { fopAc_ac_c* atActor = i_atStts->GetActor(); fopAc_ac_c* tgActor = i_tgStts->GetActor(); if (atActor == NULL || tgActor == NULL) { vec.x = vec.z = 0.0f; vec.y = -1.0f; } else { PSVECSubtract(&tgActor->current.pos, &atActor->current.pos, &vec); if (cM3d_IsZero(PSVECMag(&vec))) { vec.x = vec.z = 0.0f; vec.y = -1.0f; } else { PSVECNormalize(&vec, &vec); } } } else { PSVECNormalize(&vec, &vec); } cM3d_CalcVecZAngle(vec, o_angle); } void dCcS::ProcAtTgHitmark(bool i_setAt, bool i_setTg, cCcD_Obj* param_2, cCcD_Obj* param_3, dCcD_GObjInf* i_atObjInf, dCcD_GObjInf* i_tgObjInf, cCcD_Stts* param_6, cCcD_Stts* param_7, dCcD_GStts* param_8, dCcD_GStts* param_9, cXyz* i_hitPos, bool i_chkShield) { if (i_setAt) {} if (i_setTg) {} if (param_2) {} if (param_3) {} if (i_atObjInf->ChkAtNoHitMark()) { return; } if (i_tgObjInf->ChkTgNoHitMark()) { return; } if ( ( i_atObjInf->GetAtType() == AT_TYPE_10000000 && i_tgObjInf->GetAc() != NULL && !fopAcM_CheckStatus(i_tgObjInf->GetAc(), AT_TYPE_10000000) ) || ( ( i_atObjInf->GetAtType() & (AT_TYPE_WOLF_ATTACK | AT_TYPE_WOLF_CUT_TURN | AT_TYPE_10000000 | AT_TYPE_MIDNA_LOCK | AT_TYPE_HOOKSHOT | AT_TYPE_SHIELD_ATTACK | AT_TYPE_NORMAL_SWORD) ) && i_tgObjInf->GetTgSpl() == dCcG_Tg_Spl_UNK_1 ) ) { return; } if (i_atObjInf->GetAtType() == AT_TYPE_HOOKSHOT && i_tgObjInf->ChkTgHookShotNoHitMark()) { return; } if (i_atObjInf->GetAtType() == AT_TYPE_ARROW && i_tgObjInf->ChkTgArrowNoHitMark()) { return; } if (!param_9->ChkNoneActorPerfTblId()) { return; } if (!i_chkShield) { if ((i_atObjInf->GetAtHitMark() != 0 || i_tgObjInf->GetTgHitMark() == 8) && (i_atObjInf->GetAtHitMark() != 4 || i_tgObjInf->GetTgHitMark() != 4)) { csXyz sp10; CalcParticleAngle(i_atObjInf, param_6, param_7, &sp10); if (i_tgObjInf->GetTgHitMark() == 5 || i_tgObjInf->GetTgHitMark() == 8) { dComIfGp_setHitMark(2, i_tgObjInf->GetAc(), i_hitPos, &sp10, NULL, i_atObjInf->GetAtType()); } else { u16 hitmark; if (i_tgObjInf->GetTgHitMark() == 3) { hitmark = 3; } else { hitmark = i_atObjInf->GetAtHitMark(); } if ((hitmark != 1 && hitmark != 3) || i_atObjInf->GetAtAtp() != 0) { dComIfGp_setHitMark(hitmark, i_tgObjInf->GetAc(), i_hitPos, &sp10, NULL, i_atObjInf->GetAtType()); } } } } else if (i_tgObjInf->GetTgHitMark() != 0) { csXyz sp8; CalcParticleAngle(i_atObjInf, param_6, param_7, &sp8); dComIfGp_setHitMark(i_tgObjInf->GetTgHitMark(), i_tgObjInf->GetAc(), i_hitPos, &sp8, NULL, i_atObjInf->GetAtType()); } } void dCcS::SetAtTgGObjInf(bool i_setAt, bool i_setTg, cCcD_Obj* i_atObj, cCcD_Obj* i_tgObj, cCcD_GObjInf* i_atObjInf, cCcD_GObjInf* i_tgObjInf, cCcD_Stts* i_atStts, cCcD_Stts* i_tgStts, cCcD_GStts* i_atGStts, cCcD_GStts* i_tgGStts, cXyz* i_hitPos) { dCcD_GObjInf* atObjInf = (dCcD_GObjInf*)i_atObjInf; dCcD_GObjInf* tgObjInf = (dCcD_GObjInf*)i_tgObjInf; dCcD_GStts* at_gstts = (dCcD_GStts*)i_atGStts; dCcD_GStts* tg_gstts = (dCcD_GStts*)i_tgGStts; bool chk_shield = ChkShield(i_atObj, i_tgObj, atObjInf, tgObjInf, i_hitPos); if (i_setAt) { atObjInf->SetAtHitPos(*i_hitPos); atObjInf->SetAtRVec(*tgObjInf->GetTgVecP()); if (at_gstts != NULL && at_gstts->GetTgSpl() == 0) { at_gstts->SetTgSpl(tgObjInf->GetTgSpl()); } atObjInf->SetAtHitApid(i_tgStts->GetApid()); if (chk_shield || (tgObjInf->GetTgHitMark() == 8 && atObjInf->GetAtMtrl() != dCcD_MTRL_ICE && (atObjInf->GetAtSpl() == 0 || atObjInf->GetAtSpl() == 5 || atObjInf->GetAtSpl() == 8))) { atObjInf->OnAtShieldHit(); } if (tg_gstts->ChkNoActor()) { atObjInf->OnAtHitNoActor(); } } if (i_setTg) { tgObjInf->SetTgHitPos(*i_hitPos); tgObjInf->SetTgRVec(*atObjInf->GetAtVecP()); if (tg_gstts != NULL && at_gstts->GetAtSpl() == 0) { tg_gstts->SetAtSpl(atObjInf->GetAtSpl()); } tgObjInf->SetTgHitApid(i_atStts->GetApid()); if (chk_shield) { tgObjInf->OnTgShieldHit(); } else { int atp = i_atObj->GetAtAtp(); i_tgStts->PlusDmg(atp); } if (at_gstts->ChkNoActor()) { tgObjInf->OnTgHitNoActor(); } } if (i_setAt) { dCcD_HitCallback at_callback = atObjInf->GetAtHitCallback(); if (at_callback != NULL) { at_callback(atObjInf->GetAc(), atObjInf, tgObjInf->GetAc(), tgObjInf); } } if (i_setTg) { dCcD_HitCallback tg_callback = tgObjInf->GetTgHitCallback(); if (tg_callback != NULL) { tg_callback(tgObjInf->GetAc(), tgObjInf, atObjInf->GetAc(), atObjInf); } } if (i_setAt && i_setTg && (!atObjInf->ChkAtEffCounter() || !tgObjInf->ChkTgEffCounter())) { atObjInf->SetAtEffCounterTimer(); tgObjInf->SetTgEffCounterTimer(); ProcAtTgHitmark(i_setAt, i_setTg, i_atObj, i_tgObj, atObjInf, tgObjInf, i_atStts, i_tgStts, at_gstts, tg_gstts, i_hitPos, chk_shield); } } bool dCcS::ChkCamera(cXyz& param_0, cXyz& param_1, f32 param_2, fopAc_ac_c* param_3, fopAc_ac_c* param_4, fopAc_ac_c* param_5) { if (mObjCoCount == 0) { return false; } cCcD_Obj** temp_r29 = &mpObjCo[mObjCoCount]; cCcD_CpsAttr sp48; sp48.Set(param_0, param_1, param_2); sp48.CalcAabBox(); cCcD_DivideInfo sp18; f32 sp14; mDivideArea.CalcDivideInfoOverArea(&sp18, sp48.GetWorkAab()); for (cCcD_Obj** i = mpObjCo; i < temp_r29; i++) { if ((*i)->ChkCoSet() && (*i)->GetAc() != param_3 && (*i)->GetAc() != param_4 && (*i)->GetAc() != param_5) { if ((*i)->GetPDivideInfo()->Chk(sp18)) { dCcD_GObjInf* obj = (dCcD_GObjInf*)(*i)->GetGObjInf(); if (obj == NULL || !obj->ChkCoNoCamHit()) { cCcD_ShapeAttr* pco_sa = (*i)->GetShapeAttr(); JUT_ASSERT(1058, pco_sa != NULL); if (sp48.CrossCo(*pco_sa, &sp14)) { return true; } } } } } return false; } #if PLATFORM_WII BOOL dCcS::ChkLine(cXyz& i_p_start, cXyz& i_p_end, f32 i_radius, fopAc_ac_c** o_actor) { u16 obj_co_count = mObjCoCount; if (obj_co_count == 0) { return 0; } cCcD_Obj** max_obj_pp = &mpObjCo[mObjCoCount]; cCcD_CpsAttr cps_attr; cps_attr.Set(i_p_start, i_p_end, i_radius); cps_attr.CalcAabBox(); *o_actor = NULL; f32 z_max = -FLT_MAX; cCcD_DivideInfo sp18; mDivideArea.CalcDivideInfoOverArea(&sp18, cps_attr.mAab); cCcD_Obj** obj_pp = mpObjCo; while (obj_pp < max_obj_pp) { cCcD_Obj* obj_p = *obj_pp; if (obj_p->GetObjCo().getSPrm() & 1) { fopAc_ac_c* temp_r31 = dComIfGp_getPlayer(0); if (obj_p->GetAc() != temp_r31 && (*obj_pp)->GetDivideInfo().Chk(sp18) != 0) { f32 sp8; if ((*obj_pp)->GetShapeAttr()->CrossCo(cps_attr, &sp8) != 0) { fopAc_ac_c* actor = (*obj_pp)->GetAc(); if (actor != NULL && actor->attention_info.flags & (fopAc_AttnFlag_LOCK_e | fopAc_AttnFlag_BATTLE_e)) { Vec spC; PSMTXMultVec(dComIfGd_getViewMtx(), &actor->current.pos, &spC); if (spC.z < 0.0f && spC.z > z_max) { *o_actor = actor; z_max = spC.z; } } } } } obj_pp++; } return *o_actor != NULL; } #endif bool dCcS::chkCameraPoint(cXyz const& param_0, cCcD_ShapeAttr::Shape* param_1, fopAc_ac_c* param_2, fopAc_ac_c* param_3) { if (mObjCoCount == 0) { return false; } cCcD_Obj** temp_r29 = &mpObjCo[mObjCoCount]; cCcD_SphAttr sp48; cCcD_SrcSphAttr sp1C; sp1C.mSph.mCenter = param_0; sp1C.mSph.mRadius = 1.0f; sp48.Set(sp1C); sp48.CalcAabBox(); cCcD_DivideInfo sp18; f32 sp14; mDivideArea.CalcDivideInfoOverArea(&sp18, sp48.GetWorkAab()); for (cCcD_Obj** i = mpObjCo; i < temp_r29; i++) { if ((*i)->ChkCoSet() && (*i)->GetAc() != param_2 && (*i)->GetAc() != param_3) { if ((*i)->GetPDivideInfo()->Chk(sp18)) { dCcD_GObjInf* obj = (dCcD_GObjInf*)(*i)->GetGObjInf(); if (obj == NULL || !obj->ChkCoNoCamHit()) { cCcD_ShapeAttr* pco_sa = (*i)->GetShapeAttr(); JUT_ASSERT(1196, pco_sa != NULL); if (sp48.CrossCo(*pco_sa, &sp14)) { pco_sa->getShapeAccess(param_1); if (param_1->_0 != 2) { return true; } } } } } } return false; } void dCcS::MoveAfterCheck() {} void dCcS::DrawAfter() {} void dCcS::Move() { #if DEBUG if (s_Hio.ChkAllMassTimer()) { OnMassAllTimer(); } else { OffMassAllTimer(); } if (s_Hio.ChkMoveOff()) { return; } if (s_Hio.ChkMoveTimer()) { OSStartStopwatch(&s_move_timer); } #endif cCcS::Move(); #if DEBUG if (s_Hio.ChkMoveTimer()) { OSStopStopwatch(&s_move_timer); OSDumpStopwatch(&s_move_timer); } #endif } void dCcS::Draw() { #if DEBUG if (s_Hio.ChkMassCounter()) { OS_REPORT("Mass Counter %d\n", g_mass_counter); g_mass_counter = 0; } #endif #if TARGET_PC #define DUSK_TOGGLE_HIO_FLAG(status, flag) \ if (status) { \ s_Hio.m_flags |= flag; \ } else { \ s_Hio.m_flags &= ~flag; \ } const auto& collisionViewSettings = dusk::getTransientSettings().collisionView; DUSK_TOGGLE_HIO_FLAG(collisionViewSettings.enableAtView, dCcS_HIO::FLAG_AT_ON_e); DUSK_TOGGLE_HIO_FLAG(collisionViewSettings.enableTgView, dCcS_HIO::FLAG_TG_ON_e); DUSK_TOGGLE_HIO_FLAG(collisionViewSettings.enableCoView, dCcS_HIO::FLAG_CO_ON_e); f32 view_opacity = 255 * (collisionViewSettings.colliderViewOpacity / 100.0f); #endif if (s_Hio.CheckAtOn()) { for (int i = 0; i < field_0x280c; i++) { if (mpObjAt[i] != NULL && mpObjAt[i]->ChkAtSet()) { dCcD_GObjInf* gobj = (dCcD_GObjInf*)mpObjAt[i]->GetGObjInf(); if (gobj->ChkAtHit()) { GXColor color = {0xFF, 0, 0, 0xB4}; color.a = view_opacity; mpObjAt[i]->Draw(color); } else { GXColor color = {0xFF, 0, 0, 0x50}; color.a = view_opacity; mpObjAt[i]->Draw(color); } } } } if (s_Hio.CheckTgOn()) { for (int i = 0; i < field_0x280e; i++) { if (mpObjTg[i] != NULL && mpObjTg[i]->ChkTgSet()) { dCcD_GObjInf* gobj = (dCcD_GObjInf*)mpObjTg[i]->GetGObjInf(); if (gobj->ChkTgHit()) { GXColor color = {0, 0xFF, 0, 0xB4}; color.a = view_opacity; mpObjTg[i]->Draw(color); } else { GXColor color = {0, 0xFF, 0, 0x50}; color.a = view_opacity; mpObjTg[i]->Draw(color); } } } } if (s_Hio.CheckCoOn()) { for (int i = 0; i < field_0x2810; i++) { if (mpObjCo[i] != NULL && mpObjCo[i]->ChkCoSet()) { dCcD_GObjInf* gobj = (dCcD_GObjInf*)mpObjCo[i]->GetGObjInf(); if (gobj->ChkCoHit()) { GXColor color = {0xFF, 0xFF, 0xFF, 0xB4}; color.a = view_opacity; mpObjCo[i]->Draw(color); } else { GXColor color = {0xFF, 0xFF, 0xFF, 0x50}; color.a = view_opacity; mpObjCo[i]->Draw(color); } } } } if (s_Hio.ChkCamColDisp()) { for (int i = 0; i < field_0x2810; i++) { if (mpObjCo[i] != NULL && mpObjCo[i]->ChkCoSet()) { dCcD_GObjInf* gobj = (dCcD_GObjInf*)mpObjCo[i]->GetGObjInf(); if (!gobj->ChkCoNoCamHit()) { GXColor color = {0xFF, 0xFF, 0, 0x50}; mpObjCo[i]->Draw(color); } } } } #if DEBUG if (s_Hio.ChkCounter()) { OS_REPORT("At:%d,Tg:%d,Co:%d\n", field_0x280c, field_0x280e, field_0x2810); } #endif DrawAfter(); #if DEBUG if (!s_Hio.ChkDrawClearOff()) #endif { DrawClear(); } mMass_Mng.Clear(); } void dCcS::MassClear() { mMass_Mng.Clear(); } // clang-format off bool dCcS::m_mtrl_hit_tbl[64] = { true, true, true, true, true, true, true, true, false, true, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, true, false, true, true, true, true, false, true, true, true, }; // clang-format on BOOL dCcS::ChkAtTgMtrlHit(u8 i_atMtrl, u8 i_tgMtrl) { return m_mtrl_hit_tbl[i_atMtrl + i_tgMtrl * 8]; } bool dCcS::ChkNoHitGAtTg(cCcD_GObjInf const* i_atObjInf, cCcD_GObjInf const* i_tgObjInf, cCcD_GStts* i_atStts, cCcD_GStts* i_tgStts) { UNUSED(i_atStts); UNUSED(i_tgStts); dCcD_GObjInf* atObjInf = (dCcD_GObjInf*)i_atObjInf; dCcD_GObjInf* tgObjInf = (dCcD_GObjInf*)i_tgObjInf; if (tgObjInf->ChkTgWolfSpNoDamage() && atObjInf->GetAtMtrl() == dCcD_MTRL_NONE && atObjInf->GetAtType() & (AT_TYPE_CSTATUE_BOSS_SWING | AT_TYPE_1000 | AT_TYPE_800 | AT_TYPE_CSTATUE_SWING)) { return true; } return ChkAtTgMtrlHit(atObjInf->GetAtMtrl(), tgObjInf->GetTgMtrl()) == 0; }