commit
47102ce621
@ -10,6 +10,9 @@ namespace cheat::feature
|
|||||||
{
|
{
|
||||||
static void LCBaseCombat_DoHitEntity_Hook(app::LCBaseCombat* __this, uint32_t targetID, app::AttackResult* attackResult,
|
static void LCBaseCombat_DoHitEntity_Hook(app::LCBaseCombat* __this, uint32_t targetID, app::AttackResult* attackResult,
|
||||||
bool ignoreCheckCanBeHitInMP, MethodInfo* method);
|
bool ignoreCheckCanBeHitInMP, MethodInfo* method);
|
||||||
|
static void VCAnimatorEvent_HandleProcessItem_Hook(app::MoleMole_VCAnimatorEvent* __this,
|
||||||
|
app::MoleMole_VCAnimatorEvent_MoleMole_VCAnimatorEvent_AnimatorEventPatternProcessItem* processItem,
|
||||||
|
app::AnimatorStateInfo processStateInfo, app::MoleMole_VCAnimatorEvent_MoleMole_VCAnimatorEvent_TriggerMode__Enum mode, MethodInfo* method);
|
||||||
|
|
||||||
RapidFire::RapidFire() : Feature(),
|
RapidFire::RapidFire() : Feature(),
|
||||||
NF(f_Enabled, "Attack Multiplier", "RapidFire", false),
|
NF(f_Enabled, "Attack Multiplier", "RapidFire", false),
|
||||||
@ -20,9 +23,11 @@ namespace cheat::feature
|
|||||||
NF(f_minMultiplier, "Min Multiplier", "RapidFire", 1),
|
NF(f_minMultiplier, "Min Multiplier", "RapidFire", 1),
|
||||||
NF(f_maxMultiplier, "Max Multiplier", "RapidFire", 3),
|
NF(f_maxMultiplier, "Max Multiplier", "RapidFire", 3),
|
||||||
NF(f_MultiTarget, "Multi-target", "RapidFire", false),
|
NF(f_MultiTarget, "Multi-target", "RapidFire", false),
|
||||||
NF(f_MultiTargetRadius, "Multi-target Radius", "RapidFire", 20.0f)
|
NF(f_MultiTargetRadius, "Multi-target Radius", "RapidFire", 20.0f),
|
||||||
|
NF(f_MultiAnimation, "Multi-animation", "RapidFire", false)
|
||||||
{
|
{
|
||||||
HookManager::install(app::MoleMole_LCBaseCombat_DoHitEntity, LCBaseCombat_DoHitEntity_Hook);
|
HookManager::install(app::MoleMole_LCBaseCombat_DoHitEntity, LCBaseCombat_DoHitEntity_Hook);
|
||||||
|
HookManager::install(app::MoleMole_VCAnimatorEvent_HandleProcessItem, VCAnimatorEvent_HandleProcessItem_Hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
const FeatureGUIInfo& RapidFire::GetGUIInfo() const
|
const FeatureGUIInfo& RapidFire::GetGUIInfo() const
|
||||||
@ -77,11 +82,14 @@ namespace cheat::feature
|
|||||||
ImGui::Indent();
|
ImGui::Indent();
|
||||||
ConfigWidget("Radius (m)", f_MultiTargetRadius, 0.1f, 5.0f, 50.0f, "Radius to check for valid targets.");
|
ConfigWidget("Radius (m)", f_MultiTargetRadius, 0.1f, 5.0f, 50.0f, "Radius to check for valid targets.");
|
||||||
ImGui::Unindent();
|
ImGui::Unindent();
|
||||||
|
|
||||||
|
ConfigWidget("Multi-animation", f_MultiAnimation, "Enables multi-animation attacks.\n" \
|
||||||
|
"Do keep in mind that the character's audio will also be spammed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RapidFire::NeedStatusDraw() const
|
bool RapidFire::NeedStatusDraw() const
|
||||||
{
|
{
|
||||||
return f_Enabled && (f_MultiHit || f_MultiTarget);
|
return f_Enabled && (f_MultiHit || f_MultiTarget || f_MultiAnimation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RapidFire::DrawStatus()
|
void RapidFire::DrawStatus()
|
||||||
@ -97,6 +105,9 @@ namespace cheat::feature
|
|||||||
}
|
}
|
||||||
if (f_MultiTarget)
|
if (f_MultiTarget)
|
||||||
ImGui::Text("Multi-Target [%.01fm]", f_MultiTargetRadius.value());
|
ImGui::Text("Multi-Target [%.01fm]", f_MultiTargetRadius.value());
|
||||||
|
|
||||||
|
if (f_MultiAnimation)
|
||||||
|
ImGui::Text("Multi-Animation");
|
||||||
}
|
}
|
||||||
|
|
||||||
RapidFire& RapidFire::GetInstance()
|
RapidFire& RapidFire::GetInstance()
|
||||||
@ -183,6 +194,20 @@ namespace cheat::feature
|
|||||||
return attackerID == avatarID || IsAvatarOwner(attacker);
|
return attackerID == avatarID || IsAvatarOwner(attacker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsConfigByAvatar(game::Entity& attacker)
|
||||||
|
{
|
||||||
|
if (attacker.raw() == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto& manager = game::EntityManager::instance();
|
||||||
|
auto avatarID = manager.avatar()->raw()->fields._configID_k__BackingField;
|
||||||
|
auto attackerID = attacker.raw()->fields._configID_k__BackingField;
|
||||||
|
// Taiga#5555: IDs can be found in ConfigAbility_Avatar_*.json or GadgetExcelConfigData.json
|
||||||
|
bool bulletID = attackerID >= 40000160 && attackerID <= 41069999;
|
||||||
|
|
||||||
|
return avatarID == attackerID || bulletID;
|
||||||
|
}
|
||||||
|
|
||||||
bool IsValidByFilter(game::Entity* entity)
|
bool IsValidByFilter(game::Entity* entity)
|
||||||
{
|
{
|
||||||
if (game::filters::combined::OrganicTargets.IsValid(entity) ||
|
if (game::filters::combined::OrganicTargets.IsValid(entity) ||
|
||||||
@ -203,7 +228,7 @@ namespace cheat::feature
|
|||||||
{
|
{
|
||||||
auto attacker = game::Entity(__this->fields._._._entity);
|
auto attacker = game::Entity(__this->fields._._._entity);
|
||||||
RapidFire& rapidFire = RapidFire::GetInstance();
|
RapidFire& rapidFire = RapidFire::GetInstance();
|
||||||
if (!IsAttackByAvatar(attacker) || !rapidFire.f_Enabled)
|
if (!IsConfigByAvatar(attacker) || !IsAttackByAvatar(attacker) || !rapidFire.f_Enabled)
|
||||||
return CALL_ORIGIN(LCBaseCombat_DoHitEntity_Hook, __this, targetID, attackResult, ignoreCheckCanBeHitInMP, method);
|
return CALL_ORIGIN(LCBaseCombat_DoHitEntity_Hook, __this, targetID, attackResult, ignoreCheckCanBeHitInMP, method);
|
||||||
|
|
||||||
auto& manager = game::EntityManager::instance();
|
auto& manager = game::EntityManager::instance();
|
||||||
@ -242,9 +267,23 @@ namespace cheat::feature
|
|||||||
if (rapidFire.f_MultiHit) {
|
if (rapidFire.f_MultiHit) {
|
||||||
int attackCount = rapidFire.GetAttackCount(__this, entity->runtimeID(), attackResult);
|
int attackCount = rapidFire.GetAttackCount(__this, entity->runtimeID(), attackResult);
|
||||||
for (int i = 0; i < attackCount; i++)
|
for (int i = 0; i < attackCount; i++)
|
||||||
CALL_ORIGIN(LCBaseCombat_DoHitEntity_Hook, __this, entity->runtimeID(), attackResult, ignoreCheckCanBeHitInMP, method);
|
app::MoleMole_LCBaseCombat_FireBeingHitEvent(__this, entity->runtimeID(), attackResult, method);
|
||||||
} else CALL_ORIGIN(LCBaseCombat_DoHitEntity_Hook, __this, entity->runtimeID(), attackResult, ignoreCheckCanBeHitInMP, method);
|
|
||||||
}
|
}
|
||||||
|
else app::MoleMole_LCBaseCombat_FireBeingHitEvent(__this, entity->runtimeID(), attackResult, method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void VCAnimatorEvent_HandleProcessItem_Hook(app::MoleMole_VCAnimatorEvent* __this,
|
||||||
|
app::MoleMole_VCAnimatorEvent_MoleMole_VCAnimatorEvent_AnimatorEventPatternProcessItem* processItem,
|
||||||
|
app::AnimatorStateInfo processStateInfo, app::MoleMole_VCAnimatorEvent_MoleMole_VCAnimatorEvent_TriggerMode__Enum mode, MethodInfo* method)
|
||||||
|
{
|
||||||
|
auto attacker = game::Entity(__this->fields._._._entity);
|
||||||
|
RapidFire& rapidFire = RapidFire::GetInstance();
|
||||||
|
|
||||||
|
if (rapidFire.f_MultiAnimation && IsAttackByAvatar(attacker))
|
||||||
|
processItem->fields.lastTime = 0;
|
||||||
|
|
||||||
|
CALL_ORIGIN(VCAnimatorEvent_HandleProcessItem_Hook, __this, processItem, processStateInfo, mode, method);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ namespace cheat::feature
|
|||||||
config::Field<int> f_maxMultiplier;
|
config::Field<int> f_maxMultiplier;
|
||||||
config::Field<config::Toggle<Hotkey>> f_MultiTarget;
|
config::Field<config::Toggle<Hotkey>> f_MultiTarget;
|
||||||
config::Field<float> f_MultiTargetRadius;
|
config::Field<float> f_MultiTargetRadius;
|
||||||
|
config::Field<config::Toggle<Hotkey>> f_MultiAnimation;
|
||||||
|
|
||||||
static RapidFire& GetInstance();
|
static RapidFire& GetInstance();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user