mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 09:31:30 +00:00
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:
parent
4629c7c8c4
commit
0521cae8d0
@ -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
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user