2014-08-19 16:57:35 +06:00
|
|
|
#include "StdAfxSA.h"
|
|
|
|
#include "PedSA.h"
|
2018-01-29 04:53:17 +05:00
|
|
|
#include "VehicleSA.h"
|
2014-08-19 16:57:35 +06:00
|
|
|
|
2014-08-22 04:10:23 +06:00
|
|
|
static void* varGetWeaponSkill = AddressByVersion<void*>(0x5E6580, 0x5E6DA0, 0x6039F0);
|
2019-05-18 14:06:17 +05:00
|
|
|
WRAPPER uint8_t CPed::GetWeaponSkill() { VARJMP(varGetWeaponSkill); }
|
2014-08-22 04:10:23 +06:00
|
|
|
static void* varSetGunFlashAlpha = AddressByVersion<void*>(0x5DF400, 0x5DFC20, 0x5FC120);
|
2014-08-19 16:57:35 +06:00
|
|
|
WRAPPER void CPed::SetGunFlashAlpha(bool bSecondWeapon) { WRAPARG(bSecondWeapon); VARJMP(varSetGunFlashAlpha); }
|
|
|
|
|
2018-09-23 00:23:40 +05:00
|
|
|
static void* varSay = AddressByVersion<void*>(0x5EFFE0, 0, 0); // TODO: Do
|
|
|
|
WRAPPER void CPed::Say(uint16_t phrase, uint32_t param2, float volume, bool param4, bool param5, bool param6) { VARJMP(varSay); }
|
|
|
|
|
2014-08-22 04:10:23 +06:00
|
|
|
static void* varGetTaskJetPack = AddressByVersion<void*>(0x601110, 0x601930, 0x620E70);
|
2014-08-19 17:16:38 +06:00
|
|
|
WRAPPER CTaskSimpleJetPack* CPedIntelligence::GetTaskJetPack() const { VARJMP(varGetTaskJetPack); }
|
|
|
|
|
2014-08-22 04:10:23 +06:00
|
|
|
static void* varRenderJetPack = AddressByVersion<void*>(0x67F6A0, 0x67FEC0, 0x6AB110);
|
2014-08-19 17:16:38 +06:00
|
|
|
WRAPPER void CTaskSimpleJetPack::RenderJetPack(CPed* pPed) { WRAPARG(pPed); VARJMP(varRenderJetPack); }
|
|
|
|
|
2018-01-28 22:30:52 +05:00
|
|
|
void (CPed::*CPed::orgGiveWeapon)(uint32_t weapon, uint32_t ammo, bool flag);
|
2018-02-17 17:59:44 +05:00
|
|
|
void (CPlayerPed::*CPlayerPed::orgDoStuffToGoOnFire)();
|
2018-01-28 22:30:52 +05:00
|
|
|
|
2024-02-20 02:47:35 +05:00
|
|
|
void (*CClothes::RebuildPlayer)(CPlayerPed* ped, bool bForReplay) = AddressByVersion<void(*)(CPlayerPed*, bool)>(0x5A82C0, { "8B 8E ? ? ? ? 83 C4 04 6A 05", -0x11 });
|
|
|
|
|
2014-08-19 16:57:35 +06:00
|
|
|
RwObject* GetFirstObject(RwFrame* pFrame)
|
|
|
|
{
|
|
|
|
RwObject* pObject = nullptr;
|
2017-03-28 00:17:43 +05:00
|
|
|
RwFrameForAllObjects( pFrame, [&pObject]( RwObject* object ) -> RwObject* {
|
|
|
|
pObject = object;
|
|
|
|
return nullptr;
|
|
|
|
} );
|
2014-08-19 16:57:35 +06:00
|
|
|
return pObject;
|
|
|
|
}
|
|
|
|
|
2018-01-29 04:53:17 +05:00
|
|
|
void CPed::ResetGunFlashAlpha()
|
|
|
|
{
|
|
|
|
if ( m_pMuzzleFlashFrame != nullptr )
|
|
|
|
{
|
|
|
|
if ( RpAtomic* atomic = reinterpret_cast<RpAtomic*>(GetFirstObject(m_pMuzzleFlashFrame)) )
|
|
|
|
{
|
|
|
|
RpAtomicSetFlags(atomic, 0);
|
|
|
|
CVehicle::SetComponentAtomicAlpha(atomic, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-07 01:59:14 +05:00
|
|
|
void CPed::RenderWeapon(bool bWeapon, bool bMuzzleFlash, bool bForShadow)
|
2014-08-19 16:57:35 +06:00
|
|
|
{
|
|
|
|
if ( m_pWeaponObject )
|
|
|
|
{
|
|
|
|
RpHAnimHierarchy* pAnimHierarchy = GetAnimHierarchyFromSkinClump(m_pRwObject);
|
|
|
|
bool bHasParachute = weaponSlots[m_bActiveWeapon].m_eWeaponType == WEAPONTYPE_PARACHUTE;
|
|
|
|
|
|
|
|
RwFrame* pFrame = RpClumpGetFrame(reinterpret_cast<RpClump*>(m_pWeaponObject));
|
|
|
|
*RwFrameGetMatrix(pFrame) = RpHAnimHierarchyGetMatrixArray(pAnimHierarchy)[RpHAnimIDGetIndex(pAnimHierarchy, bHasParachute ? 3 : 24)];
|
|
|
|
|
2019-05-18 14:46:49 +05:00
|
|
|
auto renderOneWeapon = [this](bool bWeapon, bool bMuzzleFlash, bool bForShadow, bool bRightGun)
|
2014-08-19 16:57:35 +06:00
|
|
|
{
|
2019-05-18 14:46:49 +05:00
|
|
|
RwFrameUpdateObjects(RpClumpGetFrame(reinterpret_cast<RpClump*>(m_pWeaponObject)));
|
2019-04-13 21:17:30 +05:00
|
|
|
|
2014-08-19 17:16:38 +06:00
|
|
|
if ( bForShadow )
|
2017-03-28 00:17:43 +05:00
|
|
|
RpClumpForAllAtomics(reinterpret_cast<RpClump*>(m_pWeaponObject), ShadowCameraRenderCB);
|
2019-03-07 01:59:14 +05:00
|
|
|
else
|
2014-08-19 16:57:35 +06:00
|
|
|
{
|
2019-03-07 01:59:14 +05:00
|
|
|
if ( bWeapon )
|
|
|
|
{
|
|
|
|
RpClumpRender(reinterpret_cast<RpClump*>(m_pWeaponObject));
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( bMuzzleFlash && m_pMuzzleFlashFrame != nullptr )
|
|
|
|
{
|
2024-05-17 20:35:46 +05:00
|
|
|
RwScopedRenderState<rwRENDERSTATEZWRITEENABLE> zWrite;
|
2019-04-13 21:17:30 +05:00
|
|
|
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, FALSE);
|
|
|
|
|
2019-05-18 14:46:49 +05:00
|
|
|
SetGunFlashAlpha(bRightGun);
|
2019-03-07 01:59:14 +05:00
|
|
|
RpAtomic* atomic = reinterpret_cast<RpAtomic*>(GetFirstObject(m_pMuzzleFlashFrame));
|
|
|
|
RpAtomicRender( atomic );
|
|
|
|
}
|
2014-08-19 16:57:35 +06:00
|
|
|
}
|
2019-05-18 14:46:49 +05:00
|
|
|
};
|
|
|
|
|
|
|
|
if ( bHasParachute )
|
|
|
|
{
|
|
|
|
const RwV3d vecParachuteTranslation = { 0.1f, -0.15f, 0.0f };
|
|
|
|
const RwV3d vecParachuteRotation = { 0.0f, 1.0f, 0.0f };
|
|
|
|
RwMatrixTranslate(RwFrameGetMatrix(pFrame), &vecParachuteTranslation, rwCOMBINEPRECONCAT);
|
|
|
|
RwMatrixRotate(RwFrameGetMatrix(pFrame), &vecParachuteRotation, 90.0f, rwCOMBINEPRECONCAT);
|
|
|
|
}
|
|
|
|
|
|
|
|
renderOneWeapon(bWeapon, bMuzzleFlash, bForShadow, false);
|
|
|
|
|
|
|
|
// Dual weapons
|
|
|
|
if ( CWeaponInfo::GetWeaponInfo(weaponSlots[m_bActiveWeapon].m_eWeaponType, GetWeaponSkillForRenderWeaponPedsForPC())->hexFlags >> 11 & 1 )
|
|
|
|
{
|
|
|
|
*RwFrameGetMatrix(pFrame) = RpHAnimHierarchyGetMatrixArray(pAnimHierarchy)[RpHAnimIDGetIndex(pAnimHierarchy, 34)];
|
|
|
|
|
|
|
|
const RwV3d vecParachuteRotation = { 1.0f, 0.0f, 0.0f };
|
|
|
|
const RwV3d vecParachuteTranslation = { 0.04f, -0.05f, 0.0f };
|
|
|
|
RwMatrixRotate(RwFrameGetMatrix(pFrame), &vecParachuteRotation, 180.0f, rwCOMBINEPRECONCAT);
|
|
|
|
RwMatrixTranslate(RwFrameGetMatrix(pFrame), &vecParachuteTranslation, rwCOMBINEPRECONCAT);
|
|
|
|
|
|
|
|
renderOneWeapon(bWeapon, bMuzzleFlash, bForShadow, true);
|
2014-08-19 16:57:35 +06:00
|
|
|
}
|
|
|
|
if ( bMuzzleFlash )
|
|
|
|
ResetGunFlashAlpha();
|
|
|
|
}
|
2014-08-19 17:16:38 +06:00
|
|
|
}
|
|
|
|
|
|
|
|
void CPed::RenderForShadow()
|
|
|
|
{
|
2017-03-28 00:17:43 +05:00
|
|
|
RpClumpForAllAtomics(reinterpret_cast<RpClump*>(m_pRwObject), ShadowCameraRenderCB);
|
2019-03-07 01:59:14 +05:00
|
|
|
RenderWeapon(true, false, true);
|
2014-08-19 17:16:38 +06:00
|
|
|
|
|
|
|
// Render jetpack
|
|
|
|
auto* pJetPackTask = pPedIntelligence->GetTaskJetPack();
|
|
|
|
if ( pJetPackTask )
|
|
|
|
pJetPackTask->RenderJetPack(this);
|
2018-01-28 22:30:52 +05:00
|
|
|
}
|
|
|
|
|
|
|
|
void CPed::GiveWeapon_SP(uint32_t weapon, uint32_t ammo, bool flag)
|
|
|
|
{
|
|
|
|
if ( ammo == 0 ) ammo = 1;
|
|
|
|
(this->*(orgGiveWeapon))( weapon, ammo, flag );
|
|
|
|
}
|
2019-05-18 14:06:17 +05:00
|
|
|
|
|
|
|
uint8_t CPed::GetWeaponSkillForRenderWeaponPedsForPC_SAMP()
|
|
|
|
{
|
|
|
|
uint8_t (CPed::*funcCall)();
|
|
|
|
Memory::ReadCall( 0x7330A2, funcCall );
|
|
|
|
return std::invoke( funcCall, this );
|
2024-02-01 02:35:59 +05:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CTaskComplexSequence::Contains(int taskID) const
|
|
|
|
{
|
2024-11-18 22:32:09 +05:00
|
|
|
for (const CTask* task : m_taskSequence)
|
2024-02-01 02:35:59 +05:00
|
|
|
{
|
2024-11-15 16:25:18 +05:00
|
|
|
if (task != nullptr && task->GetTaskType() == taskID)
|
2024-02-01 02:35:59 +05:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|