Implemented npc specialability (44) COUNTER_AVOID_DAMAGE which when applied to the ATTACKING NPC will make their attacks more difficult to be avoided by riposte/dodge/parry/block.

Parama0: Negative modifer value that affects ALL avoid damage types dodge/parry/riposte/block) chance on defender. Ie (44,50 = 50 pct reduction to ALL)
Parama1: Negative modifer value that affects RIPOSTE chance on defender. Ie (44,1,0,50 = 50 pct reduction to riposte chance)
Parama2: Negative modifer value that affects PARRY chance on defender.  Ie (44,1,0,0,50 = 50 pct reduction to parry chance)
Parama3: Negative modifer value that affects BLOCK chance on defender.  Ie (44,1,0,0,0,50 = 50 pct reduction to block chance)
Parama4: Negative modifer value that affects DODGE chance on defender.  e (44,1,0,0,0,0,50 = 50 pct reduction to dodge chance)
Example of usage: Player has Improved Dodge V (+50 pct dodge chance), you want to negate this bonus you would set 44,1,0,0,0,0,50 on your NPC.

Clean up and minor fixes to AvoidDamage function.
Added support to a few AA bonuses there.
This commit is contained in:
KayenEQ 2015-02-08 20:17:51 -05:00
parent 4629c7c8c4
commit 0521cae8d0
6 changed files with 78 additions and 51 deletions

View File

@ -1,5 +1,14 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50) EQEMu Changelog (Started on Sept 24, 2003 15:50)
------------------------------------------------------- -------------------------------------------------------
== 02/08/2015 ==
Kayen: Implemented npc specialability (44) COUNTER_AVOID_DAMAGE which when applied to the ATTACKING NPC will make their attacks more difficult to be avoided by riposte/dodge/parry/block.
Parama0: Negative modifer value that affects ALL avoid damage types dodge/parry/riposte/block) chance on defender. Ie (44,50 = 50 pct reduction to ALL)
Parama1: Negative modifer value that affects RIPOSTE chance on defender. Ie (44,1,0,50 = 50 pct reduction to riposte chance)
Parama2: Negative modifer value that affects PARRY chance on defender. Ie (44,1,0,0,50 = 50 pct reduction to parry chance)
Parama3: Negative modifer value that affects BLOCK chance on defender. Ie (44,1,0,0,0,50 = 50 pct reduction to block chance)
Parama4: Negative modifer value that affects DODGE chance on defender. e (44,1,0,0,0,0,50 = 50 pct reduction to dodge chance)
Example of usage: Player has Improved Dodge V (+50 pct dodge chance), you want to negate this bonus you would set 44,1,0,0,0,0,50 on your NPC.
== 02/07/2015 == == 02/07/2015 ==
Akkadius: Reduced #repop time dramatically by taking down hundreds of individual SELECT/DELETE/INSERT queries in routines and bringing it down to very few Akkadius: Reduced #repop time dramatically by taking down hundreds of individual SELECT/DELETE/INSERT queries in routines and bringing it down to very few
See: https://www.youtube.com/watch?v=9kSFbyTBuAk See: https://www.youtube.com/watch?v=9kSFbyTBuAk

View File

