Rework bash/kick stun based on client

This is what the client is doing. It doesn't reuse all the old rules, so those
can't be tweaked unless someone wants to add them back in
This commit is contained in:
Michael Cook (mackal)
2016-08-03 17:37:09 -04:00
parent 538d6a2a33
commit 60f2d14caa
4 changed files with 55 additions and 57 deletions
+51 -55
View File
@@ -23,6 +23,7 @@
#include "../common/skills.h"
#include "../common/spdat.h"
#include "../common/string_util.h"
#include "../common/data_verification.h"
#include "queryserv.h"
#include "quest_parser_collection.h"
#include "string_ids.h"
@@ -3169,68 +3170,63 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
BuffFadeByEffect(SE_Mez);
}
//check stun chances if bashing
if (damage > 0 && ((skill_used == EQEmu::skills::SkillBash || skill_used == EQEmu::skills::SkillKick) && attacker)) {
// NPCs can stun with their bash/kick as soon as they receive it.
// Clients can stun mobs under level 56 with their kick when they get level 55 or greater.
// Clients have a chance to stun if the mob is 56+
// Calculate the chance to stun
int stun_chance = 0;
if (!GetSpecialAbility(UNSTUNABLE)) {
if (attacker->IsNPC()) {
stun_chance = RuleI(Combat, NPCBashKickStunChance);
} else if (attacker->IsClient()) {
// Less than base immunity
// Client vs. Client always uses the chance
if (!IsClient() && GetLevel() <= RuleI(Spells, BaseImmunityLevel)) {
if (skill_used == EQEmu::skills::SkillBash) // Bash always will
stun_chance = 100;
else if (attacker->GetLevel() >= RuleI(Combat, ClientStunLevel))
stun_chance = 100; // only if you're over level 55 and using kick
} else { // higher than base immunity or Client vs. Client
// not sure on this number, use same as NPC for now
if (skill_used == EQEmu::skills::SkillKick && attacker->GetLevel() < RuleI(Combat, ClientStunLevel))
stun_chance = RuleI(Combat, NPCBashKickStunChance);
else if (skill_used == EQEmu::skills::SkillBash)
stun_chance = RuleI(Combat, NPCBashKickStunChance) +
attacker->spellbonuses.StunBashChance +
attacker->itembonuses.StunBashChance +
attacker->aabonuses.StunBashChance;
}
}
// broken up for readability
// This is based on what the client is doing
// We had a bunch of stuff like BaseImmunityLevel checks, which I think is suppose to just be for spells
// This is missing some merc checks, but those mostly just skipped the spell bonuses I think ...
bool can_stun = false;
int stunbash_chance = 0; // bonus
if (attacker) {
if (skill_used == EQEmu::skills::SkillBash) {
can_stun = true;
if (attacker->IsClient())
stunbash_chance = attacker->spellbonuses.StunBashChance +
attacker->itembonuses.StunBashChance +
attacker->aabonuses.StunBashChance;
} else if (skill_used == EQEmu::skills::SkillKick &&
(attacker->GetLevel() > 55 || attacker->IsNPC()) && GetClass() == WARRIOR) {
can_stun = true;
}
if (stun_chance && zone->random.Roll(stun_chance)) {
// Passed stun, try to resist now
int stun_resist = itembonuses.StunResist + spellbonuses.StunResist;
int frontal_stun_resist = itembonuses.FrontalStunResist + spellbonuses.FrontalStunResist;
Log.Out(Logs::Detail, Logs::Combat, "Stun passed, checking resists. Was %d chance.", stun_chance);
if (IsClient()) {
stun_resist += aabonuses.StunResist;
frontal_stun_resist += aabonuses.FrontalStunResist;
}
// frontal stun check for ogres/bonuses
if (((GetBaseRace() == OGRE && IsClient()) ||
(frontal_stun_resist && zone->random.Roll(frontal_stun_resist))) &&
!attacker->BehindMob(this, attacker->GetX(), attacker->GetY())) {
Log.Out(Logs::Detail, Logs::Combat, "Frontal stun resisted. %d chance.", frontal_stun_resist);
} else {
// Normal stun resist check.
if (stun_resist && zone->random.Roll(stun_resist)) {
if ((GetBaseRace() == OGRE || GetBaseRace() == OGGOK_CITIZEN) &&
!attacker->BehindMob(this, attacker->GetX(), attacker->GetY()))
can_stun = false;
if (GetSpecialAbility(UNSTUNABLE))
can_stun = false;
}
if (can_stun) {
int bashsave_roll = zone->random.Int(0, 100);
if (bashsave_roll > 98 || bashsave_roll > (55 - stunbash_chance)) {
// did stun -- roll other resists
// SE_FrontalStunResist description says any angle now a days
int stun_resist2 = spellbonuses.FrontalStunResist + itembonuses.FrontalStunResist +
aabonuses.FrontalStunResist;
if (zone->random.Int(1, 100) > stun_resist2) {
// stun resist 2 failed
// time to check SE_StunResist and mod2 stun resist
int stun_resist =
spellbonuses.StunResist + itembonuses.StunResist + aabonuses.StunResist;
if (zone->random.Int(0, 100) >= stun_resist) {
// did stun
// nothing else to check!
Stun(2000); // straight 2 seconds every time
} else {
// stun resist passed!
if (IsClient())
Message_StringID(MT_Stun, SHAKE_OFF_STUN);
Log.Out(Logs::Detail, Logs::Combat, "Stun Resisted. %d chance.", stun_resist);
} else {
Log.Out(Logs::Detail, Logs::Combat, "Stunned. %d resist chance.", stun_resist);
Stun(zone->random.Int(0, 2) * 1000); // 0-2 seconds
}
} else {
// stun resist 2 passed!
if (IsClient())
Message_StringID(MT_Stun, AVOID_STUNNING_BLOW);
}
} else {
Log.Out(Logs::Detail, Logs::Combat, "Stun failed. %d chance.", stun_chance);
// main stun failed -- extra interrupt roll
if (IsCasting() &&
!EQEmu::ValueWithin(casting_spell_id, 859, 1023)) // these spells are excluded
// 90% chance >< -- stun immune won't reach this branch though :(
if (zone->random.Int(0, 9) > 1)
InterruptSpell();
}
}
+2 -1
View File
@@ -297,6 +297,7 @@
#define ADVENTURE_COMPLETE 5147 //You received %1 points for successfully completing the adventure.
#define SUCCOR_FAIL 5169 //The portal collapes before you can escape!
#define PET_ATTACKING 5501 //%1 tells you, 'Attacking %2 Master.'
#define AVOID_STUNNING_BLOW 5753 //You avoid the stunning blow.
#define FATAL_BOW_SHOT 5745 //%1 performs a FATAL BOW SHOT!!
#define MELEE_SILENCE 5806 //You *CANNOT* use this melee ability, you are suffering from amnesia!
#define DISCIPLINE_REUSE_MSG 5807 //You can use the ability %1 again in %2 hour(s) %3 minute(s) %4 seconds.
@@ -354,7 +355,7 @@
#define HIT_NON_MELEE 9073 //%1 hit %2 for %3 points of non-melee damage.
#define GLOWS_BLUE 9074 //Your %1 glows blue.
#define GLOWS_RED 9075 //Your %1 glows red.
#define SHAKE_OFF_STUN 9077
#define SHAKE_OFF_STUN 9077 //You shake off the stun effect!
#define STRIKETHROUGH_STRING 9078 //You strike through your opponent's defenses!
#define SPELL_REFLECT 9082 //%1's spell has been reflected by %2.
#define NEW_SPELLS_AVAIL 9149 //You have new spells available to you. Check the merchants near your guild master.