diff --git a/Mods/Player/Src/Player.cpp b/Mods/Player/Src/Player.cpp index a289dd9f..fe1cd9a7 100644 --- a/Mods/Player/Src/Player.cpp +++ b/Mods/Player/Src/Player.cpp @@ -25,6 +25,16 @@ void Player::Init() { &Player::ZSecuritySystemCameraManager_OnFrameUpdate ); Hooks::ZSecuritySystemCamera_FrameUpdate->AddDetour(this, &Player::ZSecuritySystemCamera_FrameUpdate); + + Hooks::ZHM5ItemWeapon_SetBulletsInMagazine->AddDetour(this, &Player::ZHM5ItemWeapon_SetBulletsInMagazine); + Hooks::ZHitmanMorphemePostProcessor_UpdateWeaponRecoil->AddDetour( + this, + &Player::ZHitmanMorphemePostProcessor_UpdateWeaponRecoil + ); + Hooks::ZHM5WeaponRecoilController_RecoilWeapon->AddDetour(this, &Player::ZHM5WeaponRecoilController_RecoilWeapon); + Hooks::ZHM5ItemWeapon_FireProjectiles->AddDetour(this, &Player::ZHM5ItemWeapon_FireProjectiles); + Hooks::ZHM5ItemWeapon_IsFiring->AddDetour(this, &Player::ZHM5ItemWeapon_IsFiring); + Hooks::ZActor_YouGotHit->AddDetour(this, &Player::ZActor_YouGotHit); } void Player::OnDrawMenu() { @@ -59,6 +69,16 @@ void Player::OnDrawUI(const bool p_HasFocus) { ToggleInfiniteAmmo(); } + ImGui::Checkbox("No Reload", &m_IsNoReloadEnabled); + + ImGui::Checkbox("No Recoil", &m_IsNoRecoilEnabled); + + ImGui::Checkbox("Super Accuracy", &m_IsSuperAccuracyEnabled); + + ImGui::Checkbox("RapidFire", &m_IsRapidFireEnabled); + + ImGui::Checkbox("One Hit Kill", &m_IsOneHitKillEnabled); + static char s_OutfitName[2048] { "" }; static uint8_t s_CurrentCharacterSetIndex = 0; static std::string s_CurrentCharSetCharacterType = "HeroA"; @@ -606,7 +626,7 @@ DEFINE_PLUGIN_DETOUR(Player, void, OnClearScene, ZEntitySceneContext* th, bool p m_IsInfiniteAmmoEnabled = false; m_GlobalOutfitKit = {}; - return HookResult(HookAction::Continue()); + return { HookAction::Continue() }; } DEFINE_PLUGIN_DETOUR( @@ -614,13 +634,13 @@ DEFINE_PLUGIN_DETOUR( void, ZSecuritySystemCameraManager_OnFrameUpdate, ZSecuritySystemCameraManager* th, - const SGameUpdateEvent* const updateEvent + const SGameUpdateEvent& updateEvent ) { if (m_IsInvisible) { - return HookResult(HookAction::Return()); + return { HookAction::Return() }; } - return HookResult(HookAction::Continue()); + return { HookAction::Continue() }; } DEFINE_PLUGIN_DETOUR( @@ -628,13 +648,155 @@ DEFINE_PLUGIN_DETOUR( void, ZSecuritySystemCamera_FrameUpdate, ZSecuritySystemCamera* th, - const SGameUpdateEvent* const updateEvent + const SGameUpdateEvent& updateEvent ) { if (m_IsInvisible) { - return HookResult(HookAction::Return()); + return { HookAction::Return() }; + } + + return { HookAction::Continue() }; +} + +DEFINE_PLUGIN_DETOUR(Player, void, ZHM5ItemWeapon_SetBulletsInMagazine, IFirearm* th, int32_t nBullets) { + if (!m_IsNoReloadEnabled) { + return { HookAction::Continue() }; + } + + const auto s_LocalHitman = SDK()->GetLocalPlayer(); + + if (!s_LocalHitman) { + return { HookAction::Continue() }; + } + + ZHM5ItemWeapon* s_HM5ItemWeapon = static_cast(th); + + if (s_HM5ItemWeapon->m_pOwner != s_LocalHitman.m_entityRef) { + return { HookAction::Continue() }; + } + + if (s_HM5ItemWeapon->m_nBulletsFired == s_HM5ItemWeapon->m_nBulletsToFire) { + s_HM5ItemWeapon->m_nBulletsFired = 0; + } + + if (nBullets != 0) { + return { HookAction::Continue() }; + } + + if (!s_LocalHitman.m_pInterfaceRef->IsInfiniteAmmoEnabled()) { + auto s_Character = s_LocalHitman.m_pInterfaceRef->m_pCharacter.m_pInterfaceRef; + auto s_Controllers = &s_Character->m_rSubcontrollerContainer.m_pInterfaceRef->m_aReferencedControllers; + auto s_Inventory = static_cast((*s_Controllers)[6].m_pInterfaceRef); + + const eAmmoType s_AmmoType = th->GetAmmoType(); + + uint32 s_AmmoInPocket = Functions::ZCharacterSubcontrollerInventory_GetAmmoInPocketForType->Call( + s_Inventory, + s_AmmoType + ); + + if (s_AmmoInPocket > 0) { + s_AmmoInPocket -= s_HM5ItemWeapon->GetMagazineCapacity(); + + s_Inventory->m_nAmmoInPocket[static_cast(s_AmmoType)] = s_AmmoInPocket; + + nBullets = s_HM5ItemWeapon->GetMagazineCapacity(); + } + } + else { + nBullets = s_HM5ItemWeapon->GetMagazineCapacity(); + } + + p_Hook->CallOriginal(th, nBullets); + + return { HookAction::Return() }; +} + +DEFINE_PLUGIN_DETOUR( + Player, + void, + ZHitmanMorphemePostProcessor_UpdateWeaponRecoil, + ZHitmanMorphemePostProcessor* th, + float fDeltaTime, + const THashMap>& charboneMap, + TArrayRef hierarchy +) { + if (m_IsNoRecoilEnabled) { + return { HookAction::Return() }; + } + + return { HookAction::Continue() }; +} + +DEFINE_PLUGIN_DETOUR( + Player, + void, + ZHM5WeaponRecoilController_RecoilWeapon, + ZHM5WeaponRecoilController* th, + const TEntityRef& rWeapon +) { + if (!m_IsNoRecoilEnabled) { + return { HookAction::Continue() }; + } + + p_Hook->CallOriginal(th, rWeapon); + + th->m_vRecoil = SVector2(0.f, 0.f); + + return { HookAction::Return() }; +} + +DEFINE_PLUGIN_DETOUR(Player, bool, ZHM5ItemWeapon_FireProjectiles, ZHM5ItemWeapon* th, bool bMayStartSound) { + if (!m_IsSuperAccuracyEnabled) { + return { HookAction::Continue() }; + } + + const auto s_LocalHitman = SDK()->GetLocalPlayer(); + + if (!s_LocalHitman) { + return { HookAction::Continue() }; + } + + if (th->m_pOwner != s_LocalHitman.m_entityRef) { + return { HookAction::Continue() }; + } + + bool s_Result = p_Hook->CallOriginal(th, bMayStartSound); + + th->m_fPrecisionFactor = 0.f; + + return { HookAction::Return(), s_Result }; +} + +DEFINE_PLUGIN_DETOUR(Player, bool, ZHM5ItemWeapon_IsFiring, IFirearm* th) { + if (!m_IsRapidFireEnabled) { + return { HookAction::Continue() }; + } + + const auto s_LocalHitman = SDK()->GetLocalPlayer(); + + if (!s_LocalHitman) { + return { HookAction::Continue() }; + } + + ZHM5ItemWeapon* s_HM5ItemWeapon = static_cast(th); + + if (s_HM5ItemWeapon->m_pOwner != s_LocalHitman.m_entityRef) { + return { HookAction::Continue() }; + } + + s_HM5ItemWeapon->m_tLastShootTime = ZGameTime {}; + + return { HookAction::Continue() }; +} + +DEFINE_PLUGIN_DETOUR(Player, bool, ZActor_YouGotHit, IBaseCharacter* th, const SHitInfo& hitInfo) { + if (m_IsOneHitKillEnabled) { + ZActor* s_Actor = static_cast(th); + + s_Actor->m_fCurrentHitPoints = 0.f; } - return HookResult(HookAction::Continue()); + return { HookAction::Continue() }; } DEFINE_ZHM_PLUGIN(Player); diff --git a/Mods/Player/Src/Player.h b/Mods/Player/Src/Player.h index 01e17273..1a1042a7 100644 --- a/Mods/Player/Src/Player.h +++ b/Mods/Player/Src/Player.h @@ -28,13 +28,56 @@ class Player : public IPluginInterface { DECLARE_PLUGIN_DETOUR(Player, void, OnClearScene, ZEntitySceneContext* th, bool p_FullyUnloadScene); - DECLARE_PLUGIN_DETOUR(Player, void, ZSecuritySystemCameraManager_OnFrameUpdate, ZSecuritySystemCameraManager* th, const SGameUpdateEvent* const updateEvent); - DECLARE_PLUGIN_DETOUR(Player, void, ZSecuritySystemCamera_FrameUpdate, ZSecuritySystemCamera* th, const SGameUpdateEvent* const updateEvent); + DECLARE_PLUGIN_DETOUR( + Player, + void, + ZSecuritySystemCameraManager_OnFrameUpdate, + ZSecuritySystemCameraManager* th, + const SGameUpdateEvent& updateEvent + ); + DECLARE_PLUGIN_DETOUR( + Player, + void, + ZSecuritySystemCamera_FrameUpdate, + ZSecuritySystemCamera* th, + const SGameUpdateEvent& updateEvent + ); + + DECLARE_PLUGIN_DETOUR(Player, void, ZHM5ItemWeapon_SetBulletsInMagazine, IFirearm* th, int32_t nBullets); + + DECLARE_PLUGIN_DETOUR( + Player, + void, + ZHitmanMorphemePostProcessor_UpdateWeaponRecoil, + ZHitmanMorphemePostProcessor* th, + float fDeltaTime, + const THashMap>& charboneMap, + TArrayRef hierarchy + ); + + DECLARE_PLUGIN_DETOUR( + Player, + void, + ZHM5WeaponRecoilController_RecoilWeapon, + ZHM5WeaponRecoilController* th, + const TEntityRef& rWeapon + ); + + DECLARE_PLUGIN_DETOUR(Player, bool, ZHM5ItemWeapon_FireProjectiles, ZHM5ItemWeapon* th, bool bMayStartSound); + + DECLARE_PLUGIN_DETOUR(Player, bool, ZHM5ItemWeapon_IsFiring, IFirearm* th); + + DECLARE_PLUGIN_DETOUR(Player, bool, ZActor_YouGotHit, IBaseCharacter* th, const SHitInfo& hitInfo); bool m_PlayerMenuActive = false; bool m_IsInvincible = false; bool m_IsInvisible = false; bool m_IsInfiniteAmmoEnabled = false; + bool m_IsNoReloadEnabled = false; + bool m_IsNoRecoilEnabled = false; + bool m_IsSuperAccuracyEnabled = false; + bool m_IsRapidFireEnabled = false; + bool m_IsOneHitKillEnabled = false; const std::vector m_CharSetCharacterTypes = { "Actor", "Nude", "HeroA" }; diff --git a/ZHMModSDK/Include/Functions.h b/ZHMModSDK/Include/Functions.h index fb5fca5f..d05c1ad8 100644 --- a/ZHMModSDK/Include/Functions.h +++ b/ZHMModSDK/Include/Functions.h @@ -52,6 +52,7 @@ class IItemBase; class ZStashPointEntity; class ZTimeOfDayManager; class ZHM5Health; +class ZHM5WeaponControl; namespace bfx { class AreaHandle; @@ -247,4 +248,10 @@ class ZHMSDK_API Functions { static EngineFunction* ZHM5Health_GetHP; static EngineFunction* ZHM5Health_GetMaxHitpoints; + + static EngineFunction* ZCharacterSubcontrollerInventory_GetAmmoInPocketForType; + + static EngineFunction* ZHM5WeaponControl_GetCrosshairScale; }; \ No newline at end of file diff --git a/ZHMModSDK/Include/Glacier/ZGameTime.h b/ZHMModSDK/Include/Glacier/ZGameTime.h index 71f0ee26..1d6729b2 100644 --- a/ZHMModSDK/Include/Glacier/ZGameTime.h +++ b/ZHMModSDK/Include/Glacier/ZGameTime.h @@ -2,12 +2,90 @@ #include "Reflection.h" -struct ZGameTime { - int64_t m_nTicks; +class ZGameTime { +public: + ZGameTime() = default; + + explicit ZGameTime(int64_t p_Ticks) { + m_nTicks = p_Ticks; + } + + explicit ZGameTime(float p_Seconds) { + m_nTicks = static_cast(p_Seconds * (1 << FractionBits)); + } + + explicit ZGameTime(double p_Seconds) { + m_nTicks = static_cast(p_Seconds * (1 << FractionBits)); + } + + explicit operator int64_t() const { + return m_nTicks; + } + + explicit operator float() const { + return m_nTicks * TicksToSeconds; + } + + ZGameTime operator+(const ZGameTime& p_Other) const { + return ZGameTime(m_nTicks + p_Other.m_nTicks); + } + + ZGameTime& operator+=(const ZGameTime& p_Other) { + m_nTicks += p_Other.m_nTicks; + + return *this; + } + + ZGameTime operator-(const ZGameTime& p_Other) const { + return ZGameTime(m_nTicks - p_Other.m_nTicks); + } + + ZGameTime& operator-=(const ZGameTime& p_Other) { + m_nTicks -= p_Other.m_nTicks; + + return *this; + } + + ZGameTime operator*(const ZGameTime& p_Other) const { + return ZGameTime((m_nTicks * p_Other.m_nTicks) >> FractionBits); + } + + ZGameTime& operator*=(const ZGameTime& p_Other) { + m_nTicks = (m_nTicks * p_Other.m_nTicks) >> FractionBits; + + return *this; + } + + ZGameTime operator/(const ZGameTime& p_Other) const { + return ZGameTime((m_nTicks << FractionBits) / p_Other.m_nTicks); + } + + ZGameTime& operator/=(const ZGameTime& p_Other) { + m_nTicks = (m_nTicks << FractionBits) / p_Other.m_nTicks; + + return *this; + } + + bool operator<(const ZGameTime& rhs) const { + return m_nTicks < rhs.m_nTicks; + } + + static ZGameTime FromSeconds(float p_Seconds) { + return ZGameTime(static_cast(p_Seconds * (1 << FractionBits))); + } + + static ZGameTime FromSeconds(double p_Seconds) { + return ZGameTime(static_cast(p_Seconds * (1 << FractionBits))); + } double ToSeconds() const { - return static_cast(m_nTicks) / 1024.0 / 1024.0; + return static_cast(m_nTicks) / (1 << FractionBits); } + + int64_t m_nTicks; + + static constexpr int FractionBits = 20; + static constexpr float TicksToSeconds = 1.0f / (1 << FractionBits); }; class ZGameTimeManager : public IComponentInterface { @@ -22,7 +100,7 @@ class ZGameTimeManager : public IComponentInterface { ZGameTime m_tRealTimeDelta; // 0x40 float m_fGameTimeMultiplier; // 0x48 float m_fDebugTimeMultiplier; // 0x4C - PAD(0x8); // 0x50 + bool m_Unk; // 0x50 ZGameTime m_FrameWait; // 0x58 ZGameTime m_FrameStep; // 0x60 ZGameTime m_FrameRemain; // 0x68 diff --git a/ZHMModSDK/Include/Glacier/ZHitman5.h b/ZHMModSDK/Include/Glacier/ZHitman5.h index 3c9802b1..1ec708a6 100644 --- a/ZHMModSDK/Include/Glacier/ZHitman5.h +++ b/ZHMModSDK/Include/Glacier/ZHitman5.h @@ -7,6 +7,12 @@ #include "ZOutfit.h" #include "TCheatProtect.h" +class IFirearm; + +enum class ECustomFlags { + eLIMITED_AMMO = 0x2000000 +}; + class IFutureCameraState : public IComponentInterface { public: @@ -31,7 +37,7 @@ class IInventoryOwner { }; class IIKControllerOwner : - public IComponentInterface { + public IComponentInterface { public: virtual ~IIKControllerOwner() {} virtual void IIKControllerOwner_unk0() = 0; @@ -65,10 +71,11 @@ class IIKControllerOwner : virtual void IIKControllerOwner_unk28() = 0; virtual void IIKControllerOwner_unk29() = 0; virtual void IIKControllerOwner_unk30() = 0; - virtual void IIKControllerOwner_unk31() = 0; + virtual bool IsCustomFlagEnabled(ECustomFlags eCustomFlags) const = 0; virtual void IIKControllerOwner_unk32() = 0; virtual void IIKControllerOwner_unk33() = 0; virtual void IIKControllerOwner_unk34() = 0; + virtual void IIKControllerOwner_unk35() = 0; }; class IControllableCharacter : @@ -255,7 +262,7 @@ class ICharacterInventoryState : virtual void ICharacterInventoryState_unk17() = 0; virtual void ICharacterInventoryState_unk18() = 0; virtual void ICharacterInventoryState_unk19() = 0; - virtual void ICharacterInventoryState_unk20() = 0; + virtual uint32 GetAmmoInPocketFor(const TEntityRef& rWeapon) = 0; virtual void ICharacterInventoryState_unk21() = 0; virtual void ICharacterInventoryState_unk22() = 0; virtual void ICharacterInventoryState_unk23() = 0; @@ -401,11 +408,23 @@ class ZFabricColliderBaseEntity; class ZHM5Health { public: - PAD(0x228); + PAD(0x228); // 0x0 TCheatProtect m_fHitPoints; // 0x228 TCheatProtect m_fMaxHitPoints; // 0x238 }; +class ZHM5BaseController { +public: + virtual ~ZHM5BaseController() = 0; +}; + +class ZHM5WeaponRecoilController : public ZHM5BaseController { +public: + PAD(0x40); // 0x8 + SVector2 m_vRecoil; // 0x48 + SVector2 m_vAccumlatedRecoil; // 0x50 +}; + class ZHitman5 : public ZHM5BaseCharacter, public IFutureCameraState, // 720 @@ -427,6 +446,10 @@ class ZHitman5 : public ICharacterCameraState // 848 { public: + bool IsInfiniteAmmoEnabled() const { + return !IsCustomFlagEnabled(ECustomFlags::eLIMITED_AMMO); + } + PAD(0x3B8); // 0x358 ZRepositoryID m_InitialOutfitId; // 0x710 ZEntityRef m_MorphemeEntityID; // 0x720 diff --git a/ZHMModSDK/Include/Glacier/ZInventory.h b/ZHMModSDK/Include/Glacier/ZInventory.h index ab8c3fbf..5b926db4 100644 --- a/ZHMModSDK/Include/Glacier/ZInventory.h +++ b/ZHMModSDK/Include/Glacier/ZInventory.h @@ -25,7 +25,7 @@ class ZCharacterSubcontrollerInventory : public ZCharacterSubcontroller //Size: ECIT_ContainerItem = 4 }; - PAD(0x140); + PAD(0x120); uint32 m_nMaxGunAmmo; // 0x158 uint32 m_nMaxRevolverAmmo; // 0x15C uint32 m_nMaxSMGAmmo; // 0x160 diff --git a/ZHMModSDK/Include/Glacier/ZItem.h b/ZHMModSDK/Include/Glacier/ZItem.h index 211050f1..3f1aa46a 100644 --- a/ZHMModSDK/Include/Glacier/ZItem.h +++ b/ZHMModSDK/Include/Glacier/ZItem.h @@ -4,6 +4,7 @@ #include "ZSpatialEntity.h" #include "ZGeomEntity.h" #include "ZHitman5.h" +#include "ZGameTime.h" class IItemBase : public IComponentInterface {}; @@ -121,17 +122,109 @@ class ZHM5Item : TEntityRef m_rItemCanTurnOn; // 0x2E8 TEntityRef m_rItemCanTurnOff; // 0x2F8 TEntityRef m_pVariationResource; // 0x308 - ZEntityRef m_rSpawner; - ZEntityRef m_rFactoryEntity; - PAD(0x10); - TEntityRef m_pGeomEntity; //0x2C0 - PAD(0x1A8); + ZEntityRef m_rSpawner; // 0x318 + ZEntityRef m_rFactoryEntity; // 0x320 + PAD(0x10); // 0x328 + TEntityRef m_pGeomEntity; //0x338 + PAD(0x10); // 0x2D0 + ZEntityRef m_pOwner; // 0x358 + PAD(0x190); }; class IItemWeapon : public IComponentInterface { }; +struct SWeaponConfig; + class IFirearm : public IComponentInterface { +public: + virtual ~IFirearm() = 0; + virtual void IFirearm_unk5() = 0; + virtual void IFirearm_unk6() = 0; + virtual void IFirearm_unk7() = 0; + virtual void IFirearm_unk8() = 0; + virtual void IFirearm_unk9() = 0; + virtual void IFirearm_unk10() = 0; + virtual void IFirearm_unk11() = 0; + virtual void IFirearm_unk12() = 0; + virtual void IFirearm_unk13() = 0; + virtual void IFirearm_unk14() = 0; + virtual void IFirearm_unk15() = 0; + virtual void IFirearm_unk16() = 0; + virtual const SWeaponConfig& GetWeaponConfig() const = 0; + virtual void IFirearm_unk18() = 0; + virtual void IFirearm_unk19() = 0; + virtual void SetBulletsInMagazine(int32_t nBullets) = 0; + virtual uint16_t GetBulletsInMagazine() const = 0; + virtual void IFirearm_unk22() = 0; + virtual void IFirearm_unk23() = 0; + virtual void IFirearm_unk24() = 0; + virtual void IFirearm_unk25() = 0; + virtual void IFirearm_unk26() = 0; + virtual void IFirearm_unk27() = 0; + virtual void IFirearm_unk28() = 0; + virtual int GetMagazineCapacity() const = 0; + virtual eAmmoType GetAmmoType() const = 0; + virtual void IFirearm_unk31() = 0; + virtual void IFirearm_unk32() = 0; + virtual void IFirearm_unk33() = 0; + virtual void IFirearm_unk34() = 0; + virtual void IFirearm_unk35() = 0; + virtual void IFirearm_unk36() = 0; + virtual void IFirearm_unk37() = 0; + virtual void IFirearm_unk38() = 0; + virtual void IFirearm_unk39() = 0; + virtual void IFirearm_unk40() = 0; + virtual void IFirearm_unk41() = 0; + virtual void IFirearm_unk42() = 0; + virtual void IFirearm_unk43() = 0; + virtual void IFirearm_unk44() = 0; + virtual void IFirearm_unk45() = 0; + virtual void IFirearm_unk46() = 0; + virtual void IFirearm_unk47() = 0; + virtual void IFirearm_unk48() = 0; + virtual void IFirearm_unk49() = 0; + virtual void IFirearm_unk50() = 0; + virtual void IFirearm_unk51() = 0; + virtual void IFirearm_unk52() = 0; + virtual void IFirearm_unk53() = 0; + virtual void IFirearm_unk54() = 0; + virtual void IFirearm_unk55() = 0; + virtual void IFirearm_unk56() = 0; + virtual void IFirearm_unk57() = 0; + virtual void IFirearm_unk58() = 0; + virtual bool IsFiring() const = 0; + virtual float GetTimeBetweenBullets() const = 0; + virtual void IFirearm_unk61() = 0; + virtual void IFirearm_unk62() = 0; + virtual void IFirearm_unk63() = 0; + virtual void IFirearm_unk64() = 0; + virtual void IFirearm_unk65() = 0; + virtual void IFirearm_unk66() = 0; + virtual void IFirearm_unk67() = 0; + virtual void IFirearm_unk68() = 0; + virtual void IFirearm_unk69() = 0; + virtual void IFirearm_unk70() = 0; + virtual void IFirearm_unk71() = 0; + virtual void IFirearm_unk72() = 0; + virtual void IFirearm_unk73() = 0; + virtual void IFirearm_unk74() = 0; + virtual void IFirearm_unk75() = 0; + virtual void IFirearm_unk76() = 0; + virtual void IFirearm_unk77() = 0; + virtual void IFirearm_unk78() = 0; + virtual void IFirearm_unk79() = 0; + virtual void IFirearm_unk80() = 0; + virtual void IFirearm_unk81() = 0; + virtual void IFirearm_unk82() = 0; + virtual void IFirearm_unk83() = 0; + virtual void IFirearm_unk84() = 0; + virtual void IFirearm_unk85() = 0; + virtual void IFirearm_unk86() = 0; + virtual void IFirearm_unk87() = 0; + virtual void IFirearm_unk88() = 0; + virtual void IFirearm_unk89() = 0; + virtual void IFirearm_unk90() = 0; }; class IParticleEmitterEntity; @@ -172,7 +265,15 @@ class ZHM5ItemWeapon : ZEntityRef m_rSuperSpecialTriggerEffect; // 0x5E0 TArray> m_rClipMeshProviders; // 0x5E8 TArray> m_aManualReloadSettings; // 0x600 - PAD(0x398); + PAD(0x310); // 0x618 + uint16 m_nBulletsToFire; // 0x928 + PAD(0x6); // 0x92A + uint16 m_nBulletsFired; // 0x930 + PAD(0xE); // 0x932 + ZGameTime m_tLastShootTime; // 0x940 + float32 m_fTimeBetweenBullets; // 0x948 + float m_fPrecisionFactor; // 0x94C + PAD(0x60); }; class ZItemSpawner : public ZSpatialEntity, public IItemOwner, public ISavableEntity //Size: 0x138 diff --git a/ZHMModSDK/Include/Hooks.h b/ZHMModSDK/Include/Hooks.h index 9a1e454b..cf21194f 100644 --- a/ZHMModSDK/Include/Hooks.h +++ b/ZHMModSDK/Include/Hooks.h @@ -86,6 +86,12 @@ class ZActorInventoryHandler; class ZItemRepositoryKeyEntity; class ZGlobalOutfitKit; class ZClothBundleEntity; +class ZHM5ItemWeapon; +class IFirearm; +struct SHitInfo; +class IBaseCharacter; +class ZHitmanMorphemePostProcessor; +class ZHM5WeaponRecoilController; class ZHMSDK_API Hooks { public: @@ -239,8 +245,8 @@ class ZHMSDK_API Hooks { static Hook* ZEntitySceneContext_SetLoadingStage; static Hook* ZSecuritySystemCameraManager_UpdateCameraState; - static Hook* ZSecuritySystemCameraManager_OnFrameUpdate; - static Hook* ZSecuritySystemCamera_FrameUpdate; + static Hook* ZSecuritySystemCameraManager_OnFrameUpdate; + static Hook* ZSecuritySystemCamera_FrameUpdate; static Hook* ZClothBundleEntity_CreateClothBundle; + + static Hook* ZHM5ItemWeapon_SetBulletsInMagazine; + + static Hook* ZActor_YouGotHit; + + static Hook>& charboneMap, + TArrayRef hierarchy + )>* ZHitmanMorphemePostProcessor_UpdateWeaponRecoil; + + static Hook& rWeapon + )>* ZHM5WeaponRecoilController_RecoilWeapon; + + static Hook* ZHM5ItemWeapon_FireProjectiles; + + static Hook* ZHM5ItemWeapon_IsFiring; }; \ No newline at end of file diff --git a/ZHMModSDK/Src/Functions.cpp b/ZHMModSDK/Src/Functions.cpp index 98c47ba6..7a5c3bff 100644 --- a/ZHMModSDK/Src/Functions.cpp +++ b/ZHMModSDK/Src/Functions.cpp @@ -484,4 +484,18 @@ PATTERN_FUNCTION( "xxxxxxxxxxxxxxxxx?xxxxxxx", ZHM5Health_GetMaxHitpoints, float32(const ZHM5Health* th) +); + +PATTERN_FUNCTION( + "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x48\x89\x7C\x24\x18\x55\x48\x8B\xEC\x48\x83\xEC\x00\x48\x8B\x41\x20", + "xxxxxxxxxxxxxxxxxxxxxx?xxxx", + ZCharacterSubcontrollerInventory_GetAmmoInPocketForType, + uint32_t(ZCharacterSubcontrollerInventory* th, eAmmoType AmmoType) +); + +PATTERN_FUNCTION( + "\x40\x53\x48\x81\xEC\x00\x00\x00\x00\x48\x8B\xD9\x48\x8B\x49\x38", + "xxxxx????xxxxxxx", + ZHM5WeaponControl_GetCrosshairScale, + float(ZHM5WeaponControl* th) ); \ No newline at end of file diff --git a/ZHMModSDK/Src/Hooks.cpp b/ZHMModSDK/Src/Hooks.cpp index ff5c18c9..271d6abe 100644 --- a/ZHMModSDK/Src/Hooks.cpp +++ b/ZHMModSDK/Src/Hooks.cpp @@ -424,14 +424,14 @@ PATTERN_HOOK( "\x48\x89\x4C\x24\x08\x55\x41\x56\x48\x8D\xAC\x24\x58\xEE\xFF\xFF", "xxxxxxxxxxxxxxxx", ZSecuritySystemCameraManager_OnFrameUpdate, - void(ZSecuritySystemCameraManager* th, const SGameUpdateEvent* const updateEvent) + void(ZSecuritySystemCameraManager* th, const SGameUpdateEvent& updateEvent) ); PATTERN_HOOK( "\x40\x55\x41\x56\x48\x8D\x6C\x24\x88", "xxxxxxxxx", ZSecuritySystemCamera_FrameUpdate, - void(ZSecuritySystemCamera* th, const SGameUpdateEvent* const a2) + void(ZSecuritySystemCamera* th, const SGameUpdateEvent& updateEvent) ); PATTERN_HOOK( @@ -552,4 +552,47 @@ PATTERN_HOOK( ZClothBundleEntity_CreateClothBundle, TEntityRef* (TEntityRef& result, const SMatrix& mat, ZRepositoryID id, int32_t nOutfitVariation, int32_t nOutfitCharset, bool bSpawnedByHitman, bool bEnableOutfitModifiers) +); + +PATTERN_HOOK( + "\x48\x8B\xC1\x44\x8B\xC2\x48\x81\xC1", + "xxxxxxxxx", + ZHM5ItemWeapon_SetBulletsInMagazine, + void(IFirearm* th, int32_t nBullets) +); + +PATTERN_HOOK( + "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x00\x48\x8B\x99\x78\x11\x00\x00", + "xxxxxxxxx?xxxxxxx", + ZActor_YouGotHit, + bool(IBaseCharacter* th, const SHitInfo& hitInfo) +); + +PATTERN_HOOK( + "\x48\x8B\xC4\x4C\x89\x48\x20\x4C\x89\x40\x18\xF3\x0F\x11\x48\x10", + "xxxxxxxxxxxxxxxx", + ZHitmanMorphemePostProcessor_UpdateWeaponRecoil, + void(ZHitmanMorphemePostProcessor* th, float fDeltaTime, + const THashMap>& charboneMap, TArrayRef hierarchy) +); + +PATTERN_HOOK( + "\x40\x53\x48\x83\xEC\x00\x48\x8B\xD9\x0F\x29\x74\x24\x50\x48\x8B\x4A\x08", + "xxxxx?xxxxxxxxxxxx", + ZHM5WeaponRecoilController_RecoilWeapon, + void(ZHM5WeaponRecoilController* th, const TEntityRef& rWeapon) +); + +PATTERN_HOOK( + "\x88\x54\x24\x10\x55\x53\x56\x57\x41\x54\x41\x55\x41\x57", + "xxxxxxxxxxxxxx", + ZHM5ItemWeapon_FireProjectiles, + bool(ZHM5ItemWeapon* th, bool bMayStartSound) +); + +PATTERN_HOOK( + "\x40\x53\x48\x83\xEC\x00\x48\x8B\x01\x48\x8B\xD9\xFF\x90\xE0\x01\x00\x00", + "xxxxx?xxxxxxxxxxxx", + ZHM5ItemWeapon_IsFiring, + bool(IFirearm* th) ); \ No newline at end of file