move bot backstab to mob

This commit is contained in:
nytmyr
2024-12-12 15:33:11 -06:00
parent 96bc292ad6
commit f44af609e1
4 changed files with 88 additions and 31 deletions
+2 -1
View File
@@ -6446,8 +6446,9 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraAttac
} }
else { else {
int ass = TryAssassinate(defender, hit.skill); int ass = TryAssassinate(defender, hit.skill);
if (ass > 0) if (ass > 0) {
hit.damage_done = ass; hit.damage_done = ass;
}
} }
} }
else if (hit.skill == EQ::skills::SkillFrenzy && GetClass() == Class::Berserker && GetLevel() > 50) { else if (hit.skill == EQ::skills::SkillFrenzy && GetClass() == Class::Berserker && GetLevel() > 50) {
+21 -7
View File
@@ -5372,18 +5372,32 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) {
} }
if (skill_to_use == EQ::skills::SkillFrenzy) { if (skill_to_use == EQ::skills::SkillFrenzy) {
int AtkRounds = 3; int AtkRounds = 1;
float HasteMod = (FrenzyReuseTime - 1) / (GetHaste() * 0.01f);
reuse = (FrenzyReuseTime * 1000);
DoAnim(anim2HSlashing); DoAnim(anim2HSlashing);
reuse = (FrenzyReuseTime * 1000); // bards can do riposte frenzy for some reason
did_attack = true; if (!IsRiposte && GetClass() == Class::Berserker) {
while(AtkRounds > 0) { int chance = GetLevel() * 2 + GetSkill(EQ::skills::SkillFrenzy);
if (GetTarget() && (AtkRounds == 1 || zone->random.Int(0, 100) < 75)) { if (zone->random.Roll0(450) < chance)
DoSpecialAttackDamage(GetTarget(), EQ::skills::SkillFrenzy, dmg, 0, dmg, reuse, true); AtkRounds++;
} if (zone->random.Roll0(450) < chance)
AtkRounds++;
}
while (AtkRounds > 0) {
if (GetTarget() != this)
DoSpecialAttackDamage(GetTarget(), EQ::skills::SkillFrenzy, dmg, 0, dmg, HasteMod);
AtkRounds--; AtkRounds--;
} }
if (reuse > 0 && IsRiposte) {
reuse = 0;
}
did_attack = true;
} }
if (skill_to_use == EQ::skills::SkillKick) { if (skill_to_use == EQ::skills::SkillKick) {
-3
View File
@@ -249,9 +249,6 @@ public:
inline uint16 MaxSkill(EQ::skills::SkillType skillid) { return MaxSkill(skillid, GetClass(), GetLevel()); } inline uint16 MaxSkill(EQ::skills::SkillType skillid) { return MaxSkill(skillid, GetClass(), GetLevel()); }
int GetBaseSkillDamage(EQ::skills::SkillType skill, Mob *target = nullptr) override; int GetBaseSkillDamage(EQ::skills::SkillType skill, Mob *target = nullptr) override;
void DoSpecialAttackDamage(Mob *who, EQ::skills::SkillType skill, int32 max_damage, int32 min_damage = 1, int32 hate_override = -1, int ReuseTime = 10, bool HitChance = false); void DoSpecialAttackDamage(Mob *who, EQ::skills::SkillType skill, int32 max_damage, int32 min_damage = 1, int32 hate_override = -1, int ReuseTime = 10, bool HitChance = false);
void TryBackstab(Mob *other,int ReuseTime = 10) override;
void RogueBackstab(Mob* other, bool min_damage = false, int ReuseTime = 10) override;
void RogueAssassinate(Mob* other) override;
void DoClassAttacks(Mob *target, bool IsRiposte=false); void DoClassAttacks(Mob *target, bool IsRiposte=false);
void CalcBonuses() override; void CalcBonuses() override;
+65 -20
View File
@@ -709,54 +709,78 @@ int Mob::MonkSpecialAttack(Mob *other, uint8 unchecked_type)
} }
void Mob::TryBackstab(Mob *other, int ReuseTime) { void Mob::TryBackstab(Mob *other, int ReuseTime) {
if(!other) if (!other) {
return; return;
}
bool bIsBehind = false; bool bIsBehind = false;
bool bCanFrontalBS = false; bool bCanFrontalBS = false;
//make sure we have a proper weapon if we are a client. //make sure we have a proper weapon if we are a client.
if(IsClient()) { if (IsClient()) {
const EQ::ItemInstance *wpn = CastToClient()->GetInv().GetItem(EQ::invslot::slotPrimary); const EQ::ItemInstance *wpn = CastToClient()->GetInv().GetItem(EQ::invslot::slotPrimary);
if (!wpn || (wpn->GetItem()->ItemType != EQ::item::ItemType1HPiercing)){ if (!wpn || (wpn->GetItem()->ItemType != EQ::item::ItemType1HPiercing)){
MessageString(Chat::Red, BACKSTAB_WEAPON); MessageString(Chat::Red, BACKSTAB_WEAPON);
return; return;
} }
} }
else if (IsBot()) {
const EQ::ItemInstance* inst = CastToBot()->GetBotItem(EQ::invslot::slotPrimary);
const EQ::ItemData* botpiercer = nullptr;
if (inst) {
botpiercer = inst->GetItem();
}
if (!botpiercer || (botpiercer->ItemType != EQ::item::ItemType1HPiercing)) {
if (!CastToBot()->GetCombatRoundForAlerts()) {
CastToBot()->SetCombatRoundForAlerts();
CastToBot()->BotGroupSay(this, "I can't backstab with this weapon!");
}
return;
}
}
//Live AA - Triple Backstab //Live AA - Triple Backstab
int tripleChance = itembonuses.TripleBackstab + spellbonuses.TripleBackstab + aabonuses.TripleBackstab; int tripleChance = itembonuses.TripleBackstab + spellbonuses.TripleBackstab + aabonuses.TripleBackstab;
if (BehindMob(other, GetX(), GetY())) if (BehindMob(other, GetX(), GetY())) {
bIsBehind = true; bIsBehind = true;
}
else { else {
//Live AA - Seized Opportunity //Live AA - Seized Opportunity
int FrontalBSChance = itembonuses.FrontalBackstabChance + spellbonuses.FrontalBackstabChance + aabonuses.FrontalBackstabChance; int FrontalBSChance = itembonuses.FrontalBackstabChance + spellbonuses.FrontalBackstabChance + aabonuses.FrontalBackstabChance;
if (FrontalBSChance && zone->random.Roll(FrontalBSChance)) if (FrontalBSChance && zone->random.Roll(FrontalBSChance)) {
bCanFrontalBS = true; bCanFrontalBS = true;
}
} }
if (bIsBehind || bCanFrontalBS || (IsNPC() && CanFacestab())) { // Player is behind other OR can do Frontal Backstab if (bIsBehind || bCanFrontalBS || (IsNPC() && CanFacestab())) { // Player is behind other OR can do Frontal Backstab
if (bCanFrontalBS && IsClient()) // I don't think there is any message ... if (bCanFrontalBS && IsClient()) { // I don't think there is any message ...
CastToClient()->Message(Chat::White,"Your fierce attack is executed with such grace, your target did not see it coming!"); CastToClient()->Message(Chat::White, "Your fierce attack is executed with such grace, your target did not see it coming!");
}
RogueBackstab(other,false,ReuseTime); RogueBackstab(other,false,ReuseTime);
if (level >= RuleI(Combat, DoubleBackstabLevelRequirement)) { if (level >= RuleI(Combat, DoubleBackstabLevelRequirement)) {
// TODO: 55-59 doesn't appear to match just checking double attack, 60+ does though // TODO: 55-59 doesn't appear to match just checking double attack, 60+ does though
if(IsClient() && CastToClient()->CheckDoubleAttack()) if(IsOfClientBot() && CastToClient()->CheckDoubleAttack()) {
{ if (other->GetHP() > 0) {
if(other->GetHP() > 0) RogueBackstab(other, false, ReuseTime);
RogueBackstab(other,false,ReuseTime); }
if (tripleChance && other->GetHP() > 0 && zone->random.Roll(tripleChance)) if (tripleChance && other->GetHP() > 0 && zone->random.Roll(tripleChance)) {
RogueBackstab(other,false,ReuseTime); RogueBackstab(other, false, ReuseTime);
}
} }
} }
if(IsClient()) if (IsClient()) {
CastToClient()->CheckIncreaseSkill(EQ::skills::SkillBackstab, other, 10); CastToClient()->CheckIncreaseSkill(EQ::skills::SkillBackstab, other, 10);
}
} }
//Live AA - Chaotic Backstab //Live AA - Chaotic Backstab
@@ -766,14 +790,20 @@ void Mob::TryBackstab(Mob *other, int ReuseTime) {
//we can stab from any angle, we do min damage though. //we can stab from any angle, we do min damage though.
// chaotic backstab can't double etc Seized can, but that's because it's a chance to do normal BS // chaotic backstab can't double etc Seized can, but that's because it's a chance to do normal BS
// Live actually added SPA 473 which grants chance to double here when they revamped chaotic/seized // Live actually added SPA 473 which grants chance to double here when they revamped chaotic/seized
RogueBackstab(other, true, ReuseTime); RogueBackstab(other, true, ReuseTime);
if(IsClient())
if (IsClient()) {
CastToClient()->CheckIncreaseSkill(EQ::skills::SkillBackstab, other, 10); CastToClient()->CheckIncreaseSkill(EQ::skills::SkillBackstab, other, 10);
}
m_specialattacks = eSpecialAttacks::None; m_specialattacks = eSpecialAttacks::None;
int double_bs_front = aabonuses.Double_Backstab_Front + itembonuses.Double_Backstab_Front + spellbonuses.Double_Backstab_Front; int double_bs_front = aabonuses.Double_Backstab_Front + itembonuses.Double_Backstab_Front + spellbonuses.Double_Backstab_Front;
if (double_bs_front && other->GetHP() > 0 && zone->random.Roll(double_bs_front))
if (double_bs_front && other->GetHP() > 0 && zone->random.Roll(double_bs_front)) {
RogueBackstab(other, false, ReuseTime); RogueBackstab(other, false, ReuseTime);
}
} }
else { //We do a single regular attack if we attack from the front without chaotic stab else { //We do a single regular attack if we attack from the front without chaotic stab
Attack(other, EQ::invslot::slotPrimary); Attack(other, EQ::invslot::slotPrimary);
@@ -790,10 +820,25 @@ void Mob::RogueBackstab(Mob* other, bool min_damage, int ReuseTime)
// make sure we can hit (bane, magical, etc) // make sure we can hit (bane, magical, etc)
if (IsClient()) { if (IsClient()) {
const EQ::ItemInstance *wpn = CastToClient()->GetInv().GetItem(EQ::invslot::slotPrimary); const EQ::ItemInstance* wpn = CastToClient()->GetInv().GetItem(EQ::invslot::slotPrimary);
if (!GetWeaponDamage(other, wpn))
if (!GetWeaponDamage(other, wpn)) {
return; return;
} else if (!GetWeaponDamage(other, (const EQ::ItemData*)nullptr)){ }
}
else if (IsBot()) {
EQ::ItemInstance* botweaponInst = CastToBot()->GetBotItem(EQ::invslot::slotPrimary);
if (botweaponInst) {
if (!GetWeaponDamage(other, botweaponInst)) {
return;
}
}
else if (!GetWeaponDamage(other, (const EQ::ItemData*)nullptr)) {
return;
}
}
else if (!GetWeaponDamage(other, (const EQ::ItemData*)nullptr)) {
return; return;
} }
@@ -2454,7 +2499,7 @@ int Mob::TryAssassinate(Mob *defender, EQ::skills::SkillType skillInUse)
int chance = GetDEX(); int chance = GetDEX();
if (skillInUse == EQ::skills::SkillBackstab) { if (skillInUse == EQ::skills::SkillBackstab) {
chance = 100 * chance / (chance + 3500); chance = 100 * chance / (chance + 3500);
if (IsClient() || IsBot()) { if (IsOfClientBot()) {
chance += GetHeroicDEX(); chance += GetHeroicDEX();
} }
chance *= 10; chance *= 10;