mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-15 20:51:29 +00:00
[Combat] Implemented rule for live like Riposte mechanics (#1927)
* Live like Riposte * [Combat] Implemented rule for live like Riposte mechanics bot fix
This commit is contained in:
parent
91aa950304
commit
5f482a9b30
@ -508,7 +508,7 @@ RULE_INT(Combat, SneakPullAssistRange, 400, "Modified range of assist for sneak
|
|||||||
RULE_BOOL(Combat, Classic2HBAnimation, false, "2HB will use the 2 hand piercing animation instead of the overhead slashing animation")
|
RULE_BOOL(Combat, Classic2HBAnimation, false, "2HB will use the 2 hand piercing animation instead of the overhead slashing animation")
|
||||||
RULE_BOOL(Combat, ArcheryConsumesAmmo, true, "Set to false to disable Archery Ammo Consumption")
|
RULE_BOOL(Combat, ArcheryConsumesAmmo, true, "Set to false to disable Archery Ammo Consumption")
|
||||||
RULE_BOOL(Combat, ThrowingConsumesAmmo, true, "Set to false to disable Throwing Ammo Consumption")
|
RULE_BOOL(Combat, ThrowingConsumesAmmo, true, "Set to false to disable Throwing Ammo Consumption")
|
||||||
RULE_BOOL(Combat, ImmuneToEnrageFromRiposteSpellEffect, true, "Set to false to disable SPA 173 SE_RiposteChance from making those with the effect on them immune to enrage")
|
RULE_BOOL(Combat, UseLiveRiposteMechanics, false, "Set to true to disable SPA 173 SE_RiposteChance from making those with the effect on them immune to enrage, can longer riposte from a riposte.")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(NPC)
|
RULE_CATEGORY(NPC)
|
||||||
|
|||||||
@ -433,9 +433,20 @@ bool Mob::AvoidDamage(Mob *other, DamageHitInfo &hit)
|
|||||||
|
|
||||||
// riposte -- it may seem crazy, but if the attacker has SPA 173 on them, they are immune to Ripo
|
// riposte -- it may seem crazy, but if the attacker has SPA 173 on them, they are immune to Ripo
|
||||||
bool ImmuneRipo = false;
|
bool ImmuneRipo = false;
|
||||||
if (RuleB(Combat, ImmuneToEnrageFromRiposteSpellEffect)) {
|
if (!RuleB(Combat, UseLiveRiposteMechanics)) {
|
||||||
ImmuneRipo = attacker->aabonuses.RiposteChance || attacker->spellbonuses.RiposteChance || attacker->itembonuses.RiposteChance || attacker->IsEnraged();
|
ImmuneRipo = attacker->aabonuses.RiposteChance || attacker->spellbonuses.RiposteChance || attacker->itembonuses.RiposteChance || attacker->IsEnraged();
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
Live Riposte Mechanics (~Kayen updated 1/22)
|
||||||
|
-Ripostes can not trigger another riposte. (Ie. Riposte from defender can't then trigger the attacker to riposte)
|
||||||
|
-Ripostes can not be 'avoided', only hit or miss.
|
||||||
|
-Attacker with SPA 173 is not immune to riposte. The defender can riposte against the attackers melee hits.
|
||||||
|
|
||||||
|
Legacy Riposte Mechanics
|
||||||
|
-Ripostes can trigger another riposte
|
||||||
|
-Attacker with SPA 173 is immune to riposte
|
||||||
|
-Attacker that is enraged is immune to riposte
|
||||||
|
*/
|
||||||
|
|
||||||
// Need to check if we have something in MainHand to actually attack with (or fists)
|
// Need to check if we have something in MainHand to actually attack with (or fists)
|
||||||
if (hit.hand != EQ::invslot::slotRange && (CanThisClassRiposte() || IsEnraged()) && InFront && !ImmuneRipo) {
|
if (hit.hand != EQ::invslot::slotRange && (CanThisClassRiposte() || IsEnraged()) && InFront && !ImmuneRipo) {
|
||||||
@ -1373,25 +1384,27 @@ int Client::DoDamageCaps(int base_damage)
|
|||||||
|
|
||||||
// other is the defender, this is the attacker
|
// other is the defender, this is the attacker
|
||||||
//SYNC WITH: tune.cpp, mob.h TuneDoAttack
|
//SYNC WITH: tune.cpp, mob.h TuneDoAttack
|
||||||
void Mob::DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts)
|
void Mob::DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts, bool FromRiposte)
|
||||||
{
|
{
|
||||||
if (!other)
|
if (!other)
|
||||||
return;
|
return;
|
||||||
LogCombat("[{}]::DoAttack vs [{}] base [{}] min [{}] offense [{}] tohit [{}] skill [{}]", GetName(),
|
LogCombat("[{}]::DoAttack vs [{}] base [{}] min [{}] offense [{}] tohit [{}] skill [{}]", GetName(),
|
||||||
other->GetName(), hit.base_damage, hit.min_damage, hit.offense, hit.tohit, hit.skill);
|
other->GetName(), hit.base_damage, hit.min_damage, hit.offense, hit.tohit, hit.skill);
|
||||||
|
|
||||||
// check to see if we hit..
|
if (!RuleB(Combat, UseLiveRiposteMechanics)) {
|
||||||
if (other->AvoidDamage(this, hit)) {
|
FromRiposte = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check to see if we hit..
|
||||||
|
if (!FromRiposte && other->AvoidDamage(this, hit)) {
|
||||||
int strike_through = itembonuses.StrikeThrough + spellbonuses.StrikeThrough + aabonuses.StrikeThrough;
|
int strike_through = itembonuses.StrikeThrough + spellbonuses.StrikeThrough + aabonuses.StrikeThrough;
|
||||||
if (strike_through && zone->random.Roll(strike_through)) {
|
if (strike_through && zone->random.Roll(strike_through)) {
|
||||||
MessageString(Chat::StrikeThrough,
|
MessageString(Chat::StrikeThrough,
|
||||||
STRIKETHROUGH_STRING); // You strike through your opponents defenses!
|
STRIKETHROUGH_STRING); // You strike through your opponents defenses!
|
||||||
hit.damage_done = 1; // set to one, we will check this to continue
|
hit.damage_done = 1; // set to one, we will check this to continue
|
||||||
}
|
}
|
||||||
// I'm pretty sure you can riposte a riposte
|
|
||||||
if (hit.damage_done == DMG_RIPOSTED) {
|
if (hit.damage_done == DMG_RIPOSTED) {
|
||||||
DoRiposte(other);
|
DoRiposte(other);
|
||||||
//if (IsDead())
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LogCombat("Avoided/strikethrough damage with code [{}]", hit.damage_done);
|
LogCombat("Avoided/strikethrough damage with code [{}]", hit.damage_done);
|
||||||
@ -1574,7 +1587,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
|||||||
|
|
||||||
my_hit.tohit = GetTotalToHit(my_hit.skill, hit_chance_bonus);
|
my_hit.tohit = GetTotalToHit(my_hit.skill, hit_chance_bonus);
|
||||||
|
|
||||||
DoAttack(other, my_hit, opts);
|
DoAttack(other, my_hit, opts, bRiposte);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
my_hit.damage_done = DMG_INVULNERABLE;
|
my_hit.damage_done = DMG_INVULNERABLE;
|
||||||
@ -2166,7 +2179,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
|||||||
my_hit.offense = offense(my_hit.skill);
|
my_hit.offense = offense(my_hit.skill);
|
||||||
my_hit.tohit = GetTotalToHit(my_hit.skill, hit_chance_bonus);
|
my_hit.tohit = GetTotalToHit(my_hit.skill, hit_chance_bonus);
|
||||||
|
|
||||||
DoAttack(other, my_hit, opts);
|
DoAttack(other, my_hit, opts, bRiposte);
|
||||||
|
|
||||||
other->AddToHateList(this, hate);
|
other->AddToHateList(this, hate);
|
||||||
|
|
||||||
@ -4822,6 +4835,7 @@ void Mob::DoRiposte(Mob *defender)
|
|||||||
}
|
}
|
||||||
|
|
||||||
defender->Attack(this, EQ::invslot::slotPrimary, true);
|
defender->Attack(this, EQ::invslot::slotPrimary, true);
|
||||||
|
|
||||||
if (HasDied())
|
if (HasDied())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@ -4906,7 +4906,7 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
|
|||||||
|
|
||||||
my_hit.tohit = GetTotalToHit(my_hit.skill, hit_chance_bonus);
|
my_hit.tohit = GetTotalToHit(my_hit.skill, hit_chance_bonus);
|
||||||
|
|
||||||
DoAttack(other, my_hit, opts);
|
DoAttack(other, my_hit, opts, FromRiposte);
|
||||||
|
|
||||||
LogCombat("Final damage after all reductions: [{}]", my_hit.damage_done);
|
LogCombat("Final damage after all reductions: [{}]", my_hit.damage_done);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -195,7 +195,7 @@ public:
|
|||||||
// 13 = Primary (default), 14 = secondary
|
// 13 = Primary (default), 14 = secondary
|
||||||
virtual bool Attack(Mob* other, int Hand = EQ::invslot::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false,
|
virtual bool Attack(Mob* other, int Hand = EQ::invslot::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false,
|
||||||
bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) = 0;
|
bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) = 0;
|
||||||
void DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts = nullptr);
|
void DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts = nullptr, bool FromRiposte = false);
|
||||||
int MonkSpecialAttack(Mob* other, uint8 skill_used);
|
int MonkSpecialAttack(Mob* other, uint8 skill_used);
|
||||||
virtual void TryBackstab(Mob *other,int ReuseTime = 10);
|
virtual void TryBackstab(Mob *other,int ReuseTime = 10);
|
||||||
bool AvoidDamage(Mob *attacker, DamageHitInfo &hit);
|
bool AvoidDamage(Mob *attacker, DamageHitInfo &hit);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user