From 03c74a6eaa8562ea4d11e19aa6fe751f66fdaf66 Mon Sep 17 00:00:00 2001 From: Andrei Abrudan Date: Sat, 23 Jul 2022 03:32:01 +0100 Subject: [PATCH 1/4] Added small fix for fast dialogue --- cheat-library/src/user/cheat/world/DialogSkip.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cheat-library/src/user/cheat/world/DialogSkip.cpp b/cheat-library/src/user/cheat/world/DialogSkip.cpp index 0d4814a..4e937a3 100644 --- a/cheat-library/src/user/cheat/world/DialogSkip.cpp +++ b/cheat-library/src/user/cheat/world/DialogSkip.cpp @@ -85,6 +85,8 @@ namespace cheat::feature if (f_FastDialog) app::Time_set_timeScale(f_TimeSpeedup, nullptr); + else + app::Time_set_timeScale(1.0f, nullptr); bool isImportant = false; if (f_ExcludeImportant) From 38aa9835390a30fa9ad5c515a23d9ab19a7b27c3 Mon Sep 17 00:00:00 2001 From: RyujinZX Date: Mon, 25 Jul 2022 19:11:19 +0300 Subject: [PATCH 2/4] Custom Weather & Lightning target --- cheat-library/cheat-library.vcxproj | 2 + cheat-library/cheat-library.vcxproj.filters | 6 + cheat-library/src/appdata/il2cpp-functions.h | 5 + cheat-library/src/user/cheat/cheat.cpp | 3 + cheat-library/src/user/cheat/game/filters.cpp | 2 + cheat-library/src/user/cheat/game/filters.h | 1 + .../src/user/cheat/world/CustomWeather.cpp | 114 ++++++++++++++++++ .../src/user/cheat/world/CustomWeather.h | 28 +++++ 8 files changed, 161 insertions(+) create mode 100644 cheat-library/src/user/cheat/world/CustomWeather.cpp create mode 100644 cheat-library/src/user/cheat/world/CustomWeather.h diff --git a/cheat-library/cheat-library.vcxproj b/cheat-library/cheat-library.vcxproj index 4b97d16..af6ba65 100644 --- a/cheat-library/cheat-library.vcxproj +++ b/cheat-library/cheat-library.vcxproj @@ -24,6 +24,7 @@ + false @@ -115,6 +116,7 @@ + false diff --git a/cheat-library/cheat-library.vcxproj.filters b/cheat-library/cheat-library.vcxproj.filters index 27e4666..7392f94 100644 --- a/cheat-library/cheat-library.vcxproj.filters +++ b/cheat-library/cheat-library.vcxproj.filters @@ -249,6 +249,9 @@ Header Files + + Header Files + @@ -456,6 +459,9 @@ Source Files + + Source Files + diff --git a/cheat-library/src/appdata/il2cpp-functions.h b/cheat-library/src/appdata/il2cpp-functions.h index b7fefa6..f13f8bc 100644 --- a/cheat-library/src/appdata/il2cpp-functions.h +++ b/cheat-library/src/appdata/il2cpp-functions.h @@ -155,6 +155,11 @@ DO_APP_FUNC(0x012BC260, void, CookingQtePageContext_CloseItemGotPanel, (CookingQ DO_APP_FUNC(0x02A37D50, Button_1*, ProfilePage, (MonoInLevelPlayerProfilePage* __this, MethodInfo* method)); // MonoInLevelPlayerProfilePage_get_logoutButton DO_APP_FUNC(0x01B101B0, void, ProfileEditPage, (MonoFriendInformationDialog* __this, Sprite* value, MethodInfo* method)); // MonoFriendInformationDialog_set_icon +// Custom Weather | RyujinZX#6666 +DO_APP_FUNC(0x027774F0, bool, EnviroSky_ChangeWeather, (void* /*app::EnviroSky*/ __this, String* weatherPath, float transTime, float ratio, MethodInfo* method)); +DO_APP_FUNC(0x014EDB10, void* /*app::EnviroSky*/, EnviroSky_get_Instance, (MethodInfo* method)); + + // Free Camera DO_APP_FUNC(0x057E9C00, float, Camera_get_fieldOfView, (Camera* __this, MethodInfo* method)); DO_APP_FUNC(0x057EA060, void, Camera_set_fieldOfView, (Camera* __this, float value, MethodInfo* method)); diff --git a/cheat-library/src/user/cheat/cheat.cpp b/cheat-library/src/user/cheat/cheat.cpp index a0f2093..5093d7f 100644 --- a/cheat-library/src/user/cheat/cheat.cpp +++ b/cheat-library/src/user/cheat/cheat.cpp @@ -42,6 +42,7 @@ #include #include +#include #include #include @@ -109,6 +110,8 @@ namespace cheat FEAT_INST(AutoFish), FEAT_INST(AutoCook), + FEAT_INST(CustomWeather), + FEAT_INST(NoFog), FEAT_INST(FPSUnlock), FEAT_INST(CameraZoom), diff --git a/cheat-library/src/user/cheat/game/filters.cpp b/cheat-library/src/user/cheat/game/filters.cpp index 6a0e1df..acb3964 100644 --- a/cheat-library/src/user/cheat/game/filters.cpp +++ b/cheat-library/src/user/cheat/game/filters.cpp @@ -529,5 +529,7 @@ namespace cheat::game::filters SimpleFilter OrganicTargets = { Monsters, Animals }; // Solael: Please don't mess around with this filter. //m0nkrel: We can choose the entities we need ourselves so as not to magnetize cats, dogs, etc. //AdvancedFilter Animals = { {EntityType__Enum_1::EnvAnimal, EntityType__Enum_1::Monster }, {"Crane", "Tit", "Boar", "Squirrel", "Fox", "Pigeon", "Wigeon", "Falcon" ,"Marten" } }; + + SimpleFilter Lightning = { EntityType__Enum_1::Lightning }; } } diff --git a/cheat-library/src/user/cheat/game/filters.h b/cheat-library/src/user/cheat/game/filters.h index 2910149..04d2f74 100644 --- a/cheat-library/src/user/cheat/game/filters.h +++ b/cheat-library/src/user/cheat/game/filters.h @@ -337,5 +337,6 @@ namespace cheat::game::filters extern SimpleFilter MonsterEquips; extern BlacklistFilter Living; extern SimpleFilter OrganicTargets; + extern SimpleFilter Lightning; } } \ No newline at end of file diff --git a/cheat-library/src/user/cheat/world/CustomWeather.cpp b/cheat-library/src/user/cheat/world/CustomWeather.cpp new file mode 100644 index 0000000..960a873 --- /dev/null +++ b/cheat-library/src/user/cheat/world/CustomWeather.cpp @@ -0,0 +1,114 @@ +#include "pch-il2cpp.h" +#include "CustomWeather.h" +#include +#include +#include +#include +#include + +namespace cheat::feature +{ + const char* WeatherType[]{ "ClearSky", "Cloudy", "Foggy", "Storm", "RainHeavy", "FountainRain", "SnowLight", "EastCoast" }; + std::string CustomWeather::GetWeather() { + switch (current_weather) + { + case 0: + return "Data/Environment/Weather/BigWorld/Weather_ClearSky"; + + case 1: + return "Data/Environment/Weather/BigWorld/Weather_Cloudy"; + + case 2: + return "Data/Environment/Weather/BigWorld/Weather_Foggy"; + + case 3: + return "Data/Environment/Weather/BigWorld/Weather_Storm"; + + case 4: + return "Data/Environment/Weather/BigWorld/Weather_Dq_Tabeisha_Rain_Heavy"; + + case 5: + return "Data/Environment/Weather/BigWorld/Weather_LY_Fountain_Rain"; + + case 6: + return "Data/Environment/Weather/BigWorld/Weather_Snowmountain_Snow_Light"; + + case 7: + return "Data/Environment/Weather/BigWorld/Weather_Snowmountain_EastCoast"; + + default: + return "Data/Environment/Weather/BigWorld/Weather_ClearSky"; + } + } + + CustomWeather::CustomWeather() : Feature(), + NF(f_Enabled, "Custom Weather", "World", false), + NF(f_Lightning, "Lightning", "World", false), + toBeUpdate(), nextUpdate(0) + { + events::GameUpdateEvent += MY_METHOD_HANDLER(CustomWeather::OnGameUpdate); + } + + const FeatureGUIInfo& CustomWeather::GetGUIInfo() const + { + static const FeatureGUIInfo info{ "CustomWeather", "Visuals", true }; + return info; + } + + void CustomWeather::DrawMain() + { + ConfigWidget(f_Enabled, "Custom Weather."); + if (f_Enabled) { + ImGui::Combo(("Weather Type"), ¤t_weather, WeatherType, ARRAYSIZE(WeatherType)); + } + ConfigWidget(f_Lightning, "Lightning target enemy, works with RainHeavy weather."); + } + + bool CustomWeather::NeedStatusDraw() const + { + return f_Enabled; + } + + void CustomWeather::DrawStatus() + { + ImGui::Text("Custom Weather"); + if (f_Lightning) + ImGui::Text("Lightning"); + } + + CustomWeather& CustomWeather::GetInstance() + { + static CustomWeather instance; + return instance; + } + + void CustomWeather::OnGameUpdate() + { + if (!f_Enabled) + return; + + auto currentTime = util::GetCurrentTimeMillisec(); + if (currentTime < nextUpdate) + return; + + auto Enviro = app::EnviroSky_get_Instance(nullptr); + if (Enviro != nullptr) { + app::EnviroSky_ChangeWeather(Enviro, string_to_il2cppi(GetWeather()), 1, 1, nullptr); + + if (f_Lightning && current_weather == 4) { + auto& manager = game::EntityManager::instance(); + + for (auto& Monsters : manager.entities(game::filters::combined::Monsters)) { + if (manager.avatar()->distance(Monsters) >= 30) + continue; + + for (auto& entity : manager.entities(game::filters::combined::Lightning)) { + entity->setRelativePosition(Monsters->relativePosition()); + } + } + } + } + + nextUpdate = currentTime + (int)f_DelayUpdate; + } +} \ No newline at end of file diff --git a/cheat-library/src/user/cheat/world/CustomWeather.h b/cheat-library/src/user/cheat/world/CustomWeather.h new file mode 100644 index 0000000..738b38a --- /dev/null +++ b/cheat-library/src/user/cheat/world/CustomWeather.h @@ -0,0 +1,28 @@ +#pragma once +#include +#include +#include + +namespace cheat::feature +{ + class CustomWeather : public Feature + { + public: + config::Field> f_Enabled; + config::Field> f_Lightning; + + static CustomWeather& GetInstance(); + const FeatureGUIInfo& GetGUIInfo() const override; + void DrawMain() override; + bool NeedStatusDraw() const override; + void DrawStatus() override; + private: + int current_weather; + std::string GetWeather(); + SafeQueue toBeUpdate; + SafeValue nextUpdate; + int f_DelayUpdate = 1; + void OnGameUpdate(); + CustomWeather(); + }; +} \ No newline at end of file From f0ae3753f97dcc989be34bf2826d5921e5f511dd Mon Sep 17 00:00:00 2001 From: RyujinZX Date: Wed, 27 Jul 2022 14:14:09 +0300 Subject: [PATCH 3/4] Fix Exception in Console, when loading ptr null --- cheat-library/src/user/cheat/imap/InteractiveMap.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cheat-library/src/user/cheat/imap/InteractiveMap.cpp b/cheat-library/src/user/cheat/imap/InteractiveMap.cpp index 5cf9b3c..e338c8f 100644 --- a/cheat-library/src/user/cheat/imap/InteractiveMap.cpp +++ b/cheat-library/src/user/cheat/imap/InteractiveMap.cpp @@ -1358,6 +1358,12 @@ namespace cheat::feature if (_monoMiniMap == nullptr) return false; + // Fix Exception in Console, when loading ptr null | RyujinZX#7832 + if (_monoMiniMap->fields._._._._.m_CachedPtr == 0) { + _monoMiniMap = nullptr; + return false; + } + SAFE_BEGIN(); return app::Behaviour_get_isActiveAndEnabled(reinterpret_cast(_monoMiniMap), nullptr); SAFE_ERROR(); From eb88186865cda9df57b574d0878e142fa1db2ec2 Mon Sep 17 00:00:00 2001 From: RyujinZX Date: Wed, 27 Jul 2022 18:17:21 +0300 Subject: [PATCH 4/4] hotfix bug issues: 243 issues: 281 --- cheat-library/src/appdata/il2cpp-functions.h | 6 ++--- cheat-library/src/appdata/il2cpp-types.h | 23 +++++++++++++++++++ cheat-library/src/user/cheat/game/filters.cpp | 3 ++- cheat-library/src/user/cheat/game/filters.h | 3 ++- cheat-library/src/user/cheat/player/NoCD.cpp | 16 +++++++++---- .../src/user/cheat/player/RapidFire.cpp | 5 +++- 6 files changed, 45 insertions(+), 11 deletions(-) diff --git a/cheat-library/src/appdata/il2cpp-functions.h b/cheat-library/src/appdata/il2cpp-functions.h index f13f8bc..f9ceaba 100644 --- a/cheat-library/src/appdata/il2cpp-functions.h +++ b/cheat-library/src/appdata/il2cpp-functions.h @@ -51,9 +51,8 @@ DO_APP_FUNC(0x026F0820, bool, MoleMole_LCAvatarCombat_IsEnergyMax, (void* __this DO_APP_FUNC(0x026F0500, void, MoleMole_LCAvatarCombat_ChangeEnergy_1, (LCAvatarCombat* __this, ElementType__Enum type, float value, DataPropOp__Enum state, MethodInfo* method)); DO_APP_FUNC(0x026F13C0, bool, MoleMole_LCAvatarCombat_OnSkillStart, (LCAvatarCombat* __this, uint32_t skillID, float cdMultipler, MethodInfo* method)); DO_APP_FUNC(0x026F54A0, bool, MoleMole_LCAvatarCombat_IsSkillInCD_1, (LCAvatarCombat* __this, LCAvatarCombat_LCAvatarCombat_SkillInfo* skillInfo, MethodInfo* method)); - -DO_APP_FUNC(0x02DB4680, void, MoleMole_ActorAbilityPlugin_AddDynamicFloatWithRange, (void* __this, String* key, float value, float min, float max, bool forceDoAtRemote, MethodInfo* method)); - +DO_APP_FUNC(0x02DB4680, void, MoleMole_ActorAbilityPlugin_AddDynamicFloatWithRange, (MoleMole_ActorAbilityPlugin* __this, String* key, float value, float min, float max, bool forceDoAtRemote, MethodInfo* method)); + // Rapid fire DO_APP_FUNC(0x017B1D50, void, MoleMole_LCBaseCombat_DoHitEntity, (LCBaseCombat* __this, uint32_t targetID, AttackResult* attackResult, bool ignoreCheckCanBeHitInMP, MethodInfo* method)); DO_APP_FUNC(0x019DDF40, void, MoleMole_Formula_CalcAttackResult, (CombatProperty* attackCombatProperty, CombatProperty* defenseCombatProperty, AttackResult* attackResult, BaseEntity* attackerEntity, BaseEntity* attackeeEntity, MethodInfo* method)); @@ -250,6 +249,7 @@ DO_APP_FUNC(0x0596AFF0, LCBaseCombat*, MoleMole_BaseEntity_GetLogicCombatCompone DO_APP_FUNC_METHODINFO(0x099D4410, MoleMole_BaseEntity_GetLogicCombatComponent_1__MethodInfo); DO_APP_FUNC(0x031ACE30, String*, MoleMole_BaseEntity_ToStringRelease, (BaseEntity* __this, MethodInfo* method)); + DO_APP_FUNC(0x03180C10, void, MoleMole_BaseEntity_SetRelativePosition, (BaseEntity* __this, Vector3 position, bool forceSyncToRigidbody, MethodInfo* method)); DO_APP_FUNC(0x0319D8B0, void, MoleMole_BaseEntity_SetAbsolutePosition, (BaseEntity* __this, Vector3 abpos, bool forceSyncToRigidbody, MethodInfo* method)); DO_APP_FUNC(0x031AA160, Vector3, MoleMole_BaseEntity_GetAbsolutePosition, (BaseEntity* __this, MethodInfo* method)); diff --git a/cheat-library/src/appdata/il2cpp-types.h b/cheat-library/src/appdata/il2cpp-types.h index 4988724..5fb7cd1 100644 --- a/cheat-library/src/appdata/il2cpp-types.h +++ b/cheat-library/src/appdata/il2cpp-types.h @@ -11975,6 +11975,29 @@ namespace app { struct Avatar__Fields fields; }; + struct MoleMole_ActorAbilityPlugin__Fields { + struct BaseComponentPlugin__Fields _; + struct Action_3_MoleMole_BaseEntity_MoleMole_Config_AddGlobalValue_MoleMole_ActorAbility_* _addGlobalValueHandlerClosureDelegate; + struct Action_3_MoleMole_BaseEntity_MoleMole_Config_SetGlobalValue_MoleMole_ActorAbility_* _setGlobalValueHandlerClosureDelegate; + struct Action_3_MoleMole_BaseEntity_MoleMole_Config_MultiplyGlobalValue_MoleMole_ActorAbility_* _multiplyGlobalValueHandlerClosureDelegate; + struct Action_4_MoleMole_BaseEntity_MoleMole_Config_MultiplyGlobalValue_MoleMole_ActorAbility_Single_* MEEAPCINNBE; + struct Action_4_MoleMole_BaseEntity_String_Single_CPKJHKOJDIF_* LLAIOCNHNPM; + struct List_1_MoleMole_MonoEffectProxyHandle_* _effectProxyListCache; + struct List_1_MoleMole_MonoEffectProxyHandle_* _effectProxyListCacheForChangFollowDampTime; + struct List_1_UnityEngine_Vector3_* _pushedPosList; + struct MoleMole_LCAbility* _owner; + struct List_1_MoleMole_ActorAbility_* _appliedAbilities; + struct Dictionary_2_System_UInt32_System_Int32_* _appliedAbilitiesIndex; + struct Dictionary_2_System_String_MoleMole_ActorAbility_* CKDBIBGCPOB; + uint32_t nextValidAbilityID; + }; + + struct MoleMole_ActorAbilityPlugin { + struct MoleMole_ActorAbilityPlugin__Class* klass; + MonitorData* monitor; + struct MoleMole_ActorAbilityPlugin__Fields fields; + }; + #if !defined(_GHIDRA_) && !defined(_IDA_) } #endif diff --git a/cheat-library/src/user/cheat/game/filters.cpp b/cheat-library/src/user/cheat/game/filters.cpp index acb3964..0827961 100644 --- a/cheat-library/src/user/cheat/game/filters.cpp +++ b/cheat-library/src/user/cheat/game/filters.cpp @@ -221,7 +221,8 @@ namespace cheat::game::filters SimpleFilter JadeplumeTerrorshroom = { EntityType__Enum_1::Monster, "Fungus_Raptor" }; SimpleFilter RishbolandTiger = { EntityType__Enum_1::Monster, "_Megamoth_" }; SimpleFilter ShaggySumpterBeast = { EntityType__Enum_1::Monster, "_Panther" }; - SimpleFilter Spincrocodile = { EntityType__Enum_1::Monster, "_Gator" }; + SimpleFilter Spincrocodile = { EntityType__Enum_1::Monster, "_Gator" }; + SimpleFilter SentryTurrets = { EntityType__Enum_1::Field, "SentryTurrets_" }; } namespace plant diff --git a/cheat-library/src/user/cheat/game/filters.h b/cheat-library/src/user/cheat/game/filters.h index 04d2f74..8a9f2a2 100644 --- a/cheat-library/src/user/cheat/game/filters.h +++ b/cheat-library/src/user/cheat/game/filters.h @@ -220,7 +220,8 @@ namespace cheat::game::filters extern SimpleFilter Beisht; extern SimpleFilter RishbolandTiger; extern SimpleFilter ShaggySumpterBeast; - extern SimpleFilter Spincrocodile; + extern SimpleFilter Spincrocodile; + extern SimpleFilter SentryTurrets; } namespace plant diff --git a/cheat-library/src/user/cheat/player/NoCD.cpp b/cheat-library/src/user/cheat/player/NoCD.cpp index eec629a..d6dc429 100644 --- a/cheat-library/src/user/cheat/player/NoCD.cpp +++ b/cheat-library/src/user/cheat/player/NoCD.cpp @@ -11,14 +11,14 @@ namespace cheat::feature static bool LCAvatarCombat_OnSkillStart(app::LCAvatarCombat* __this, uint32_t skillID, float cdMultipler, MethodInfo* method); static bool LCAvatarCombat_IsSkillInCD_1(app::LCAvatarCombat* __this, app::LCAvatarCombat_LCAvatarCombat_SkillInfo* skillInfo, MethodInfo* method); - static void ActorAbilityPlugin_AddDynamicFloatWithRange_Hook(void* __this, app::String* key, float value, float minValue, float maxValue, + static void ActorAbilityPlugin_AddDynamicFloatWithRange_Hook(app::MoleMole_ActorAbilityPlugin* __this, app::String* key, float value, float minValue, float maxValue, bool forceDoAtRemote, MethodInfo* method); static std::list abilityLog; NoCD::NoCD() : Feature(), NF(f_AbilityReduce, "Reduce Skill/Burst Cooldown", "NoCD", false), - NF(f_TimerReduce, "Reduce Timer", "NoCD", 1.f), + NF(f_TimerReduce, "Reduce Timer", "NoCD", 1.f), NF(f_UtimateMaxEnergy, "Burst max energy", "NoCD", false), NF(f_Sprint, "No Sprint Cooldown", "NoCD", false), NF(f_InstantBow, "Instant bow", "NoCD", false) @@ -28,6 +28,7 @@ namespace cheat::feature HookManager::install(app::MoleMole_HumanoidMoveFSM_CheckSprintCooldown, HumanoidMoveFSM_CheckSprintCooldown_Hook); HookManager::install(app::MoleMole_ActorAbilityPlugin_AddDynamicFloatWithRange, ActorAbilityPlugin_AddDynamicFloatWithRange_Hook); + } const FeatureGUIInfo& NoCD::GetGUIInfo() const @@ -153,21 +154,26 @@ namespace cheat::feature // value - increase value // min and max - bounds of charge. // So, to charge make full charge m_Instantly, just replace value to maxValue. - static void ActorAbilityPlugin_AddDynamicFloatWithRange_Hook(void* __this, app::String* key, float value, float minValue, float maxValue, + static void ActorAbilityPlugin_AddDynamicFloatWithRange_Hook(app::MoleMole_ActorAbilityPlugin* __this, app::String* key, float value, float minValue, float maxValue, bool forceDoAtRemote, MethodInfo* method) { std::time_t t = std::time(nullptr); - auto logEntry = fmt::format("{:%H:%M:%S} | Key: {} value {}.", fmt::localtime(t), il2cppi_to_string(key), value); + auto logEntry = fmt::format("{:%H:%M:%S} | Key: {} value: {} | min: {} | max: {}.", fmt::localtime(t), il2cppi_to_string(key), value, minValue, maxValue); abilityLog.push_front(logEntry); if (abilityLog.size() > 50) abilityLog.pop_back(); - + NoCD& noCD = NoCD::GetInstance(); // This function is calling not only for bows, so if don't put key filter it cause various game mechanic bugs. // For now only "_Enchanted_Time" found for bow charging, maybe there are more. Need to continue research. if (noCD.f_InstantBow && il2cppi_to_string(key) == "_Enchanted_Time") + { value = maxValue; + __this->fields.nextValidAbilityID = 36; // HotFix Yelan, Fishl | It's essentially a game bug. | RyujinZX#7832 + } + CALL_ORIGIN(ActorAbilityPlugin_AddDynamicFloatWithRange_Hook, __this, key, value, minValue, maxValue, forceDoAtRemote, method); } + } diff --git a/cheat-library/src/user/cheat/player/RapidFire.cpp b/cheat-library/src/user/cheat/player/RapidFire.cpp index 4d5dcd2..bcad5ee 100644 --- a/cheat-library/src/user/cheat/player/RapidFire.cpp +++ b/cheat-library/src/user/cheat/player/RapidFire.cpp @@ -186,12 +186,13 @@ namespace cheat::feature bool IsValidByFilter(game::Entity* entity) { if (game::filters::combined::OrganicTargets.IsValid(entity) || + game::filters::monster::SentryTurrets.IsValid(entity) || game::filters::combined::Ores.IsValid(entity) || game::filters::puzzle::Geogranum.IsValid(entity) || game::filters::puzzle::LargeRockPile.IsValid(entity) || game::filters::puzzle::SmallRockPile.IsValid(entity)) return true; - return false; + return false; } // Raises when any entity do hit event. @@ -207,6 +208,7 @@ namespace cheat::feature auto& manager = game::EntityManager::instance(); auto originalTarget = manager.entity(targetID); + if (!IsValidByFilter(originalTarget)) return CALL_ORIGIN(LCBaseCombat_DoHitEntity_Hook, __this, targetID, attackResult, ignoreCheckCanBeHitInMP, method); @@ -236,6 +238,7 @@ namespace cheat::feature } for (const auto& entity : validEntities) { + if (rapidFire.f_MultiHit) { int attackCount = rapidFire.GetAttackCount(__this, entity->runtimeID(), attackResult); for (int i = 0; i < attackCount; i++)