diff options
-rw-r--r-- | src/entities/Ped.cpp | 55 | ||||
-rw-r--r-- | src/entities/Ped.h | 47 | ||||
-rw-r--r-- | src/entities/PedIK.cpp | 7 | ||||
-rw-r--r-- | src/entities/PedIK.h | 26 |
4 files changed, 131 insertions, 4 deletions
diff --git a/src/entities/Ped.cpp b/src/entities/Ped.cpp index 55e33a2d..b4b980e5 100644 --- a/src/entities/Ped.cpp +++ b/src/entities/Ped.cpp @@ -11,6 +11,8 @@ void *CPed::operator new(size_t sz) { return CPools::GetPedPool()->New(); } void CPed::operator delete(void *p, size_t sz) { CPools::GetPedPool()->Delete((CPed*)p); } WRAPPER void CPed::KillPedWithCar(CVehicle *veh, float impulse) { EAXJMP(0x4EC430); } +WRAPPER void CPed::Say(uint16 audio) { EAXJMP(0x4E5A10); } +WRAPPER void CPed::SetLookFlag(CEntity* to, bool set) { EAXJMP(0x4C6460); } static char ObjectiveText[34][28] = { "No Obj", @@ -175,3 +177,56 @@ CPed::UseGroundColModel(void) m_nPedState == PED_DIE || m_nPedState == PED_DEAD; } + +void +CPed::AddWeaponModel(int id) +{ + RpAtomic* atm; + + if (id != -1) { + atm = (RpAtomic*)CModelInfo::GetModelInfo(id)->CreateInstance(); + RwFrameDestroy(RpAtomicGetFrame(atm)); + RpAtomicSetFrame(atm, m_pFrames[PED_HANDR]->frame); + RpClumpAddAtomic((RpClump*)m_rwObject, atm); + m_wepModelID = id; + } +} + +void +CPed::AimGun() +{ + RwV3d pos; + CVector vector; + uint8 newFlag; + + if (m_pSeekTarget) { + if (m_pSeekTarget->m_status == STATUS_PHYSICS) { + m_pSeekTarget->m_pedIK.GetComponentPosition(&pos, 1); + vector.x = pos.x; + vector.y = pos.y; + vector.z = pos.z; + } else { + vector = *(m_pSeekTarget->GetMatrix().GetPosition()); + } + CPed::Say(0x74); + + m_ped_flagB40 = m_pedIK.PointGunAtPosition(&vector); + if (m_pPedFight != m_pSeekTarget) { + CPed::SetLookFlag(m_pSeekTarget, 1); + } + + } else { + if (CPed::IsPlayer()) { + newFlag = m_pedIK.PointGunInDirection(m_fLookDirection, m_vecMoveSpeedAvg.y); + } else { + newFlag = m_pedIK.PointGunInDirection(m_fLookDirection, 0.0); + } + + m_ped_flagB40 = newFlag; + } +} + +STARTPATCHES + InjectHook(0x4CF8F0, &CPed::AddWeaponModel, PATCH_JUMP); + InjectHook(0x4C6AA0, &CPed::AimGun, PATCH_JUMP); +ENDPATCHES
\ No newline at end of file diff --git a/src/entities/Ped.h b/src/entities/Ped.h index adf24c88..4a616e22 100644 --- a/src/entities/Ped.h +++ b/src/entities/Ped.h @@ -2,6 +2,8 @@ #include "Physical.h" #include "Weapon.h" +#include "PedIK.h" +#include <animation\AnimBlendClumpData.h> enum { PED_MAX_WEAPONS = 13 @@ -79,6 +81,22 @@ enum { PEDMOVE_SPRINT, }; +enum PedNode { + PED_WAIST = 0, + PED_TORSO, // Smid on PS2/PC, Storso on mobile/xbox. We follow mobile/xbox (makes kicking on ground look better) + PED_HEAD, + PED_UPPERARML, + PED_UPPERARMR, + PED_HANDL, + PED_HANDR, + PED_UPPERLEGL, + PED_UPPERLEGR, + PED_FOOTL, + PED_FOOTR, + PED_NODE_11, + PED_NODE_MAX +}; + class CVehicle; class CPed : public CPhysical @@ -159,7 +177,16 @@ public: uint8 m_ped_flagI20 : 1; uint8 m_ped_flagI40 : 1; uint8 m_ped_flagI80 : 1; - uint8 stuff1[199]; + uint8 stuff10[60]; + int32 m_pEventEntity; + int32 m_fAngleToEvent; + AnimBlendFrameData *m_pFrames[PED_FRAME_MAX]; + int32 m_animGroup; + int32 m_pVehicleAnim; + CVector2D m_vecAnimMoveDelta; + CVector m_vecOffsetSeek; + CPedIK m_pedIK; + uint8 stuff1[12]; int32 m_nPedState; int32 m_nLastPedState; int32 m_nMoveState; @@ -167,7 +194,8 @@ public: CEntity *m_pCurrentPhysSurface; CVector m_vecOffsetFromPhysSurface; CEntity *m_pCurSurface; - uint8 stuff3[16]; + uint8 stuff3[12]; + CPed* m_pSeekTarget; CVehicle *m_pMyVehicle; bool bInVehicle; uint8 stuff4[23]; @@ -179,14 +207,25 @@ public: CWeapon m_weapons[PED_MAX_WEAPONS]; int32 stuff7; uint8 m_currentWeapon; - uint8 stuff[163]; + uint8 stuff[3]; + int32 m_pPointGunAt; + CVector m_vecHitLastPos; + uint8 stuff8[12]; + CPed *m_pPedFight; + float m_fLookDirection; + int32 m_wepModelID; + uint8 stuff9[120]; static void *operator new(size_t); static void operator delete(void*, size_t); bool IsPlayer(void) { return m_nPedType == 0 || m_nPedType== 1 || m_nPedType == 2 || m_nPedType == 3; } bool UseGroundColModel(void); + void AddWeaponModel(int id); + void AimGun(); void KillPedWithCar(CVehicle *veh, float impulse); + void Say(uint16 audio); + void SetLookFlag(CEntity *to, bool set); CWeapon *GetWeapon(void) { return &m_weapons[m_currentWeapon]; } static Bool &bNastyLimbsCheat; @@ -200,4 +239,4 @@ static_assert(offsetof(CPed, m_nPedType) == 0x32C, "CPed: error"); static_assert(offsetof(CPed, m_pCollidingEntity) == 0x34C, "CPed: error"); static_assert(offsetof(CPed, m_weapons) == 0x35C, "CPed: error"); static_assert(offsetof(CPed, m_currentWeapon) == 0x498, "CPed: error"); -static_assert(sizeof(CPed) == 0x53C, "CPed: error"); +static_assert(sizeof(CPed) == 0x53C, "CPed: error");
\ No newline at end of file diff --git a/src/entities/PedIK.cpp b/src/entities/PedIK.cpp new file mode 100644 index 00000000..f262fab5 --- /dev/null +++ b/src/entities/PedIK.cpp @@ -0,0 +1,7 @@ +#include "common.h" +#include "patcher.h" +#include "Ped.h" + +WRAPPER void CPedIK::GetComponentPosition(RwV3d* pos, int id) { EAXJMP(0x4ED0F0); } +WRAPPER bool CPedIK::PointGunInDirection(float phi, float theta) { EAXJMP(0x4ED9B0); } +WRAPPER bool CPedIK::PointGunAtPosition(CVector* position) { EAXJMP(0x4ED920); }
\ No newline at end of file diff --git a/src/entities/PedIK.h b/src/entities/PedIK.h new file mode 100644 index 00000000..5e873bf5 --- /dev/null +++ b/src/entities/PedIK.h @@ -0,0 +1,26 @@ +#pragma once +#include <common.h> + +struct LimbOrientation +{ + float phi; + float theta; +}; + +class CPed; + +class CPedIK +{ +public: + CPed* m_ped; + LimbOrientation m_headOrient; + LimbOrientation m_torsoOrient; + LimbOrientation m_upperArmOrient; + LimbOrientation m_lowerArmOrient; + int32 m_flags; + + void GetComponentPosition(RwV3d* pos, int id); + bool PointGunInDirection(float phi, float theta); + bool PointGunAtPosition(CVector* position); +}; +static_assert(sizeof(CPedIK) == 0x28, "CPedIK: error"); |