@ -362,13 +362,40 @@ bool Mob::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
//garunteed hit //garunteed hit
bool ghit = false; bool ghit = false;
if((attacker->spellbonuses.MeleeSkillCheck + attacker->itembonuses.MeleeSkillCheck) > 500) if((attacker->aabonuses.MeleeSkillCheck + attacker->spellbonuses.MeleeSkillCheck + attacker->itembonuses.MeleeSkillCheck) > 500)
ghit = true; ghit = true;
bool InFront = false;
if (attacker->InFrontMob(this, attacker->GetX(), attacker->GetY()))
InFront = true;
/*
This special ability adds a negative modifer to the defenders riposte/block/parry/chance
therefore reducing the defenders chance to successfully avoid the melee attack. At present
time this is the only way to fine tune counter these mods on players. This may
ultimately end up being more useful as fields in npc_types.
*/
int counter_all = 0;
int counter_riposte = 0;
int counter_block = 0;
int counter_parry = 0;
int counter_dodge = 0;
if (attacker->GetSpecialAbility(COUNTER_AVOID_DAMAGE)){
counter_all = attacker->GetSpecialAbilityParam(COUNTER_AVOID_DAMAGE, 0);
counter_riposte = attacker->GetSpecialAbilityParam(COUNTER_AVOID_DAMAGE,1);
counter_block = attacker->GetSpecialAbilityParam(COUNTER_AVOID_DAMAGE, 2);
counter_parry = attacker->GetSpecialAbilityParam(COUNTER_AVOID_DAMAGE, 3);
counter_dodge = attacker->GetSpecialAbilityParam(COUNTER_AVOID_DAMAGE, 4);
}
////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////
// make enrage same as riposte // make enrage same as riposte
///////////////////////////////////////////////////////// /////////////////////////////////////////////////////////
if (IsEnraged() && other->InFrontMob(this, other->GetX(), other->GetY())) { if (IsEnraged() && InFront) {
damage = -3; damage = -3;
Log.Out(Logs::Detail, Logs::Combat, "I am enraged, riposting frontal attack."); Log.Out(Logs::Detail, Logs::Combat, "I am enraged, riposting frontal attack.");
} }
@ -377,9 +404,10 @@ bool Mob::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
// riposte // riposte
///////////////////////////////////////////////////////// /////////////////////////////////////////////////////////
float riposte_chance = 0.0f; float riposte_chance = 0.0f;
if (CanRiposte && damage > 0 && CanThisClassRiposte() && other->InFrontMob(this, other->GetX(), other->GetY())) if (CanRiposte && damage > 0 && CanThisClassRiposte() && InFront)
{ {
riposte_chance = (100.0f + (float)defender->aabonuses.RiposteChance + (float)defender->spellbonuses.RiposteChance + (float)defender->itembonuses.RiposteChance) / 100.0f; riposte_chance = (100.0f + static_cast<float>(aabonuses.RiposteChance + spellbonuses.RiposteChance +
itembonuses.RiposteChance - counter_riposte - counter_all)) / 100.0f;
skill = GetSkill(SkillRiposte); skill = GetSkill(SkillRiposte);
if (IsClient()) { if (IsClient()) {
CastToClient()->CheckIncreaseSkill(SkillRiposte, other, -10); CastToClient()->CheckIncreaseSkill(SkillRiposte, other, -10);
@ -398,28 +426,19 @@ bool Mob::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
bool bBlockFromRear = false; bool bBlockFromRear = false;
bool bShieldBlockFromRear = false;
if (this->IsClient()) { // a successful roll on this does not mean a successful block is forthcoming. only that a chance to block
int aaChance = 0; // from a direction other than the rear is granted.
// a successful roll on this does not mean a successful block is forthcoming. only that a chance to block int BlockBehindChance = aabonuses.BlockBehind + spellbonuses.BlockBehind + itembonuses.BlockBehind;
// from a direction other than the rear is granted.
//Live AA - HightenedAwareness if (BlockBehindChance && zone->random.Roll(BlockBehindChance))
int BlockBehindChance = aabonuses.BlockBehind + spellbonuses.BlockBehind + itembonuses.BlockBehind; bBlockFromRear = true;
if (BlockBehindChance && zone->random.Roll(BlockBehindChance)) {
bBlockFromRear = true;
if (spellbonuses.BlockBehind || itembonuses.BlockBehind)
bShieldBlockFromRear = true; //This bonus should allow a chance to Shield Block from behind.
}
}
float block_chance = 0.0f; float block_chance = 0.0f;
if (damage > 0 && CanThisClassBlock() && (other->InFrontMob(this, other->GetX(), other->GetY()) || bBlockFromRear)) { if (damage > 0 && CanThisClassBlock() && (InFront || bBlockFromRear)) {
block_chance = (100.0f + (float)spellbonuses.IncreaseBlockChance + (float)itembonuses.IncreaseBlockChance) / 100.0f; block_chance = (100.0f + static_cast<float>(aabonuses.IncreaseBlockChance + spellbonuses.IncreaseBlockChance +
itembonuses.IncreaseBlockChance - counter_block - counter_all)) / 100.0f;
skill = CastToClient()->GetSkill(SkillBlock); skill = CastToClient()->GetSkill(SkillBlock);
if (IsClient()) { if (IsClient()) {
CastToClient()->CheckIncreaseSkill(SkillBlock, other, -10); CastToClient()->CheckIncreaseSkill(SkillBlock, other, -10);
@ -435,32 +454,20 @@ bool Mob::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
RollTable[1] = RollTable[0]; RollTable[1] = RollTable[0];
} }
if(damage > 0 && HasShieldEquiped() && (aabonuses.ShieldBlock || spellbonuses.ShieldBlock || itembonuses.ShieldBlock) //Try Shield Block OR TwoHandBluntBlockCheck
&& (other->InFrontMob(this, other->GetX(), other->GetY()) || bShieldBlockFromRear)) { if(damage > 0 && HasShieldEquiped() && (aabonuses.ShieldBlock || spellbonuses.ShieldBlock || itembonuses.ShieldBlock) && (InFront || bBlockFromRear))
RollTable[1] += static_cast<float>(aabonuses.ShieldBlock + spellbonuses.ShieldBlock + itembonuses.ShieldBlock - counter_block - counter_all);
float bonusShieldBlock = 0.0f; else if(damage > 0 && HasTwoHandBluntEquiped() && (aabonuses.TwoHandBluntBlock || spellbonuses.TwoHandBluntBlock || itembonuses.TwoHandBluntBlock) && (InFront || bBlockFromRear))
bonusShieldBlock = static_cast<float>(aabonuses.ShieldBlock + spellbonuses.ShieldBlock + itembonuses.ShieldBlock); RollTable[1] += static_cast<float>(aabonuses.TwoHandBluntBlock + spellbonuses.TwoHandBluntBlock + itembonuses.TwoHandBluntBlock - counter_block - counter_all);
RollTable[1] += bonusShieldBlock;
}
if(IsClient() && damage > 0 && (aabonuses.TwoHandBluntBlock || spellbonuses.TwoHandBluntBlock || itembonuses.TwoHandBluntBlock)
&& (other->InFrontMob(this, other->GetX(), other->GetY()) || bShieldBlockFromRear)) {
if(CastToClient()->m_inv.GetItem(MainPrimary)) {
float bonusStaffBlock = 0.0f;
if (CastToClient()->m_inv.GetItem(MainPrimary)->GetItem()->ItemType == ItemType2HBlunt){
bonusStaffBlock = static_cast<float>(aabonuses.TwoHandBluntBlock + spellbonuses.TwoHandBluntBlock + itembonuses.TwoHandBluntBlock);
RollTable[1] += bonusStaffBlock;
}
}
}
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
// parry // parry
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
float parry_chance = 0.0f; float parry_chance = 0.0f;
if (damage > 0 && CanThisClassParry() && other->InFrontMob(this, other->GetX(), other->GetY())) if (damage > 0 && CanThisClassParry() && InFront){
{ parry_chance = (100.0f + static_cast<float>(aabonuses.ParryChance + itembonuses.ParryChance +
parry_chance = (100.0f + (float)defender->spellbonuses.ParryChance + (float)defender->itembonuses.ParryChance) / 100.0f; itembonuses.ParryChance - counter_parry - counter_all)) / 100.0f;
skill = CastToClient()->GetSkill(SkillParry); skill = CastToClient()->GetSkill(SkillParry);
if (IsClient()) { if (IsClient()) {
CastToClient()->CheckIncreaseSkill(SkillParry, other, -10); CastToClient()->CheckIncreaseSkill(SkillParry, other, -10);
@ -481,9 +488,11 @@ bool Mob::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
// dodge // dodge
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
float dodge_chance = 0.0f; float dodge_chance = 0.0f;
if (damage > 0 && CanThisClassDodge() && other->InFrontMob(this, other->GetX(), other->GetY())) if (damage > 0 && CanThisClassDodge() && InFront){
{
dodge_chance = (100.0f + (float)defender->spellbonuses.DodgeChance + (float)defender->itembonuses.DodgeChance) / 100.0f; dodge_chance = (100.0f + static_cast<float>(aabonuses.DodgeChance + spellbonuses.DodgeChance +
itembonuses.DodgeChance - counter_dodge - counter_all)) / 100.0f;
skill = CastToClient()->GetSkill(SkillDodge); skill = CastToClient()->GetSkill(SkillDodge);
if (IsClient()) { if (IsClient()) {
CastToClient()->CheckIncreaseSkill(SkillDodge, other, -10); CastToClient()->CheckIncreaseSkill(SkillDodge, other, -10);

View File

@ -139,7 +139,8 @@ void Client::CalcItemBonuses(StatBonuses* newbon) {
// Clear item faction mods // Clear item faction mods
ClearItemFactionBonuses(); ClearItemFactionBonuses();
ShieldEquiped(false); SetShieldEquiped(false);
SetTwoHandBluntEquiped(false);
unsigned int i; unsigned int i;
//should not include 21 (SLOT_AMMO) //should not include 21 (SLOT_AMMO)
@ -149,9 +150,12 @@ void Client::CalcItemBonuses(StatBonuses* newbon) {
continue; continue;
AddItemBonuses(inst, newbon); AddItemBonuses(inst, newbon);
//Check if item is secondary slot is a 'shield'. Required for multiple spelll effects. //These are given special flags due to how often they are checked for various spell effects.
if (i == MainSecondary && (m_inv.GetItem(MainSecondary)->GetItem()->ItemType == ItemTypeShield)) const Item_Struct *item = inst->GetItem();
ShieldEquiped(true); if (i == MainSecondary && (item && item->ItemType == ItemTypeShield))
SetShieldEquiped(true);
else if (i == MainPrimary && (item && item->ItemType == ItemType2HBlunt))
SetTwoHandBluntEquiped(true);
} }
//Power Source Slot //Power Source Slot

View File

@ -136,7 +136,8 @@ enum {
ALLOW_TO_TANK = 41, ALLOW_TO_TANK = 41,
IGNORE_ROOT_AGGRO_RULES = 42, IGNORE_ROOT_AGGRO_RULES = 42,
CASTING_RESIST_DIFF = 43, CASTING_RESIST_DIFF = 43,
MAX_SPECIAL_ATTACK = 44 COUNTER_AVOID_DAMAGE = 44,
MAX_SPECIAL_ATTACK = 45
}; };
typedef enum { //fear states typedef enum { //fear states

View File

@ -170,6 +170,7 @@ Mob::Mob(const char* in_name,
findable = false; findable = false;
trackable = true; trackable = true;
has_shieldequiped = false; has_shieldequiped = false;
has_twohandbluntequiped = false;
has_numhits = false; has_numhits = false;
has_MGB = false; has_MGB = false;
has_ProjectIllusion = false; has_ProjectIllusion = false;

View File

@ -308,7 +308,9 @@ public:
void SetTargetable(bool on); void SetTargetable(bool on);
bool IsTargetable() const { return m_targetable; } bool IsTargetable() const { return m_targetable; }
bool HasShieldEquiped() const { return has_shieldequiped; } bool HasShieldEquiped() const { return has_shieldequiped; }
inline void ShieldEquiped(bool val) { has_shieldequiped = val; } inline void SetShieldEquiped(bool val) { has_shieldequiped = val; }
bool HasTwoHandBluntEquiped() const { return has_twohandbluntequiped; }
inline void SetTwoHandBluntEquiped(bool val) { has_twohandbluntequiped = val; }
virtual uint16 GetSkill(SkillUseTypes skill_num) const { return 0; } virtual uint16 GetSkill(SkillUseTypes skill_num) const { return 0; }
virtual uint32 GetEquipment(uint8 material_slot) const { return(0); } virtual uint32 GetEquipment(uint8 material_slot) const { return(0); }
virtual int32 GetEquipmentMaterial(uint8 material_slot) const; virtual int32 GetEquipmentMaterial(uint8 material_slot) const;
@ -1150,6 +1152,7 @@ protected:
uint16 viral_spells[MAX_SPELL_TRIGGER*2]; // Stores the spell ids of the viruses on target and caster ids uint16 viral_spells[MAX_SPELL_TRIGGER*2]; // Stores the spell ids of the viruses on target and caster ids
bool offhand; bool offhand;
bool has_shieldequiped; bool has_shieldequiped;
bool has_twohandbluntequiped;
bool has_numhits; bool has_numhits;
bool has_MGB; bool has_MGB;
bool has_ProjectIllusion; bool has_ProjectIllusion;