diff --git a/Client/game_sa/CCameraSA.cpp b/Client/game_sa/CCameraSA.cpp index 960ec7cfa7b..2e8f6b6eb81 100644 --- a/Client/game_sa/CCameraSA.cpp +++ b/Client/game_sa/CCameraSA.cpp @@ -458,3 +458,8 @@ void CCameraSA::ResetShakeCamera() noexcept { GetInterface()->m_fCamShakeForce = 0.0f; } + +std::uint8_t CCameraSA::GetTransitionState() +{ + return GetInterface()->m_uiTransitionState; +} diff --git a/Client/game_sa/CCameraSA.h b/Client/game_sa/CCameraSA.h index 246f3362d8d..6ccf5fe4719 100644 --- a/Client/game_sa/CCameraSA.h +++ b/Client/game_sa/CCameraSA.h @@ -82,6 +82,7 @@ class CCameraSAInterface public: // CPlaceable CPlaceableSAInterface Placeable; + std::uint8_t specialPadding[4]; // Temporary padding due to incorrect CPlaceableSAInterface class // End CPlaceable // move these out the class, have decided to set up a mirrored enumerated type thingy at the top @@ -131,16 +132,6 @@ class CCameraSAInterface bool m_bCooperativeCamMode; bool m_bAllowShootingWith2PlayersInCar; bool m_bDisableFirstPersonInCar; - static bool m_bUseMouse3rdPerson; -#ifndef FINALBUILD - bool bStaticFrustum; -#endif - - // for debug keyboard stuff -#ifndef MASTER - unsigned char display_kbd_debug; - float kbd_fov_value; -#endif // MASTER // The following fields allow the level designers to specify the camera for 2 player games. short m_ModeForTwoPlayersSeparateCars; @@ -430,4 +421,6 @@ class CCameraSA : public CCamera void ShakeCamera(float radius, float x, float y, float z) noexcept override; void ResetShakeCamera() noexcept override; + + std::uint8_t GetTransitionState(); }; diff --git a/Client/game_sa/CEntitySA.h b/Client/game_sa/CEntitySA.h index 548cb657f6b..fe0f2d77ae2 100644 --- a/Client/game_sa/CEntitySA.h +++ b/Client/game_sa/CEntitySA.h @@ -123,7 +123,7 @@ class CPlaceableSAInterface // 20 bytes class CEntitySAInterface { public: - CEntitySAInterfaceVTBL* vtbl; // the virtual table + CEntitySAInterfaceVTBL* vtbl; // the virtual table it should be in the CPlaceableSAInterface CPlaceableSAInterface Placeable; // 4 diff --git a/Client/game_sa/CHudSA.cpp b/Client/game_sa/CHudSA.cpp index a63f4703496..6b9c2ff770c 100644 --- a/Client/game_sa/CHudSA.cpp +++ b/Client/game_sa/CHudSA.cpp @@ -13,6 +13,8 @@ #include "CHudSA.h" #include "CGameSA.h" #include "CCameraSA.h" +#include "CPlayerInfoSA.h" +#include "TaskAttackSA.h" extern CGameSA* pGame; @@ -178,35 +180,51 @@ void CHudSA::ResetComponentAdjustment() bool CHudSA::IsCrosshairVisible() { - if (!IsComponentVisible(HUD_CROSSHAIR)) - return false; + bool specialAiming = false; + bool simpleAiming = false; + // Get camera view mode CCamera* camera = pGame->GetCamera(); eCamMode cameraViewMode = static_cast(camera->GetCam(camera->GetActiveCam())->GetMode()); - switch (cameraViewMode) + // Get player + CPed* playerPed = pGame->GetPedContext(); + CWeapon* weapon = nullptr; + eWeaponType weaponType; + + // Get player current weapon + if (playerPed) + { + weapon = playerPed->GetWeapon(playerPed->GetCurrentWeaponSlot()); + if (weapon) + weaponType = weapon->GetType(); + } + + // Special aiming + if (cameraViewMode == MODE_SNIPER || cameraViewMode == MODE_1STPERSON || cameraViewMode == MODE_ROCKETLAUNCHER || cameraViewMode == MODE_ROCKETLAUNCHER_HS || cameraViewMode == MODE_M16_1STPERSON || cameraViewMode == MODE_HELICANNON_1STPERSON || cameraViewMode == MODE_CAMERA) + { + if (weapon && cameraViewMode != MODE_1STPERSON && pGame->GetWeaponInfo(weaponType, WEAPONSKILL_STD)->GetFireType() != FIRETYPE_MELEE) + specialAiming = true; + } + + // Simple aiming + if (cameraViewMode == MODE_M16_1STPERSON_RUNABOUT || cameraViewMode == MODE_ROCKETLAUNCHER_RUNABOUT || cameraViewMode == MODE_ROCKETLAUNCHER_RUNABOUT_HS || cameraViewMode == MODE_SNIPER_RUNABOUT) + simpleAiming = true; + + if ((playerPed && weapon) && !playerPed->GetTargetedObject() && playerPed->GetPedInterface()->pPlayerData->m_bFreeAiming) { - case MODE_SNIPER_RUNABOUT: - case MODE_ROCKETLAUNCHER_RUNABOUT: - case MODE_ROCKETLAUNCHER_RUNABOUT_HS: - case MODE_M16_1STPERSON_RUNABOUT: - case MODE_1STPERSON_RUNABOUT: - case MODE_AIMWEAPON: - case MODE_AIMWEAPON_ATTACHED: - case MODE_AIMWEAPON_FROMCAR: - case MODE_M16_1STPERSON: - case MODE_HELICANNON_1STPERSON: - case MODE_SNIPER: - case MODE_ROCKETLAUNCHER: - case MODE_ROCKETLAUNCHER_HS: - case MODE_AIMING: - case MODE_CAMERA: - return true; - default: - break; + CTaskSimpleUseGun* taskUseGun = playerPed->GetPedIntelligence()->GetTaskUseGun(); + if ((!taskUseGun || !taskUseGun->GetSkipAim()) && (cameraViewMode == MODE_AIMWEAPON || cameraViewMode == MODE_AIMWEAPON_FROMCAR || cameraViewMode == MODE_AIMWEAPON_ATTACHED)) + { + if (playerPed->GetPedState() != PED_ENTER_CAR && playerPed->GetPedState() != PED_CARJACK) + { + if ((weaponType >= WEAPONTYPE_PISTOL && weaponType <= WEAPONTYPE_M4) || weaponType == WEAPONTYPE_TEC9 || weaponType == WEAPONTYPE_COUNTRYRIFLE || weaponType == WEAPONTYPE_MINIGUN || weaponType == WEAPONTYPE_FLAMETHROWER) + simpleAiming = cameraViewMode != MODE_AIMWEAPON || camera->GetTransitionState() == 0; + } + } } // Check CTheScripts::bDrawCrossHair std::uint8_t crossHairType = *reinterpret_cast(VAR_CTheScripts_bDrawCrossHair); - return crossHairType > 0; + return specialAiming || simpleAiming || crossHairType > 0; } diff --git a/Client/game_sa/CPedIntelligenceSA.cpp b/Client/game_sa/CPedIntelligenceSA.cpp index 3c5b1359d0b..e6752a96dab 100644 --- a/Client/game_sa/CPedIntelligenceSA.cpp +++ b/Client/game_sa/CPedIntelligenceSA.cpp @@ -14,6 +14,7 @@ #include "CPedSA.h" #include "CTaskManagementSystemSA.h" #include "CTaskManagerSA.h" +#include "TaskAttackSA.h" CPedIntelligenceSA::CPedIntelligenceSA(CPedIntelligenceSAInterface* pedIntelligenceSAInterface, CPed* ped) { @@ -55,3 +56,16 @@ CTaskSAInterface* CPedIntelligenceSA::SetTaskDuckSecondary(unsigned short nLengt auto SetTaskDuckSecondary = (CTaskSAInterface * (__thiscall*)(CPedIntelligenceSAInterface*, unsigned short))0x601230; return SetTaskDuckSecondary(internalInterface, nLengthOfDuck); } + +CTaskSimpleUseGun* CPedIntelligenceSA::GetTaskUseGun() +{ + CTaskManager* taskMgr = GetTaskManager(); + if (!taskMgr) + return nullptr; + + CTask* secondaryTask = taskMgr->GetTaskSecondary(TASK_SECONDARY_ATTACK); + if (secondaryTask && secondaryTask->GetTaskType() == TASK_SIMPLE_USE_GUN) + return dynamic_cast(secondaryTask); + + return nullptr; +} diff --git a/Client/game_sa/CPedIntelligenceSA.h b/Client/game_sa/CPedIntelligenceSA.h index 7e813193c0e..10cfe322cef 100644 --- a/Client/game_sa/CPedIntelligenceSA.h +++ b/Client/game_sa/CPedIntelligenceSA.h @@ -54,4 +54,5 @@ class CPedIntelligenceSA : public CPedIntelligence CTaskManager* GetTaskManager(); bool TestForStealthKill(CPed* pPed, bool bUnk); CTaskSAInterface* SetTaskDuckSecondary(unsigned short nLengthOfDuck); + CTaskSimpleUseGun* GetTaskUseGun(); }; diff --git a/Client/game_sa/CPedSA.h b/Client/game_sa/CPedSA.h index fee84fd651d..668d2367c73 100644 --- a/Client/game_sa/CPedSA.h +++ b/Client/game_sa/CPedSA.h @@ -230,7 +230,12 @@ class CPedSAInterface : public CPhysicalSAInterface // +1420 = curre int iMoveAnimGroup; // 1236 BYTE bPad4b[52]; CPedIKSAInterface pedIK; // 1292 (length 32 bytes) - int bPad5[5]; + + std::uint32_t field_52C; + ePedState pedState; + eMoveState moveState; + eMoveState swimmingMoveState; + std::uint32_t field_53C; float fHealth; int iUnknown121; @@ -258,7 +263,8 @@ class CPedSAInterface : public CPhysicalSAInterface // +1420 = curre // weapons at +1440 ends at +1804 BYTE bPad4[12]; BYTE bCurrentWeaponSlot; // is actually here - BYTE bPad6[20]; + BYTE bPad6[3]; + CEntitySAInterface* pTargetedObject; BYTE bFightingStyle; // 1837 BYTE bFightingStyleExtra; BYTE bPad7[1]; @@ -408,5 +414,8 @@ class CPedSA : public virtual CPed, public virtual CPhysicalSA std::unique_ptr GetPedIK() { return std::make_unique(GetPedIKInterface()); } static void StaticSetHooks(); + CEntitySAInterface* GetTargetedObject() { return GetPedInterface()->pTargetedObject; } + ePedState GetPedState() { return GetPedInterface()->pedState; } + void GetAttachedSatchels(std::vector &satchelsList) const override; }; diff --git a/Client/game_sa/CPlayerInfoSA.h b/Client/game_sa/CPlayerInfoSA.h index a8b3a84f44e..fd73385f056 100644 --- a/Client/game_sa/CPlayerInfoSA.h +++ b/Client/game_sa/CPlayerInfoSA.h @@ -41,8 +41,9 @@ class CPlayerPedDataSAInterface CVector2D m_vecFightMovement; // 12 float m_moveBlendRatio; // 20 - float m_fSprintEnergy; // 24 - // FLOAT m_fSprintControlCounter; // Removed arbitatrily to aligned next byte, should be here really + float m_fTimeCanRun; + float m_fSprintEnergy; + BYTE m_nChosenWeapon; // 28 BYTE m_nCarDangerCounter; // 29 BYTE m_pad0; // 30 @@ -68,8 +69,6 @@ class CPlayerPedDataSAInterface DWORD m_bInVehicleDontAllowWeaponChange : 1; // stop weapon change once driveby weapon has been given DWORD m_bRenderWeapon : 1; // set to false during cutscenes so that knuckledusters are not rendered - DWORD m_pad2; // 56 - long m_PlayerGroup; // 60 DWORD m_AdrenalineEndTime; // 64 diff --git a/Client/sdk/game/CCamera.h b/Client/sdk/game/CCamera.h index 7dc104e3c09..57ede01f018 100644 --- a/Client/sdk/game/CCamera.h +++ b/Client/sdk/game/CCamera.h @@ -146,4 +146,6 @@ class CCamera virtual void ShakeCamera(float radius, float x, float y, float z) noexcept = 0; virtual void ResetShakeCamera() noexcept = 0; + + virtual std::uint8_t GetTransitionState() = 0; }; diff --git a/Client/sdk/game/CPed.h b/Client/sdk/game/CPed.h index 4e91cdb8b43..22fb276923f 100644 --- a/Client/sdk/game/CPed.h +++ b/Client/sdk/game/CPed.h @@ -285,5 +285,8 @@ class CPed : public virtual CPhysical virtual void* GetPedNodeInterface(std::int32_t nodeId) = 0; virtual std::unique_ptr GetPedIK() = 0; + virtual CEntitySAInterface* GetTargetedObject() = 0; + virtual ePedState GetPedState() = 0; + virtual void GetAttachedSatchels(std::vector &satchelsList) const = 0; }; diff --git a/Client/sdk/game/CPedIntelligence.h b/Client/sdk/game/CPedIntelligence.h index 37704ed893c..f9d662e94d7 100644 --- a/Client/sdk/game/CPedIntelligence.h +++ b/Client/sdk/game/CPedIntelligence.h @@ -14,6 +14,7 @@ class CPed; class CTaskSAInterface; class CTaskManager; +class CTaskSimpleUseGun; class CPedIntelligence { @@ -21,4 +22,5 @@ class CPedIntelligence virtual CTaskManager* GetTaskManager() = 0; virtual bool TestForStealthKill(CPed* pPed, bool bUnk) = 0; virtual CTaskSAInterface* SetTaskDuckSecondary(unsigned short nLengthOfDuck) = 0; + virtual CTaskSimpleUseGun* GetTaskUseGun() = 0; }; diff --git a/Client/sdk/game/TaskAttack.h b/Client/sdk/game/TaskAttack.h index 9a63e8da200..c98d0628484 100644 --- a/Client/sdk/game/TaskAttack.h +++ b/Client/sdk/game/TaskAttack.h @@ -44,6 +44,8 @@ class CTaskSimpleUseGun : public virtual CTaskSimple virtual bool ControlGun(CPed* pPed, CEntity* pTargetEntity, char nCommand) = 0; virtual bool ControlGunMove(CVector2D* pMoveVec) = 0; virtual void Reset(CPed* pPed, CEntity* pTargetEntity, CVector vecTarget, char nCommand, short nBurstLength = 1) = 0; + + virtual bool GetSkipAim() = 0; }; class CTaskSimpleFight : public virtual CTaskSimple