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

View File

@ -45,6 +45,7 @@
#define TIGER 63 #define TIGER 63
#define ELEMENTAL 75 #define ELEMENTAL 75
#define ALLIGATOR 91 #define ALLIGATOR 91
#define OGGOK_CITIZEN 93
#define EYE_OF_ZOMM 108 #define EYE_OF_ZOMM 108
#define WOLF_ELEMENTAL 120 #define WOLF_ELEMENTAL 120
#define INVISIBLE_MAN 127 #define INVISIBLE_MAN 127

View File

@ -446,7 +446,7 @@ typedef enum {
#define SE_IncreaseRunSpeedCap 290 // implemented[AA] - increases run speed over the hard cap #define SE_IncreaseRunSpeedCap 290 // implemented[AA] - increases run speed over the hard cap
#define SE_Purify 291 // implemented - Removes determental effects #define SE_Purify 291 // implemented - Removes determental effects
#define SE_StrikeThrough2 292 // implemented[AA] - increasing chance of bypassing an opponent's special defenses, such as dodge, block, parry, and riposte. #define SE_StrikeThrough2 292 // implemented[AA] - increasing chance of bypassing an opponent's special defenses, such as dodge, block, parry, and riposte.
#define SE_FrontalStunResist 293 // implemented[AA] - Reduce chance to be stunned from front. #define SE_FrontalStunResist 293 // implemented[AA] - Reduce chance to be stunned from front. -- live descriptions sounds like this isn't limited to frontal anymore
#define SE_CriticalSpellChance 294 // implemented - increase chance to critical hit and critical damage modifier. #define SE_CriticalSpellChance 294 // implemented - increase chance to critical hit and critical damage modifier.
//#define SE_ReduceTimerSpecial 295 // not used //#define SE_ReduceTimerSpecial 295 // not used
#define SE_FcSpellVulnerability 296 // implemented - increase in incoming spell damage #define SE_FcSpellVulnerability 296 // implemented - increase in incoming spell damage

View File

@ -23,6 +23,7 @@
#include "../common/skills.h" #include "../common/skills.h"
#include "../common/spdat.h" #include "../common/spdat.h"
#include "../common/string_util.h" #include "../common/string_util.h"
#include "../common/data_verification.h"
#include "queryserv.h" #include "queryserv.h"
#include "quest_parser_collection.h" #include "quest_parser_collection.h"
#include "string_ids.h" #include "string_ids.h"
@ -3169,68 +3170,63 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
BuffFadeByEffect(SE_Mez); BuffFadeByEffect(SE_Mez);
} }
//check stun chances if bashing // broken up for readability
if (damage > 0 && ((skill_used == EQEmu::skills::SkillBash || skill_used == EQEmu::skills::SkillKick) && attacker)) { // This is based on what the client is doing
// NPCs can stun with their bash/kick as soon as they receive it. // We had a bunch of stuff like BaseImmunityLevel checks, which I think is suppose to just be for spells
// Clients can stun mobs under level 56 with their kick when they get level 55 or greater. // This is missing some merc checks, but those mostly just skipped the spell bonuses I think ...
// Clients have a chance to stun if the mob is 56+ bool can_stun = false;
int stunbash_chance = 0; // bonus
// Calculate the chance to stun if (attacker) {
int stun_chance = 0; if (skill_used == EQEmu::skills::SkillBash) {
if (!GetSpecialAbility(UNSTUNABLE)) { can_stun = true;
if (attacker->IsNPC()) { if (attacker->IsClient())
stun_chance = RuleI(Combat, NPCBashKickStunChance); stunbash_chance = attacker->spellbonuses.StunBashChance +
} 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->itembonuses.StunBashChance +
attacker->aabonuses.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)) { if ((GetBaseRace() == OGRE || GetBaseRace() == OGGOK_CITIZEN) &&
// Passed stun, try to resist now !attacker->BehindMob(this, attacker->GetX(), attacker->GetY()))
int stun_resist = itembonuses.StunResist + spellbonuses.StunResist; can_stun = false;
int frontal_stun_resist = itembonuses.FrontalStunResist + spellbonuses.FrontalStunResist; if (GetSpecialAbility(UNSTUNABLE))
can_stun = false;
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;
} }
if (can_stun) {
// frontal stun check for ogres/bonuses int bashsave_roll = zone->random.Int(0, 100);
if (((GetBaseRace() == OGRE && IsClient()) || if (bashsave_roll > 98 || bashsave_roll > (55 - stunbash_chance)) {
(frontal_stun_resist && zone->random.Roll(frontal_stun_resist))) && // did stun -- roll other resists
!attacker->BehindMob(this, attacker->GetX(), attacker->GetY())) { // SE_FrontalStunResist description says any angle now a days
Log.Out(Logs::Detail, Logs::Combat, "Frontal stun resisted. %d chance.", frontal_stun_resist); 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 { } else {
// Normal stun resist check. // stun resist passed!
if (stun_resist && zone->random.Roll(stun_resist)) {
if (IsClient()) if (IsClient())
Message_StringID(MT_Stun, SHAKE_OFF_STUN); 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 { } else {
Log.Out(Logs::Detail, Logs::Combat, "Stun failed. %d chance.", stun_chance); // stun resist 2 passed!
if (IsClient())
Message_StringID(MT_Stun, AVOID_STUNNING_BLOW);
}
} else {
// 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();
} }
} }

View File

@ -297,6 +297,7 @@
#define ADVENTURE_COMPLETE 5147 //You received %1 points for successfully completing the adventure. #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 SUCCOR_FAIL 5169 //The portal collapes before you can escape!
#define PET_ATTACKING 5501 //%1 tells you, 'Attacking %2 Master.' #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 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 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. #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 HIT_NON_MELEE 9073 //%1 hit %2 for %3 points of non-melee damage.
#define GLOWS_BLUE 9074 //Your %1 glows blue. #define GLOWS_BLUE 9074 //Your %1 glows blue.
#define GLOWS_RED 9075 //Your %1 glows red. #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 STRIKETHROUGH_STRING 9078 //You strike through your opponent's defenses!
#define SPELL_REFLECT 9082 //%1's spell has been reflected by %2. #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. #define NEW_SPELLS_AVAIL 9149 //You have new spells available to you. Check the merchants near your guild master.