Skip to content

Commit

Permalink
CWeapon:SetUpPelletCol + Fix a few bugs (#738)
Browse files Browse the repository at this point in the history
* Fix `CMatrix::operator=`
* `SetUpPelletCol`
* Fix `CTaskSimpleUseGun`

Co-authored-by: yukani <yukani@zohomail.eu>

---------

Co-authored-by: yukani <yukani@zohomail.eu>
  • Loading branch information
Pirulax and yukani authored Jul 10, 2024
1 parent f6e0847 commit 787d79e
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 15 deletions.
8 changes: 4 additions & 4 deletions source/game_sa/Core/Matrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,10 +505,10 @@ void CMatrix::ConvertFromEulerAngles(float x, float y, float z, uint32 uiFlags)
m_up.Set (fArr[2][0], fArr[2][1], fArr[2][2]);
}

void CMatrix::operator=(const CMatrix& rvalue)
{
CMatrix::CopyOnlyMatrix(rvalue);
CMatrix::UpdateRW();
void CMatrix::operator=(const CMatrix& other) {
m_pAttachMatrix = other.m_pAttachMatrix;
CopyOnlyMatrix(other);
UpdateRW();
}

void CMatrix::operator+=(const CMatrix& rvalue)
Expand Down
6 changes: 5 additions & 1 deletion source/game_sa/Tasks/TaskTypes/TaskComplexEnterCar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ CTask* CTaskComplexEnterCar::CreateNextSubTask(CPed* ped) {
return C(m_DraggedPed ? TASK_SIMPLE_WAIT_UNTIL_PED_OUT_CAR : TASK_FINISHED);
}
case TASK_COMPLEX_FALL_AND_GET_UP:
case TASK_SIMPLE_CAR_DRIVE_TIMED:
return C(TASK_FINISHED);
default:
NOTSA_UNREACHABLE("SubTaskType = {}", tt);
Expand Down Expand Up @@ -518,7 +519,10 @@ CTask* CTaskComplexEnterCar::CreateFirstSubTask(CPed* ped) {
}

if (ped->bInVehicle) {
return C(ped->m_pVehicle == m_Car ? TASK_SIMPLE_CAR_DRIVE_TIMED : TASK_COMPLEX_LEAVE_CAR);
return C(ped->m_pVehicle == m_Car
? TASK_SIMPLE_CAR_DRIVE_TIMED
: TASK_COMPLEX_LEAVE_CAR
);
}

if (m_Car->IsBoat()) {
Expand Down
16 changes: 11 additions & 5 deletions source/game_sa/Tasks/TaskTypes/TaskSimpleUseGun.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "TaskSimpleUseGun.h"
#include "TaskSimpleGetUp.h"
#include "TaskSimpleDuck.h"
#include "TaskSimpleFight.h"

void CTaskSimpleUseGun::InjectHooks() {
RH_ScopedVirtualClass(CTaskSimpleUseGun, 0x86D724, 9);
Expand Down Expand Up @@ -782,7 +783,9 @@ void CTaskSimpleUseGun::StartAnim(CPed* ped) {
m_Anim = CAnimManager::BlendAnimation( // 0x62503A
ped->m_pRwClump,
m_WeaponInfo->m_eAnimGroup,
ped->bIsDucking && m_WeaponInfo->flags.bCrouchFire ? ANIM_ID_CROUCHFIRE : ANIM_ID_FIRE
ped->bIsDucking && m_WeaponInfo->flags.bCrouchFire
? ANIM_ID_CROUCHFIRE
: ANIM_ID_FIRE
);

if (m_LastCmd == eGunCommand::RELOAD) {
Expand All @@ -809,7 +812,9 @@ void CTaskSimpleUseGun::StartAnim(CPed* ped) {
m_Anim = CAnimManager::BlendAnimation( // 0x62511C
ped->m_pRwClump,
m_WeaponInfo->m_eAnimGroup,
ped->bIsDucking && m_WeaponInfo->flags.bCrouchFire ? ANIM_ID_CROUCHRELOAD : ANIM_ID_RELOAD
ped->bIsDucking && m_WeaponInfo->flags.bCrouchFire
? ANIM_ID_CROUCHRELOAD
: ANIM_ID_RELOAD
);
m_Anim->Start();
m_Anim->SetFinishCallback(FinishGunAnimCB, this);
Expand All @@ -825,11 +830,12 @@ void CTaskSimpleUseGun::StartAnim(CPed* ped) {
if (tDuck && tDuck->StopFireGun()) {
return;
}

m_Anim = CAnimManager::BlendAnimation( // 0x6251DC
ped->m_pRwClump,
ANIM_GROUP_DEFAULT,
ped->bIsDucking ? ANIM_ID_FIGHT_2 : ANIM_ID_FIGHT_1
CTaskSimpleFight::m_aComboData[12].m_nAnimGroup,
ped->bIsDucking
? ANIM_ID_FIGHT_2
: ANIM_ID_FIGHT_1
);
m_Anim->SetFinishCallback(FinishGunAnimCB, this);
break;
Expand Down
95 changes: 90 additions & 5 deletions source/game_sa/Weapon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ void CWeapon::InjectHooks() {
RH_ScopedInstall(GenerateDamageEvent, 0x73A530);
RH_ScopedInstall(FireInstantHitFromCar2, 0x73CBA0);
RH_ScopedInstall(Update, 0x73DB40);
RH_ScopedInstall(SetUpPelletCol, 0x73C710, { .reversed = false });
RH_ScopedInstall(SetUpPelletCol, 0x73C710);
RH_ScopedInstall(FireAreaEffect, 0x73E800);
RH_ScopedInstall(FireInstantHitFromCar, 0x73EC40, { .reversed = false });
RH_ScopedInstall(FireFromCar, 0x73FA20);
Expand Down Expand Up @@ -501,12 +501,13 @@ void CWeapon::DoBulletImpact(CEntity* firedBy, CEntity* victim, const CVector& s

const auto DoBulletHitFx = [&] {
if (incrementalHit <= 0) {
if ((endPoint - startPoint).Dot(hitCP.m_vecNormal) < 0.f) { // Normal is opposite to that of the bullet's direction
const auto angle = (endPoint - startPoint).Normalized().Dot(hitCP.m_vecNormal);
if (angle < 0.f) { // Normal is opposite to that of the bullet's direction
AudioEngine.ReportBulletHit(
victim,
hitCP.m_nSurfaceTypeB,
hitCP.m_vecPoint,
RWRAD2DEG((float)std::asin(-incrementalHit))
RWRAD2DEG(std::asin(-angle))
);
}
}
Expand Down Expand Up @@ -845,8 +846,92 @@ bool CWeapon::TakePhotograph(CEntity* owner, CVector* point) {
}

// 0x73C710
void CWeapon::SetUpPelletCol(int32 numPellets, CEntity* owner, CEntity* victim, CVector& point, CColPoint& colPoint, CMatrix& outMatrix) {
plugin::CallMethod<0x73C710, CWeapon*, int32, CEntity*, CEntity*, CVector&, CColPoint&, CMatrix&>(this, numPellets, owner, victim, point, colPoint, outMatrix);
void CWeapon::SetUpPelletCol(int32 numPellets, CEntity* owner, CEntity* victim, CVector& point, CColPoint& colPoint, CMatrix& outMat) {
constexpr int32 MAX_NUM_PELLETS = 15;

assert(numPellets <= MAX_NUM_PELLETS);

auto* const cm = &ms_PelletTestCol;
if (!cm->GetData()) {
cm->AllocateData(0, 0, MAX_NUM_PELLETS, 0, 0, false);
cm->GetBoundingSphere().Set(1.f, {0.f, 0.f, 0.f});
cm->m_nColSlot = 0;
}
auto* const cd = ms_PelletTestCol.GetData();

auto hitDir = (colPoint.m_vecPoint - point);
const float depth = hitDir.NormaliseAndMag() * CWorld::fWeaponSpreadRate * 1.3f;

//> 0x73C806 - Create pellet lines
cd->m_nNumLines = (uint8)numPellets;
const auto lines = cd->GetLines();
lines[0].Set(
{ 0.f, -depth, 0.f },
{ 0.f, depth, 0.f }
);
for (int32 i = 1; i < numPellets; i++) {
const auto angle = CGeneral::GetRandomNumberInRange(-PI, PI);
const auto spread = CGeneral::GetRandomNumberInRange(0.f, depth * 0.8f);

const auto oX = std::cos(angle) * spread;
const auto oZ = std::sin(angle) * spread;

lines[i].Set(
{ oX, -depth * 2.f, oZ },
{ oX, depth * 2.f, oZ }
);
}

//> 0x73C923 - Calculate bounding volumes
cm->GetBoundingBox().Set(
{ -depth, -depth * 2.f, -depth },
{ depth, depth * 2.f, depth }
);
cm->GetBoundingSphere().Set(
depth * 2.5f,
{0.f, 0.f, 0.f}
);

const auto CalculateMatrixRotation = [&](CVector fwd, CVector zaxis) {
const auto r = zaxis.Cross(fwd).Normalized();
outMat.GetForward() = fwd;
outMat.GetRight() = r;
outMat.GetUp() = r.Cross(fwd);
};

if (victim->IsBuilding()) { // 0x73C98E
const auto& n = colPoint.m_vecNormal;
CalculateMatrixRotation(
-n,
std::abs(n.z) >= 0.9f
? CVector{0.f, 1.f, 0.f}
: CVector{1.f, 0.f, 0.f}
);

} else if (std::abs(hitDir.z) <= 0.9f) { // 0x73CA4C
CalculateMatrixRotation(
hitDir,
{0.f, 0.f, 1.f}
);
} else if (!owner->IsPed()) { // 0x73CA59
CalculateMatrixRotation(
hitDir,
{1.f, 0.f, 0.f}
);
} else { // 0x73CA5B
CalculateMatrixRotation(
hitDir,
owner->GetForward()
);
}

// 0x73CAFF
outMat.GetPosition() = colPoint.m_vecPoint;

// 0x73CB1A
if (!victim->IsBuilding()) {
outMat.GetPosition() -= colPoint.m_vecNormal.ProjectOnToNormal(outMat.GetForward()) * depth;
}
}

// 0x73CBA0
Expand Down

0 comments on commit 787d79e

Please sign in to comment.