From 80be6cf8a9b0827d72968c34534eba4f49981b99 Mon Sep 17 00:00:00 2001 From: FileEX Date: Fri, 21 Feb 2025 19:15:23 +0100 Subject: [PATCH 1/5] Refactor --- Client/game_sa/CWeaponInfoSA.h | 3 + Client/game_sa/CWeaponSA.cpp | 379 ++++++++------------------------- Client/game_sa/CWeaponSA.h | 111 ++++++---- Client/sdk/game/CWeapon.h | 67 +++--- 4 files changed, 192 insertions(+), 368 deletions(-) diff --git a/Client/game_sa/CWeaponInfoSA.h b/Client/game_sa/CWeaponInfoSA.h index bfe401b6de..0325143b6d 100644 --- a/Client/game_sa/CWeaponInfoSA.h +++ b/Client/game_sa/CWeaponInfoSA.h @@ -19,6 +19,7 @@ class CEntitySAInterface; // Flame shot array for flamethrower flames and maybe molotovs #define ARRAY_CFlameShotInfo 0xC89690 #define MAX_FLAME_SHOT_INFOS 100 +#define FUNC_CWeaponInfo_GetWeaponReloadTime 0x743D70 class CFlameShotInfo { @@ -88,6 +89,8 @@ class CWeaponInfoSAInterface // 112 byte long class ///////////////////////////////// BYTE m_defaultCombo; // base combo for this melee weapon BYTE m_nCombosAvailable; // how many further combos are available + + int GetWeaponReloadTime() { return ((int(__thiscall*)(CWeaponInfoSAInterface*))FUNC_CWeaponInfo_GetWeaponReloadTime)(this); } }; class CWeaponInfoSA : public CWeaponInfo diff --git a/Client/game_sa/CWeaponSA.cpp b/Client/game_sa/CWeaponSA.cpp index d419734b8e..b6e1257cde 100644 --- a/Client/game_sa/CWeaponSA.cpp +++ b/Client/game_sa/CWeaponSA.cpp @@ -1,11 +1,11 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory * FILE: game_sa/CWeaponSA.cpp * PURPOSE: Weapon class * - * Multi Theft Auto is available from http://www.multitheftauto.com/ + * Multi Theft Auto is available from https://www.multitheftauto.com/ * *****************************************************************************/ @@ -20,230 +20,83 @@ extern CGameSA* pGame; -CWeaponSA::CWeaponSA(CWeaponSAInterface* pInterface, CPed* pOwner, eWeaponSlot weaponSlot) - : m_pInterface{pInterface}, m_pOwner{pOwner}, m_weaponSlot{weaponSlot} +CWeaponInfo* CWeaponSA::GetInfo(const eWeaponSkill& skill) const { -} - -void CWeaponSA::Destroy() -{ - if (!m_pOwner) - { - delete m_pInterface; - delete this; - } -} - -eWeaponType CWeaponSA::GetType() -{ - return m_pInterface->m_eWeaponType; -}; - -void CWeaponSA::SetType(eWeaponType type) -{ - m_pInterface->m_eWeaponType = type; -} - -eWeaponState CWeaponSA::GetState() -{ - return m_pInterface->m_eState; -} - -void CWeaponSA::SetState(eWeaponState state) -{ - m_pInterface->m_eState = state; -} - -DWORD CWeaponSA::GetAmmoInClip() -{ - return m_pInterface->m_nAmmoInClip; -} - -void CWeaponSA::SetAmmoInClip(DWORD dwAmmoInClip) -{ - m_pInterface->m_nAmmoInClip = dwAmmoInClip; -} - -DWORD CWeaponSA::GetAmmoTotal() -{ - return m_pInterface->m_nAmmoTotal; -} - -void CWeaponSA::SetAmmoTotal(DWORD dwAmmoTotal) -{ - m_pInterface->m_nAmmoTotal = dwAmmoTotal; -} - -CPed* CWeaponSA::GetPed() -{ - return m_pOwner; -} - -eWeaponSlot CWeaponSA::GetSlot() -{ - return m_weaponSlot; + return m_interface ? pGame->GetWeaponInfo(m_interface->m_eWeaponType, skill) : nullptr; } void CWeaponSA::SetAsCurrentWeapon() { - m_pOwner->SetCurrentWeaponSlot(m_weaponSlot); + if (m_owner) + m_owner->SetCurrentWeaponSlot(m_weaponSlot); } -CWeaponInfo* CWeaponSA::GetInfo(eWeaponSkill skill) +void CWeaponSA::Destroy() { - return pGame->GetWeaponInfo(m_pInterface->m_eWeaponType, skill); + if (m_interface) + delete m_interface; + + delete this; } void CWeaponSA::Remove() { - DWORD dwFunc = FUNC_Shutdown; - DWORD dwThis = (DWORD)m_pInterface; - _asm - { - mov ecx, dwThis - call dwFunc - } + if (!m_interface) + return; + + m_interface->Shutdown(); // If the removed weapon was the currently active weapon, switch to empty-handed - if (m_pOwner->GetCurrentWeaponSlot() == m_weaponSlot) + if (m_owner && m_owner->GetCurrentWeaponSlot() == m_weaponSlot) { - CWeaponInfo* pInfo = pGame->GetWeaponInfo(m_pInterface->m_eWeaponType); - if (pInfo) - { - int iModel = pInfo->GetModel(); - m_pOwner->RemoveWeaponModel(iModel); - } - m_pOwner->SetCurrentWeaponSlot(WEAPONSLOT_TYPE_UNARMED); + if (CWeaponInfo* info = pGame->GetWeaponInfo(m_interface->m_eWeaponType)) + m_owner->RemoveWeaponModel(info->GetModel()); + + m_owner->SetCurrentWeaponSlot(WEAPONSLOT_TYPE_UNARMED); } } -void CWeaponSA::Initialize(eWeaponType type, unsigned int uiAmmo, CPed* pPed) +void CWeaponSA::Initialize(const eWeaponType& type, std::uint32_t ammo, CPed* ped) { - DWORD dwPedInterface = 0; - if (pPed) - dwPedInterface = (DWORD)pPed->GetInterface(); - unsigned int uiType = (unsigned int)type; - DWORD dwThis = (DWORD)m_pInterface; - DWORD dwFunc = FUNC_CWeapon_Initialize; - _asm - { - mov ecx, dwThis - push dwPedInterface - push uiAmmo - push uiType - call dwFunc - } + if (m_interface) + m_interface->Initialize(type, ammo, ped); } -void CWeaponSA::Update(CPed* pPed) +void CWeaponSA::Update(CPed* ped) { // Note: CWeapon::Update is called mainly to check for reload - DWORD dwPedInterface = (DWORD)pPed->GetInterface(); - DWORD dwThis = (DWORD)m_pInterface; - DWORD dwFunc = FUNC_CWeapon_Update; - _asm - { - mov ecx, dwThis - push dwPedInterface - call dwFunc - } + if (m_interface) + m_interface->Update(ped); } -bool CWeaponSA::Fire(CEntity* pFiringEntity, CVector* pvecOrigin, CVector* pvecTarget, CEntity* pTargetEntity, CVector* pvec_1, CVector* pvec_2) +void CWeaponSA::AddGunshell(CEntity* firingEntity, CVector* vecOrigin, CVector2D* vecDirection, float size) const { - bool bReturn; - DWORD dwFiringInterface = 0; - if (pFiringEntity) - dwFiringInterface = (DWORD)pFiringEntity->GetInterface(); - DWORD dwTargetInterface = 0; - if (pTargetEntity) - dwTargetInterface = (DWORD)pTargetEntity->GetInterface(); - DWORD dwThis = (DWORD)m_pInterface; - DWORD dwFunc = FUNC_CWeapon_Fire; - _asm - { - mov ecx, dwThis - push pvec_2 - push pvec_1 - push dwTargetInterface - push pvecTarget - push pvecOrigin - push dwFiringInterface - call dwFunc - mov bReturn, al - } - return bReturn; + if (m_interface && firingEntity) + m_interface->AddGunshell(firingEntity, vecOrigin, vecDirection, size); } -void CWeaponSA::AddGunshell(CEntity* pFiringEntity, CVector* pvecOrigin, CVector2D* pvecDirection, float fSize) +void CWeaponSA::DoBulletImpact(CEntity* firingEntity, CEntitySAInterface* hitEntityInterface, CVector* vecOrigin, CVector* vecTarget, CColPoint* colPoint, int incrementalHit) const { - DWORD dwEntityInterface = 0; - if (pFiringEntity) - dwEntityInterface = (DWORD)pFiringEntity->GetInterface(); - DWORD dwThis = (DWORD)m_pInterface; - DWORD dwFunc = FUNC_CWeapon_AddGunshell; - _asm - { - mov ecx, dwThis - push fSize - push pvecDirection - push pvecOrigin - push dwEntityInterface - call dwFunc - } + if (m_interface) + m_interface->DoBulletImpact(firingEntity, hitEntityInterface, vecOrigin, vecTarget, colPoint, incrementalHit); } -void CWeaponSA::DoBulletImpact(CEntity* pFiringEntity, CEntitySAInterface* pEntityInterface, CVector* pvecOrigin, CVector* pvecTarget, CColPoint* pColPoint, - int i_1) +bool CWeaponSA::Fire(CEntity* firingEntity, CVector* vecOrigin, CVector* vecEffectPos, CEntity* targetEntity, CVector* vecTarget, CVector* vecAlt) { - DWORD dwEntityInterface = 0; - if (pFiringEntity) - dwEntityInterface = (DWORD)pFiringEntity->GetInterface(); - DWORD dwEntityInterface_2 = (DWORD)pEntityInterface; - DWORD dwColPointInterface = 0; - if (pColPoint) - dwColPointInterface = (DWORD)pColPoint->GetInterface(); - DWORD dwThis = (DWORD)m_pInterface; - DWORD dwFunc = FUNC_CWeapon_DoBulletImpact; - _asm - { - mov ecx, dwThis - push i_1 - push dwColPointInterface - push pvecTarget - push pvecOrigin - push dwEntityInterface_2 - push dwEntityInterface - call dwFunc - } + if (!firingEntity) + return false; + + return m_interface ? m_interface->Fire(firingEntity, vecOrigin, vecEffectPos, targetEntity, vecTarget, vecAlt) : false; } -unsigned char CWeaponSA::GenerateDamageEvent(CPed* pPed, CEntity* pResponsible, eWeaponType weaponType, int iDamagePerHit, ePedPieceTypes hitZone, int i_2) +bool CWeaponSA::FireInstantHit(CEntity* firingEntity, const CVector* vecOrigin, const CVector* vecMuzzle, CEntity* targetEntity, const CVector* vecTarget, const CVector* vecForDriveby, bool crossHairGun, bool createGunFx) { - unsigned int ucReturn; - DWORD dwPedInterface = (DWORD)pPed->GetInterface(); - DWORD dwResponsibleInterface = 0; - if (pResponsible) - dwResponsibleInterface = (DWORD)pResponsible->GetInterface(); - DWORD dwFunc = FUNC_CWeapon_GenerateDamageEvent; - _asm - { - push i_2 - push hitZone - push iDamagePerHit - push weaponType - push dwResponsibleInterface - push dwPedInterface - call dwFunc - add esp, 24 - mov ucReturn, eax - } - return (unsigned char)ucReturn; + return m_interface ? m_interface->FireInstantHit(firingEntity, const_cast(vecOrigin), const_cast(vecMuzzle), targetEntity, const_cast(vecTarget), const_cast(vecForDriveby), crossHairGun, createGunFx) : false; } -bool CWeaponSA::FireBullet(CEntity* pFiringEntity, const CVector& vecOrigin, const CVector& vecTarget) +bool CWeaponSA::FireBullet(CEntity* firingEntity, const CVector& vecOrigin, const CVector& vecTarget) { - if (!pFiringEntity) + if (!firingEntity) return false; switch (GetType()) @@ -264,145 +117,89 @@ bool CWeaponSA::FireBullet(CEntity* pFiringEntity, const CVector& vecOrigin, con case WEAPONTYPE_MINIGUN: { // Don't hit shooter - pGame->GetWorld()->IgnoreEntity(pFiringEntity); + pGame->GetWorld()->IgnoreEntity(firingEntity); // Do pre shot lag compensation - CPlayerPed* pFiringPlayerPed = dynamic_cast(pFiringEntity); - if (pGame->m_pPreWeaponFireHandler && pFiringPlayerPed) - pGame->m_pPreWeaponFireHandler(pFiringPlayerPed, false); + CPlayerPed* firingPlayerPed = dynamic_cast(firingEntity); + if (pGame->m_pPreWeaponFireHandler && firingPlayerPed) + pGame->m_pPreWeaponFireHandler(firingPlayerPed, false); // Get the gun muzzle position - float fSkill = 999.f; - CWeaponStat* pCurrentWeaponInfo = pGame->GetWeaponStatManager()->GetWeaponStatsFromSkillLevel(GetType(), fSkill); - CVector vecGunMuzzle = *pCurrentWeaponInfo->GetFireOffset(); - if (pFiringPlayerPed) - pFiringPlayerPed->GetTransformedBonePosition(BONE_RIGHTWRIST, &vecGunMuzzle); + CWeaponStat* currentWeaponInfo = pGame->GetWeaponStatManager()->GetWeaponStatsFromSkillLevel(GetType(), 999.0f); + CVector vecGunMuzzle = *currentWeaponInfo->GetFireOffset(); + if (firingPlayerPed) + firingPlayerPed->GetTransformedBonePosition(BONE_RIGHTWRIST, &vecGunMuzzle); // Bullet trace - FireInstantHit(pFiringEntity, &vecOrigin, &vecGunMuzzle, nullptr, &vecTarget, nullptr, false, true); + FireInstantHit(firingEntity, &vecOrigin, &vecGunMuzzle, nullptr, &vecTarget, nullptr, false, true); // Fire sound - if (pFiringPlayerPed) - pFiringPlayerPed->AddWeaponAudioEvent(EPedWeaponAudioEvent::FIRE); + if (firingPlayerPed) + firingPlayerPed->AddWeaponAudioEvent(EPedWeaponAudioEvent::FIRE); // Do post shot lag compensation reset & script events - if (pGame->m_pPostWeaponFireHandler && pFiringPlayerPed) + if (pGame->m_pPostWeaponFireHandler && firingPlayerPed) pGame->m_pPostWeaponFireHandler(); pGame->GetWorld()->IgnoreEntity(nullptr); - return true; } default: break; } + return false; } -bool CWeaponSA::FireInstantHit(CEntity* pFiringEntity, const CVector* pvecOrigin, const CVector* pvecMuzzle, CEntity* pTargetEntity, const CVector* pvecTarget, - const CVector* pvec, bool bFlag1, bool bFlag2) +bool CWeaponSA::GenerateDamageEvent(CPed* ped, CEntity* responsible, eWeaponType weaponType, int damagePerHit, ePedPieceTypes hitZone, std::uint8_t dir) const { - bool bReturn; - DWORD dwEntityInterface = 0; - if (pFiringEntity) - dwEntityInterface = (DWORD)pFiringEntity->GetInterface(); - DWORD dwTargetInterface = 0; - if (pTargetEntity) - dwTargetInterface = (DWORD)pTargetEntity->GetInterface(); - DWORD dwThis = (DWORD)m_pInterface; - DWORD dwFunc = FUNC_CWeapon_FireInstantHit; - _asm - { - mov ecx, dwThis - push bFlag2 - push bFlag1 - push pvec - push pvecTarget - push dwTargetInterface - push pvecMuzzle - push pvecOrigin - push dwEntityInterface - call dwFunc - mov bReturn, al - } - return bReturn; + if (!ped || !m_interface) + return false; + + return m_interface->GenerateDamageEvent(ped, responsible, weaponType, damagePerHit, hitZone, dir); } -bool CWeaponSA::ProcessLineOfSight(const CVector* vecStart, const CVector* vecEnd, CColPoint** colCollision, CEntity** CollisionEntity, - const SLineOfSightFlags flags, SLineOfSightBuildingResult* pBuildingResult, eWeaponType weaponType, - CEntitySAInterface** pEntity) +bool CWeaponSA::ProcessLineOfSight(const CVector* vecStart, const CVector* vecEnd, CColPoint** colCollision, CEntity** collisionEntity, const SLineOfSightFlags& flags, SLineOfSightBuildingResult* buildingResult, const eWeaponType& weaponType, CEntitySAInterface** entity) { - DWORD dwFunction = FUNC_CBirds_CheckForHit; - _asm - { - push vecEnd - push vecStart - call dwFunction - } - dwFunction = FUNC_CShadows_CheckForHit; - _asm - { - push vecEnd - push vecStart - call dwFunction - } - bool bReturn = pGame->GetWorld()->ProcessLineOfSight(vecStart, vecEnd, colCollision, CollisionEntity, flags, pBuildingResult); - _asm - { - add esp, 10h - } + // Call CBirds::HandleGunShot + ((void(__cdecl*)(CVector*, CVector*))FUNC_CBirds_CheckForHit)(const_cast(vecStart), const_cast(vecEnd)); + + // Call CShadows::GunShotSetsOilOnFire + ((void(__cdecl*)(CVector*, CVector*))FUNC_CShadows_CheckForHit)(const_cast(vecStart), const_cast(vecEnd)); - if (bReturn) + bool hit = pGame->GetWorld()->ProcessLineOfSight(vecStart, vecEnd, colCollision, collisionEntity, flags, buildingResult); + + if (hit) { - if (*CollisionEntity) - { - *pEntity = (*CollisionEntity)->GetInterface(); - } + if (*collisionEntity) + *entity = (*collisionEntity)->GetInterface(); else { - if (pBuildingResult->bValid) - *pEntity = pBuildingResult->pInterface; - } - } - if (*pEntity && (*pEntity)->nType == ENTITY_TYPE_VEHICLE) - { - CEntitySAInterface* pHitInterface = *pEntity; - CColPointSAInterface* pColPointSAInterface = (*colCollision)->GetInterface(); - DWORD dwFunc = FUNC_CWeapon_CheckForShootingVehicleOccupant; - _asm - { - push vecEnd - push vecStart - push weaponType - push pColPointSAInterface - lea eax, pHitInterface - push eax - call dwFunc - add esp, 14h + if (buildingResult->bValid) + *entity = buildingResult->pInterface; } } - return bReturn; + + // Call CWeapon::CheckForShootingVehicleOccupant + if (*entity && (*entity)->nType == ENTITY_TYPE_VEHICLE) + ((void(__cdecl*)(CEntitySAInterface*, CColPointSAInterface*, eWeaponType, CVector*, CVector*))FUNC_CWeapon_CheckForShootingVehicleOccupant)(*entity, (*colCollision)->GetInterface(), weaponType, const_cast(vecStart), const_cast(vecEnd)); + + return hit; } -int CWeaponSA::GetWeaponReloadTime(CWeaponStat* pWeaponStat) +int CWeaponSA::GetWeaponReloadTime(CWeaponStat* weaponStat) const { - CWeaponStatSA* pWeaponStats = (CWeaponStatSA*)pWeaponStat; - DWORD dwReturn = 0; - DWORD dwFunction = FUNC_CWeaponInfo_GetWeaponReloadTime; - DWORD dwInterface = (DWORD)pWeaponStats->GetInterface(); - _asm - { - mov ecx, dwInterface - call dwFunction - mov dwReturn, eax - } - return dwReturn; + auto* weaponStats = static_cast(weaponStat); + if (CWeaponInfoSAInterface* statInterface = weaponStats->GetInterface()) + return statInterface->GetWeaponReloadTime(); + + return 0; } -int CWeaponSA::GetWeaponFireTime(CWeaponStat* pWeaponStat) +int CWeaponSA::GetWeaponFireTime(CWeaponStat* weaponStat) { - int iGlobalTimer = pGame->GetSystemTime(); - float fWeaponFireTime = (pWeaponStat->GetWeaponAnimLoopStop() - pWeaponStat->GetWeaponAnimLoopStart()) * 1000.0f; - return (int)fWeaponFireTime; + std::uint32_t timer = pGame->GetSystemTime(); + float weaponFireTime = (weaponStat->GetWeaponAnimLoopStop() - weaponStat->GetWeaponAnimLoopStart()) * 1000.0f; + return static_cast(weaponFireTime); } diff --git a/Client/game_sa/CWeaponSA.h b/Client/game_sa/CWeaponSA.h index 147f9017d9..6cd8fbc4e4 100644 --- a/Client/game_sa/CWeaponSA.h +++ b/Client/game_sa/CWeaponSA.h @@ -1,11 +1,11 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory * FILE: game_sa/CWeaponSA.h * PURPOSE: Header file for weapon class * - * Multi Theft Auto is available from http://www.multitheftauto.com/ + * Multi Theft Auto is available from https://www.multitheftauto.com/ * *****************************************************************************/ @@ -14,7 +14,7 @@ #include #include -#define FUNC_Shutdown 0x73A380 +#define FUNC_CWeapon_Shutdown 0x73A380 #define FUNC_CWeapon_CheckForShootingVehicleOccupant 0x73f480 #define FUNC_CWeapon_Initialize 0x73b4a0 #define FUNC_CWeapon_Update 0x73db40 @@ -23,58 +23,77 @@ #define FUNC_CWeapon_DoBulletImpact 0x73b550 #define FUNC_CWeapon_GenerateDamageEvent 0x73a530 #define FUNC_CWeapon_FireInstantHit 0x73FB10 -#define FUNC_CWeaponInfo_GetWeaponReloadTime 0x743D70 #define FUNC_CBirds_CheckForHit 0x712E40 #define FUNC_CShadows_CheckForHit 0x707550 class CWeaponSAInterface { public: - eWeaponType m_eWeaponType; - eWeaponState m_eState; - DWORD m_nAmmoInClip; - DWORD m_nAmmoTotal; - DWORD m_nTimer; - DWORD m_Unknown; - DWORD m_Unknown_2; + eWeaponType m_eWeaponType{}; + eWeaponState m_eState{}; + std::uint32_t m_ammoInClip{0}; + std::uint32_t m_ammoTotal{0}; + std::uint32_t m_timeToNextShootInMS{0}; + bool m_firstPersonEnabled{false}; // Unused + bool m_dontPlaceInHand{false}; // Used in case of goggles + FxSystem_c* m_fxSystem{nullptr}; // Fx system (flamethrower, spraycan, extinguisher) + + void Shutdown() { ((void(__thiscall*)(CWeaponSAInterface*))FUNC_CWeapon_Shutdown)(this); } + void Initialize(const eWeaponType& weaponType, std::uint32_t ammo, CPed* ped) { ((void(__thiscall*)(CWeaponSAInterface*, eWeaponType, std::uint32_t, CPedSAInterface*))FUNC_CWeapon_Initialize)(this, weaponType, ammo, ped ? ped->GetPedInterface() : nullptr); } + void Update(CPed* ped) { ((void(__thiscall*)(CWeaponSAInterface*, CPedSAInterface*))FUNC_CWeapon_Update)(this, ped ? ped->GetPedInterface() : nullptr); } + void AddGunshell(CEntity* firingEntity, CVector* vecOrigin, CVector2D* vecDirection, float size) { ((void(__thiscall*)(CWeaponSAInterface*, CEntitySAInterface*, CVector*, CVector2D*, float))FUNC_CWeapon_AddGunshell)(this, firingEntity ? firingEntity->GetInterface() : nullptr, vecOrigin, vecDirection, size); } + void DoBulletImpact(CEntity* firingEntity, CEntitySAInterface* hitEntityInterface, CVector* vecOrigin, CVector* vecTarget, CColPoint* colPoint, int incrementalHit) { ((void(__thiscall*)(CWeaponSAInterface*, CEntitySAInterface*, CEntitySAInterface*, CVector*, CVector*, CColPoint*, int))FUNC_CWeapon_DoBulletImpact)(this, firingEntity ? firingEntity->GetInterface() : nullptr, hitEntityInterface, vecOrigin, vecTarget, colPoint, incrementalHit); } + bool Fire(CEntity* firingEntity, CVector* vecOrigin, CVector* vecEffectPos, CEntity* targetEntity, CVector* vecTarget, CVector* vecAlt) { return ((bool(__thiscall*)(CWeaponSAInterface*, CEntitySAInterface*, CVector*, CVector*, CEntitySAInterface*, CVector*, CVector*))FUNC_CWeapon_Fire)(this, firingEntity ? firingEntity->GetInterface() : nullptr, vecOrigin, vecEffectPos, targetEntity ? targetEntity->GetInterface() : nullptr, vecTarget, vecAlt); } + bool FireInstantHit(CEntity* firingEntity, CVector* vecOrigin, CVector* vecMuzzle, CEntity* targetEntity, CVector* vecTarget, CVector* vecForDriveby, bool crossHairGun, bool createGunFx) { return ((bool(__thiscall*)(CWeaponSAInterface*, CEntitySAInterface*, CVector*, CVector*, CEntitySAInterface*, CVector*, CVector*, bool, bool))FUNC_CWeapon_FireInstantHit)(this, firingEntity ? firingEntity->GetInterface() : nullptr, vecOrigin, vecMuzzle, targetEntity ? targetEntity->GetInterface() : nullptr, vecTarget, vecForDriveby, crossHairGun, createGunFx); } + bool GenerateDamageEvent(CPed* ped, CEntity* responsible, eWeaponType weaponType, int damagePerHit, ePedPieceTypes hitZone, std::uint8_t dir) { return ((bool(__thiscall*)(CWeaponSAInterface*, CPedSAInterface*, CEntitySAInterface*, eWeaponType, int, ePedPieceTypes, std::uint8_t))FUNC_CWeapon_GenerateDamageEvent)(this, ped ? ped->GetPedInterface() : nullptr, responsible ? responsible->GetInterface() : nullptr, weaponType, damagePerHit, hitZone, dir); } }; +static_assert(sizeof(CWeaponSAInterface) == 0x1C, "Invalid size for CWeaponSAInterface"); class CWeaponSA : public CWeapon { -private: - CWeaponSAInterface* m_pInterface; - CPed* m_pOwner; - eWeaponSlot m_weaponSlot; - public: - CWeaponSA(CWeaponSAInterface* pInterface, CPed* pOwner, eWeaponSlot weaponSlot); - eWeaponType GetType(); - void SetType(eWeaponType type); - eWeaponState GetState(); - void SetState(eWeaponState state); - DWORD GetAmmoInClip(); - void SetAmmoInClip(DWORD dwAmmoInClip); - DWORD GetAmmoTotal(); - void SetAmmoTotal(DWORD dwAmmoTotal); - - CPed* GetPed(); - eWeaponSlot GetSlot(); - - void SetAsCurrentWeapon(); - CWeaponInfo* GetInfo(eWeaponSkill skill); - void Destroy(); - void Remove(); - void Initialize(eWeaponType type, unsigned int uiAmmo, CPed* pPed); - void Update(CPed* pPed); - bool Fire(CEntity* pFiringEntity, CVector* pvecOrigin, CVector* pvecOffset, CEntity* pTargetEntity, CVector* pvec_1, CVector* pvec_2); - void AddGunshell(CEntity* pFiringEntity, CVector* pvecOrigin, CVector2D* pvecDirection, float fSize); - void DoBulletImpact(CEntity* pFiringEntity, CEntitySAInterface* pEntityInterface, CVector* pvecOrigin, CVector* pvecTarget, CColPoint* pColPoint, int i_1); - unsigned char GenerateDamageEvent(CPed* pPed, CEntity* pResponsible, eWeaponType weaponType, int iDamagePerHit, ePedPieceTypes hitZone, int i_2); - bool ProcessLineOfSight(const CVector* vecStart, const CVector* vecEnd, CColPoint** colCollision, CEntity** CollisionEntity, const SLineOfSightFlags flags, - SLineOfSightBuildingResult* pBuildingResult, eWeaponType weaponType, CEntitySAInterface** pEntity); - bool FireInstantHit(CEntity* pFiringEntity, const CVector* pvecOrigin, const CVector* pvecMuzzle, CEntity* pTargetEntity, const CVector* pvecTarget, - const CVector* pvec, bool bCrossHairGun, bool bCreateGunFx); - bool FireBullet(CEntity* pFiringEntity, const CVector& vecOrigin, const CVector& vecTarget); - int GetWeaponReloadTime(CWeaponStat* pWeaponStat); - static int GetWeaponFireTime(CWeaponStat* pWeaponStat); + CWeaponSA(CWeaponSAInterface* weaponInterface, CPed* owner, eWeaponSlot weaponSlot) : m_interface(weaponInterface), m_owner(owner), m_weaponSlot(weaponSlot) {} + CWeaponSAInterface* GetInterface() { return m_interface; } + CWeaponSAInterface* GetInterface() const { return m_interface; } + + eWeaponType GetType() const override { return m_interface ? m_interface->m_eWeaponType : eWeaponType::WEAPONTYPE_UNIDENTIFIED; } + void SetType(const eWeaponType& type) override { if (m_interface) m_interface->m_eWeaponType = type; } + + eWeaponState GetState() const override { return m_interface ? m_interface->m_eState : eWeaponState::WEAPONSTATE_READY; } + void SetState(const eWeaponState& state) override { if (m_interface) m_interface->m_eState = state; } + + std::uint32_t GetAmmoInClip() const override { return m_interface ? m_interface->m_ammoInClip : 0; } + void SetAmmoInClip(std::uint32_t ammoInClip) override { if (m_interface) m_interface->m_ammoInClip = ammoInClip; } + + std::uint32_t GetAmmoTotal() const override { return m_interface ? m_interface->m_ammoTotal : 0; } + void SetAmmoTotal(std::uint32_t ammoTotal) override { if (m_interface) m_interface->m_ammoTotal = ammoTotal; } + + CPed* GetPed() const noexcept override { return m_owner; } + eWeaponSlot GetSlot() const noexcept override { return m_weaponSlot; } + CWeaponInfo* GetInfo(const eWeaponSkill& skill) const override; + + void SetAsCurrentWeapon() override; + + void Destroy() override; + void Remove() override; + void Initialize(const eWeaponType& type, std::uint32_t ammo, CPed* ped) override; + void Update(CPed* ped) override; + + void AddGunshell(CEntity* firingEntity, CVector* vecOrigin, CVector2D* vecDirection, float size) const override; + void DoBulletImpact(CEntity* firingEntity, CEntitySAInterface* hitEntityInterface, CVector* vecOrigin, CVector* vecTarget, CColPoint* colPoint, int incrementalHit) const override; + bool Fire(CEntity* firingEntity, CVector* vecOrigin, CVector* vecEffectPos, CEntity* targetEntity, CVector* vecTarget, CVector* vecAlt) override; + bool FireInstantHit(CEntity* firingEntity, const CVector* vecOrigin, const CVector* vecMuzzle, CEntity* targetEntity, const CVector* vecTarget, const CVector* vecForDriveby, bool crossHairGun, bool createGunFx) override; + bool FireBullet(CEntity* firingEntity, const CVector& vecOrigin, const CVector& vecTarget) override; + + bool GenerateDamageEvent(CPed* ped, CEntity* responsible, eWeaponType weaponType, int damagePerHit, ePedPieceTypes hitZone, std::uint8_t dir) const override; + + bool ProcessLineOfSight(const CVector* vecStart, const CVector* vecEnd, CColPoint** colCollision, CEntity** collisionEntity, const SLineOfSightFlags& flags, SLineOfSightBuildingResult* buildingResult, const eWeaponType& weaponType, CEntitySAInterface** entity) override; + + int GetWeaponReloadTime(CWeaponStat* weaponStat) const override; + static int GetWeaponFireTime(CWeaponStat* weaponStat); + +private: + CWeaponSAInterface* m_interface{nullptr}; + CPed* m_owner{nullptr}; + eWeaponSlot m_weaponSlot{}; }; diff --git a/Client/sdk/game/CWeapon.h b/Client/sdk/game/CWeapon.h index 3dbb96c642..4a5dae1a1f 100644 --- a/Client/sdk/game/CWeapon.h +++ b/Client/sdk/game/CWeapon.h @@ -1,11 +1,11 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory * FILE: sdk/game/CWeapon.h * PURPOSE: Weapon entity interface * - * Multi Theft Auto is available from http://www.multitheftauto.com/ + * Multi Theft Auto is available from https://www.multitheftauto.com/ * *****************************************************************************/ @@ -28,33 +28,38 @@ struct SWeaponConfiguration; class CWeapon { public: - virtual eWeaponType GetType() = 0; - virtual void SetType(eWeaponType type) = 0; - virtual eWeaponState GetState() = 0; - virtual void SetState(eWeaponState state) = 0; - virtual DWORD GetAmmoInClip() = 0; - virtual void SetAmmoInClip(DWORD dwAmmoInClip) = 0; - virtual DWORD GetAmmoTotal() = 0; - virtual void SetAmmoTotal(DWORD dwAmmoTotal) = 0; - virtual CPed* GetPed() = 0; - virtual eWeaponSlot GetSlot() = 0; - virtual void SetAsCurrentWeapon() = 0; - virtual CWeaponInfo* GetInfo(eWeaponSkill skill) = 0; - virtual void Remove() = 0; - virtual void Destroy() = 0; - virtual void Initialize(eWeaponType type, unsigned int uiAmmo, CPed* pPed) = 0; - virtual void Update(CPed* pPed) = 0; - virtual bool Fire(CEntity* pFiringEntity, CVector* pvecOrigin, CVector* pvecOffset, CEntity* pTargetEntity, CVector* pvec_1, CVector* pvec2) = 0; - virtual void AddGunshell(CEntity* pFiringEntity, CVector* pvecOrigin, CVector2D* pvecDirection, float fSize) = 0; - virtual void DoBulletImpact(CEntity* pFiringEntity, CEntitySAInterface* pEntityInterface, CVector* pvecOrigin, CVector* pvecTarget, CColPoint* pColPoint, - int i_1) = 0; - virtual unsigned char GenerateDamageEvent(CPed* pPed, CEntity* pResponsible, eWeaponType weaponType, int iDamagePerHit, ePedPieceTypes hitZone, - int i_2) = 0; - virtual bool ProcessLineOfSight(const CVector* vecStart, const CVector* vecEnd, CColPoint** colCollision, CEntity** CollisionEntity, - const SLineOfSightFlags flags, SLineOfSightBuildingResult* pBuildingResult, eWeaponType weaponType, - CEntitySAInterface** pEntity) = 0; - virtual bool FireInstantHit(CEntity* pFiringEntity, const CVector* pvecOrigin, const CVector* pvecMuzzle, CEntity* pTargetEntity, const CVector* pvecTarget, - const CVector* pvec, bool bCrossHairGun, bool bCreateGunFx) = 0; - virtual bool FireBullet(CEntity* pFiringEntity, const CVector& vecOrigin, const CVector& vecTarget) = 0; - virtual int GetWeaponReloadTime(CWeaponStat* pWeaponStat) = 0; + virtual eWeaponType GetType() const = 0; + virtual void SetType(const eWeaponType& type) = 0; + + virtual eWeaponState GetState() const = 0; + virtual void SetState(const eWeaponState& state) = 0; + + virtual std::uint32_t GetAmmoInClip() const = 0; + virtual void SetAmmoInClip(std::uint32_t ammoInClip) = 0; + + virtual std::uint32_t GetAmmoTotal() const = 0; + virtual void SetAmmoTotal(std::uint32_t ammoTotal) = 0; + + virtual CPed* GetPed() const noexcept = 0; + virtual eWeaponSlot GetSlot() const noexcept = 0; + virtual CWeaponInfo* GetInfo(const eWeaponSkill& skill) const = 0; + + virtual void SetAsCurrentWeapon() = 0; + + virtual void Destroy() = 0; + virtual void Remove() = 0; + virtual void Initialize(const eWeaponType& type, std::uint32_t ammo, CPed* ped) = 0; + virtual void Update(CPed* ped) = 0; + + virtual void AddGunshell(CEntity* firingEntity, CVector* vecOrigin, CVector2D* vecDirection, float size) const = 0; + virtual void DoBulletImpact(CEntity* firingEntity, CEntitySAInterface* hitEntityInterface, CVector* vecOrigin, CVector* vecTarget, CColPoint* colPoint, int incrementalHit) const = 0; + virtual bool Fire(CEntity* firingEntity, CVector* vecOrigin, CVector* vecEffectPos, CEntity* targetEntity, CVector* vecTarget, CVector* vecAlt) = 0; + virtual bool FireInstantHit(CEntity* firingEntity, const CVector* vecOrigin, const CVector* vecMuzzle, CEntity* targetEntity, const CVector* vecTarget, const CVector* vecForDriveby, bool crossHairGun, bool createGunFx) = 0; + virtual bool FireBullet(CEntity* firingEntity, const CVector& vecOrigin, const CVector& vecTarget) = 0; + + virtual bool GenerateDamageEvent(CPed* ped, CEntity* responsible, eWeaponType weaponType, int damagePerHit, ePedPieceTypes hitZone, std::uint8_t dir) const = 0; + + virtual bool ProcessLineOfSight(const CVector* vecStart, const CVector* vecEnd, CColPoint** colCollision, CEntity** collisionEntity, const SLineOfSightFlags& flags, SLineOfSightBuildingResult* buildingResult, const eWeaponType& weaponType, CEntitySAInterface** entity) = 0; + + virtual int GetWeaponReloadTime(CWeaponStat* weaponStat) const = 0; }; From ea190e516f9a37a32685b3d81c08d159ed651d75 Mon Sep 17 00:00:00 2001 From: FileEX Date: Fri, 21 Feb 2025 19:21:56 +0100 Subject: [PATCH 2/5] Remove includes --- Client/game_sa/CWeaponSA.cpp | 1 - Client/game_sa/CWeaponSA.h | 3 --- Client/sdk/game/CWeapon.h | 4 ---- 3 files changed, 8 deletions(-) diff --git a/Client/game_sa/CWeaponSA.cpp b/Client/game_sa/CWeaponSA.cpp index b6e1257cde..b977ae5184 100644 --- a/Client/game_sa/CWeaponSA.cpp +++ b/Client/game_sa/CWeaponSA.cpp @@ -10,7 +10,6 @@ *****************************************************************************/ #include "StdInc.h" -#include "CColPointSA.h" #include "CGameSA.h" #include "CPlayerPedSA.h" #include "CWeaponSA.h" diff --git a/Client/game_sa/CWeaponSA.h b/Client/game_sa/CWeaponSA.h index 6cd8fbc4e4..f3826b5292 100644 --- a/Client/game_sa/CWeaponSA.h +++ b/Client/game_sa/CWeaponSA.h @@ -11,9 +11,6 @@ #pragma once -#include -#include - #define FUNC_CWeapon_Shutdown 0x73A380 #define FUNC_CWeapon_CheckForShootingVehicleOccupant 0x73f480 #define FUNC_CWeapon_Initialize 0x73b4a0 diff --git a/Client/sdk/game/CWeapon.h b/Client/sdk/game/CWeapon.h index 4a5dae1a1f..964368a58c 100644 --- a/Client/sdk/game/CWeapon.h +++ b/Client/sdk/game/CWeapon.h @@ -11,9 +11,6 @@ #pragma once -#include "Common.h" -#include "CWeaponInfo.h" - class CColPoint; class CPed; class CVector; @@ -23,7 +20,6 @@ class CWeaponStat; enum ePedPieceTypes; struct SLineOfSightBuildingResult; struct SLineOfSightFlags; -struct SWeaponConfiguration; class CWeapon { From 5273a2da1a55794c86ca625a1e04a3b0b65ff71f Mon Sep 17 00:00:00 2001 From: FileEX Date: Fri, 21 Feb 2025 22:50:13 +0100 Subject: [PATCH 3/5] Review --- Client/game_sa/CWeaponSA.cpp | 2 +- Client/game_sa/CWeaponSA.h | 4 ++-- Client/mods/deathmatch/logic/CClientWeapon.cpp | 2 +- Client/sdk/game/CWeapon.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Client/game_sa/CWeaponSA.cpp b/Client/game_sa/CWeaponSA.cpp index b977ae5184..8bc213d7a3 100644 --- a/Client/game_sa/CWeaponSA.cpp +++ b/Client/game_sa/CWeaponSA.cpp @@ -68,7 +68,7 @@ void CWeaponSA::Update(CPed* ped) m_interface->Update(ped); } -void CWeaponSA::AddGunshell(CEntity* firingEntity, CVector* vecOrigin, CVector2D* vecDirection, float size) const +void CWeaponSA::AddGunshell(CEntity* firingEntity, const CVector& vecOrigin, const CVector2D& vecDirection, float size) const { if (m_interface && firingEntity) m_interface->AddGunshell(firingEntity, vecOrigin, vecDirection, size); diff --git a/Client/game_sa/CWeaponSA.h b/Client/game_sa/CWeaponSA.h index f3826b5292..a7387ff2a5 100644 --- a/Client/game_sa/CWeaponSA.h +++ b/Client/game_sa/CWeaponSA.h @@ -38,7 +38,7 @@ class CWeaponSAInterface void Shutdown() { ((void(__thiscall*)(CWeaponSAInterface*))FUNC_CWeapon_Shutdown)(this); } void Initialize(const eWeaponType& weaponType, std::uint32_t ammo, CPed* ped) { ((void(__thiscall*)(CWeaponSAInterface*, eWeaponType, std::uint32_t, CPedSAInterface*))FUNC_CWeapon_Initialize)(this, weaponType, ammo, ped ? ped->GetPedInterface() : nullptr); } void Update(CPed* ped) { ((void(__thiscall*)(CWeaponSAInterface*, CPedSAInterface*))FUNC_CWeapon_Update)(this, ped ? ped->GetPedInterface() : nullptr); } - void AddGunshell(CEntity* firingEntity, CVector* vecOrigin, CVector2D* vecDirection, float size) { ((void(__thiscall*)(CWeaponSAInterface*, CEntitySAInterface*, CVector*, CVector2D*, float))FUNC_CWeapon_AddGunshell)(this, firingEntity ? firingEntity->GetInterface() : nullptr, vecOrigin, vecDirection, size); } + void AddGunshell(CEntity* firingEntity, const CVector& vecOrigin, const CVector2D& vecDirection, float size) { ((void(__thiscall*)(CWeaponSAInterface*, CEntitySAInterface*, const CVector&, const CVector2D&, float))FUNC_CWeapon_AddGunshell)(this, firingEntity ? firingEntity->GetInterface() : nullptr, vecOrigin, vecDirection, size); } void DoBulletImpact(CEntity* firingEntity, CEntitySAInterface* hitEntityInterface, CVector* vecOrigin, CVector* vecTarget, CColPoint* colPoint, int incrementalHit) { ((void(__thiscall*)(CWeaponSAInterface*, CEntitySAInterface*, CEntitySAInterface*, CVector*, CVector*, CColPoint*, int))FUNC_CWeapon_DoBulletImpact)(this, firingEntity ? firingEntity->GetInterface() : nullptr, hitEntityInterface, vecOrigin, vecTarget, colPoint, incrementalHit); } bool Fire(CEntity* firingEntity, CVector* vecOrigin, CVector* vecEffectPos, CEntity* targetEntity, CVector* vecTarget, CVector* vecAlt) { return ((bool(__thiscall*)(CWeaponSAInterface*, CEntitySAInterface*, CVector*, CVector*, CEntitySAInterface*, CVector*, CVector*))FUNC_CWeapon_Fire)(this, firingEntity ? firingEntity->GetInterface() : nullptr, vecOrigin, vecEffectPos, targetEntity ? targetEntity->GetInterface() : nullptr, vecTarget, vecAlt); } bool FireInstantHit(CEntity* firingEntity, CVector* vecOrigin, CVector* vecMuzzle, CEntity* targetEntity, CVector* vecTarget, CVector* vecForDriveby, bool crossHairGun, bool createGunFx) { return ((bool(__thiscall*)(CWeaponSAInterface*, CEntitySAInterface*, CVector*, CVector*, CEntitySAInterface*, CVector*, CVector*, bool, bool))FUNC_CWeapon_FireInstantHit)(this, firingEntity ? firingEntity->GetInterface() : nullptr, vecOrigin, vecMuzzle, targetEntity ? targetEntity->GetInterface() : nullptr, vecTarget, vecForDriveby, crossHairGun, createGunFx); } @@ -76,7 +76,7 @@ class CWeaponSA : public CWeapon void Initialize(const eWeaponType& type, std::uint32_t ammo, CPed* ped) override; void Update(CPed* ped) override; - void AddGunshell(CEntity* firingEntity, CVector* vecOrigin, CVector2D* vecDirection, float size) const override; + void AddGunshell(CEntity* firingEntity, const CVector& vecOrigin, const CVector2D& vecDirection, float size) const override; void DoBulletImpact(CEntity* firingEntity, CEntitySAInterface* hitEntityInterface, CVector* vecOrigin, CVector* vecTarget, CColPoint* colPoint, int incrementalHit) const override; bool Fire(CEntity* firingEntity, CVector* vecOrigin, CVector* vecEffectPos, CEntity* targetEntity, CVector* vecTarget, CVector* vecAlt) override; bool FireInstantHit(CEntity* firingEntity, const CVector* vecOrigin, const CVector* vecMuzzle, CEntity* targetEntity, const CVector* vecTarget, const CVector* vecForDriveby, bool crossHairGun, bool createGunFx) override; diff --git a/Client/mods/deathmatch/logic/CClientWeapon.cpp b/Client/mods/deathmatch/logic/CClientWeapon.cpp index af068f5e01..92fb7422a5 100644 --- a/Client/mods/deathmatch/logic/CClientWeapon.cpp +++ b/Client/mods/deathmatch/logic/CClientWeapon.cpp @@ -680,7 +680,7 @@ void CClientWeapon::DoGunShells(CVector vecOrigin, CVector vecDirection) // Note: Nozzle flare lags behind attached object if it is moving, but we can't set attached entity here as it will crash if not a ped g_pGame->GetFx()->TriggerGunshot(NULL, vecOrigin, vecDirection, true); - m_pWeapon->AddGunshell(m_pObject, &vecOrigin, &CVector2D(0, -1), fShellSize); + m_pWeapon->AddGunshell(m_pObject, vecOrigin, CVector2D(0, -1), fShellSize); } if (m_Type != WEAPONTYPE_MINIGUN) { diff --git a/Client/sdk/game/CWeapon.h b/Client/sdk/game/CWeapon.h index 964368a58c..6e9e82affc 100644 --- a/Client/sdk/game/CWeapon.h +++ b/Client/sdk/game/CWeapon.h @@ -47,7 +47,7 @@ class CWeapon virtual void Initialize(const eWeaponType& type, std::uint32_t ammo, CPed* ped) = 0; virtual void Update(CPed* ped) = 0; - virtual void AddGunshell(CEntity* firingEntity, CVector* vecOrigin, CVector2D* vecDirection, float size) const = 0; + virtual void AddGunshell(CEntity* firingEntity, const CVector& vecOrigin, const CVector2D& vecDirection, float size) const = 0; virtual void DoBulletImpact(CEntity* firingEntity, CEntitySAInterface* hitEntityInterface, CVector* vecOrigin, CVector* vecTarget, CColPoint* colPoint, int incrementalHit) const = 0; virtual bool Fire(CEntity* firingEntity, CVector* vecOrigin, CVector* vecEffectPos, CEntity* targetEntity, CVector* vecTarget, CVector* vecAlt) = 0; virtual bool FireInstantHit(CEntity* firingEntity, const CVector* vecOrigin, const CVector* vecMuzzle, CEntity* targetEntity, const CVector* vecTarget, const CVector* vecForDriveby, bool crossHairGun, bool createGunFx) = 0; From b6695036a7fab3a832f7131e8f0f430d2764598c Mon Sep 17 00:00:00 2001 From: FileEX Date: Sun, 23 Feb 2025 16:21:54 +0100 Subject: [PATCH 4/5] Review --- Client/game_sa/CWeaponSA.cpp | 2 +- Client/game_sa/CWeaponSA.h | 4 ++-- Client/mods/deathmatch/logic/CClientWeapon.cpp | 2 +- Client/sdk/game/CWeapon.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Client/game_sa/CWeaponSA.cpp b/Client/game_sa/CWeaponSA.cpp index 8bc213d7a3..e36697170f 100644 --- a/Client/game_sa/CWeaponSA.cpp +++ b/Client/game_sa/CWeaponSA.cpp @@ -74,7 +74,7 @@ void CWeaponSA::AddGunshell(CEntity* firingEntity, const CVector& vecOrigin, con m_interface->AddGunshell(firingEntity, vecOrigin, vecDirection, size); } -void CWeaponSA::DoBulletImpact(CEntity* firingEntity, CEntitySAInterface* hitEntityInterface, CVector* vecOrigin, CVector* vecTarget, CColPoint* colPoint, int incrementalHit) const +void CWeaponSA::DoBulletImpact(CEntity* firingEntity, CEntitySAInterface* hitEntityInterface, const CVector& vecOrigin, const CVector& vecTarget, const CColPoint& colPoint, int incrementalHit) const { if (m_interface) m_interface->DoBulletImpact(firingEntity, hitEntityInterface, vecOrigin, vecTarget, colPoint, incrementalHit); diff --git a/Client/game_sa/CWeaponSA.h b/Client/game_sa/CWeaponSA.h index a7387ff2a5..cb3de5d2ed 100644 --- a/Client/game_sa/CWeaponSA.h +++ b/Client/game_sa/CWeaponSA.h @@ -39,7 +39,7 @@ class CWeaponSAInterface void Initialize(const eWeaponType& weaponType, std::uint32_t ammo, CPed* ped) { ((void(__thiscall*)(CWeaponSAInterface*, eWeaponType, std::uint32_t, CPedSAInterface*))FUNC_CWeapon_Initialize)(this, weaponType, ammo, ped ? ped->GetPedInterface() : nullptr); } void Update(CPed* ped) { ((void(__thiscall*)(CWeaponSAInterface*, CPedSAInterface*))FUNC_CWeapon_Update)(this, ped ? ped->GetPedInterface() : nullptr); } void AddGunshell(CEntity* firingEntity, const CVector& vecOrigin, const CVector2D& vecDirection, float size) { ((void(__thiscall*)(CWeaponSAInterface*, CEntitySAInterface*, const CVector&, const CVector2D&, float))FUNC_CWeapon_AddGunshell)(this, firingEntity ? firingEntity->GetInterface() : nullptr, vecOrigin, vecDirection, size); } - void DoBulletImpact(CEntity* firingEntity, CEntitySAInterface* hitEntityInterface, CVector* vecOrigin, CVector* vecTarget, CColPoint* colPoint, int incrementalHit) { ((void(__thiscall*)(CWeaponSAInterface*, CEntitySAInterface*, CEntitySAInterface*, CVector*, CVector*, CColPoint*, int))FUNC_CWeapon_DoBulletImpact)(this, firingEntity ? firingEntity->GetInterface() : nullptr, hitEntityInterface, vecOrigin, vecTarget, colPoint, incrementalHit); } + void DoBulletImpact(CEntity* firingEntity, CEntitySAInterface* hitEntityInterface, const CVector& vecOrigin, const CVector& vecTarget, const CColPoint& colPoint, int incrementalHit) { ((void(__thiscall*)(CWeaponSAInterface*, CEntitySAInterface*, CEntitySAInterface*, const CVector&, const CVector&, const CColPoint&, int))FUNC_CWeapon_DoBulletImpact)(this, firingEntity ? firingEntity->GetInterface() : nullptr, hitEntityInterface, vecOrigin, vecTarget, colPoint, incrementalHit); } bool Fire(CEntity* firingEntity, CVector* vecOrigin, CVector* vecEffectPos, CEntity* targetEntity, CVector* vecTarget, CVector* vecAlt) { return ((bool(__thiscall*)(CWeaponSAInterface*, CEntitySAInterface*, CVector*, CVector*, CEntitySAInterface*, CVector*, CVector*))FUNC_CWeapon_Fire)(this, firingEntity ? firingEntity->GetInterface() : nullptr, vecOrigin, vecEffectPos, targetEntity ? targetEntity->GetInterface() : nullptr, vecTarget, vecAlt); } bool FireInstantHit(CEntity* firingEntity, CVector* vecOrigin, CVector* vecMuzzle, CEntity* targetEntity, CVector* vecTarget, CVector* vecForDriveby, bool crossHairGun, bool createGunFx) { return ((bool(__thiscall*)(CWeaponSAInterface*, CEntitySAInterface*, CVector*, CVector*, CEntitySAInterface*, CVector*, CVector*, bool, bool))FUNC_CWeapon_FireInstantHit)(this, firingEntity ? firingEntity->GetInterface() : nullptr, vecOrigin, vecMuzzle, targetEntity ? targetEntity->GetInterface() : nullptr, vecTarget, vecForDriveby, crossHairGun, createGunFx); } bool GenerateDamageEvent(CPed* ped, CEntity* responsible, eWeaponType weaponType, int damagePerHit, ePedPieceTypes hitZone, std::uint8_t dir) { return ((bool(__thiscall*)(CWeaponSAInterface*, CPedSAInterface*, CEntitySAInterface*, eWeaponType, int, ePedPieceTypes, std::uint8_t))FUNC_CWeapon_GenerateDamageEvent)(this, ped ? ped->GetPedInterface() : nullptr, responsible ? responsible->GetInterface() : nullptr, weaponType, damagePerHit, hitZone, dir); } @@ -77,7 +77,7 @@ class CWeaponSA : public CWeapon void Update(CPed* ped) override; void AddGunshell(CEntity* firingEntity, const CVector& vecOrigin, const CVector2D& vecDirection, float size) const override; - void DoBulletImpact(CEntity* firingEntity, CEntitySAInterface* hitEntityInterface, CVector* vecOrigin, CVector* vecTarget, CColPoint* colPoint, int incrementalHit) const override; + void DoBulletImpact(CEntity* firingEntity, CEntitySAInterface* hitEntityInterface, const CVector& vecOrigin, const CVector& vecTarget, const CColPoint& colPoint, int incrementalHit) const override; bool Fire(CEntity* firingEntity, CVector* vecOrigin, CVector* vecEffectPos, CEntity* targetEntity, CVector* vecTarget, CVector* vecAlt) override; bool FireInstantHit(CEntity* firingEntity, const CVector* vecOrigin, const CVector* vecMuzzle, CEntity* targetEntity, const CVector* vecTarget, const CVector* vecForDriveby, bool crossHairGun, bool createGunFx) override; bool FireBullet(CEntity* firingEntity, const CVector& vecOrigin, const CVector& vecTarget) override; diff --git a/Client/mods/deathmatch/logic/CClientWeapon.cpp b/Client/mods/deathmatch/logic/CClientWeapon.cpp index 92fb7422a5..e0dbba1d57 100644 --- a/Client/mods/deathmatch/logic/CClientWeapon.cpp +++ b/Client/mods/deathmatch/logic/CClientWeapon.cpp @@ -449,7 +449,7 @@ void CClientWeapon::FireInstantHit(CVector vecOrigin, CVector vecTarget, bool bS #ifdef MARKER_DEBUG m_pMarker2->SetPosition(vecTarget); #endif - m_pWeapon->DoBulletImpact(m_pObject, pEntity, &vecOrigin, &vecTarget, pColPoint, 0); + m_pWeapon->DoBulletImpact(m_pObject, pEntity, vecOrigin, vecTarget, *pColPoint, 0); if (!IsLocalEntity() && m_pOwner) { diff --git a/Client/sdk/game/CWeapon.h b/Client/sdk/game/CWeapon.h index 6e9e82affc..7bc0df9394 100644 --- a/Client/sdk/game/CWeapon.h +++ b/Client/sdk/game/CWeapon.h @@ -48,7 +48,7 @@ class CWeapon virtual void Update(CPed* ped) = 0; virtual void AddGunshell(CEntity* firingEntity, const CVector& vecOrigin, const CVector2D& vecDirection, float size) const = 0; - virtual void DoBulletImpact(CEntity* firingEntity, CEntitySAInterface* hitEntityInterface, CVector* vecOrigin, CVector* vecTarget, CColPoint* colPoint, int incrementalHit) const = 0; + virtual void DoBulletImpact(CEntity* firingEntity, CEntitySAInterface* hitEntityInterface, const CVector& vecOrigin, const CVector& vecTarget, const CColPoint& colPoint, int incrementalHit) const = 0; virtual bool Fire(CEntity* firingEntity, CVector* vecOrigin, CVector* vecEffectPos, CEntity* targetEntity, CVector* vecTarget, CVector* vecAlt) = 0; virtual bool FireInstantHit(CEntity* firingEntity, const CVector* vecOrigin, const CVector* vecMuzzle, CEntity* targetEntity, const CVector* vecTarget, const CVector* vecForDriveby, bool crossHairGun, bool createGunFx) = 0; virtual bool FireBullet(CEntity* firingEntity, const CVector& vecOrigin, const CVector& vecTarget) = 0; From 1af1652885600a42cf03265f468344b8a2e10561 Mon Sep 17 00:00:00 2001 From: FileEX Date: Thu, 6 Mar 2025 15:45:35 +0100 Subject: [PATCH 5/5] Fix issue --- Client/game_sa/CWeaponSA.cpp | 57 +++++---- Client/game_sa/CWeaponSA.h | 117 ++++++++++++------ .../mods/deathmatch/logic/CClientWeapon.cpp | 4 +- Client/sdk/game/CWeapon.h | 25 ++-- 4 files changed, 125 insertions(+), 78 deletions(-) diff --git a/Client/game_sa/CWeaponSA.cpp b/Client/game_sa/CWeaponSA.cpp index d0fcc3785f..3d09657c8c 100644 --- a/Client/game_sa/CWeaponSA.cpp +++ b/Client/game_sa/CWeaponSA.cpp @@ -19,7 +19,7 @@ extern CGameSA* pGame; -CWeaponInfo* CWeaponSA::GetInfo(const eWeaponSkill& skill) const +CWeaponInfo* CWeaponSA::GetInfo(eWeaponSkill skill) const { return m_interface ? pGame->GetWeaponInfo(m_interface->m_eWeaponType, skill) : nullptr; } @@ -55,42 +55,41 @@ void CWeaponSA::Remove() } } -void CWeaponSA::Initialize(const eWeaponType& type, std::uint32_t ammo, CPed* ped) +void CWeaponSA::Initialize(eWeaponType type, std::uint32_t ammo, CPed* ped) { if (m_interface) - m_interface->Initialize(type, ammo, ped); -} - -void CWeaponSA::Update(CPed* ped) -{ - // Note: CWeapon::Update is called mainly to check for reload - if (m_interface) - m_interface->Update(ped); + m_interface->Initialize(type, ammo, ped ? ped->GetPedInterface() : nullptr); } void CWeaponSA::AddGunshell(CEntity* firingEntity, const CVector& vecOrigin, const CVector2D& vecDirection, float size) const { if (m_interface && firingEntity) - m_interface->AddGunshell(firingEntity, vecOrigin, vecDirection, size); + m_interface->AddGunshell(firingEntity->GetInterface(), vecOrigin, vecDirection, size); } -void CWeaponSA::DoBulletImpact(CEntity* firingEntity, CEntitySAInterface* hitEntityInterface, const CVector& vecOrigin, const CVector& vecTarget, const CColPoint& colPoint, int incrementalHit) const +void CWeaponSA::DoBulletImpact(CEntity* firingEntity, CEntitySAInterface* hitEntityInterface, const CVector& vecOrigin, const CVector& vecTarget, + const CColPointSAInterface& colPoint, int incrementalHit) const { if (m_interface) - m_interface->DoBulletImpact(firingEntity, hitEntityInterface, vecOrigin, vecTarget, colPoint, incrementalHit); + m_interface->DoBulletImpact(firingEntity ? firingEntity->GetInterface() : nullptr, hitEntityInterface, vecOrigin, vecTarget, colPoint, incrementalHit); } bool CWeaponSA::Fire(CEntity* firingEntity, CVector* vecOrigin, CVector* vecEffectPos, CEntity* targetEntity, CVector* vecTarget, CVector* vecAlt) { - if (!firingEntity) + if (!firingEntity || !m_interface) return false; - return m_interface ? m_interface->Fire(firingEntity, vecOrigin, vecEffectPos, targetEntity, vecTarget, vecAlt) : false; + return m_interface->Fire(firingEntity->GetInterface(), vecOrigin, vecEffectPos, targetEntity ? targetEntity->GetInterface() : nullptr, vecTarget, vecAlt); } -bool CWeaponSA::FireInstantHit(CEntity* firingEntity, const CVector* vecOrigin, const CVector* vecMuzzle, CEntity* targetEntity, const CVector* vecTarget, const CVector* vecForDriveby, bool crossHairGun, bool createGunFx) +bool CWeaponSA::FireInstantHit(CEntity* firingEntity, CVector* vecOrigin, CVector* vecMuzzle, CEntity* targetEntity, CVector* vecTarget, CVector* vecForDriveby, + bool crossHairGun, bool createGunFx) { - return m_interface ? m_interface->FireInstantHit(firingEntity, const_cast(vecOrigin), const_cast(vecMuzzle), targetEntity, const_cast(vecTarget), const_cast(vecForDriveby), crossHairGun, createGunFx) : false; + if (!m_interface) + return false; + + return m_interface->FireInstantHit(firingEntity ? firingEntity->GetInterface() : nullptr, vecOrigin, vecMuzzle, + targetEntity ? targetEntity->GetInterface() : nullptr, vecTarget, vecForDriveby, crossHairGun, createGunFx); } bool CWeaponSA::FireBullet(CEntity* firingEntity, const CVector& vecOrigin, const CVector& vecTarget) @@ -130,7 +129,7 @@ bool CWeaponSA::FireBullet(CEntity* firingEntity, const CVector& vecOrigin, cons firingPlayerPed->GetTransformedBonePosition(BONE_RIGHTWRIST, &vecGunMuzzle); // Bullet trace - FireInstantHit(firingEntity, &vecOrigin, &vecGunMuzzle, nullptr, &vecTarget, nullptr, false, true); + FireInstantHit(firingEntity, const_cast(&vecOrigin), &vecGunMuzzle, nullptr, const_cast(&vecTarget), nullptr, false, true); // Fire sound if (firingPlayerPed) @@ -156,23 +155,26 @@ bool CWeaponSA::GenerateDamageEvent(CPed* ped, CEntity* responsible, eWeaponType if (!ped || !m_interface) return false; - return m_interface->GenerateDamageEvent(ped, responsible, weaponType, damagePerHit, hitZone, dir); + return m_interface->GenerateDamageEvent(ped ? ped->GetPedInterface() : nullptr, responsible ? responsible->GetInterface() : nullptr, weaponType, + damagePerHit, hitZone, dir); } -bool CWeaponSA::ProcessLineOfSight(const CVector* vecStart, const CVector* vecEnd, CColPoint** colCollision, CEntity** collisionEntity, const SLineOfSightFlags& flags, SLineOfSightBuildingResult* buildingResult, const eWeaponType& weaponType, CEntitySAInterface** entity) +bool CWeaponSA::ProcessLineOfSight(const CVector& vecStart, const CVector& vecEnd, CColPoint** colCollision, CEntity*& collisionEntity, + const SLineOfSightFlags& flags, SLineOfSightBuildingResult* buildingResult, eWeaponType weaponType, + CEntitySAInterface** entity) { // Call CBirds::HandleGunShot - ((void(__cdecl*)(CVector*, CVector*))FUNC_CBirds_CheckForHit)(const_cast(vecStart), const_cast(vecEnd)); + ((void(__cdecl*)(const CVector*, const CVector*))FUNC_CBirds_CheckForHit)(&vecStart, &vecEnd); // Call CShadows::GunShotSetsOilOnFire - ((void(__cdecl*)(CVector*, CVector*))FUNC_CShadows_CheckForHit)(const_cast(vecStart), const_cast(vecEnd)); + ((void(__cdecl*)(const CVector&, const CVector&))FUNC_CShadows_CheckForHit)(vecStart, vecEnd); - bool hit = pGame->GetWorld()->ProcessLineOfSight(vecStart, vecEnd, colCollision, collisionEntity, flags, buildingResult); + bool hit = pGame->GetWorld()->ProcessLineOfSight(&vecStart, &vecEnd, colCollision, &collisionEntity, flags, buildingResult); if (hit) { - if (*collisionEntity) - *entity = (*collisionEntity)->GetInterface(); + if (collisionEntity) + *entity = collisionEntity->GetInterface(); else { if (buildingResult->bValid) @@ -182,7 +184,8 @@ bool CWeaponSA::ProcessLineOfSight(const CVector* vecStart, const CVector* vecEn // Call CWeapon::CheckForShootingVehicleOccupant if (*entity && (*entity)->nType == ENTITY_TYPE_VEHICLE) - ((void(__cdecl*)(CEntitySAInterface*, CColPointSAInterface*, eWeaponType, CVector*, CVector*))FUNC_CWeapon_CheckForShootingVehicleOccupant)(*entity, (*colCollision)->GetInterface(), weaponType, const_cast(vecStart), const_cast(vecEnd)); + ((bool(__cdecl*)(CEntitySAInterface**, CColPointSAInterface*, eWeaponType, const CVector&, + const CVector&))FUNC_CWeapon_CheckForShootingVehicleOccupant)(entity, (*colCollision)->GetInterface(), weaponType, vecStart, vecEnd); return hit; } @@ -199,6 +202,6 @@ int CWeaponSA::GetWeaponReloadTime(CWeaponStat* weaponStat) const int CWeaponSA::GetWeaponFireTime(CWeaponStat* weaponStat) { std::uint32_t timer = pGame->GetSystemTime(); - float weaponFireTime = (weaponStat->GetWeaponAnimLoopStop() - weaponStat->GetWeaponAnimLoopStart()) * 1000.0f; + float weaponFireTime = (weaponStat->GetWeaponAnimLoopStop() - weaponStat->GetWeaponAnimLoopStart()) * 1000.0f; return static_cast(weaponFireTime); } diff --git a/Client/game_sa/CWeaponSA.h b/Client/game_sa/CWeaponSA.h index cb3de5d2ed..9ef7124493 100644 --- a/Client/game_sa/CWeaponSA.h +++ b/Client/game_sa/CWeaponSA.h @@ -11,17 +11,9 @@ #pragma once -#define FUNC_CWeapon_Shutdown 0x73A380 -#define FUNC_CWeapon_CheckForShootingVehicleOccupant 0x73f480 -#define FUNC_CWeapon_Initialize 0x73b4a0 -#define FUNC_CWeapon_Update 0x73db40 -#define FUNC_CWeapon_Fire 0x742300 -#define FUNC_CWeapon_AddGunshell 0x73a3e0 -#define FUNC_CWeapon_DoBulletImpact 0x73b550 -#define FUNC_CWeapon_GenerateDamageEvent 0x73a530 -#define FUNC_CWeapon_FireInstantHit 0x73FB10 -#define FUNC_CBirds_CheckForHit 0x712E40 -#define FUNC_CShadows_CheckForHit 0x707550 +#define FUNC_CWeapon_CheckForShootingVehicleOccupant 0x73f480 +#define FUNC_CBirds_CheckForHit 0x712E40 +#define FUNC_CShadows_CheckForHit 0x707550 class CWeaponSAInterface { @@ -31,64 +23,111 @@ class CWeaponSAInterface std::uint32_t m_ammoInClip{0}; std::uint32_t m_ammoTotal{0}; std::uint32_t m_timeToNextShootInMS{0}; - bool m_firstPersonEnabled{false}; // Unused - bool m_dontPlaceInHand{false}; // Used in case of goggles - FxSystem_c* m_fxSystem{nullptr}; // Fx system (flamethrower, spraycan, extinguisher) - - void Shutdown() { ((void(__thiscall*)(CWeaponSAInterface*))FUNC_CWeapon_Shutdown)(this); } - void Initialize(const eWeaponType& weaponType, std::uint32_t ammo, CPed* ped) { ((void(__thiscall*)(CWeaponSAInterface*, eWeaponType, std::uint32_t, CPedSAInterface*))FUNC_CWeapon_Initialize)(this, weaponType, ammo, ped ? ped->GetPedInterface() : nullptr); } - void Update(CPed* ped) { ((void(__thiscall*)(CWeaponSAInterface*, CPedSAInterface*))FUNC_CWeapon_Update)(this, ped ? ped->GetPedInterface() : nullptr); } - void AddGunshell(CEntity* firingEntity, const CVector& vecOrigin, const CVector2D& vecDirection, float size) { ((void(__thiscall*)(CWeaponSAInterface*, CEntitySAInterface*, const CVector&, const CVector2D&, float))FUNC_CWeapon_AddGunshell)(this, firingEntity ? firingEntity->GetInterface() : nullptr, vecOrigin, vecDirection, size); } - void DoBulletImpact(CEntity* firingEntity, CEntitySAInterface* hitEntityInterface, const CVector& vecOrigin, const CVector& vecTarget, const CColPoint& colPoint, int incrementalHit) { ((void(__thiscall*)(CWeaponSAInterface*, CEntitySAInterface*, CEntitySAInterface*, const CVector&, const CVector&, const CColPoint&, int))FUNC_CWeapon_DoBulletImpact)(this, firingEntity ? firingEntity->GetInterface() : nullptr, hitEntityInterface, vecOrigin, vecTarget, colPoint, incrementalHit); } - bool Fire(CEntity* firingEntity, CVector* vecOrigin, CVector* vecEffectPos, CEntity* targetEntity, CVector* vecTarget, CVector* vecAlt) { return ((bool(__thiscall*)(CWeaponSAInterface*, CEntitySAInterface*, CVector*, CVector*, CEntitySAInterface*, CVector*, CVector*))FUNC_CWeapon_Fire)(this, firingEntity ? firingEntity->GetInterface() : nullptr, vecOrigin, vecEffectPos, targetEntity ? targetEntity->GetInterface() : nullptr, vecTarget, vecAlt); } - bool FireInstantHit(CEntity* firingEntity, CVector* vecOrigin, CVector* vecMuzzle, CEntity* targetEntity, CVector* vecTarget, CVector* vecForDriveby, bool crossHairGun, bool createGunFx) { return ((bool(__thiscall*)(CWeaponSAInterface*, CEntitySAInterface*, CVector*, CVector*, CEntitySAInterface*, CVector*, CVector*, bool, bool))FUNC_CWeapon_FireInstantHit)(this, firingEntity ? firingEntity->GetInterface() : nullptr, vecOrigin, vecMuzzle, targetEntity ? targetEntity->GetInterface() : nullptr, vecTarget, vecForDriveby, crossHairGun, createGunFx); } - bool GenerateDamageEvent(CPed* ped, CEntity* responsible, eWeaponType weaponType, int damagePerHit, ePedPieceTypes hitZone, std::uint8_t dir) { return ((bool(__thiscall*)(CWeaponSAInterface*, CPedSAInterface*, CEntitySAInterface*, eWeaponType, int, ePedPieceTypes, std::uint8_t))FUNC_CWeapon_GenerateDamageEvent)(this, ped ? ped->GetPedInterface() : nullptr, responsible ? responsible->GetInterface() : nullptr, weaponType, damagePerHit, hitZone, dir); } + bool m_firstPersonEnabled{false}; // Unused + bool m_dontPlaceInHand{false}; // Used in case of goggles + FxSystem_c* m_fxSystem{nullptr}; // Fx system (flamethrower, spraycan, extinguisher) + + void Shutdown() { ((void(__thiscall*)(CWeaponSAInterface*))0x73A380)(this); } + void Initialize(eWeaponType weaponType, std::uint32_t ammo, CPedSAInterface* ped) + { + ((void(__thiscall*)(CWeaponSAInterface*, eWeaponType, std::uint32_t, CPedSAInterface*))0x73B4A0)(this, weaponType, ammo, ped); + } + void AddGunshell(CEntitySAInterface* firingEntity, const CVector& vecOrigin, const CVector2D& vecDirection, float size) + { + ((void(__thiscall*)(CWeaponSAInterface*, CEntitySAInterface*, const CVector&, const CVector2D&, float))0x73A3E0)(this, firingEntity, vecOrigin, + vecDirection, size); + } + void DoBulletImpact(CEntitySAInterface* firingEntity, CEntitySAInterface* hitEntityInterface, const CVector& vecOrigin, const CVector& vecTarget, + const CColPointSAInterface& colPoint, int incrementalHit) + { + ((void(__thiscall*)(CWeaponSAInterface*, CEntitySAInterface*, CEntitySAInterface*, const CVector&, const CVector&, const CColPointSAInterface&, + int))0x73B550)(this, firingEntity, hitEntityInterface, vecOrigin, vecTarget, colPoint, incrementalHit); + } + bool Fire(CEntitySAInterface* firingEntity, CVector* vecOrigin, CVector* vecEffectPos, CEntitySAInterface* targetEntity, CVector* vecTarget, + CVector* vecAlt) + { + return ((bool(__thiscall*)(CWeaponSAInterface*, CEntitySAInterface*, CVector*, CVector*, CEntitySAInterface*, CVector*, CVector*))0x742300)( + this, firingEntity, vecOrigin, vecEffectPos, targetEntity, vecTarget, vecAlt); + } + bool FireInstantHit(CEntitySAInterface* firingEntity, CVector* vecOrigin, CVector* vecMuzzle, CEntitySAInterface* targetEntity, CVector* vecTarget, + CVector* vecForDriveby, bool crossHairGun, bool createGunFx) + { + return ((bool(__thiscall*)(CWeaponSAInterface*, CEntitySAInterface*, CVector*, CVector*, CEntitySAInterface*, CVector*, CVector*, bool, bool))0x73FB10)( + this, firingEntity, vecOrigin, vecMuzzle, targetEntity, vecTarget, vecForDriveby, crossHairGun, createGunFx); + } + bool GenerateDamageEvent(CPedSAInterface* ped, CEntitySAInterface* responsible, eWeaponType weaponType, int damagePerHit, ePedPieceTypes hitZone, + std::uint8_t dir) + { + return ((bool(__thiscall*)(CWeaponSAInterface*, CPedSAInterface*, CEntitySAInterface*, eWeaponType, int, ePedPieceTypes, std::uint8_t))0x73A530)( + this, ped, responsible, weaponType, damagePerHit, hitZone, dir); + } }; static_assert(sizeof(CWeaponSAInterface) == 0x1C, "Invalid size for CWeaponSAInterface"); class CWeaponSA : public CWeapon { public: - CWeaponSA(CWeaponSAInterface* weaponInterface, CPed* owner, eWeaponSlot weaponSlot) : m_interface(weaponInterface), m_owner(owner), m_weaponSlot(weaponSlot) {} + CWeaponSA(CWeaponSAInterface* weaponInterface, CPed* owner, eWeaponSlot weaponSlot) : m_interface(weaponInterface), m_owner(owner), m_weaponSlot(weaponSlot) + { + } CWeaponSAInterface* GetInterface() { return m_interface; } CWeaponSAInterface* GetInterface() const { return m_interface; } eWeaponType GetType() const override { return m_interface ? m_interface->m_eWeaponType : eWeaponType::WEAPONTYPE_UNIDENTIFIED; } - void SetType(const eWeaponType& type) override { if (m_interface) m_interface->m_eWeaponType = type; } + void SetType(eWeaponType type) override + { + if (m_interface) + m_interface->m_eWeaponType = type; + } eWeaponState GetState() const override { return m_interface ? m_interface->m_eState : eWeaponState::WEAPONSTATE_READY; } - void SetState(const eWeaponState& state) override { if (m_interface) m_interface->m_eState = state; } + void SetState(eWeaponState state) override + { + if (m_interface) + m_interface->m_eState = state; + } std::uint32_t GetAmmoInClip() const override { return m_interface ? m_interface->m_ammoInClip : 0; } - void SetAmmoInClip(std::uint32_t ammoInClip) override { if (m_interface) m_interface->m_ammoInClip = ammoInClip; } + void SetAmmoInClip(std::uint32_t ammoInClip) override + { + if (m_interface) + m_interface->m_ammoInClip = ammoInClip; + } std::uint32_t GetAmmoTotal() const override { return m_interface ? m_interface->m_ammoTotal : 0; } - void SetAmmoTotal(std::uint32_t ammoTotal) override { if (m_interface) m_interface->m_ammoTotal = ammoTotal; } + void SetAmmoTotal(std::uint32_t ammoTotal) override + { + if (m_interface) + m_interface->m_ammoTotal = ammoTotal; + } - CPed* GetPed() const noexcept override { return m_owner; } - eWeaponSlot GetSlot() const noexcept override { return m_weaponSlot; } - CWeaponInfo* GetInfo(const eWeaponSkill& skill) const override; + CPed* GetPed() const noexcept override { return m_owner; } + eWeaponSlot GetSlot() const noexcept override { return m_weaponSlot; } + CWeaponInfo* GetInfo(eWeaponSkill skill) const override; void SetAsCurrentWeapon() override; void Destroy() override; void Remove() override; - void Initialize(const eWeaponType& type, std::uint32_t ammo, CPed* ped) override; - void Update(CPed* ped) override; + void Initialize(eWeaponType type, std::uint32_t ammo, CPed* ped) override; void AddGunshell(CEntity* firingEntity, const CVector& vecOrigin, const CVector2D& vecDirection, float size) const override; - void DoBulletImpact(CEntity* firingEntity, CEntitySAInterface* hitEntityInterface, const CVector& vecOrigin, const CVector& vecTarget, const CColPoint& colPoint, int incrementalHit) const override; + void DoBulletImpact(CEntity* firingEntity, CEntitySAInterface* hitEntityInterface, const CVector& vecOrigin, const CVector& vecTarget, + const CColPointSAInterface& colPoint, int incrementalHit) const override; bool Fire(CEntity* firingEntity, CVector* vecOrigin, CVector* vecEffectPos, CEntity* targetEntity, CVector* vecTarget, CVector* vecAlt) override; - bool FireInstantHit(CEntity* firingEntity, const CVector* vecOrigin, const CVector* vecMuzzle, CEntity* targetEntity, const CVector* vecTarget, const CVector* vecForDriveby, bool crossHairGun, bool createGunFx) override; + bool FireInstantHit(CEntity* firingEntity, CVector* vecOrigin, CVector* vecMuzzle, CEntity* targetEntity, CVector* vecTarget, CVector* vecForDriveby, + bool crossHairGun, bool createGunFx) override; bool FireBullet(CEntity* firingEntity, const CVector& vecOrigin, const CVector& vecTarget) override; - bool GenerateDamageEvent(CPed* ped, CEntity* responsible, eWeaponType weaponType, int damagePerHit, ePedPieceTypes hitZone, std::uint8_t dir) const override; + bool GenerateDamageEvent(CPed* ped, CEntity* responsible, eWeaponType weaponType, int damagePerHit, ePedPieceTypes hitZone, + std::uint8_t dir) const override; - bool ProcessLineOfSight(const CVector* vecStart, const CVector* vecEnd, CColPoint** colCollision, CEntity** collisionEntity, const SLineOfSightFlags& flags, SLineOfSightBuildingResult* buildingResult, const eWeaponType& weaponType, CEntitySAInterface** entity) override; + bool ProcessLineOfSight(const CVector& vecStart, const CVector& vecEnd, CColPoint** colCollision, CEntity*& collisionEntity, const SLineOfSightFlags& flags, + SLineOfSightBuildingResult* buildingResult, eWeaponType weaponType, CEntitySAInterface** entity) override; - int GetWeaponReloadTime(CWeaponStat* weaponStat) const override; + int GetWeaponReloadTime(CWeaponStat* weaponStat) const override; static int GetWeaponFireTime(CWeaponStat* weaponStat); - + private: CWeaponSAInterface* m_interface{nullptr}; CPed* m_owner{nullptr}; diff --git a/Client/mods/deathmatch/logic/CClientWeapon.cpp b/Client/mods/deathmatch/logic/CClientWeapon.cpp index e0dbba1d57..14f8e6338f 100644 --- a/Client/mods/deathmatch/logic/CClientWeapon.cpp +++ b/Client/mods/deathmatch/logic/CClientWeapon.cpp @@ -393,7 +393,7 @@ void CClientWeapon::FireInstantHit(CVector vecOrigin, CVector vecTarget, bool bS } } // if ( pAttachedTo ) pAttachedTo->WorldIgnore ( true ); - if (m_pWeapon->ProcessLineOfSight(&vecOrigin, &vecTarget, &pColPoint, &pColEntity, m_weaponConfig.flags, &pBuildingResult, m_Type, &pEntity)) + if (m_pWeapon->ProcessLineOfSight(vecOrigin, vecTarget, &pColPoint, pColEntity, m_weaponConfig.flags, &pBuildingResult, m_Type, &pEntity)) { vecTarget = pColPoint->GetPosition(); } @@ -449,7 +449,7 @@ void CClientWeapon::FireInstantHit(CVector vecOrigin, CVector vecTarget, bool bS #ifdef MARKER_DEBUG m_pMarker2->SetPosition(vecTarget); #endif - m_pWeapon->DoBulletImpact(m_pObject, pEntity, vecOrigin, vecTarget, *pColPoint, 0); + m_pWeapon->DoBulletImpact(m_pObject, pEntity, vecOrigin, vecTarget, *pColPoint->GetInterface(), 0); if (!IsLocalEntity() && m_pOwner) { diff --git a/Client/sdk/game/CWeapon.h b/Client/sdk/game/CWeapon.h index 7bc0df9394..b765924659 100644 --- a/Client/sdk/game/CWeapon.h +++ b/Client/sdk/game/CWeapon.h @@ -12,6 +12,7 @@ #pragma once class CColPoint; +class CColPointSAInterface; class CPed; class CVector; class CVector2D; @@ -24,11 +25,11 @@ struct SLineOfSightFlags; class CWeapon { public: - virtual eWeaponType GetType() const = 0; - virtual void SetType(const eWeaponType& type) = 0; + virtual eWeaponType GetType() const = 0; + virtual void SetType(eWeaponType type) = 0; virtual eWeaponState GetState() const = 0; - virtual void SetState(const eWeaponState& state) = 0; + virtual void SetState(eWeaponState state) = 0; virtual std::uint32_t GetAmmoInClip() const = 0; virtual void SetAmmoInClip(std::uint32_t ammoInClip) = 0; @@ -38,24 +39,28 @@ class CWeapon virtual CPed* GetPed() const noexcept = 0; virtual eWeaponSlot GetSlot() const noexcept = 0; - virtual CWeaponInfo* GetInfo(const eWeaponSkill& skill) const = 0; + virtual CWeaponInfo* GetInfo(eWeaponSkill skill) const = 0; virtual void SetAsCurrentWeapon() = 0; virtual void Destroy() = 0; virtual void Remove() = 0; - virtual void Initialize(const eWeaponType& type, std::uint32_t ammo, CPed* ped) = 0; - virtual void Update(CPed* ped) = 0; + virtual void Initialize(eWeaponType type, std::uint32_t ammo, CPed* ped) = 0; virtual void AddGunshell(CEntity* firingEntity, const CVector& vecOrigin, const CVector2D& vecDirection, float size) const = 0; - virtual void DoBulletImpact(CEntity* firingEntity, CEntitySAInterface* hitEntityInterface, const CVector& vecOrigin, const CVector& vecTarget, const CColPoint& colPoint, int incrementalHit) const = 0; + virtual void DoBulletImpact(CEntity* firingEntity, CEntitySAInterface* hitEntityInterface, const CVector& vecOrigin, const CVector& vecTarget, + const CColPointSAInterface& colPoint, int incrementalHit) const = 0; virtual bool Fire(CEntity* firingEntity, CVector* vecOrigin, CVector* vecEffectPos, CEntity* targetEntity, CVector* vecTarget, CVector* vecAlt) = 0; - virtual bool FireInstantHit(CEntity* firingEntity, const CVector* vecOrigin, const CVector* vecMuzzle, CEntity* targetEntity, const CVector* vecTarget, const CVector* vecForDriveby, bool crossHairGun, bool createGunFx) = 0; + virtual bool FireInstantHit(CEntity* firingEntity, CVector* vecOrigin, CVector* vecMuzzle, CEntity* targetEntity, CVector* vecTarget, + CVector* vecForDriveby, bool crossHairGun, bool createGunFx) = 0; virtual bool FireBullet(CEntity* firingEntity, const CVector& vecOrigin, const CVector& vecTarget) = 0; - virtual bool GenerateDamageEvent(CPed* ped, CEntity* responsible, eWeaponType weaponType, int damagePerHit, ePedPieceTypes hitZone, std::uint8_t dir) const = 0; + virtual bool GenerateDamageEvent(CPed* ped, CEntity* responsible, eWeaponType weaponType, int damagePerHit, ePedPieceTypes hitZone, + std::uint8_t dir) const = 0; - virtual bool ProcessLineOfSight(const CVector* vecStart, const CVector* vecEnd, CColPoint** colCollision, CEntity** collisionEntity, const SLineOfSightFlags& flags, SLineOfSightBuildingResult* buildingResult, const eWeaponType& weaponType, CEntitySAInterface** entity) = 0; + virtual bool ProcessLineOfSight(const CVector& vecStart, const CVector& vecEnd, CColPoint** colCollision, CEntity*& collisionEntity, + const SLineOfSightFlags& flags, SLineOfSightBuildingResult* buildingResult, eWeaponType weaponType, + CEntitySAInterface** entity) = 0; virtual int GetWeaponReloadTime(CWeaponStat* weaponStat) const = 0; };