From f9316d9cc3cfb748366758c41cf02634b6df9a08 Mon Sep 17 00:00:00 2001 From: erorcun Date: Tue, 7 Jan 2020 17:23:09 +0300 Subject: CPlayerPed & CMenuManager (#286) Make Frontend great again! --- src/peds/PlayerPed.cpp | 529 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 374 insertions(+), 155 deletions(-) (limited to 'src/peds/PlayerPed.cpp') diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp index a4ffdc7c..df234bfb 100644 --- a/src/peds/PlayerPed.cpp +++ b/src/peds/PlayerPed.cpp @@ -1,116 +1,117 @@ -#include "common.h" -#include "patcher.h" -#include "PlayerPed.h" -#include "Camera.h" -#include "WeaponEffects.h" -#include "ModelIndices.h" -#include "World.h" -#include "RpAnimBlend.h" -#include "General.h" -#include "Pools.h" - -CPlayerPed::~CPlayerPed() -{ - delete m_pWanted; -} - -WRAPPER void CPlayerPed::KeepAreaAroundPlayerClear(void) { EAXJMP(0x4F3460); } -WRAPPER void CPlayerPed::ProcessControl(void) { EAXJMP(0x4EFD90); } - -CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1) -{ - m_fMoveSpeed = 0.0f; - SetModelIndex(MI_PLAYER); - SetInitialState(); - - m_pWanted = new CWanted(); - m_pWanted->Initialise(); - m_pArrestingCop = nil; - m_currentWeapon = WEAPONTYPE_UNARMED; - m_nSelectedWepSlot = WEAPONTYPE_UNARMED; - m_nSpeedTimer = 0; - m_bSpeedTimerFlag = 0; - m_pPointGunAt = nil; - m_nPedState = PED_IDLE; - m_fMaxStamina = 150.0f; - m_fCurrentStamina = m_fMaxStamina; - m_fStaminaProgress = 0.0f; - m_bShouldEvade = 0; - field_1367 = 0; - m_nShotDelay = 0; - field_1376 = 0.0f; - field_1380 = 0; - m_bHasLockOnTarget = false; - m_bCanBeDamaged = true; - m_fWalkAngle = 0.0f; - m_fFPSMoveHeading = 0.0f; - m_nTargettableObjects[0] = m_nTargettableObjects[1] = m_nTargettableObjects[2] = m_nTargettableObjects[3] = -1; - field_1413 = 0; - for (int i = 0; i < 6; i++) { - m_vecSafePos[i] = CVector(0.0f, 0.0f, 0.0f); - m_pPedAtSafePos[i] = nil; - } -} - -void CPlayerPed::ClearWeaponTarget() -{ - if (m_nPedType == PEDTYPE_PLAYER1) { - m_pPointGunAt = nil; - TheCamera.ClearPlayerWeaponMode(); - CWeaponEffects::ClearCrosshair(); - } - ClearPointGunAt(); -} - -void -CPlayerPed::SetWantedLevel(int32 level) -{ - m_pWanted->SetWantedLevel(level); -} - -void -CPlayerPed::SetWantedLevelNoDrop(int32 level) -{ - m_pWanted->SetWantedLevelNoDrop(level); -} - -void -CPlayerPed::MakeObjectTargettable(int32 handle) -{ - for (int i = 0; i < ARRAY_SIZE(m_nTargettableObjects); i++) { - if (CPools::GetObjectPool()->GetAt(m_nTargettableObjects[i]) == nil) { - m_nTargettableObjects[i] = handle; - return; - } - } -} - -// I don't know the actual purpose of parameter -void -CPlayerPed::AnnoyPlayerPed(bool annoyedByPassingEntity) -{ - if (m_pedStats->m_temper < 52) { - m_pedStats->m_temper++; - } else { - if (annoyedByPassingEntity) { - if (m_pedStats->m_temper < 55) { - m_pedStats->m_temper++; - } else { - m_pedStats->m_temper = 46; - } - } - } -} - -void -CPlayerPed::ClearAdrenaline(void) -{ - if (m_bAdrenalineActive && m_nAdrenalineTime != 0) { - m_nAdrenalineTime = 0; - CTimer::SetTimeScale(1.0f); - } -} - +#include "common.h" +#include "patcher.h" +#include "PlayerPed.h" +#include "Camera.h" +#include "WeaponEffects.h" +#include "ModelIndices.h" +#include "World.h" +#include "RpAnimBlend.h" +#include "General.h" +#include "Pools.h" +#include "Darkel.h" + +CPlayerPed::~CPlayerPed() +{ + delete m_pWanted; +} + +WRAPPER void CPlayerPed::KeepAreaAroundPlayerClear(void) { EAXJMP(0x4F3460); } +WRAPPER void CPlayerPed::ProcessControl(void) { EAXJMP(0x4EFD90); } + +CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1) +{ + m_fMoveSpeed = 0.0f; + SetModelIndex(MI_PLAYER); + SetInitialState(); + + m_pWanted = new CWanted(); + m_pWanted->Initialise(); + m_pArrestingCop = nil; + m_currentWeapon = WEAPONTYPE_UNARMED; + m_nSelectedWepSlot = WEAPONTYPE_UNARMED; + m_nSpeedTimer = 0; + m_bSpeedTimerFlag = 0; + m_pPointGunAt = nil; + m_nPedState = PED_IDLE; + m_fMaxStamina = 150.0f; + m_fCurrentStamina = m_fMaxStamina; + m_fStaminaProgress = 0.0f; + m_bShouldEvade = 0; + field_1367 = 0; + m_nShotDelay = 0; + field_1376 = 0.0f; + field_1380 = 0; + m_bHasLockOnTarget = false; + m_bCanBeDamaged = true; + m_fWalkAngle = 0.0f; + m_fFPSMoveHeading = 0.0f; + m_nTargettableObjects[0] = m_nTargettableObjects[1] = m_nTargettableObjects[2] = m_nTargettableObjects[3] = -1; + field_1413 = 0; + for (int i = 0; i < 6; i++) { + m_vecSafePos[i] = CVector(0.0f, 0.0f, 0.0f); + m_pPedAtSafePos[i] = nil; + } +} + +void CPlayerPed::ClearWeaponTarget() +{ + if (m_nPedType == PEDTYPE_PLAYER1) { + m_pPointGunAt = nil; + TheCamera.ClearPlayerWeaponMode(); + CWeaponEffects::ClearCrosshair(); + } + ClearPointGunAt(); +} + +void +CPlayerPed::SetWantedLevel(int32 level) +{ + m_pWanted->SetWantedLevel(level); +} + +void +CPlayerPed::SetWantedLevelNoDrop(int32 level) +{ + m_pWanted->SetWantedLevelNoDrop(level); +} + +void +CPlayerPed::MakeObjectTargettable(int32 handle) +{ + for (int i = 0; i < ARRAY_SIZE(m_nTargettableObjects); i++) { + if (CPools::GetObjectPool()->GetAt(m_nTargettableObjects[i]) == nil) { + m_nTargettableObjects[i] = handle; + return; + } + } +} + +// I don't know the actual purpose of parameter +void +CPlayerPed::AnnoyPlayerPed(bool annoyedByPassingEntity) +{ + if (m_pedStats->m_temper < 52) { + m_pedStats->m_temper++; + } else { + if (annoyedByPassingEntity) { + if (m_pedStats->m_temper < 55) { + m_pedStats->m_temper++; + } else { + m_pedStats->m_temper = 46; + } + } + } +} + +void +CPlayerPed::ClearAdrenaline(void) +{ + if (m_bAdrenalineActive && m_nAdrenalineTime != 0) { + m_nAdrenalineTime = 0; + CTimer::SetTimeScale(1.0f); + } +} + CPlayerInfo * CPlayerPed::GetPlayerInfoForThisPlayerPed() { @@ -118,8 +119,8 @@ CPlayerPed::GetPlayerInfoForThisPlayerPed() return &CWorld::Players[0]; return nil; -} - +} + void CPlayerPed::SetupPlayerPed(int32 index) { @@ -129,21 +130,21 @@ CPlayerPed::SetupPlayerPed(int32 index) player->SetOrientation(0.0f, 0.0f, 0.0f); CWorld::Add(player); - player->m_wepAccuracy = 100; -} - + player->m_wepAccuracy = 100; +} + void CPlayerPed::DeactivatePlayerPed(int32 index) { - CWorld::Remove(CWorld::Players[index].m_pPed); -} - + CWorld::Remove(CWorld::Players[index].m_pPed); +} + void CPlayerPed::ReactivatePlayerPed(int32 index) { - CWorld::Add(CWorld::Players[index].m_pPed); -} - + CWorld::Add(CWorld::Players[index].m_pPed); +} + void CPlayerPed::UseSprintEnergy(void) { @@ -158,8 +159,8 @@ CPlayerPed::UseSprintEnergy(void) if (m_fMaxStamina < 1000.0f) m_fMaxStamina += 10.0f; } -} - +} + void CPlayerPed::MakeChangesForNewWeapon(int8 weapon) { @@ -179,9 +180,9 @@ CPlayerPed::MakeChangesForNewWeapon(int8 weapon) weaponAnim->SetRun(); weaponAnim->flags |= ASSOC_FADEOUTWHENDONE; } - TheCamera.ClearPlayerWeaponMode(); -} - + TheCamera.ClearPlayerWeaponMode(); +} + void CPlayerPed::ReApplyMoveAnims(void) { @@ -199,8 +200,8 @@ CPlayerPed::ReApplyMoveAnims(void) } } } -} - +} + void CPlayerPed::SetInitialState(void) { @@ -236,8 +237,8 @@ CPlayerPed::SetInitialState(void) m_bCanBeDamaged = true; m_pedStats->m_temper = 50; m_fWalkAngle = 0.0f; -} - +} + void CPlayerPed::SetRealMoveAnim(void) { @@ -392,7 +393,9 @@ CPlayerPed::SetRealMoveAnim(void) curRunAssoc->flags &= ~ASSOC_RUNNING; curRunAssoc->blendAmount = 0.0f; curRunAssoc->blendDelta = 0.0f; - } else if (curSprintAssoc->blendDelta < 0.0f) { + } else if (curSprintAssoc->blendDelta >= 0.0f) { + + // Stop sprinting when tired curSprintAssoc->flags |= ASSOC_DELETEFADEDOUT; curSprintAssoc->blendDelta = -1.0f; curRunAssoc->blendDelta = 1.0f; @@ -460,24 +463,240 @@ CPlayerPed::SetRealMoveAnim(void) curSprintAssoc->speed = 2.0f; } } -} - -class CPlayerPed_ : public CPlayerPed -{ -public: - CPlayerPed* ctor(void) { return ::new (this) CPlayerPed(); } - void dtor(void) { CPlayerPed::~CPlayerPed(); } - void SetMoveAnim_(void) { CPlayerPed::SetMoveAnim(); } -}; - -STARTPATCHES - InjectHook(0x4EF7E0, &CPlayerPed_::ctor, PATCH_JUMP); - InjectHook(0x4EFB30, &CPlayerPed_::dtor, PATCH_JUMP); - InjectHook(0x4F3760, &CPlayerPed_::SetMoveAnim_, PATCH_JUMP); - InjectHook(0x4F28A0, &CPlayerPed::ClearWeaponTarget, PATCH_JUMP); - InjectHook(0x4F3700, &CPlayerPed::AnnoyPlayerPed, PATCH_JUMP); - InjectHook(0x4F36C0, &CPlayerPed::GetPlayerInfoForThisPlayerPed, PATCH_JUMP); - InjectHook(0x4F2560, &CPlayerPed::MakeChangesForNewWeapon, PATCH_JUMP); - InjectHook(0x4F07C0, &CPlayerPed::ReApplyMoveAnims, PATCH_JUMP); - InjectHook(0x4F0880, &CPlayerPed::SetRealMoveAnim, PATCH_JUMP); -ENDPATCHES +} + +void +CPlayerPed::RestoreSprintEnergy(float restoreSpeed) +{ + if (m_fCurrentStamina < m_fMaxStamina) + m_fCurrentStamina += restoreSpeed * CTimer::GetTimeStep() * 0.5f; +} + +bool +CPlayerPed::DoWeaponSmoothSpray(void) +{ + if (m_nPedState == PED_ATTACK && !m_pPointGunAt) { + eWeaponType weapon = GetWeapon()->m_eWeaponType; + if (weapon == WEAPONTYPE_FLAMETHROWER || weapon == WEAPONTYPE_COLT45 || weapon == WEAPONTYPE_UZI || weapon == WEAPONTYPE_SHOTGUN || + weapon == WEAPONTYPE_AK47 || weapon == WEAPONTYPE_M16 || weapon == WEAPONTYPE_HELICANNON) + return true; + } + return false; +} + +void +CPlayerPed::DoStuffToGoOnFire(void) +{ + if (m_nPedState == PED_SNIPER_MODE) + TheCamera.ClearPlayerWeaponMode(); +} + +bool +CPlayerPed::DoesTargetHaveToBeBroken(CVector target, CWeapon *weaponUsed) +{ + CVector distVec = target - GetPosition(); + + if (distVec.Magnitude() > CWeaponInfo::GetWeaponInfo(weaponUsed->m_eWeaponType)->m_fRange) + return true; + + if (weaponUsed->m_eWeaponType != WEAPONTYPE_SHOTGUN && weaponUsed->m_eWeaponType != WEAPONTYPE_AK47) + return false; + + distVec.Normalise(); + + if (DotProduct(distVec,GetForward()) < 0.4f) + return true; + + return false; +} + +// Cancels landing anim while running & jumping? I think +void +CPlayerPed::RunningLand(CPad *padUsed) +{ + CAnimBlendAssociation *landAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_LAND); + if (landAssoc && landAssoc->currentTime == 0.0f && m_fMoveSpeed > 1.5f + && padUsed && (padUsed->GetPedWalkLeftRight() != 0.0f || padUsed->GetPedWalkUpDown() != 0.0f)) { + + landAssoc->blendDelta = -1000.0f; + landAssoc->flags |= ASSOC_DELETEFADEDOUT; + + CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_JUMP_LAND)->SetFinishCallback(FinishJumpCB, this); + + if (m_nPedState == PED_JUMP) + RestorePreviousState(); + } +} + +bool +CPlayerPed::IsThisPedAttackingPlayer(CPed *suspect) +{ + if (suspect->m_pPointGunAt == this) + return true; + + switch (suspect->m_objective) { + case OBJECTIVE_KILL_CHAR_ON_FOOT: + case OBJECTIVE_KILL_CHAR_ANY_MEANS: + if (suspect->m_pedInObjective == this) + return true; + + break; + default: + break; + } + return false; +} + +void +CPlayerPed::PlayerControlSniper(CPad *padUsed) +{ + ProcessWeaponSwitch(padUsed); + TheCamera.PlayerExhaustion = (1.0f - (m_fCurrentStamina - -150.0f) / 300.0f) * 0.9f + 0.1f; + + if (!padUsed->GetTarget()) { + RestorePreviousState(); + TheCamera.ClearPlayerWeaponMode(); + } + + if (padUsed->WeaponJustDown()) { + CVector firePos(0.0f, 0.0f, 0.6f); + firePos = GetMatrix() * firePos; + GetWeapon()->Fire(this, &firePos); + } + GetWeapon()->Update(m_audioEntityId); +} + +// I think R* also used goto in here. +void +CPlayerPed::ProcessWeaponSwitch(CPad *padUsed) +{ + if (CDarkel::FrenzyOnGoing()) + goto switchDetectDone; + + // The fact that m_nSelectedWepSlot is int8 makes below loops circular loop. + + if (padUsed->CycleWeaponRightJustDown() && !m_pPointGunAt) { + + if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON + && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON_RUNABOUT + && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER + && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER_RUNABOUT + && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER + && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER_RUNABOUT) { + + for (m_nSelectedWepSlot = m_currentWeapon + 1; m_nSelectedWepSlot < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; ++m_nSelectedWepSlot) { + if (HasWeapon(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) { + goto switchDetectDone; + } + } + m_nSelectedWepSlot = WEAPONTYPE_UNARMED; + } + } else if (padUsed->CycleWeaponLeftJustDown() && !m_pPointGunAt) { + if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON + && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER + && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER) { + + for (m_nSelectedWepSlot = m_currentWeapon - 1; m_nSelectedWepSlot >= 0; --m_nSelectedWepSlot) { + if (HasWeapon(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) { + goto switchDetectDone; + } + } + m_nSelectedWepSlot = WEAPONTYPE_DETONATOR; + } + } else if (CWeaponInfo::GetWeaponInfo((eWeaponType)m_currentWeapon)->m_eWeaponFire != WEAPON_FIRE_MELEE) { + if (GetWeapon(m_currentWeapon).m_nAmmoTotal <= 0) { + if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON + && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER + && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER) { + + for (m_nSelectedWepSlot = m_currentWeapon - 1; m_nSelectedWepSlot >= 0; --m_nSelectedWepSlot) { + if (m_nSelectedWepSlot == WEAPONTYPE_BASEBALLBAT && HasWeapon(WEAPONTYPE_BASEBALLBAT) + || GetWeapon(m_nSelectedWepSlot).m_nAmmoTotal > 0 && m_nSelectedWepSlot != WEAPONTYPE_MOLOTOV && m_nSelectedWepSlot != WEAPONTYPE_GRENADE) { + goto switchDetectDone; + } + } + m_nSelectedWepSlot = WEAPONTYPE_UNARMED; + } + } + } + +switchDetectDone: + if (m_nSelectedWepSlot != m_currentWeapon) { + if (m_nPedState != PED_ATTACK && m_nPedState != PED_AIM_GUN && m_nPedState != PED_FIGHT) + MakeChangesForNewWeapon(m_nSelectedWepSlot); + } +} + +void +CPlayerPed::PlayerControlM16(CPad *padUsed) +{ + ProcessWeaponSwitch(padUsed); + TheCamera.PlayerExhaustion = (1.0f - (m_fCurrentStamina - -150.0f) / 300.0f) * 0.9f + 0.1f; + + if (!padUsed->GetTarget()) { + RestorePreviousState(); + TheCamera.ClearPlayerWeaponMode(); + } + + if (padUsed->GetWeapon()) { + CVector firePos(0.0f, 0.0f, 0.6f); + firePos = GetMatrix() * firePos; + GetWeapon()->Fire(this, &firePos); + } + GetWeapon()->Update(m_audioEntityId); +} + +void +CPlayerPed::PlayerControlFighter(CPad *padUsed) +{ + float leftRight = padUsed->GetPedWalkLeftRight(); + float upDown = padUsed->GetPedWalkUpDown(); + float displacement = sqrt(upDown * upDown + leftRight * leftRight); + + if (displacement > 0.0f) { + m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown) - TheCamera.Orientation; + m_takeAStepAfterAttack = displacement > 120.0f; + if (padUsed->GetSprint() && displacement > 60.0f) + bIsAttacking = false; + } + + if (!CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy && padUsed->JumpJustDown()) { + if (m_bShouldEvade && m_pEvadingFrom) { + SetEvasiveDive((CPhysical*)m_pEvadingFrom, 1); + m_bShouldEvade = false; + m_pEvadingFrom = nil; + } else { + SetJump(); + } + } +} + +class CPlayerPed_ : public CPlayerPed +{ +public: + CPlayerPed* ctor(void) { return ::new (this) CPlayerPed(); } + void dtor(void) { CPlayerPed::~CPlayerPed(); } + void SetMoveAnim_(void) { CPlayerPed::SetMoveAnim(); } +}; + +STARTPATCHES + InjectHook(0x4EF7E0, &CPlayerPed_::ctor, PATCH_JUMP); + InjectHook(0x4EFB30, &CPlayerPed_::dtor, PATCH_JUMP); + InjectHook(0x4F3760, &CPlayerPed_::SetMoveAnim_, PATCH_JUMP); + InjectHook(0x4F28A0, &CPlayerPed::ClearWeaponTarget, PATCH_JUMP); + InjectHook(0x4F3700, &CPlayerPed::AnnoyPlayerPed, PATCH_JUMP); + InjectHook(0x4F36C0, &CPlayerPed::GetPlayerInfoForThisPlayerPed, PATCH_JUMP); + InjectHook(0x4F2560, &CPlayerPed::MakeChangesForNewWeapon, PATCH_JUMP); + InjectHook(0x4F07C0, &CPlayerPed::ReApplyMoveAnims, PATCH_JUMP); + InjectHook(0x4F0880, &CPlayerPed::SetRealMoveAnim, PATCH_JUMP); + InjectHook(0x4F1810, &CPlayerPed::PlayerControlFighter, PATCH_JUMP); + InjectHook(0x4F1340, &CPlayerPed::RestoreSprintEnergy, PATCH_JUMP); + InjectHook(0x4F1380, &CPlayerPed::DoWeaponSmoothSpray, PATCH_JUMP); + InjectHook(0x4F36E0, &CPlayerPed::DoStuffToGoOnFire, PATCH_JUMP); + InjectHook(0x4F3350, &CPlayerPed::DoesTargetHaveToBeBroken, PATCH_JUMP); + InjectHook(0x4F31D0, &CPlayerPed::RunningLand, PATCH_JUMP); + InjectHook(0x4F2D00, &CPlayerPed::IsThisPedAttackingPlayer, PATCH_JUMP); + InjectHook(0x4F1CF0, &CPlayerPed::PlayerControlSniper, PATCH_JUMP); + InjectHook(0x4F2310, &CPlayerPed::ProcessWeaponSwitch, PATCH_JUMP); + InjectHook(0x4F1DF0, &CPlayerPed::PlayerControlM16, PATCH_JUMP); +ENDPATCHES -- cgit v1.2.3