[Cleanup] Merge Client::Attack and Bot::Attack into Mob::Attack (#2756)

* [Cleanup] Merge Client::Attack and Bot::Attack into Mob::Attack (#11)

* Remove #ifdef Bots to go along with KK fix

* Remove method in logging

* remove method from logging

* Fixes

* Rename
This commit is contained in:
Aeadoin
2023-01-20 15:52:45 -05:00
committed by GitHub
parent 5c095ab87a
commit 886f80117c
10 changed files with 82 additions and 237 deletions
+60 -48
View File
@@ -1275,7 +1275,7 @@ int64 Mob::GetWeaponDamage(Mob *against, const EQ::ItemInstance *weapon_item, in
return std::max((int64)0, dmg);
}
int64 Client::DoDamageCaps(int64 base_damage)
int64 Mob::DoDamageCaps(int64 base_damage)
{
// this is based on a client function that caps melee base_damage
auto level = GetLevel();
@@ -1404,8 +1404,8 @@ void Mob::DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts, boo
// check to see if we hit..
if (!FromRiposte && other->AvoidDamage(this, hit)) {
int strike_through = itembonuses.StrikeThrough + spellbonuses.StrikeThrough + aabonuses.StrikeThrough;
if (strike_through && zone->random.Roll(strike_through)) {
if (int strike_through = itembonuses.StrikeThrough + spellbonuses.StrikeThrough + aabonuses.StrikeThrough;
strike_through && zone->random.Roll(strike_through)) {
MessageString(Chat::StrikeThrough,
STRIKETHROUGH_STRING); // You strike through your opponents defenses!
hit.damage_done = 1; // set to one, we will check this to continue
@@ -1460,71 +1460,77 @@ void Mob::DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts, boo
//stop the attack calculations
// IsFromSpell added to allow spell effects to use Attack. (Mainly for the Rampage AA right now.)
//SYNC WITH: tune.cpp, mob.h TuneClientAttack
bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts)
bool Mob::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts)
{
if (!other) {
SetTarget(nullptr);
LogError("A null Mob object was passed to Client::Attack() for evaluation!");
LogError("A null Mob object was passed for evaluation!");
return false;
}
if (!GetTarget())
if (!GetTarget()) {
SetTarget(other);
}
LogCombat("Attacking [{}] with hand [{}] [{}]", other ? other->GetName() : "(nullptr)", Hand, bRiposte ? "(this is a riposte)" : "");
LogCombatDetail("Attacking [{}] with hand [{}] [{}]", other ? other->GetName() : "nullptr", Hand, bRiposte ? "this is a riposte" : "");
//SetAttackTimer();
if (
(IsCasting() && GetClass() != BARD && !IsFromSpell)
|| other == nullptr
|| ((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead))
|| (GetHP() < 0)
|| (!IsAttackAllowed(other))
|| (IsBot() && GetAppearance() == eaDead)
) {
LogCombat("Attack cancelled, invalid circumstances");
return false; // Only bards can attack while casting
}
if (DivineAura() && !GetGM()) {//cant attack while invulnerable unless your a gm
if (DivineAura() && !CastToClient()->GetGM()) { //cant attack while invulnerable unless your a gm
LogCombat("Attack cancelled, Divine Aura is in effect");
MessageString(Chat::DefaultText, DIVINE_AURA_NO_ATK); //You can't attack while invulnerable
MessageString(Chat::DefaultText, DIVINE_AURA_NO_ATK);
return false;
}
if (GetFeigned())
if (GetFeigned()) {
return false; // Rogean: How can you attack while feigned? Moved up from Aggro Code.
}
EQ::ItemInstance* weapon = nullptr;
if (Hand == EQ::invslot::slotSecondary) { // Kaiyodo - Pick weapon from the attacking hand
weapon = GetInv().GetItem(EQ::invslot::slotSecondary);
const EQ::ItemInstance* weapon = nullptr;
if (IsBot()) {
FaceTarget(GetTarget());
}
if (Hand == EQ::invslot::slotSecondary) {
weapon = (IsClient()) ? GetInv().GetItem(EQ::invslot::slotSecondary) : CastToBot()->GetBotItem(EQ::invslot::slotPrimary);
OffHandAtk(true);
}
else {
weapon = GetInv().GetItem(EQ::invslot::slotPrimary);
weapon = (IsClient()) ? GetInv().GetItem(EQ::invslot::slotPrimary) : CastToBot()->GetBotItem(EQ::invslot::slotPrimary);
OffHandAtk(false);
}
if (weapon != nullptr) {
if (!weapon->IsWeapon()) {
LogCombat("Attack cancelled, Item [{}] ([{}]) is not a weapon", weapon->GetItem()->Name, weapon->GetID());
return(false);
}
LogCombat("Attacking with weapon: [{}] ([{}])", weapon->GetItem()->Name, weapon->GetID());
LogCombatDetail("Attacking with weapon: [{}] ([{}])", weapon->GetItem()->Name, weapon->GetID());
}
else {
LogCombat("Attacking without a weapon");
LogCombatDetail("Attacking without a weapon");
}
DamageHitInfo my_hit;
// calculate attack_skill and skillinuse depending on hand and weapon
// also send Packet to near clients
my_hit.skill = AttackAnimation(Hand, weapon);
LogCombat("Attacking with [{}] in slot [{}] using skill [{}]", weapon ? weapon->GetItem()->Name : "Fist", Hand, my_hit.skill);
LogCombatDetail("Attacking with [{}] in slot [{}] using skill [{}]", weapon ? weapon->GetItem()->Name : "Fist", Hand, my_hit.skill);
// Now figure out damage
my_hit.damage_done = 1;
my_hit.min_damage = 0;
uint8 mylevel = GetLevel() ? GetLevel() : 1;
int64 hate = 0;
if (weapon)
hate = (weapon->GetItem()->Damage + weapon->GetItem()->ElemDmgAmt);
@@ -1546,8 +1552,10 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
hate = hate * (100 + shield_inc) / 100;
}
CheckIncreaseSkill(my_hit.skill, other, -15);
CheckIncreaseSkill(EQ::skills::SkillOffense, other, -15);
if (IsClient()) {
CastToClient()->CheckIncreaseSkill(my_hit.skill, other, -15);
CastToClient()->CheckIncreaseSkill(EQ::skills::SkillOffense, other, -15);
}
// ***************************************************************
// *** Calculate the damage bonus, if applicable, for this hit ***
@@ -1575,19 +1583,20 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
}
#endif
//Live AA - Sinister Strikes *Adds weapon damage bonus to offhand weapon.
if (Hand == EQ::invslot::slotSecondary) {
if (aabonuses.SecondaryDmgInc || itembonuses.SecondaryDmgInc || spellbonuses.SecondaryDmgInc) {
if (Hand == EQ::invslot::slotSecondary &&
(
aabonuses.SecondaryDmgInc ||
itembonuses.SecondaryDmgInc ||
spellbonuses.SecondaryDmgInc
)
) {
ucDamageBonus = GetWeaponDamageBonus(weapon ? weapon->GetItem() : (const EQ::ItemData*) nullptr, true);
ucDamageBonus = GetWeaponDamageBonus(weapon ? weapon->GetItem() : (const EQ::ItemData*) nullptr, true);
my_hit.min_damage = ucDamageBonus;
hate += ucDamageBonus;
}
my_hit.min_damage = ucDamageBonus;
hate += ucDamageBonus;
}
// damage = mod_client_damage(damage, skillinuse, Hand, weapon, other);
LogCombat("Damage calculated: base [{}] min damage [{}] skill [{}]", my_hit.base_damage, my_hit.min_damage, my_hit.skill);
LogCombatDetail("Damage calculated base [{}] min damage [{}] skill [{}]", my_hit.base_damage, my_hit.min_damage, my_hit.skill);
int hit_chance_bonus = 0;
my_hit.offense = offense(my_hit.skill); // we need this a few times
@@ -1604,6 +1613,8 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
my_hit.tohit = GetTotalToHit(my_hit.skill, hit_chance_bonus);
DoAttack(other, my_hit, opts, bRiposte);
LogCombatDetail("Final damage after all reductions [{}]", my_hit.damage_done);
}
else {
my_hit.damage_done = DMG_INVULNERABLE;
@@ -1615,22 +1626,23 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
other->AddToHateList(this, hate);
//Guard Assist Code
if (RuleB(Character, PVPEnableGuardFactionAssist)) {
if (IsClient() && other->IsClient() || (HasOwner() && GetOwner()->IsClient() && other->IsClient() )) {
auto& mob_list = entity_list.GetCloseMobList(other);
for (auto& e : mob_list) {
auto mob = e.second;
if (!mob) {
continue;
}
if (RuleB(Character, PVPEnableGuardFactionAssist) &&
(
(IsClient() && other->IsClient()) ||
(HasOwner() && GetOwner()->IsClient() && other->IsClient())
)
) {
for (auto const& [id, mob] : entity_list.GetCloseMobList(other)) {
if (!mob) {
continue;
}
if (mob->IsNPC() && mob->CastToNPC()->IsGuard()) {
float distance = Distance(other->CastToClient()->m_Position, mob->GetPosition());
if ((mob->CheckLosFN(other) || mob->CheckLosFN(this)) && distance <= 70) {
auto petorowner = GetOwnerOrSelf();
if (other->GetReverseFactionCon(mob) <= petorowner->GetReverseFactionCon(mob)) {
mob->AddToHateList(this);
}
if (mob->IsNPC() && mob->CastToNPC()->IsGuard()) {
float distance = Distance(other->CastToClient()->m_Position, mob->GetPosition());
if ((mob->CheckLosFN(other) || mob->CheckLosFN(this)) && distance <= 70) {
auto petorowner = GetOwnerOrSelf();
if (other->GetReverseFactionCon(mob) <= petorowner->GetReverseFactionCon(mob)) {
mob->AddToHateList(this);
}
}
}
@@ -1642,7 +1654,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
///////////////////////////////////////////////////////////
other->Damage(this, my_hit.damage_done, SPELL_UNKNOWN, my_hit.skill, true, -1, false, m_specialattacks);
if (IsDead()) {
if (CastToClient()->IsDead() || (IsBot() && GetAppearance() == eaDead)) {
return false;
}