diff --git a/cheat-library/src/user/cheat/player/RapidFire.cpp b/cheat-library/src/user/cheat/player/RapidFire.cpp index acb9cc5..27d00aa 100644 --- a/cheat-library/src/user/cheat/player/RapidFire.cpp +++ b/cheat-library/src/user/cheat/player/RapidFire.cpp @@ -14,6 +14,12 @@ namespace cheat::feature app::AnimatorStateInfo processStateInfo, app::MoleMole_VCAnimatorEvent_MoleMole_VCAnimatorEvent_TriggerMode__Enum mode, MethodInfo* method); static void LCBaseCombat_FireBeingHitEvent_Hook(app::LCBaseCombat* __this, uint32_t attackeeRuntimeID, app::AttackResult* attackResult, MethodInfo* method); + static int32_t attackTags[] = { + 1638193991, // Normal and Charged + 1498431743, // Plunge + -584054938, 0, // Skill, Burst and Charged Bow Release + }; + RapidFire::RapidFire() : Feature(), NF(f_Enabled, "Attack Multiplier", "RapidFire", false), NF(f_MultiHit, "Multi-hit", "RapidFire", false), @@ -24,7 +30,12 @@ namespace cheat::feature NF(f_maxMultiplier, "Max Multiplier", "RapidFire", 3), NF(f_MultiTarget, "Multi-target", "RapidFire", false), NF(f_MultiTargetRadius, "Multi-target Radius", "RapidFire", 20.0f), - NF(f_MultiAnimation, "Multi-animation", "RapidFire", false) + NF(f_MultiAnimation, "Multi-animation", "RapidFire", false), + NF(f_AnimationMultiplier, "Animation Multiplier", "RapidFire", 100), + NF(f_AnimationState, "Animation State", "RapidFire", 0.5f), + NF(f_AttackSpeed, "Attack Speed", "RapidFire", false), + NF(f_SpeedMultiplier, "Speed Multiplier", "RapidFire", 1.5f), + animationCounter(1) { // HookManager::install(app::MoleMole_LCBaseCombat_DoHitEntity, LCBaseCombat_DoHitEntity_Hook); -- Looks like FireBeingHitEvent is superior to this. HookManager::install(app::MoleMole_VCAnimatorEvent_HandleProcessItem, VCAnimatorEvent_HandleProcessItem_Hook); @@ -85,29 +96,40 @@ namespace cheat::feature ConfigWidget("Multi-animation", f_MultiAnimation, "Enables multi-animation attacks.\n" \ "Do keep in mind that the character's audio will also be spammed."); + ConfigWidget("Animation Multiplier", f_AnimationMultiplier, 1, 1, 150, "Configure to how many times it will update the animation state.\n" \ + "Results can vary alongside Animation State"); + ConfigWidget("Animation State", f_AnimationState, 0.01f, 0.f, 2.f, "Animation state to replay.\n"\ + "Results can vary alongside Animation Multiplier"); + ConfigWidget("Attack Speed", f_AttackSpeed, "Enables fast animation attacks.\n"); + ConfigWidget("Speed Multiplier", f_SpeedMultiplier, 0.1f, 1.0f, 5.0f, "Attack speed multiplier."); } bool RapidFire::NeedStatusDraw() const { - return f_Enabled && (f_MultiHit || f_MultiTarget || f_MultiAnimation); + return (f_Enabled && (f_MultiHit || f_MultiTarget)) || f_MultiAnimation || f_AttackSpeed; } void RapidFire::DrawStatus() { - if (f_MultiHit) - { - if (f_Randomize) - ImGui::Text("Multi-Hit Random[%d|%d]", f_minMultiplier.value(), f_maxMultiplier.value()); - else if (f_OnePunch) - ImGui::Text("Multi-Hit [OnePunch]"); - else - ImGui::Text("Multi-Hit [%d]", f_Multiplier.value()); + if (f_Enabled) { + ImGui::Text("Rapid Fire:"); + if (f_MultiHit) + { + if (f_Randomize) + ImGui::Text("Multi-Hit Random[%d|%d]", f_minMultiplier.value(), f_maxMultiplier.value()); + else if (f_OnePunch) + ImGui::Text("Multi-Hit [OnePunch]"); + else + ImGui::Text("Multi-Hit [%d]", f_Multiplier.value()); + } + if (f_MultiTarget) + ImGui::Text("Multi-Target [%.01fm]", f_MultiTargetRadius.value()); } - if (f_MultiTarget) - ImGui::Text("Multi-Target [%.01fm]", f_MultiTargetRadius.value()); if (f_MultiAnimation) - ImGui::Text("Multi-Animation"); + ImGui::Text("Multi-Animation [%d|%0.2f]", f_AnimationMultiplier.value(), f_AnimationState.value()); + if(f_AttackSpeed) + ImGui::Text("Attack Speed [%0.1f]", f_SpeedMultiplier.value()); } RapidFire& RapidFire::GetInstance() @@ -116,7 +138,6 @@ namespace cheat::feature return instance; } - int RapidFire::CalcCountToKill(float attackDamage, uint32_t targetID) { if (attackDamage == 0) @@ -203,6 +224,7 @@ namespace cheat::feature return false; auto& manager = game::EntityManager::instance(); + auto patterID = manager.avatar()->combat()->monitor; auto avatarID = manager.avatar()->raw()->fields._configID_k__BackingField; auto attackerID = attacker.raw()->fields._configID_k__BackingField; // LOG_DEBUG("configID = %d", attackerID); @@ -329,11 +351,30 @@ namespace cheat::feature { auto attacker = game::Entity(__this->fields._._._entity); RapidFire& rapidFire = RapidFire::GetInstance(); + bool isAttackAnimation = std::any_of(std::begin(attackTags), std::end(attackTags), + [&](uint32_t tag) { return processStateInfo.m_Tag == tag; }); + bool isAttacking = IsAttackByAvatar(attacker) && isAttackAnimation; - if (rapidFire.f_MultiAnimation && IsAttackByAvatar(attacker)) - processItem->fields.lastTime = 0; + if (rapidFire.f_MultiAnimation && isAttacking) + { + // Set counter back to 1 when any new attack animation is invoked + if (processStateInfo.m_NormalizedTime <= 0.01f) + rapidFire.animationCounter = 1; + + if (rapidFire.animationCounter <= rapidFire.f_AnimationMultiplier) + { + // Can be configured up to 1.0 but 0.1 to 0.9 you can barely notice the difference + // So 0 - 0.2 is enough. + processItem->fields.lastTime = (rapidFire.f_AnimationState / 10); + rapidFire.animationCounter++; + } + } + + if (rapidFire.f_AttackSpeed && isAttacking) + app::Animator_set_speed(attacker.animator(), rapidFire.f_SpeedMultiplier, nullptr); + else + app::Animator_set_speed(attacker.animator(), processStateInfo.m_SpeedMultiplier, nullptr); CALL_ORIGIN(VCAnimatorEvent_HandleProcessItem_Hook, __this, processItem, processStateInfo, mode, method); } -} - +} \ No newline at end of file diff --git a/cheat-library/src/user/cheat/player/RapidFire.h b/cheat-library/src/user/cheat/player/RapidFire.h index 7d9d26f..e337182 100644 --- a/cheat-library/src/user/cheat/player/RapidFire.h +++ b/cheat-library/src/user/cheat/player/RapidFire.h @@ -6,7 +6,6 @@ namespace cheat::feature { - class RapidFire : public Feature { public: @@ -20,6 +19,11 @@ namespace cheat::feature config::Field> f_MultiTarget; config::Field f_MultiTargetRadius; config::Field> f_MultiAnimation; + config::Field f_AnimationMultiplier; + config::Field f_AnimationState; + config::Field> f_AttackSpeed; + config::Field f_SpeedMultiplier; + uint32_t animationCounter; static RapidFire& GetInstance(); @@ -36,3 +40,4 @@ namespace cheat::feature }; } +