From c4bbfbe0070dbfd2b71b4ed6d71585fc187e68a0 Mon Sep 17 00:00:00 2001 From: Kinglykrab Date: Wed, 11 Jun 2014 02:41:46 -0400 Subject: [PATCH] A lot of changes, Client::NukeItem(), Client::DeleteItemInInventory(), Archery damage from uint16 to uint32, a lot of "prettifying" of math, code, and comments. --- zone/client.h | 4 +- zone/mob.h | 2 +- zone/special_attacks.cpp | 1320 +++++++++++++------------------------- 3 files changed, 447 insertions(+), 879 deletions(-) diff --git a/zone/client.h b/zone/client.h index 9e2503df2..0c7da944a 100644 --- a/zone/client.h +++ b/zone/client.h @@ -787,10 +787,10 @@ public: void SetMaterial(int16 slot_id, uint32 item_id); void Undye(); uint32 GetItemIDAt(int16 slot_id); - uint32 GetAugmentIDAt(int16 slot_id, uint8 augslot); + int32 GetAugmentIDAt(int16 slot_id, uint8 augslot); bool PutItemInInventory(int16 slot_id, const ItemInst& inst, bool client_update = false); bool PushItemOnCursor(const ItemInst& inst, bool client_update = false); - void DeleteItemInInventory(int16 slot_id, int8 quantity = 0, bool client_update = false, bool update_db = true); + void DeleteItemInInventory(int16 slot_id, int16 quantity = 0, bool client_update = false, bool update_db = true); bool SwapItem(MoveItem_Struct* move_in); void SwapItemResync(MoveItem_Struct* move_slots); void QSSwapItemAuditor(MoveItem_Struct* move_in, bool postaction_call = false); diff --git a/zone/mob.h b/zone/mob.h index 6dd4befbf..f14b04a42 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -129,7 +129,7 @@ public: float HeadingAngleToMob(Mob *other); // to keep consistent with client generated messages virtual void RangedAttack(Mob* other) { } virtual void ThrowingAttack(Mob* other) { } - uint16 GetThrownDamage(int16 wDmg, int32& TotalDmg, int& minDmg); + uint32 GetThrownDamage(int16 wDmg, int32& TotalDmg, int& minDmg); // 13 = Primary (default), 14 = secondary virtual bool Attack(Mob* other, int Hand = 13, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) = 0; diff --git a/zone/special_attacks.cpp b/zone/special_attacks.cpp index 4bbd808cc..18ce9ee28 100644 --- a/zone/special_attacks.cpp +++ b/zone/special_attacks.cpp @@ -21,116 +21,91 @@ #include #include #include - #include "masterentity.h" #include "StringIDs.h" #include "../common/MiscFunctions.h" #include "../common/rulesys.h" - - - int Mob::GetKickDamage() { - int multiple=(GetLevel()*100/5); + int multiple = (GetLevel() * 100 / 5); multiple += 100; - int32 dmg=(((GetSkill(SkillKick) + GetSTR() + GetLevel())*100 / 9000) * multiple) + 600; //Set a base of 6 damage, 1 seemed too low at the sub level 30 level. - if(GetClass() == WARRIOR || GetClass() == WARRIORGM ||GetClass() == BERSERKER || GetClass() == BERSERKERGM) { - dmg*=12/10;//small increase for warriors - } + int32 dmg = ((((GetSkill(SkillKick) + GetSTR() + GetLevel()) * 100 / 9000) * multiple) + 600); //Set a base of 6 damage, 1 seemed too low at the sub level 30 level. + if(GetClass() == WARRIOR || GetClass() == WARRIORGM || GetClass() == BERSERKER || GetClass() == BERSERKERGM) + dmg *= 1.2; //small increase for warriors dmg /= 100; - int32 mindmg = 1; ApplySpecialAttackMod(SkillKick, dmg,mindmg); - dmg = mod_kick_damage(dmg); - return(dmg); } int Mob::GetBashDamage() { - int multiple=(GetLevel()*100/5); + int multiple = (GetLevel() * 100 / 5); multiple += 100; - - //this is complete shite - int32 dmg=((((GetSkill(SkillBash) + GetSTR())*100 + GetLevel()*100/2) / 10000) * multiple) + 600; //Set a base of 6 damage, 1 seemed too low at the sub level 30 level. + int32 dmg = (((((GetSkill(SkillBash) + GetSTR()) * 100 + GetLevel() * 100 / 2) / 10000) * multiple) + 600); //Set a base of 6 damage, 1 seemed too low at the sub level 30 level. - this is complete shite dmg /= 100; - int32 mindmg = 1; ApplySpecialAttackMod(SkillBash, dmg, mindmg); - dmg = mod_bash_damage(dmg); - return(dmg); } void Mob::ApplySpecialAttackMod(SkillUseTypes skill, int32 &dmg, int32 &mindmg) { - - int item_slot = -1; - //1: Apply bonus from AC (BOOT/SHIELD/HANDS) est. 40AC=6dmg + int item_slot = -1; //1: Apply bonus from AC (BOOT/SHIELD/HANDS) est. 40AC=6dmg if (IsClient()){ - switch (skill){ - case SkillFlyingKick: case SkillRoundKick: - case SkillKick: + case SkillKick: { item_slot = SLOT_FEET; break; - - case SkillBash: + } + case SkillBash: { item_slot = SLOT_SECONDARY; break; - + } case SkillDragonPunch: case SkillEagleStrike: - case SkillTigerClaw: + case SkillTigerClaw: { item_slot = SLOT_HANDS; break; - - default: + } + default: { break; + } } - - if (item_slot >= 0){ + if (item_slot >= 0) { const ItemInst* itm = nullptr; itm = CastToClient()->GetInv().GetItem(item_slot); if(itm) - dmg += itm->GetItem()->AC * (RuleI(Combat, SpecialAttackACBonus))/100; + dmg += (itm->GetItem()->AC * (RuleI(Combat, SpecialAttackACBonus)) / 100); } } } -void Mob::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage, int32 min_damage, int32 hate_override,int ReuseTime, bool HitChance) { - //this really should go through the same code as normal melee damage to - //pick up all the special behavior there - +void Mob::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage, int32 min_damage, int32 hate_override,int ReuseTime, bool HitChance) { //this really should go through the same code as normal melee damage to pick up all the special behavior there int32 hate = max_damage; if(hate_override > -1) hate = hate_override; - if(skill == SkillBash) - { - if(IsClient()) - { + if(skill == SkillBash) { + if(IsClient()) { ItemInst *item = CastToClient()->GetInv().GetItem(SLOT_SECONDARY); - if(item) - { - if(item->GetItem()->ItemType == ItemTypeShield) - { + if(item) { + if(item->GetItem()->ItemType == ItemTypeShield) { hate += item->GetItem()->AC; } const Item_Struct *itm = item->GetItem(); - hate = hate * (100 + GetFuriousBash(itm->Focus.Effect)) / 100; + hate = (hate * (100 + GetFuriousBash(itm->Focus.Effect)) / 100); } } } - - min_damage += min_damage * GetMeleeMinDamageMod_SE(skill) / 100; + + min_damage += (min_damage * GetMeleeMinDamageMod_SE(skill) / 100); if(HitChance && !who->CheckHitChance(this, skill, 13)) max_damage = 0; - - else{ + else { bool CanRiposte = true; if(skill == SkillThrowing || skill == SkillArchery) // changed from '&&' CanRiposte = false; @@ -141,7 +116,7 @@ void Mob::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage, if(max_damage > 0) { ApplyMeleeDamageBonus(skill, max_damage); max_damage += who->GetFcDamageAmtIncoming(this, 0, true, skill); - max_damage += (itembonuses.HeroicSTR / 10) + (max_damage * who->GetSkillDmgTaken(skill) / 100) + GetSkillDmgAmt(skill); + max_damage += ((itembonuses.HeroicSTR / 10) + (max_damage * who->GetSkillDmgTaken(skill) / 100) + GetSkillDmgAmt(skill)); TryCriticalHit(who, skill, max_damage); } } @@ -151,25 +126,24 @@ void Mob::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage, who->Damage(this, max_damage, SPELL_UNKNOWN, skill, false); - //Make sure 'this' has not killed the target and 'this' is not dead (Damage shield ect). - if(!GetTarget())return; - if (HasDied()) return; + if(!GetTarget()) //Make sure 'this' has not killed the target and 'this' is not dead (Damage shield ect). + return; + if(HasDied()) + return; if (max_damage > 0) CheckNumHitsRemaining(5); - - //[AA Dragon Punch] value[0] = 100 for 25%, chance value[1] = skill - if(aabonuses.SpecialAttackKBProc[0] && aabonuses.SpecialAttackKBProc[1] == skill){ + + if(aabonuses.SpecialAttackKBProc[0] && aabonuses.SpecialAttackKBProc[1] == skill){ //[AA Dragon Punch] value[0] = 100 for 25%, chance value[1] = skill int kb_chance = 25; - kb_chance += kb_chance*(100-aabonuses.SpecialAttackKBProc[0])/100; + kb_chance += (kb_chance * (100 - aabonuses.SpecialAttackKBProc[0]) / 100); if (MakeRandomInt(0, 99) < kb_chance) - SpellFinished(904, who, 10, 0, -1, spells[904].ResistDiff); - //who->Stun(100); Kayen: This effect does not stun on live, it only moves the NPC. + SpellFinished(904, who, 10, 0, -1, spells[904].ResistDiff); //who->Stun(100); Kayen: This effect does not stun on live, it only moves the NPC. } - if (HasSkillProcs()){ - float chance = (float)ReuseTime*RuleR(Combat, AvgProcsPerMinute)/60000.0f; + if (HasSkillProcs()) { + float chance = ((float)ReuseTime * RuleR(Combat, AvgProcsPerMinute) / 60000.0f); TrySkillProc(who, skill, chance); } @@ -181,8 +155,8 @@ void Mob::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage, void Client::OPCombatAbility(const EQApplicationPacket *app) { if(!GetTarget()) return; - //make sure were actually able to use such an attack. - if(spellend_timer.Enabled() || IsFeared() || IsStunned() || IsMezzed() || DivineAura() || dead) + + if(spellend_timer.Enabled() || IsFeared() || IsStunned() || IsMezzed() || DivineAura() || dead) //make sure were actually able to use such an attack. return; CombatAbility_Struct* ca_atk = (CombatAbility_Struct*) app->pBuffer; @@ -193,30 +167,24 @@ void Client::OPCombatAbility(const EQApplicationPacket *app) { if(!IsAttackAllowed(GetTarget())) return; - //These two are not subject to the combat ability timer, as they - //allready do their checking in conjunction with the attack timer - //throwing weapons - if(ca_atk->m_atk == 11) { + if(ca_atk->m_atk == 11) { //These two are not subject to the combat ability timer, as they already do their checking in conjunction with the attack timer throwing weapons if (ca_atk->m_skill == SkillThrowing) { SetAttackTimer(); ThrowingAttack(GetTarget()); if (CheckDoubleRangedAttack()) RangedAttack(GetTarget(), true); return; - } - //ranged attack (archery) - if (ca_atk->m_skill == SkillArchery) { + } + if (ca_atk->m_skill == SkillArchery) {//ranged attack (archery) SetAttackTimer(); RangedAttack(GetTarget()); if (CheckDoubleRangedAttack()) RangedAttack(GetTarget(), true); return; - } - //could we return here? Im not sure is m_atk 11 is used for real specials + } //could we return here? Im not sure is m_atk 11 is used for real specials } - //check range for all these abilities, they are all close combat stuff - if(!CombatRange(GetTarget())) + if(!CombatRange(GetTarget())) //check range for all these abilities, they are all close combat stuff return; if(!p_timers.Expired(&database, pTimerCombatAbility, false)) { @@ -228,58 +196,49 @@ void Client::OPCombatAbility(const EQApplicationPacket *app) { int ClientHaste = GetHaste(); int HasteMod = 0; - if(ClientHaste >= 0){ - HasteMod = (10000/(100+ClientHaste)); //+100% haste = 2x as many attacks - } - else{ - HasteMod = (100-ClientHaste); //-100% haste = 1/2 as many attacks - } + if(ClientHaste >= 0) + HasteMod = (10000 / (100 + ClientHaste)); //+100% haste = 2x as many attacks + else + HasteMod = (100 - ClientHaste); //-100% haste = 1/2 as many attacks int32 dmg = 0; int32 skill_reduction = this->GetSkillReuseTime(ca_atk->m_skill); if ((ca_atk->m_atk == 100) && (ca_atk->m_skill == SkillBash)) { // SLAM - Bash without a shield equipped if (GetTarget() != this) { - CheckIncreaseSkill(SkillBash, GetTarget(), 10); DoAnim(animTailRake); int32 ht = 0; - if(GetWeaponDamage(GetTarget(), GetInv().GetItem(SLOT_SECONDARY)) <= 0 && - GetWeaponDamage(GetTarget(), GetInv().GetItem(SLOT_SHOULDER)) <= 0){ + if(GetWeaponDamage(GetTarget(), GetInv().GetItem(SLOT_SECONDARY)) <= 0 && GetWeaponDamage(GetTarget(), GetInv().GetItem(SLOT_SHOULDER)) <= 0) dmg = -5; - } - else{ + else { if(!GetTarget()->CheckHitChance(this, SkillBash, 0)) { dmg = 0; ht = GetBashDamage(); } - else{ + else { if(RuleB(Combat, UseIntervalAC)) ht = dmg = GetBashDamage(); else ht = dmg = MakeRandomInt(1, GetBashDamage()); - } } - ReuseTime = BashReuseTime-1-skill_reduction; - ReuseTime = (ReuseTime*HasteMod)/100; + ReuseTime = (BashReuseTime - 1 - skill_reduction); + ReuseTime = ((ReuseTime * HasteMod) / 100); DoSpecialAttackDamage(GetTarget(), SkillBash, dmg, 1, ht, ReuseTime); if(ReuseTime > 0) - { p_timers.Start(pTimerCombatAbility, ReuseTime); - } } return; } - if ((ca_atk->m_atk == 100) && (ca_atk->m_skill == SkillFrenzy)) - { + if ((ca_atk->m_atk == 100) && (ca_atk->m_skill == SkillFrenzy)) { CheckIncreaseSkill(SkillFrenzy, GetTarget(), 10); int AtkRounds = 3; - int skillmod = 100*GetSkill(SkillFrenzy)/MaxSkill(SkillFrenzy); - int32 max_dmg = (26 + ((((GetLevel()-6) * 2)*skillmod)/100)) * ((100+RuleI(Combat, FrenzyBonus))/100); + int skillmod = (100 * GetSkill(SkillFrenzy) / MaxSkill(SkillFrenzy)); + int32 max_dmg = (26 + ((((GetLevel() - 6) * 2)*skillmod) / 100)) * ((100 + RuleI(Combat, FrenzyBonus)) / 100); int32 min_dmg = 0; DoAnim(anim2HSlashing); @@ -288,52 +247,45 @@ void Client::OPCombatAbility(const EQApplicationPacket *app) { if (GetLevel() < 51) min_dmg = 1; else - min_dmg = GetLevel()*8/10; + min_dmg = (GetLevel() * 8 / 10); if (min_dmg > max_dmg) max_dmg = min_dmg; - ReuseTime = FrenzyReuseTime-1-skill_reduction; - ReuseTime = (ReuseTime*HasteMod)/100; - - //Live parses show around 55% Triple 35% Double 10% Single, you will always get first hit. - while(AtkRounds > 0) { - - if (GetTarget() && (AtkRounds == 1 || MakeRandomInt(0,100) < 75)){ + ReuseTime = (FrenzyReuseTime - 1 - skill_reduction); + ReuseTime = ((ReuseTime*HasteMod) / 100); + + while(AtkRounds > 0) { //Live parses show around 55% Triple 35% Double 10% Single, you will always get first hit. + if (GetTarget() && (AtkRounds == 1 || MakeRandomInt(0,100) < 75)) DoSpecialAttackDamage(GetTarget(), SkillFrenzy, max_dmg, min_dmg, max_dmg , ReuseTime, true); - } AtkRounds--; } - if(ReuseTime > 0) { + if(ReuseTime > 0) p_timers.Start(pTimerCombatAbility, ReuseTime); - } return; } - switch(GetClass()) - { + switch(GetClass()) { case BERSERKER: case WARRIOR: case RANGER: - case BEASTLORD: - if (ca_atk->m_atk != 100 || ca_atk->m_skill != SkillKick) { + case BEASTLORD: { + if (ca_atk->m_atk != 100 || ca_atk->m_skill != SkillKick) break; - } if (GetTarget() != this) { CheckIncreaseSkill(SkillKick, GetTarget(), 10); DoAnim(animKick); int32 ht = 0; - if(GetWeaponDamage(GetTarget(), GetInv().GetItem(SLOT_FEET)) <= 0){ + if(GetWeaponDamage(GetTarget(), GetInv().GetItem(SLOT_FEET)) <= 0) dmg = -5; - } - else{ + else { if(!GetTarget()->CheckHitChance(this, SkillKick, 0)) { dmg = 0; ht = GetKickDamage(); } - else{ + else { if(RuleB(Combat, UseIntervalAC)) ht = dmg = GetKickDamage(); else @@ -341,58 +293,45 @@ void Client::OPCombatAbility(const EQApplicationPacket *app) { } } - ReuseTime = KickReuseTime-1-skill_reduction; + ReuseTime = (KickReuseTime - 1 - skill_reduction); DoSpecialAttackDamage(GetTarget(), SkillKick, dmg, 1, ht, ReuseTime); - } break; + } case MONK: { - ReuseTime = MonkSpecialAttack(GetTarget(), ca_atk->m_skill) - 1 - skill_reduction; - - //Live AA - Technique of Master Wu - uint16 bDoubleSpecialAttack = itembonuses.DoubleSpecialAttack + spellbonuses.DoubleSpecialAttack + aabonuses.DoubleSpecialAttack; + ReuseTime = (MonkSpecialAttack(GetTarget(), ca_atk->m_skill) - 1 - skill_reduction); + uint16 bDoubleSpecialAttack = itembonuses.DoubleSpecialAttack + spellbonuses.DoubleSpecialAttack + aabonuses.DoubleSpecialAttack; //Live AA - Technique of Master Wu if (bDoubleSpecialAttack && (bDoubleSpecialAttack >= 100 || bDoubleSpecialAttack > MakeRandomInt(0, 99))) { - int MonkSPA [5] = { SkillFlyingKick, SkillDragonPunch, SkillEagleStrike, SkillTigerClaw, SkillRoundKick }; MonkSpecialAttack(GetTarget(), MonkSPA[MakeRandomInt(0, 4)]); - - // always 1/4 of the double attack chance, 25% at rank 5 (100/4) - if ((bDoubleSpecialAttack / 4) > MakeRandomInt(0, 99)) + + if ((bDoubleSpecialAttack / 4) > MakeRandomInt(0, 99)) // always 1/4 of the double attack chance, 25% at rank 5 (100/4) MonkSpecialAttack(GetTarget(), MonkSPA[MakeRandomInt(0, 4)]); } - if(ReuseTime < 100) { - //hackish... but we return a huge reuse time if this is an - // invalid skill, otherwise, we can safely assume it is a - // valid monk skill and just cast it to a SkillType + if(ReuseTime < 100) //hackish... but we return a huge reuse time if this is an invalid skill, otherwise, we can safely assume it is a valid monk skill and just cast it to a SkillType CheckIncreaseSkill((SkillUseTypes) ca_atk->m_skill, GetTarget(), 10); - } break; } case ROGUE: { - if (ca_atk->m_atk != 100 || ca_atk->m_skill != SkillBackstab) { + if (ca_atk->m_atk != 100 || ca_atk->m_skill != SkillBackstab) break; - } TryBackstab(GetTarget(), ReuseTime); - ReuseTime = BackstabReuseTime-1 - skill_reduction; + ReuseTime = (BackstabReuseTime - 1 - skill_reduction); break; } - default: - //they have no abilities... wtf? make em wait a bit - ReuseTime = 9 - skill_reduction; + default: { + ReuseTime = (9 - skill_reduction); //they have no abilities... wtf? make em wait a bit break; + } } - ReuseTime = (ReuseTime*HasteMod)/100; + ReuseTime = ((ReuseTime * HasteMod) / 100); if(ReuseTime > 0) - { - p_timers.Start(pTimerCombatAbility, ReuseTime); - } + p_timers.Start(pTimerCombatAbility, ReuseTime); //returns the reuse time in sec for the special attack used. } -//returns the reuse time in sec for the special attack used. -int Mob::MonkSpecialAttack(Mob* other, uint8 unchecked_type) -{ +int Mob::MonkSpecialAttack(Mob* other, uint8 unchecked_type) { if(!other) return 0; @@ -400,101 +339,90 @@ int Mob::MonkSpecialAttack(Mob* other, uint8 unchecked_type) int32 max_dmg = 0; int32 min_dmg = 1; int reuse = 0; - SkillUseTypes skill_type; //to avoid casting... even though it "would work" + SkillUseTypes skill_type; //to avoid casting... even though it "would work" uint8 itemslot = SLOT_FEET; - switch(unchecked_type) - { - case SkillFlyingKick:{ + switch(unchecked_type) { + case SkillFlyingKick: { skill_type = SkillFlyingKick; - max_dmg = ((GetSTR()+GetSkill(skill_type)) * RuleI(Combat, FlyingKickBonus) / 100) + 35; - min_dmg = ((level*8)/10); + max_dmg = (((GetSTR() + GetSkill(skill_type)) * RuleI(Combat, FlyingKickBonus) / 100) + 35); + min_dmg = ((level * 8) / 10); ApplySpecialAttackMod(skill_type, max_dmg, min_dmg); DoAnim(animFlyingKick); reuse = FlyingKickReuseTime; break; } - case SkillDragonPunch:{ + case SkillDragonPunch: { skill_type = SkillDragonPunch; - max_dmg = ((GetSTR()+GetSkill(skill_type)) * RuleI(Combat, DragonPunchBonus) / 100) + 26; + max_dmg = (((GetSTR() + GetSkill(skill_type)) * RuleI(Combat, DragonPunchBonus) / 100) + 26); itemslot = SLOT_HANDS; ApplySpecialAttackMod(skill_type, max_dmg, min_dmg); DoAnim(animTailRake); reuse = TailRakeReuseTime; break; } - - case SkillEagleStrike:{ + case SkillEagleStrike: { skill_type = SkillEagleStrike; - max_dmg = ((GetSTR()+GetSkill(skill_type)) * RuleI(Combat, EagleStrikeBonus) / 100) + 19; + max_dmg = (((GetSTR() + GetSkill(skill_type)) * RuleI(Combat, EagleStrikeBonus) / 100) + 19); itemslot = SLOT_HANDS; ApplySpecialAttackMod(skill_type, max_dmg, min_dmg); DoAnim(animEagleStrike); reuse = EagleStrikeReuseTime; break; } - - case SkillTigerClaw:{ + case SkillTigerClaw: { skill_type = SkillTigerClaw; - max_dmg = ((GetSTR()+GetSkill(skill_type)) * RuleI(Combat, TigerClawBonus) / 100) + 12; + max_dmg = (((GetSTR() + GetSkill(skill_type)) * RuleI(Combat, TigerClawBonus) / 100) + 12); itemslot = SLOT_HANDS; ApplySpecialAttackMod(skill_type, max_dmg, min_dmg); DoAnim(animTigerClaw); reuse = TigerClawReuseTime; break; } - - case SkillRoundKick:{ + case SkillRoundKick: { skill_type = SkillRoundKick; - max_dmg = ((GetSTR()+GetSkill(skill_type)) * RuleI(Combat, RoundKickBonus) / 100) + 10; + max_dmg = (((GetSTR() + GetSkill(skill_type)) * RuleI(Combat, RoundKickBonus) / 100) + 10); ApplySpecialAttackMod(skill_type, max_dmg, min_dmg); DoAnim(animRoundKick); reuse = RoundKickReuseTime; break; } - - case SkillKick:{ + case SkillKick: { skill_type = SkillKick; max_dmg = GetKickDamage(); DoAnim(animKick); reuse = KickReuseTime; break; } - default: + default: { mlog(CLIENT__ERROR, "Invalid special attack type %d attempted", unchecked_type); - return(1000); /* nice long delay for them, the caller depends on this! */ + return(1000); //nice long delay for them, the caller depends on this! + } } - if(IsClient()){ - if(GetWeaponDamage(other, CastToClient()->GetInv().GetItem(itemslot)) <= 0){ + if(IsClient()) { + if(GetWeaponDamage(other, CastToClient()->GetInv().GetItem(itemslot)) <= 0) ndamage = -5; - } } - else{ - if(GetWeaponDamage(other, (const Item_Struct*)nullptr) <= 0){ + else { + if(GetWeaponDamage(other, (const Item_Struct*)nullptr) <= 0) ndamage = -5; - } } int32 ht = 0; - if(ndamage == 0){ - if(other->CheckHitChance(this, skill_type, 0)){ + if(ndamage == 0) { + if(other->CheckHitChance(this, skill_type, 0)) { if(RuleB(Combat, UseIntervalAC)) ht = ndamage = max_dmg; else ht = ndamage = MakeRandomInt(min_dmg, max_dmg); } else - { ht = max_dmg; - } } - - //This can potentially stack with changes to kick damage - ht = ndamage = mod_monk_special_damage(ndamage, skill_type); - + + ht = ndamage = mod_monk_special_damage(ndamage, skill_type); //This can potentially stack with changes to kick damage DoSpecialAttackDamage(other, skill_type, ndamage, min_dmg, ht, reuse); - return(reuse); } @@ -505,45 +433,32 @@ void Mob::TryBackstab(Mob *other, int ReuseTime) { bool bIsBehind = false; bool bCanFrontalBS = false; - //make sure we have a proper weapon if we are a client. if(IsClient()) { const ItemInst *wpn = CastToClient()->GetInv().GetItem(SLOT_PRIMARY); - if(!wpn || (wpn->GetItem()->ItemType != ItemType1HPiercing)){ + if(!wpn || (wpn->GetItem()->ItemType != ItemType1HPiercing)) { Message_StringID(13, BACKSTAB_WEAPON); return; } } - //Live AA - Triple Backstab - int tripleChance = itembonuses.TripleBackstab + spellbonuses.TripleBackstab + aabonuses.TripleBackstab; - + int tripleChance = (itembonuses.TripleBackstab + spellbonuses.TripleBackstab + aabonuses.TripleBackstab); //Live AA - Triple Backstab + if (BehindMob(other, GetX(), GetY())) bIsBehind = true; - else { - //Live AA - Seized Opportunity - int FrontalBSChance = itembonuses.FrontalBackstabChance + spellbonuses.FrontalBackstabChance + aabonuses.FrontalBackstabChance; - + else { + int FrontalBSChance = (itembonuses.FrontalBackstabChance + spellbonuses.FrontalBackstabChance + aabonuses.FrontalBackstabChance); //Live AA - Seized Opportunity + if (FrontalBSChance && (FrontalBSChance > MakeRandomInt(0, 100))) bCanFrontalBS = true; } - if (bIsBehind || bCanFrontalBS){ // Player is behind other OR can do Frontal Backstab - - if (bCanFrontalBS) { + if (bIsBehind || bCanFrontalBS) { // Player is behind other OR can do Frontal Backstab + if (bCanFrontalBS) CastToClient()->Message(0,"Your fierce attack is executed with such grace, your target did not see it coming!"); - } - // solar - chance to assassinate - int chance = 10 + (GetDEX()/10) + (itembonuses.HeroicDEX/10); //18.5% chance at 85 dex 40% chance at 300 dex - if( - level >= 60 && // player is 60 or higher - other->GetLevel() <= 45 && // mob 45 or under - !other->CastToNPC()->IsEngaged() && // not aggro - other->GetHP()<=32000 - && other->IsNPC() - && MakeRandomFloat(0, 99) < chance // chance - ) { + int chance = (10 + (GetDEX() / 10) + (itembonuses.HeroicDEX / 10)); //18.5% chance at 85 dex 40% chance at 300 dex - chance to assassinate + if(level >= 60 && other->GetLevel() <= 45 && !other->CastToNPC()->IsEngaged() && other->GetHP() <= 32000 && other->IsNPC() && MakeRandomFloat(0, 99) < chance) {// player is 60 or higher, mob 45 or under, and not aggro entity_list.MessageClose_StringID(this, false, 200, MT_CritMelee, ASSASSINATES, GetName()); if(IsClient()) CastToClient()->CheckIncreaseSkill(SkillBackstab, other, 10); @@ -552,11 +467,9 @@ void Mob::TryBackstab(Mob *other, int ReuseTime) { else { RogueBackstab(other); if (level > 54) { - float DoubleAttackProbability = (GetSkill(SkillDoubleAttack) + GetLevel()) / 500.0f; // 62.4 max - // Check for double attack with main hand assuming maxed DA Skill (MS) + float DoubleAttackProbability = ((GetSkill(SkillDoubleAttack) + GetLevel()) / 500.0f); // 62.4 max - Check for double attack with main hand assuming maxed DA Skill (MS) - if(MakeRandomFloat(0, 1) < DoubleAttackProbability) // Max 62.4 % chance of DA - { + if(MakeRandomFloat(0, 1) < DoubleAttackProbability) { // Max 62.4 % chance of DA if(other->GetHP() > 0) RogueBackstab(other,false,ReuseTime); @@ -568,17 +481,14 @@ void Mob::TryBackstab(Mob *other, int ReuseTime) { CastToClient()->CheckIncreaseSkill(SkillBackstab, other, 10); } } - //Live AA - Chaotic Backstab - else if(aabonuses.FrontalBackstabMinDmg || itembonuses.FrontalBackstabMinDmg || spellbonuses.FrontalBackstabMinDmg) { - - //we can stab from any angle, we do min damage though. - RogueBackstab(other, true); + else if(aabonuses.FrontalBackstabMinDmg || itembonuses.FrontalBackstabMinDmg || spellbonuses.FrontalBackstabMinDmg) { //Live AA - Chaotic Backstab + RogueBackstab(other, true); //we can stab from any angle, we do min damage though. if (level > 54) { - float DoubleAttackProbability = (GetSkill(SkillDoubleAttack) + GetLevel()) / 500.0f; // 62.4 max + float DoubleAttackProbability = ((GetSkill(SkillDoubleAttack) + GetLevel()) / 500.0f); // 62.4 max if(IsClient()) CastToClient()->CheckIncreaseSkill(SkillBackstab, other, 10); - // Check for double attack with main hand assuming maxed DA Skill (MS) - if(MakeRandomFloat(0, 1) < DoubleAttackProbability) // Max 62.4 % chance of DA + + if(MakeRandomFloat(0, 1) < DoubleAttackProbability) // Max 62.4 % chance of DA - Check for double attack with main hand assuming maxed DA Skill (MS) if(other->GetHP() > 0) RogueBackstab(other,true, ReuseTime); @@ -586,14 +496,11 @@ void Mob::TryBackstab(Mob *other, int 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, 13); - } } -//heko: backstab -void Mob::RogueBackstab(Mob* other, bool min_damage, int ReuseTime) -{ +void Mob::RogueBackstab(Mob* other, bool min_damage, int ReuseTime) { int32 ndamage = 0; int32 max_hit = 0; int32 min_hit = 0; @@ -601,57 +508,45 @@ void Mob::RogueBackstab(Mob* other, bool min_damage, int ReuseTime) int32 primaryweapondamage = 0; int32 backstab_dmg = 0; - if(IsClient()){ + if(IsClient()) { const ItemInst *wpn = nullptr; wpn = CastToClient()->GetInv().GetItem(SLOT_PRIMARY); if(wpn) { primaryweapondamage = GetWeaponDamage(other, wpn); backstab_dmg = wpn->GetItem()->BackstabDmg; - for(int i = 0; i < MAX_AUGMENT_SLOTS; ++i) - { + for(int i = 0; i < MAX_AUGMENT_SLOTS; ++i) { ItemInst *aug = wpn->GetAugment(i); if(aug) - { backstab_dmg += aug->GetItem()->BackstabDmg; - } } } } else{ - primaryweapondamage = (GetLevel()/7)+1; // fallback incase it's a npc without a weapon, 2 dmg at 10, 10 dmg at 65 + primaryweapondamage = ((GetLevel() / 7) + 1); // fallback incase it's a npc without a weapon, 2 dmg at 10, 10 dmg at 65 backstab_dmg = primaryweapondamage; } if(primaryweapondamage > 0){ - if(level > 25){ - max_hit = (((2*backstab_dmg) * GetDamageTable(SkillBackstab) / 100) * 10 * GetSkill(SkillBackstab) / 355) + ((level-25)/3) + 1; + if(level > 25) { + max_hit = ((((2 * backstab_dmg) * GetDamageTable(SkillBackstab) / 100) * 10 * GetSkill(SkillBackstab) / 355) + ((level - 25) / 3) + 1) * ((100 + RuleI(Combat, BackstabBonus)) / 100); hate = 20 * backstab_dmg * GetSkill(SkillBackstab) / 355; } - else{ - max_hit = (((2*backstab_dmg) * GetDamageTable(SkillBackstab) / 100) * 10 * GetSkill(SkillBackstab) / 355) + 1;; + else { + max_hit = ((((2 * backstab_dmg) * GetDamageTable(SkillBackstab) / 100) * 10 * GetSkill(SkillBackstab) / 355) + 1) * ((100 + RuleI(Combat, BackstabBonus)) / 100); hate = 20 * backstab_dmg * GetSkill(SkillBackstab) / 355; } - // determine minimum hits if (level < 51) - { - min_hit = (level*15/10); - } + min_hit = (level * 15 / 10) * ((100 + RuleI(Combat, BackstabBonus)) / 100); else - { - // Trumpcard: Replaced switch statement with formula calc. This will give minhit increases all the way to 65. - min_hit = (level * ( level*5 - 105)) / 100; - } + min_hit = ((level * (level * 5 - 105)) / 100) * ((100 + RuleI(Combat, BackstabBonus)) / 100); - if(!other->CheckHitChance(this, SkillBackstab, 0)) { + if(!other->CheckHitChance(this, SkillBackstab, 0)) ndamage = 0; - } - else{ - if(min_damage){ + else { + if(min_damage) ndamage = min_hit; - } - else - { + else { if (max_hit < min_hit) max_hit = min_hit; @@ -659,49 +554,34 @@ void Mob::RogueBackstab(Mob* other, bool min_damage, int ReuseTime) ndamage = max_hit; else ndamage = MakeRandomInt(min_hit, max_hit); - } } } - else{ + else ndamage = -5; - } ndamage = mod_backstab_damage(ndamage); - DoSpecialAttackDamage(other, SkillBackstab, ndamage, min_hit, hate, ReuseTime); DoAnim(animPiercing); } -// solar - assassinate -void Mob::RogueAssassinate(Mob* other) -{ - //can you dodge, parry, etc.. an assassinate?? - //if so, use DoSpecialAttackDamage(other, BACKSTAB, 32000); instead - if(GetWeaponDamage(other, IsClient()?CastToClient()->GetInv().GetItem(SLOT_PRIMARY):(const ItemInst*)nullptr) > 0){ +void Mob::RogueAssassinate(Mob* other) { //assassinate + if(GetWeaponDamage(other, IsClient() ? CastToClient()->GetInv().GetItem(SLOT_PRIMARY) : (const ItemInst*)nullptr) > 0) other->Damage(this, 32000, SPELL_UNKNOWN, SkillBackstab); - }else{ + else other->Damage(this, -5, SPELL_UNKNOWN, SkillBackstab); - } - DoAnim(animPiercing); //piercing animation + DoAnim(animPiercing); //piercing animation } void Client::RangedAttack(Mob* other, bool CanDoubleAttack) { - //conditions to use an attack checked before we are called - - //make sure the attack and ranged timers are up - //if the ranged timer is disabled, then they have no ranged weapon and shouldent be attacking anyhow - if(!CanDoubleAttack && ((attack_timer.Enabled() && !attack_timer.Check(false)) || (ranged_timer.Enabled() && !ranged_timer.Check()))) { - mlog(COMBAT__RANGED, "Throwing attack canceled. Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime()); - // The server and client timers are not exact matches currently, so this would spam too often if enabled - //Message(0, "Error: Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime()); + if(!CanDoubleAttack && ((attack_timer.Enabled() && !attack_timer.Check(false)) || (ranged_timer.Enabled() && !ranged_timer.Check()))) { //conditions to use an attack checked before we are called - make sure the attack and ranged timers are up - if the ranged timer is disabled, then they have no ranged weapon and shouldent be attacking anyhow + mlog(COMBAT__RANGED, "Throwing attack canceled. Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime()); //Message(0, "Error: Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime()); - The server and client timers are not exact matches currently, so this would spam too often if enabled return; } const ItemInst* RangeWeapon = m_inv[SLOT_RANGE]; - - //locate ammo - int ammo_slot = SLOT_AMMO; - const ItemInst* Ammo = m_inv[SLOT_AMMO]; + + int ammo_slot = SLOT_AMMO; //locate ammo + const ItemInst* Ammo = m_inv[SLOT_AMMO]; //locate ammo if (!RangeWeapon || !RangeWeapon->IsType(ItemClassCommon)) { mlog(COMBAT__RANGED, "Ranged attack canceled. Missing or invalid ranged weapon (%d) in slot %d", GetItemIDAt(SLOT_RANGE), SLOT_RANGE); @@ -729,10 +609,8 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) { } mlog(COMBAT__RANGED, "Shooting %s with bow %s (%d) and arrow %s (%d)", GetTarget()->GetName(), RangeItem->Name, RangeItem->ID, AmmoItem->Name, AmmoItem->ID); - - //look for ammo in inventory if we only have 1 left... - if(Ammo->GetCharges() == 1) { - //first look for quivers + + if(Ammo->GetCharges() == 1) { //look for ammo in inventory if we only have 1 left - first look for quivers int r; bool found = false; for(r = SLOT_PERSONAL_BEGIN; r <= SLOT_PERSONAL_END; r++) { @@ -741,17 +619,14 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) { continue; const Item_Struct* bagitem = pi->GetItem(); if(!bagitem || bagitem->BagType != BagTypeQuiver) - continue; - - //we found a quiver, look for the ammo in it + continue; //we found a quiver, look for the ammo in it + int i; for (i = 0; i < bagitem->BagSlots; i++) { ItemInst* baginst = pi->GetItem(i); if(!baginst) - continue; //empty - if(baginst->GetID() == Ammo->GetID()) { - //we found it... use this stack - //the item wont change, but the instance does + continue; //empty + if(baginst->GetID() == Ammo->GetID()) { //we found it... use this stack - the item wont change, but the instance does Ammo = baginst; ammo_slot = m_inv.CalcSlotId(r, i); found = true; @@ -763,9 +638,7 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) { break; } - if(!found) { - //if we dont find a quiver, look through our inventory again - //not caring if the thing is a quiver. + if(!found) { //if we dont find a quiver, look through our inventory again - not caring if the thing is a quiver. int32 aslot = m_inv.HasItem(AmmoItem->ID, 1, invWherePersonal); if(aslot != SLOT_INVALID) { ammo_slot = aslot; @@ -775,48 +648,34 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) { } } - float range = RangeItem->Range + AmmoItem->Range + 5; //Fudge it a little, client will let you hit something at 0 0 0 when you are at 205 0 0 + float range = (RangeItem->Range + AmmoItem->Range + 5); //Fudge it a little, client will let you hit something at 0 0 0 when you are at 205 0 0 mlog(COMBAT__RANGED, "Calculated bow range to be %.1f", range); range *= range; if(DistNoRootNoZ(*GetTarget()) > range) { - mlog(COMBAT__RANGED, "Ranged attack out of range... client should catch this. (%f > %f).\n", DistNoRootNoZ(*GetTarget()), range); - //target is out of range, client does a message + mlog(COMBAT__RANGED, "Ranged attack out of range... client should catch this. (%f > %f).\n", DistNoRootNoZ(*GetTarget()), range); //target is out of range, client does a message return; } - else if(DistNoRootNoZ(*GetTarget()) < (RuleI(Combat, MinRangedAttackDist)*RuleI(Combat, MinRangedAttackDist))){ + else if(DistNoRootNoZ(*GetTarget()) < (RuleI(Combat, MinRangedAttackDist) * RuleI(Combat, MinRangedAttackDist))) return; - } - if(!IsAttackAllowed(GetTarget()) || - IsCasting() || - IsSitting() || - (DivineAura() && !GetGM()) || - IsStunned() || - IsFeared() || - IsMezzed() || - (GetAppearance() == eaDead)){ + if(!IsAttackAllowed(GetTarget()) || IsCasting() || IsSitting() || (DivineAura() && !GetGM()) || IsStunned() || IsFeared() || IsMezzed() || (GetAppearance() == eaDead)) return; - } SendItemAnimation(GetTarget(), AmmoItem, SkillArchery); - DoArcheryAttackDmg(GetTarget(), RangeWeapon, Ammo); - //EndlessQuiver AA base1 = 100% Chance to avoid consumption arrow. - int ChanceAvoidConsume = aabonuses.ConsumeProjectile + itembonuses.ConsumeProjectile + spellbonuses.ConsumeProjectile; - - if (!ChanceAvoidConsume || (ChanceAvoidConsume < 100 && MakeRandomInt(0,99) > ChanceAvoidConsume)){ + int ChanceAvoidConsume = (aabonuses.ConsumeProjectile + itembonuses.ConsumeProjectile + spellbonuses.ConsumeProjectile); //EndlessQuiver AA base1 = 100% Chance to avoid consumption arrow. + if (!ChanceAvoidConsume || (ChanceAvoidConsume < 100 && MakeRandomInt(0,99) > ChanceAvoidConsume)) { DeleteItemInInventory(ammo_slot, 1, true); mlog(COMBAT__RANGED, "Consumed one arrow from slot %d", ammo_slot); - } else { - mlog(COMBAT__RANGED, "Endless Quiver prevented ammo consumption."); } + else + mlog(COMBAT__RANGED, "Endless Quiver prevented ammo consumption."); CheckIncreaseSkill(SkillArchery, GetTarget(), -15); - - //break invis when you attack - if(invisible) { + + if(invisible) { //break invis when you attack mlog(COMBAT__ATTACKS, "Removing invisibility due to melee attack."); BuffFadeByEffect(SE_Invisibility); BuffFadeByEffect(SE_Invisibility2); @@ -833,11 +692,10 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) { BuffFadeByEffect(SE_InvisVsAnimals); invisible_animals = false; } - if (spellbonuses.NegateIfCombat) BuffFadeByEffect(SE_NegateIfCombat); - if(hidden || improved_hidden){ + if(hidden || improved_hidden) { hidden = false; improved_hidden = false; EQApplicationPacket* outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct)); @@ -850,68 +708,55 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) { } } -void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const ItemInst* Ammo, uint16 weapon_damage, int16 chance_mod, int16 focus) -{ +void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const ItemInst* Ammo, uint16 weapon_damage, int16 chance_mod, int16 focus) { if (!CanDoSpecialAttack(other)) return; if (!other->CheckHitChance(this, SkillArchery, 13,chance_mod)) { mlog(COMBAT__RANGED, "Ranged attack missed %s.", other->GetName()); other->Damage(this, 0, SPELL_UNKNOWN, SkillArchery); - } else { + } + else { mlog(COMBAT__RANGED, "Ranged attack hit %s.", other->GetName()); - if(!TryHeadShot(other, SkillArchery)) - { + if(!TryHeadShot(other, SkillArchery)) { int32 TotalDmg = 0; int16 WDmg = 0; int16 ADmg = 0; - if (!weapon_damage){ + if (!weapon_damage) { WDmg = GetWeaponDamage(other, RangeWeapon); ADmg = GetWeaponDamage(other, Ammo); } else WDmg = weapon_damage; - if((WDmg > 0) || (ADmg > 0)) - { + if((WDmg > 0) || (ADmg > 0)) { if(WDmg < 0) WDmg = 0; if(ADmg < 0) ADmg = 0; - uint32 MaxDmg = (RuleR(Combat, ArcheryBaseDamageBonus)*(WDmg+ADmg)*GetDamageTable(SkillArchery)) / 100; - int32 hate = ((WDmg+ADmg)); + uint32 MaxDmg = ((RuleR(Combat, ArcheryBaseDamageBonus) * (WDmg + ADmg) * GetDamageTable(SkillArchery)) / 100); + int32 hate = ((WDmg + ADmg)); - uint16 bonusArcheryDamageModifier = aabonuses.ArcheryDamageModifier + itembonuses.ArcheryDamageModifier + spellbonuses.ArcheryDamageModifier; + uint16 bonusArcheryDamageModifier = (aabonuses.ArcheryDamageModifier + itembonuses.ArcheryDamageModifier + spellbonuses.ArcheryDamageModifier); - MaxDmg += MaxDmg*bonusArcheryDamageModifier / 100; + MaxDmg += (MaxDmg * bonusArcheryDamageModifier / 100); mlog(COMBAT__RANGED, "Bow DMG %d, Arrow DMG %d, Max Damage %d.", WDmg, ADmg, MaxDmg); bool dobonus = false; - if(GetClass() == RANGER && GetLevel() > 50) - { + if(GetClass() == RANGER && GetLevel() > 50) { int bonuschance = RuleI(Combat, ArcheryBonusChance); - bonuschance = mod_archery_bonus_chance(bonuschance, RangeWeapon); - - if( !RuleB(Combat, UseArcheryBonusRoll) || (MakeRandomInt(1, 100) < bonuschance) ) - { - if(RuleB(Combat, ArcheryBonusRequiresStationary)) - { + if(!RuleB(Combat, UseArcheryBonusRoll) || (MakeRandomInt(1, 100) < bonuschance)) { + if(RuleB(Combat, ArcheryBonusRequiresStationary)) { if(other->IsNPC() && !other->IsMoving() && !other->IsRooted()) - { dobonus = true; - } } else - { dobonus = true; - } } - - if(dobonus) - { + if(dobonus) { MaxDmg *= (float)2; hate *= (float)2; MaxDmg = mod_archery_bonus_damage(MaxDmg, RangeWeapon); @@ -930,22 +775,20 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Item TotalDmg = MakeRandomInt(1, MaxDmg); int minDmg = 1; - if(GetLevel() > 25){ - //twice, for ammo and weapon - TotalDmg += (2*((GetLevel()-25)/3)); - minDmg += (2*((GetLevel()-25)/3)); - minDmg += minDmg * GetMeleeMinDamageMod_SE(SkillArchery) / 100; - hate += (2*((GetLevel()-25)/3)); + if(GetLevel() > 25){ //twice, for ammo and weapon + TotalDmg += (2 * ((GetLevel() - 25) / 3)); + minDmg += (2 * ((GetLevel() - 25) / 3)); + minDmg += (minDmg * GetMeleeMinDamageMod_SE(SkillArchery) / 100); + hate += (2 * ((GetLevel() - 25) / 3)); } other->AvoidDamage(this, TotalDmg, false); other->MeleeMitigation(this, TotalDmg, minDmg); - if(TotalDmg > 0) - { - TotalDmg += TotalDmg*focus/100; + if(TotalDmg > 0) { + TotalDmg += (TotalDmg * focus / 100); ApplyMeleeDamageBonus(SkillArchery, TotalDmg); TotalDmg += other->GetFcDamageAmtIncoming(this, 0, true, SkillArchery); - TotalDmg += (itembonuses.HeroicDEX / 10) + (TotalDmg * other->GetSkillDmgTaken(SkillArchery) / 100) + GetSkillDmgAmt(SkillArchery); + TotalDmg += ((itembonuses.HeroicDEX / 10) + (TotalDmg * other->GetSkillDmgTaken(SkillArchery) / 100) + GetSkillDmgAmt(SkillArchery)); TotalDmg = mod_archery_damage(TotalDmg, dobonus, RangeWeapon); @@ -960,89 +803,60 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Item other->Damage(this, TotalDmg, SPELL_UNKNOWN, SkillArchery); } } - - //try proc on hits and misses - if((RangeWeapon != nullptr) && GetTarget() && other && (other->GetHP() > -10)) - { + + if((RangeWeapon != nullptr) && GetTarget() && other && (other->GetHP() > -10)) //try proc on hits and misses TryWeaponProc(RangeWeapon, other, 11); - } - - //Arrow procs because why not? - if((Ammo != NULL) && GetTarget() && other && (other->GetHP() > -10)) - { + + if((Ammo != NULL) && GetTarget() && other && (other->GetHP() > -10)) //Arrow procs because why not? TryWeaponProc(Ammo, other, 11); - } } -void NPC::RangedAttack(Mob* other) -{ - //make sure the attack and ranged timers are up - //if the ranged timer is disabled, then they have no ranged weapon and shouldent be attacking anyhow - if((attack_timer.Enabled() && !attack_timer.Check(false)) || (ranged_timer.Enabled() && !ranged_timer.Check())) - { - mlog(COMBAT__RANGED, "Archery canceled. Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime()); +void NPC::RangedAttack(Mob* other) { + if((attack_timer.Enabled() && !attack_timer.Check(false)) || (ranged_timer.Enabled() && !ranged_timer.Check())) { //make sure the attack and ranged timers are up if the ranged timer is disabled, then they have no ranged weapon and shouldent be attacking anyhow + mlog(COMBAT__RANGED, "Archery cancelled. Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime()); return; } - - //if we have SPECATK_RANGED_ATK set then we range attack without weapon or ammo + const Item_Struct* weapon = nullptr; const Item_Struct* ammo = nullptr; - if(!GetSpecialAbility(SPECATK_RANGED_ATK)) - { - //find our bow and ammo return if we can't find them... + if(!GetSpecialAbility(SPECATK_RANGED_ATK)) //if we have SPECATK_RANGED_ATK set then we range attack without weapon or ammo find our bow and ammo return if we can't find them... return; - } float range = 250; // needs to be longer than 200(most spells) mlog(COMBAT__RANGED, "Calculated bow range to be %.1f", range); range *= range; if(DistNoRootNoZ(*GetTarget()) > range) { - mlog(COMBAT__RANGED, "Ranged attack out of range...%.2f vs %.2f", DistNoRootNoZ(*GetTarget()), range); - //target is out of range, client does a message + mlog(COMBAT__RANGED, "Ranged attack out of range...%.2f vs %.2f", DistNoRootNoZ(*GetTarget()), range); //target is out of range, client does a message return; } - else if(DistNoRootNoZ(*GetTarget()) < (RuleI(Combat, MinRangedAttackDist)*RuleI(Combat, MinRangedAttackDist))){ + else if(DistNoRootNoZ(*GetTarget()) < (RuleI(Combat, MinRangedAttackDist) * RuleI(Combat, MinRangedAttackDist))) return; - } - if(!IsAttackAllowed(GetTarget()) || - IsCasting() || - DivineAura() || - IsStunned() || - IsFeared() || - IsMezzed() || - (GetAppearance() == eaDead)){ + if(!IsAttackAllowed(GetTarget()) || IsCasting() || DivineAura() || IsStunned() || IsFeared() || IsMezzed() || (GetAppearance() == eaDead)) return; - } if(!ammo) - { ammo = database.GetItem(8005); - } if(ammo) SendItemAnimation(GetTarget(), ammo, SkillArchery); - // Face the Target - FaceTarget(GetTarget()); + FaceTarget(GetTarget()); //Face the Target - // Hit? - if (!GetTarget()->CheckHitChance(this, SkillArchery, 13)) - { + + if (!GetTarget()->CheckHitChance(this, SkillArchery, 13)) { //Hit? mlog(COMBAT__RANGED, "Ranged attack missed %s.", GetTarget()->GetName()); GetTarget()->Damage(this, 0, SPELL_UNKNOWN, SkillArchery); } - else - { + else { int16 WDmg = GetWeaponDamage(GetTarget(), weapon); int16 ADmg = GetWeaponDamage(GetTarget(), ammo); - if(WDmg > 0 || ADmg > 0) - { + if(WDmg > 0 || ADmg > 0) { mlog(COMBAT__RANGED, "Ranged attack hit %s.", GetTarget()->GetName()); int32 TotalDmg = 0; - int32 MaxDmg = max_dmg * RuleR(Combat, ArcheryNPCMultiplier); // should add a field to npc_types - int32 MinDmg = min_dmg * RuleR(Combat, ArcheryNPCMultiplier); + int32 MaxDmg = (max_dmg * RuleR(Combat, ArcheryNPCMultiplier)); // should add a field to npc_types + int32 MinDmg = (min_dmg * RuleR(Combat, ArcheryNPCMultiplier)); if(RuleB(Combat, UseIntervalAC)) TotalDmg = MaxDmg; @@ -1059,13 +873,10 @@ void NPC::RangedAttack(Mob* other) CheckNumHitsRemaining(5); } else - { GetTarget()->Damage(this, -5, SPELL_UNKNOWN, SkillArchery); - } } - //break invis when you attack - if(invisible) { + if(invisible) { //break invis when you attack mlog(COMBAT__ATTACKS, "Removing invisibility due to melee attack."); BuffFadeByEffect(SE_Invisibility); BuffFadeByEffect(SE_Invisibility2); @@ -1099,8 +910,7 @@ void NPC::RangedAttack(Mob* other) } } -uint16 Mob::GetThrownDamage(int16 wDmg, int32& TotalDmg, int& minDmg) -{ +uint32 Mob::GetThrownDamage(int16 wDmg, int32& TotalDmg, int& minDmg) { uint16 MaxDmg = (((2 * wDmg) * GetDamageTable(SkillThrowing)) / 100); @@ -1113,11 +923,10 @@ uint16 Mob::GetThrownDamage(int16 wDmg, int32& TotalDmg, int& minDmg) TotalDmg = MakeRandomInt(1, MaxDmg); minDmg = 1; - if(GetLevel() > 25) - { - TotalDmg += ((GetLevel()-25)/3); - minDmg += ((GetLevel()-25)/3); - minDmg += minDmg * GetMeleeMinDamageMod_SE(SkillThrowing) / 100; + if(GetLevel() > 25) { + TotalDmg += ((GetLevel() - 25) / 3); + minDmg += ((GetLevel() - 25) / 3); + minDmg += (minDmg * GetMeleeMinDamageMod_SE(SkillThrowing) / 100); } if(MaxDmg < minDmg) @@ -1128,15 +937,9 @@ uint16 Mob::GetThrownDamage(int16 wDmg, int32& TotalDmg, int& minDmg) return MaxDmg; } -void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51 - //conditions to use an attack checked before we are called - - //make sure the attack and ranged timers are up - //if the ranged timer is disabled, then they have no ranged weapon and shouldent be attacking anyhow - if((!CanDoubleAttack && (attack_timer.Enabled() && !attack_timer.Check(false)) || (ranged_timer.Enabled() && !ranged_timer.Check()))) { - mlog(COMBAT__RANGED, "Throwing attack canceled. Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime()); - // The server and client timers are not exact matches currently, so this would spam too often if enabled - //Message(0, "Error: Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime()); +void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { + if((!CanDoubleAttack && (attack_timer.Enabled() && !attack_timer.Check(false)) || (ranged_timer.Enabled() && !ranged_timer.Check()))) { //old was 51 - conditions to use an attack checked before we are called - make sure the attack and ranged timers are up - if the ranged timer is disabled, then they have no ranged weapon and shouldent be attacking anyhow + mlog(COMBAT__RANGED, "Throwing attack canceled. Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime()); //Message(0, "Error: Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime()); - The server and client timers are not exact matches currently, so this would spam too often if enabled return; } @@ -1158,19 +961,16 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51 mlog(COMBAT__RANGED, "Throwing %s (%d) at %s", item->Name, item->ID, GetTarget()->GetName()); - if(RangeWeapon->GetCharges() == 1) { - //first check ammo + if(RangeWeapon->GetCharges() == 1) { //first check ammo const ItemInst* AmmoItem = m_inv[SLOT_AMMO]; - if(AmmoItem != nullptr && AmmoItem->GetID() == RangeWeapon->GetID()) { - //more in the ammo slot, use it + if(AmmoItem != nullptr && AmmoItem->GetID() == RangeWeapon->GetID()) { //more in the ammo slot, use it RangeWeapon = AmmoItem; ammo_slot = SLOT_AMMO; mlog(COMBAT__RANGED, "Using ammo from ammo slot, stack at slot %d. %d in stack.", ammo_slot, RangeWeapon->GetCharges()); - } else { - //look through our inventory for more + } + else { //look through our inventory for more int32 aslot = m_inv.HasItem(item->ID, 1, invWherePersonal); - if(aslot != SLOT_INVALID) { - //the item wont change, but the instance does, not that it matters + if(aslot != SLOT_INVALID) { //the item wont change, but the instance does, not that it matters ammo_slot = aslot; RangeWeapon = m_inv[aslot]; mlog(COMBAT__RANGED, "Using ammo from inventory slot, stack at slot %d. %d in stack.", ammo_slot, RangeWeapon->GetCharges()); @@ -1178,39 +978,26 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51 } } - int range = item->Range +50/*Fudge it a little, client will let you hit something at 0 0 0 when you are at 205 0 0*/; + int range = (item->Range + 50); //Fudge it a little, client will let you hit something at 0 0 0 when you are at 205 0 0 mlog(COMBAT__RANGED, "Calculated bow range to be %.1f", range); range *= range; if(DistNoRootNoZ(*GetTarget()) > range) { - mlog(COMBAT__RANGED, "Throwing attack out of range... client should catch this. (%f > %f).\n", DistNoRootNoZ(*GetTarget()), range); - //target is out of range, client does a message + mlog(COMBAT__RANGED, "Throwing attack out of range... client should catch this. (%f > %f).\n", DistNoRootNoZ(*GetTarget()), range); //target is out of range, client does a message return; } else if(DistNoRootNoZ(*GetTarget()) < (RuleI(Combat, MinRangedAttackDist)*RuleI(Combat, MinRangedAttackDist))){ return; } - if(!IsAttackAllowed(GetTarget()) || - IsCasting() || - IsSitting() || - (DivineAura() && !GetGM()) || - IsStunned() || - IsFeared() || - IsMezzed() || - (GetAppearance() == eaDead)){ + if(!IsAttackAllowed(GetTarget()) || IsCasting() || IsSitting() || (DivineAura() && !GetGM()) || IsStunned() || IsFeared() || IsMezzed() || (GetAppearance() == eaDead)) return; - } - //send item animation, also does the throw animation - SendItemAnimation(GetTarget(), item, SkillThrowing); + SendItemAnimation(GetTarget(), item, SkillThrowing); //send item animation, also does the throw animation DoThrowingAttackDmg(GetTarget(), RangeWeapon, item); - - //consume ammo - DeleteItemInInventory(ammo_slot, 1, true); + DeleteItemInInventory(ammo_slot, 1, true); //consume ammo CheckIncreaseSkill(SkillThrowing, GetTarget()); - - //break invis when you attack - if(invisible) { + + if(invisible) { //break invis when you attack mlog(COMBAT__ATTACKS, "Removing invisibility due to melee attack."); BuffFadeByEffect(SE_Invisibility); BuffFadeByEffect(SE_Invisibility2); @@ -1244,15 +1031,15 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51 } } -void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Item_Struct* item, uint16 weapon_damage, int16 chance_mod,int16 focus) -{ +void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Item_Struct* item, uint16 weapon_damage, int16 chance_mod, int16 focus) { if (!CanDoSpecialAttack(other)) return; - if (!other->CheckHitChance(this, SkillThrowing, 13, chance_mod)){ + if (!other->CheckHitChance(this, SkillThrowing, 13, chance_mod)) { mlog(COMBAT__RANGED, "Ranged attack missed %s.", other->GetName()); other->Damage(this, 0, SPELL_UNKNOWN, SkillThrowing); - } else { + } + else { mlog(COMBAT__RANGED, "Throwing attack hit %s.", other->GetName()); int16 WDmg = 0; @@ -1264,27 +1051,24 @@ void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite int32 TotalDmg = 0; - if(WDmg > 0) - { + if(WDmg > 0) { int minDmg = 1; - uint16 MaxDmg = GetThrownDamage(WDmg, TotalDmg, minDmg); + uint32 MaxDmg = GetThrownDamage(WDmg, TotalDmg, minDmg); mlog(COMBAT__RANGED, "Item DMG %d. Max Damage %d. Hit for damage %d", WDmg, MaxDmg, TotalDmg); other->AvoidDamage(this, TotalDmg, false); //CanRiposte=false - Can not riposte throw attacks. other->MeleeMitigation(this, TotalDmg, minDmg); - if(TotalDmg > 0) - { - TotalDmg += TotalDmg*focus/100; + if(TotalDmg > 0) { + TotalDmg += (TotalDmg * focus / 100); ApplyMeleeDamageBonus(SkillThrowing, TotalDmg); TotalDmg += other->GetFcDamageAmtIncoming(this, 0, true, SkillThrowing); - TotalDmg += (itembonuses.HeroicDEX / 10) + (TotalDmg * other->GetSkillDmgTaken(SkillThrowing) / 100) + GetSkillDmgAmt(SkillThrowing); + TotalDmg += ((itembonuses.HeroicDEX / 10) + (TotalDmg * other->GetSkillDmgTaken(SkillThrowing) / 100) + GetSkillDmgAmt(SkillThrowing)); TryCriticalHit(other, SkillThrowing, TotalDmg); - int32 hate = (2*WDmg); + int32 hate = (2 * WDmg); other->AddToHateList(this, hate, 0, false); CheckNumHitsRemaining(5); } } - else TotalDmg = -5; @@ -1305,36 +1089,16 @@ void Mob::SendItemAnimation(Mob *to, const Item_Struct *item, SkillUseTypes skil as->source_id = GetID(); as->target_id = to->GetID(); as->item_id = item->ID; - as->item_type = item->ItemType; as->skill = (uint8)skillInUse; strn0cpy(as->model_name, item->IDFile, 16); - - /* - The angular field affects how the object flies towards the target. - A low angular (10) makes it circle the target widely, where a high - angular (20000) makes it go straight at them. - - The tilt field causes the object to be tilted flying through the air - and also seems to have an effect on how it behaves when circling the - target based on the angular field. - - Arc causes the object to form an arc in motion. A value too high will - */ - as->velocity = 4.0; - - //these angle and tilt used together seem to make the arrow/knife throw as straight as I can make it - - as->launch_angle = CalculateHeadingToTarget(to->GetX(), to->GetY()) * 2; + as->velocity = 4.0;//The angular field affects how the object flies towards the target. A low angular (10) makes it circle the target widely, where a high angular (20000) makes it go straight at them. The tilt field causes the object to be tilted flying through the air and also seems to have an effect on how it behaves when circling the target based on the angular field. Arc causes the object to form an arc in motion. + as->launch_angle = (CalculateHeadingToTarget(to->GetX(), to->GetY()) * 2); //these angle and tilt used together seem to make the arrow/knife throw as straight as I can make it as->tilt = 125; as->arc = 50; - - - //fill in some unknowns, we dont know their meaning yet - //neither of these seem to change the behavior any - as->unknown088 = 125; + as->unknown088 = 125; //fill in some unknowns, we dont know their meaning yet neither of these seem to change the behavior any as->unknown092 = 16; entity_list.QueueCloseClients(this, outapp); @@ -1346,42 +1110,32 @@ void Mob::ProjectileAnimation(Mob* to, int item_id, bool IsArrow, float speed, f const Item_Struct* item = nullptr; uint8 item_type = 0; - if(!item_id) { + if(!item_id) item = database.GetItem(8005); // Arrow will be default - } - else { + else item = database.GetItem(item_id); // Use the item input into the command - } - - if(!item) { + + if(!item) return; - } - if(IsArrow) { + if(IsArrow) item_type = 27; - } - if(!item_type) { + if(!item_type) item_type = item->ItemType; - } - if(!speed) { + if(!speed) speed = 4.0; - } - if(!angle) { - angle = CalculateHeadingToTarget(to->GetX(), to->GetY()) * 2; - } - if(!tilt) { + if(!angle) + angle = (CalculateHeadingToTarget(to->GetX(), to->GetY()) * 2); + if(!tilt) tilt = 125; - } - if(!arc) { + if(!arc) arc = 50; - } const char *item_IDFile = item->IDFile; if (IDFile && (strncmp(IDFile, "IT", 2) == 0)) item_IDFile = IDFile; - // See SendItemAnimation() for some notes on this struct - EQApplicationPacket *outapp = new EQApplicationPacket(OP_SomeItemPacketMaybe, sizeof(Arrow_Struct)); + EQApplicationPacket *outapp = new EQApplicationPacket(OP_SomeItemPacketMaybe, sizeof(Arrow_Struct)); // See SendItemAnimation() for some notes on this struct Arrow_Struct *as = (Arrow_Struct *) outapp->pBuffer; as->type = 1; as->src_x = GetX(); @@ -1413,34 +1167,33 @@ void NPC::DoClassAttacks(Mob *target) { bool ca_time = classattack_timer.Check(false); bool ka_time = knightattack_timer.Check(false); - //only check attack allowed if we are going to do something - if((taunt_time || ca_time || ka_time) && !IsAttackAllowed(target)) + if((taunt_time || ca_time || ka_time) && !IsAttackAllowed(target)) //only check attack allowed if we are going to do something return; if(ka_time){ - int knightreuse = 1000; //lets give it a small cooldown actually. + int knightreuse = 1000; switch(GetClass()){ - case SHADOWKNIGHT: case SHADOWKNIGHTGM:{ + case SHADOWKNIGHT: + case SHADOWKNIGHTGM: { CastSpell(SPELL_NPC_HARM_TOUCH, target->GetID()); - knightreuse = HarmTouchReuseTime * 1000; + knightreuse = (HarmTouchReuseTime * 1000); break; } - case PALADIN: case PALADINGM:{ + case PALADIN: + case PALADINGM: { if(GetHPRatio() < 20) { CastSpell(SPELL_LAY_ON_HANDS, GetID()); - knightreuse = LayOnHandsReuseTime * 1000; - } else { - knightreuse = 2000; //Check again in two seconds. + knightreuse = (LayOnHandsReuseTime * 1000); } + else + knightreuse = 2000; //Check again in two seconds. break; } } knightattack_timer.Start(knightreuse); } - //general stuff, for all classes.... - //only gets used when their primary ability get used too - if (taunting && HasOwner() && target->IsNPC() && target->GetBodyType() != BT_Undead && taunt_time) { + if (taunting && HasOwner() && target->IsNPC() && target->GetBodyType() != BT_Undead && taunt_time) { //general stuff, for all classes.... only gets used when their primary ability get used too this->GetOwner()->Message_StringID(MT_PetResponse, PET_TAUNTING); Taunt(target->CastToNPC(), false); } @@ -1450,76 +1203,73 @@ void NPC::DoClassAttacks(Mob *target) { float HasteModifier = 0; if(GetHaste() > 0) - HasteModifier = 10000 / (100 + GetHaste()); + HasteModifier = (10000 / (100 + GetHaste())); else if(GetHaste() < 0) HasteModifier = (100 - GetHaste()); else HasteModifier = 100; int level = GetLevel(); - int reuse = TauntReuseTime * 1000; //make this very long since if they dont use it once, they prolly never will + int reuse = (TauntReuseTime * 1000); //make this very long since if they dont use it once, they prolly never will bool did_attack = false; - //class specific stuff... - switch(GetClass()) { - case ROGUE: case ROGUEGM: + switch(GetClass()) { //class specific stuff... + case ROGUE: + case ROGUEGM: { if(level >= 10) { - reuse = BackstabReuseTime * 1000; + reuse = (BackstabReuseTime * 1000); TryBackstab(target, reuse); did_attack = true; } break; - case MONK: case MONKGM: { + } + case MONK: + case MONKGM: { uint8 satype = SkillKick; - if(level > 29) { + if(level > 29) satype = SkillFlyingKick; - } else if(level > 24) { + else if(level > 24) satype = SkillDragonPunch; - } else if(level > 19) { + else if(level > 19) satype = SkillEagleStrike; - } else if(level > 9) { + else if(level > 9) satype = SkillTigerClaw; - } else if(level > 4) { + else if(level > 4) satype = SkillRoundKick; - } reuse = MonkSpecialAttack(target, satype); reuse *= 1000; did_attack = true; break; } - case WARRIOR: case WARRIORGM:{ - if(level >= RuleI(Combat, NPCBashKickLevel)){ - if(MakeRandomInt(0, 100) > 25) //tested on live, warrior mobs both kick and bash, kick about 75% of the time, casting doesn't seem to make a difference. - { + case WARRIOR: + case WARRIORGM: { + if(level >= RuleI(Combat, NPCBashKickLevel)) { + if(MakeRandomInt(0, 100) > 25) { //tested on live, warrior mobs both kick and bash, kick about 75% of the time, casting doesn't seem to make a difference. DoAnim(animKick); int32 dmg = 0; - if(GetWeaponDamage(target, (const Item_Struct*)nullptr) <= 0){ + if(GetWeaponDamage(target, (const Item_Struct*)nullptr) <= 0) dmg = -5; - } - else{ + else { if(target->CheckHitChance(this, SkillKick, 0)) { if(RuleB(Combat, UseIntervalAC)) dmg = GetKickDamage(); else dmg = MakeRandomInt(1, GetKickDamage()); - } } - reuse = KickReuseTime * 1000; + reuse = (KickReuseTime * 1000); DoSpecialAttackDamage(target, SkillKick, dmg, 1, -1, reuse); did_attack = true; } - else - { + else { DoAnim(animTailRake); int32 dmg = 0; - if(GetWeaponDamage(target, (const Item_Struct*)nullptr) <= 0){ + if(GetWeaponDamage(target, (const Item_Struct*)nullptr) <= 0) dmg = -5; - } - else{ + else { if(target->CheckHitChance(this, SkillBash, 0)) { if(RuleB(Combat, UseIntervalAC)) dmg = GetBashDamage(); @@ -1528,35 +1278,33 @@ void NPC::DoClassAttacks(Mob *target) { } } - reuse = BashReuseTime * 1000; + reuse = (BashReuseTime * 1000); DoSpecialAttackDamage(target, SkillBash, dmg, 1, -1, reuse); did_attack = true; } } break; } - case BERSERKER: case BERSERKERGM: - { + case BERSERKER: + case BERSERKERGM: { int AtkRounds = 3; - int32 max_dmg = 26 + ((GetLevel()-6) * 2); + int32 max_dmg = (26 + ((GetLevel() - 6) * 2)); int32 min_dmg = 0; DoAnim(anim2HSlashing); if (GetLevel() < 51) min_dmg = 1; else - min_dmg = GetLevel()*8/10; + min_dmg = (GetLevel() * 8 / 10); if (min_dmg > max_dmg) max_dmg = min_dmg; - reuse = FrenzyReuseTime * 1000; + reuse = (FrenzyReuseTime * 1000); while(AtkRounds > 0) { - - if (GetTarget() && (AtkRounds == 1 || MakeRandomInt(0,100) < 75)){ + if (GetTarget() && (AtkRounds == 1 || MakeRandomInt(0,100) < 75)) DoSpecialAttackDamage(GetTarget(), SkillFrenzy, max_dmg, min_dmg, -1 , reuse, true); - } AtkRounds--; } @@ -1564,17 +1312,17 @@ void NPC::DoClassAttacks(Mob *target) { did_attack = true; break; } - case RANGER: case RANGERGM: - case BEASTLORD: case BEASTLORDGM: { - //kick - if(level >= RuleI(Combat, NPCBashKickLevel)){ + case RANGER: + case RANGERGM: + case BEASTLORD: + case BEASTLORDGM: { + if(level >= RuleI(Combat, NPCBashKickLevel)) { //kick DoAnim(animKick); int32 dmg = 0; - if(GetWeaponDamage(target, (const Item_Struct*)nullptr) <= 0){ + if(GetWeaponDamage(target, (const Item_Struct*)nullptr) <= 0) dmg = -5; - } - else{ + else { if(target->CheckHitChance(this, SkillKick, 0)) { if(RuleB(Combat, UseIntervalAC)) dmg = GetKickDamage(); @@ -1583,24 +1331,25 @@ void NPC::DoClassAttacks(Mob *target) { } } - reuse = KickReuseTime * 1000; + reuse = (KickReuseTime * 1000); DoSpecialAttackDamage(target, SkillKick, dmg, 1, -1, reuse); did_attack = true; } break; } - case CLERIC: case CLERICGM: //clerics can bash too. - case SHADOWKNIGHT: case SHADOWKNIGHTGM: - case PALADIN: case PALADINGM: - { - if(level >= RuleI(Combat, NPCBashKickLevel)){ + case CLERIC: + case CLERICGM: + case SHADOWKNIGHT: + case SHADOWKNIGHTGM: + case PALADIN: + case PALADINGM: { //clerics can bash too. + if(level >= RuleI(Combat, NPCBashKickLevel)) { DoAnim(animTailRake); int32 dmg = 0; - if(GetWeaponDamage(target, (const Item_Struct*)nullptr) <= 0){ + if(GetWeaponDamage(target, (const Item_Struct*)nullptr) <= 0) dmg = -5; - } - else{ + else { if(target->CheckHitChance(this, SkillBash, 0)) { if(RuleB(Combat, UseIntervalAC)) dmg = GetBashDamage(); @@ -1609,7 +1358,7 @@ void NPC::DoClassAttacks(Mob *target) { } } - reuse = BashReuseTime * 1000; + reuse = (BashReuseTime * 1000); DoSpecialAttackDamage(target, SkillBash, dmg, 1, -1, reuse); did_attack = true; } @@ -1617,7 +1366,7 @@ void NPC::DoClassAttacks(Mob *target) { } } - classattack_timer.Start(reuse*HasteModifier/100); + classattack_timer.Start(reuse * HasteModifier / 100); } void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte) @@ -1630,76 +1379,61 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte) if(!IsAttackAllowed(ca_target)) return; - - //check range for all these abilities, they are all close combat stuff - if(!CombatRange(ca_target)) - { + + if(!CombatRange(ca_target)) //check range for all these abilities, they are all close combat stuff return; - } - if(!IsRiposte && (!p_timers.Expired(&database, pTimerCombatAbility, false))) { + if(!IsRiposte && (!p_timers.Expired(&database, pTimerCombatAbility, false))) return; - } - + int ReuseTime = 0; int ClientHaste = GetHaste(); int HasteMod = 0; - if(ClientHaste >= 0){ - HasteMod = (10000/(100+ClientHaste)); //+100% haste = 2x as many attacks - } - else{ - HasteMod = (100-ClientHaste); //-100% haste = 1/2 as many attacks - } + if(ClientHaste >= 0) + HasteMod = (10000 / (100 + ClientHaste)); //+100% haste = 2x as many attacks + else + HasteMod = (100 - ClientHaste); //-100% haste = 1/2 as many attacks + int32 dmg = 0; - uint16 skill_to_use = -1; - if (skill == -1){ - - switch(GetClass()) - { - case WARRIOR: - case RANGER: - case BEASTLORD: - skill_to_use = SkillKick; - break; - case BERSERKER: - skill_to_use = SkillFrenzy; - break; - case SHADOWKNIGHT: - case PALADIN: - skill_to_use = SkillBash; - break; - case MONK: - if(GetLevel() >= 30) - { - skill_to_use = SkillFlyingKick; - } - else if(GetLevel() >= 25) - { - skill_to_use = SkillDragonPunch; - } - else if(GetLevel() >= 20) - { - skill_to_use = SkillEagleStrike; - } - else if(GetLevel() >= 10) - { - skill_to_use = SkillTigerClaw; - } - else if(GetLevel() >= 5) - { - skill_to_use = SkillRoundKick; - } - else - { + if (skill == -1) { + switch(GetClass()) { + case WARRIOR: + case RANGER: + case BEASTLORD: { skill_to_use = SkillKick; + break; + } + case BERSERKER: { + skill_to_use = SkillFrenzy; + break; + } + case SHADOWKNIGHT: + case PALADIN: { + skill_to_use = SkillBash; + break; + } + case MONK: { + if(GetLevel() >= 30) + skill_to_use = SkillFlyingKick; + else if(GetLevel() >= 25) + skill_to_use = SkillDragonPunch; + else if(GetLevel() >= 20) + skill_to_use = SkillEagleStrike; + else if(GetLevel() >= 10) + skill_to_use = SkillTigerClaw; + else if(GetLevel() >= 5) + skill_to_use = SkillRoundKick; + else + skill_to_use = SkillKick; + break; + } + case ROGUE: { + skill_to_use = SkillBackstab; + break; } - break; - case ROGUE: - skill_to_use = SkillBackstab; - break; } } @@ -1709,137 +1443,106 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte) if(skill_to_use == -1) return; - if(skill_to_use == SkillBash) - { - if (ca_target!=this) - { + if(skill_to_use == SkillBash) { + if (ca_target != this) { DoAnim(animTailRake); - if(GetWeaponDamage(ca_target, GetInv().GetItem(SLOT_SECONDARY)) <= 0 && - GetWeaponDamage(ca_target, GetInv().GetItem(SLOT_SHOULDER)) <= 0){ + if(GetWeaponDamage(ca_target, GetInv().GetItem(SLOT_SECONDARY)) <= 0 && GetWeaponDamage(ca_target, GetInv().GetItem(SLOT_SHOULDER)) <= 0) dmg = -5; - } - else{ - if(!ca_target->CheckHitChance(this, SkillBash, 0)) { + else { + if(!ca_target->CheckHitChance(this, SkillBash, 0)) dmg = 0; - } - else{ + else { if(RuleB(Combat, UseIntervalAC)) dmg = GetBashDamage(); else dmg = MakeRandomInt(1, GetBashDamage()); - } } - - ReuseTime = BashReuseTime-1; - ReuseTime = (ReuseTime*HasteMod)/100; - + ReuseTime = (BashReuseTime - 1); + ReuseTime = ((ReuseTime * HasteMod) / 100); DoSpecialAttackDamage(ca_target, SkillBash, dmg, 1,-1,ReuseTime); if(ReuseTime > 0 && !IsRiposte) - { p_timers.Start(pTimerCombatAbility, ReuseTime); - } } return; } - if(skill_to_use == SkillFrenzy) - { + if(skill_to_use == SkillFrenzy) { CheckIncreaseSkill(SkillFrenzy, GetTarget(), 10); int AtkRounds = 3; - int skillmod = 100*GetSkill(SkillFrenzy)/MaxSkill(SkillFrenzy); - int32 max_dmg = (26 + ((((GetLevel()-6) * 2)*skillmod)/100)) * ((100+RuleI(Combat, FrenzyBonus))/100); + int skillmod = (100 * GetSkill(SkillFrenzy)/MaxSkill(SkillFrenzy)); + int32 max_dmg = (26 + ((((GetLevel() - 6) * 2)*skillmod) / 100)) * ((100 + RuleI(Combat, FrenzyBonus)) / 100); int32 min_dmg = 0; DoAnim(anim2HSlashing); if (GetLevel() < 51) min_dmg = 1; else - min_dmg = GetLevel()*8/10; + min_dmg = (GetLevel() * 8 / 10); if (min_dmg > max_dmg) max_dmg = min_dmg; - ReuseTime = FrenzyReuseTime-1; - ReuseTime = (ReuseTime*HasteMod)/100; + ReuseTime = (FrenzyReuseTime - 1); + ReuseTime = ((ReuseTime * HasteMod) / 100); - //Live parses show around 55% Triple 35% Double 10% Single, you will always get first hit. - while(AtkRounds > 0) { - - if (GetTarget() && (AtkRounds == 1 || MakeRandomInt(0,100) < 75)){ + while(AtkRounds > 0) { //Live parses show around 55% Triple 35% Double 10% Single, you will always get first hit. + if (GetTarget() && (AtkRounds == 1 || MakeRandomInt(0,100) < 75)) DoSpecialAttackDamage(GetTarget(), SkillFrenzy, max_dmg, min_dmg, max_dmg , ReuseTime, true); - } AtkRounds--; } - if(ReuseTime > 0 && !IsRiposte) { + if(ReuseTime > 0 && !IsRiposte) p_timers.Start(pTimerCombatAbility, ReuseTime); - } return; } - if(skill_to_use == SkillKick) - { - if(ca_target!=this) - { + if(skill_to_use == SkillKick) { + if(ca_target != this) { DoAnim(animKick); - if(GetWeaponDamage(ca_target, GetInv().GetItem(SLOT_FEET)) <= 0){ + if(GetWeaponDamage(ca_target, GetInv().GetItem(SLOT_FEET)) <= 0) dmg = -5; - } - else{ - if(!ca_target->CheckHitChance(this, SkillKick, 0)) { + else { + if(!ca_target->CheckHitChance(this, SkillKick, 0)) dmg = 0; - } - else{ + else { if(RuleB(Combat, UseIntervalAC)) dmg = GetKickDamage(); else dmg = MakeRandomInt(1, GetKickDamage()); } } - - ReuseTime = KickReuseTime-1; - + ReuseTime = (KickReuseTime - 1); DoSpecialAttackDamage(ca_target, SkillKick, dmg, 1,-1, ReuseTime); } } - if(skill_to_use == SkillFlyingKick || - skill_to_use == SkillDragonPunch || - skill_to_use == SkillEagleStrike || - skill_to_use == SkillTigerClaw || - skill_to_use == SkillRoundKick) - { - ReuseTime = MonkSpecialAttack(ca_target, skill_to_use) - 1; + if(skill_to_use == SkillFlyingKick || skill_to_use == SkillDragonPunch || skill_to_use == SkillEagleStrike || skill_to_use == SkillTigerClaw || skill_to_use == SkillRoundKick) { + ReuseTime = (MonkSpecialAttack(ca_target, skill_to_use) - 1); MonkSpecialAttack(ca_target, skill_to_use); if (IsRiposte) return; - //Live AA - Technique of Master Wu - uint16 bDoubleSpecialAttack = itembonuses.DoubleSpecialAttack + spellbonuses.DoubleSpecialAttack + aabonuses.DoubleSpecialAttack; - if( bDoubleSpecialAttack && (bDoubleSpecialAttack >= 100 || bDoubleSpecialAttack > MakeRandomInt(0,100))) { - + uint16 bDoubleSpecialAttack = itembonuses.DoubleSpecialAttack + spellbonuses.DoubleSpecialAttack + aabonuses.DoubleSpecialAttack; //Live AA - Technique of Master Wu + if(bDoubleSpecialAttack && (bDoubleSpecialAttack >= 100 || bDoubleSpecialAttack > MakeRandomInt(0,100))) { int MonkSPA [5] = { SkillFlyingKick, SkillDragonPunch, SkillEagleStrike, SkillTigerClaw, SkillRoundKick }; MonkSpecialAttack(ca_target, MonkSPA[MakeRandomInt(0,4)]); - int TripleChance = 25; if (bDoubleSpecialAttack > 100) TripleChance += TripleChance*(100-bDoubleSpecialAttack)/100; - if(TripleChance > MakeRandomInt(0,100)) { + if(TripleChance > MakeRandomInt(0,100)) MonkSpecialAttack(ca_target, MonkSPA[MakeRandomInt(0,4)]); - } } } - if(skill_to_use == SkillBackstab) - { - ReuseTime = BackstabReuseTime-1; + if(skill_to_use == SkillBackstab) { + ReuseTime = (BackstabReuseTime - 1); if (IsRiposte) ReuseTime=0; @@ -1847,99 +1550,11 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte) TryBackstab(ca_target,ReuseTime); } - ReuseTime = (ReuseTime*HasteMod)/100; + ReuseTime = ((ReuseTime * HasteMod) / 100); if(ReuseTime > 0 && !IsRiposte) - { p_timers.Start(pTimerCombatAbility, ReuseTime); - } } -/* -void Mob::Taunt(NPC* who, bool always_succeed, float chance_bonus) { - - if (who == nullptr) - return; - - if(DivineAura()) - return; - - if(!CombatRange(who)) - return; - - if(!always_succeed && IsClient()) - CastToClient()->CheckIncreaseSkill(TAUNT, who, 10); - - int level = GetLevel(); - Mob *hate_top = who->GetHateMost(); - - // Check to see if we're already at the top of the target's hate list - // a mob will not be taunted if its target's health is below 20% - if ((hate_top != this) - && (who->GetLevel() < level) - && (hate_top == nullptr || hate_top->GetHPRatio() >= 20) ) { - int32 newhate, tauntvalue; - - float tauntchance; - if(always_succeed) { - tauntchance = 101; - } else { - - // no idea how taunt success is actually calculated - // TODO: chance for level 50+ mobs should be lower - int level_difference = level - who->GetLevel(); - if (level_difference <= 5) { - tauntchance = 25.0; // minimum - tauntchance += tauntchance * (float)GetSkill(TAUNT) / 200.0; // skill modifier - if (tauntchance > 65.0) - tauntchance = 65.0; - } - else if (level_difference <= 10) { - tauntchance = 30.0; // minimum - tauntchance += tauntchance * (float)GetSkill(TAUNT) / 200.0; // skill modifier - if (tauntchance > 85.0) - tauntchance = 85.0; - } - else if (level_difference <= 15) { - tauntchance = 40.0; // minimum - tauntchance += tauntchance * (float)GetSkill(TAUNT) / 200.0; // skill modifier - if (tauntchance > 90.0) - tauntchance = 90.0; - } - else { - tauntchance = 50.0; // minimum - tauntchance += tauntchance * (float)GetSkill(TAUNT) / 200.0; // skill modifier - if (tauntchance > 95.0) - tauntchance = 95.0; - } - } - - if (chance_bonus) - tauntchance = tauntchance + (tauntchance*chance_bonus/100.0f); - - if (tauntchance > MakeRandomFloat(0, 100)) { - // this is the max additional hate added per succesfull taunt - tauntvalue = (MakeRandomInt(2, 4) * level); - //tauntvalue = (int32) ((float)level * 10.0 * (float)rand()/(float)RAND_MAX + 1); - // new hate: find diff of player's hate and whoever's at top of list, add that plus tauntvalue to players hate - newhate = who->GetNPCHate(hate_top) - who->GetNPCHate(this) + tauntvalue; - // add the hate - who->CastToNPC()->AddToHateList(this, newhate); - } - else{ - //generate at least some hate reguardless of the outcome. - who->CastToNPC()->AddToHateList(this, (MakeRandomInt(2, 4)*level)); - } - } - - //generate at least some hate reguardless of the outcome. - who->CastToNPC()->AddToHateList(this, (MakeRandomInt(2, 4)*level)); - if (HasSkillProcs()){ - float chance = (float)TauntReuseTime*RuleR(Combat, AvgProcsPerMinute)/60000.0f; - TrySkillProc(who, TAUNT, chance); - } -} -*/ - void Mob::Taunt(NPC* who, bool always_succeed, float chance_bonus) { if (who == nullptr) @@ -1955,18 +1570,14 @@ void Mob::Taunt(NPC* who, bool always_succeed, float chance_bonus) { CastToClient()->CheckIncreaseSkill(SkillTaunt, who, 10); Mob *hate_top = who->GetHateMost(); - float level_difference = GetLevel() - who->GetLevel(); - //Support for how taunt worked pre 2000 on LIVE - Can not taunt NPC over your level. - if ((RuleB(Combat,TauntOverLevel) == false) && (level_difference < 0) || who->GetSpecialAbility(IMMUNE_TAUNT)){ + if ((RuleB(Combat,TauntOverLevel) == false) && (level_difference < 0) || who->GetSpecialAbility(IMMUNE_TAUNT)) {//Support for how taunt worked pre 2000 on LIVE - Can not taunt NPC over your level. Message_StringID(MT_SpellFailure,FAILED_TAUNT); return; } - - //All values used based on live parses after taunt was updated in 2006. - if ((hate_top && hate_top->GetHPRatio() >= 20) || hate_top == nullptr) { - + + if ((hate_top && hate_top->GetHPRatio() >= 20) || hate_top == nullptr) { //All values used based on live parses after taunt was updated in 2006. int32 newhate = 0; float tauntchance = 50.0f; @@ -1974,27 +1585,24 @@ void Mob::Taunt(NPC* who, bool always_succeed, float chance_bonus) { tauntchance = 101.0f; else { - - if (level_difference < 0){ - tauntchance += level_difference*3; + if (level_difference < 0) { + tauntchance += (level_difference * 3); if (tauntchance < 20) tauntchance = 20.0f; } else { - tauntchance += level_difference*5; + tauntchance += (level_difference * 5); if (tauntchance > 65) tauntchance = 65.0f; } } - //TauntSkillFalloff rate is not based on any real data. Default of 33% gives a reasonable result. - if (IsClient() && !always_succeed) + if (IsClient() && !always_succeed) //TauntSkillFalloff rate is not based on any real data. Default of 33% gives a reasonable result. tauntchance -= (RuleR(Combat,TauntSkillFalloff) * (CastToClient()->MaxSkill(SkillTaunt) - GetSkill(SkillTaunt))); - //From SE_Taunt (Does a taunt with a chance modifier) - if (chance_bonus) - tauntchance += tauntchance*chance_bonus/100.0f; + if (chance_bonus) //From SE_Taunt (Does a taunt with a chance modifier) + tauntchance += (tauntchance * chance_bonus / 100.0f); if (tauntchance < 1) tauntchance = 1.0f; @@ -2002,9 +1610,8 @@ void Mob::Taunt(NPC* who, bool always_succeed, float chance_bonus) { tauntchance /= 100.0f; if (tauntchance > MakeRandomFloat(0, 1)) { - - if (hate_top && hate_top != this){ - newhate = (who->GetNPCHate(hate_top) - who->GetNPCHate(this)) + 1; + if (hate_top && hate_top != this) { + newhate = ((who->GetNPCHate(hate_top) - who->GetNPCHate(this)) + 1); who->CastToNPC()->AddToHateList(this, newhate); } else @@ -2013,65 +1620,41 @@ void Mob::Taunt(NPC* who, bool always_succeed, float chance_bonus) { if (who->CanTalk()) who->Say_StringID(SUCCESSFUL_TAUNT,GetCleanName()); } - else{ + else Message_StringID(MT_SpellFailure,FAILED_TAUNT); - } } else Message_StringID(MT_SpellFailure,FAILED_TAUNT); - if (HasSkillProcs()){ - float chance = (float)TauntReuseTime*RuleR(Combat, AvgProcsPerMinute)/60000.0f; + if (HasSkillProcs()) { + float chance = ((float)TauntReuseTime * RuleR(Combat, AvgProcsPerMinute) / 60000.0f); TrySkillProc(who, SkillTaunt, chance); } } void Mob::InstillDoubt(Mob *who) { - //make sure we can use this skill - /*int skill = GetSkill(INTIMIDATION);*/ //unused - - //make sure our target is an NPC - if(!who || !who->IsNPC()) + if(!who || !who->IsNPC()) //make sure we can use this skill - *int skill = GetSkill(INTIMIDATION);*/ unused - make sure our target is an NPC return; if(DivineAura()) return; - //range check - if(!CombatRange(who)) + if(!CombatRange(who)) //range check return; if(IsClient()) - { CastToClient()->CheckIncreaseSkill(SkillIntimidation, who, 10); - } - //I think this formula needs work - int value = 0; + int value = 0; //I think this formula needs work + value += (GetSkill(SkillIntimidation) + GetCHA() / 4); //user's bonus + value -= (target->GetLevel() * 4 + who->GetWIS() / 4); //target's counters - //user's bonus - value += GetSkill(SkillIntimidation) + GetCHA()/4; - - //target's counters - value -= target->GetLevel()*4 + who->GetWIS()/4; - - if (MakeRandomInt(0,99) < value) { - //temporary hack... - //cast fear on them... should prolly be a different spell - //and should be un-resistable. - SpellOnTarget(229, who, false, true, -2000); - //is there a success message? - } else { - Message_StringID(4,NOT_SCARING); - //Idea from WR: - /* if (target->IsNPC() && MakeRandomInt(0,99) < 10 ) { - entity_list.MessageClose(target, false, 50, MT_NPCRampage, "%s lashes out in anger!",target->GetName()); - //should we actually do this? and the range is completely made up, unconfirmed - entity_list.AEAttack(target, 50); - }*/ - } + if (MakeRandomInt(0,99) < value) + SpellOnTarget(229, who, false, true, -2000); //temporary hack... - cast fear on them... should prolly be a different spell -and should be un-resistable. - is there a success message? + else + Message_StringID(4,NOT_SCARING); //Idea from WR: /* if (target->IsNPC() && MakeRandomInt(0,99) < 10 ) { entity_list.MessageClose(target, false, 50, MT_NPCRampage, "%s lashes out in anger!",target->GetName()); //should we actually do this? and the range is completely made up, unconfirmed entity_list.AEAttack(target, 50); }*/ } bool Mob::TryHeadShot(Mob* defender, SkillUseTypes skillInUse) { @@ -2080,9 +1663,7 @@ bool Mob::TryHeadShot(Mob* defender, SkillUseTypes skillInUse) { if(defender && skillInUse == SkillArchery) { if(GetAA(aaHeadshot) && defender->GetBodyType() == BT_Humanoid) { if((GetLevelCon(GetLevel(), defender->GetLevel()) == CON_LIGHTBLUE || GetLevelCon(GetLevel(), defender->GetLevel()) == CON_GREEN) && defender->GetLevel() <= 60 && !defender->IsClient()) { - // WildcardX: These chance formula's below are arbitrary. If someone has a better formula that is more - // consistent with live, feel free to update these. - int AttackerChance = 20 + ((GetLevel() - 51) / 2) + (itembonuses.HeroicDEX / 10); + int AttackerChance = (20 + ((GetLevel() - 51) / 2) + (itembonuses.HeroicDEX / 10));// WildcardX: These chance formula's below are arbitrary. If someone has a better formula that is more consistent with live, feel free to update these. int DefenderChance = MakeRandomInt(0, 100); if(AttackerChance > DefenderChance) { mlog(COMBAT__ATTACKS, "Landed a headshot: Attacker chance was %f and Defender chance was %f.", AttackerChance, DefenderChance); @@ -2090,9 +1671,8 @@ bool Mob::TryHeadShot(Mob* defender, SkillUseTypes skillInUse) { defender->Damage(this, 32000, SPELL_UNKNOWN, skillInUse); Result = true; } - else { + else mlog(COMBAT__ATTACKS, "FAILED a headshot: Attacker chance was %f and Defender chance was %f.", AttackerChance, DefenderChance); - } } } } @@ -2100,43 +1680,36 @@ bool Mob::TryHeadShot(Mob* defender, SkillUseTypes skillInUse) { return Result; } -void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes skillinuse, int16 chance_mod, int16 focus, bool CanRiposte) -{ +void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes skillinuse, int16 chance_mod, int16 focus, bool CanRiposte) { if (!CanDoSpecialAttack(other)) return; - - //For spells using skill value 98 (feral swipe ect) server sets this to 67 automatically. - //Kayen: This is unlikely to be completely accurate but use OFFENSE skill value for these effects. - if (skillinuse == SkillBegging) + + if (skillinuse == SkillBegging) //For spells using skill value 98 (feral swipe ect) server sets this to 67 automatically. - Kayen: This is unlikely to be completely accurate but use OFFENSE skill value for these effects. skillinuse = SkillOffense; int damage = 0; uint32 hate = 0; int Hand = 13; - if (hate == 0 && weapon_damage > 1) hate = weapon_damage; - - if(weapon_damage > 0){ + if (hate == 0 && weapon_damage > 1) + hate = weapon_damage; + if(weapon_damage > 0) { if(GetClass() == BERSERKER){ - int bonus = 3 + GetLevel()/10; - weapon_damage = weapon_damage * (100+bonus) / 100; + int bonus = (3 + GetLevel() / 10); + weapon_damage = (weapon_damage * (100 + bonus) / 100); } int32 min_hit = 1; - int32 max_hit = (2*weapon_damage*GetDamageTable(skillinuse)) / 100; - - if(GetLevel() >= 28 && IsWarriorClass() ) - { - int ucDamageBonus = GetWeaponDamageBonus((const Item_Struct*) nullptr ); + int32 max_hit = ((2 * weapon_damage * GetDamageTable(skillinuse)) / 100); + if(GetLevel() >= 28 && IsWarriorClass()) { + int ucDamageBonus = GetWeaponDamageBonus((const Item_Struct*) nullptr); min_hit += (int) ucDamageBonus; max_hit += (int) ucDamageBonus; hate += ucDamageBonus; } - ApplySpecialAttackMod(skillinuse, max_hit, min_hit); - - min_hit += min_hit * GetMeleeMinDamageMod_SE(skillinuse) / 100; + min_hit += (min_hit * GetMeleeMinDamageMod_SE(skillinuse) / 100); if(max_hit < min_hit) max_hit = min_hit; @@ -2146,16 +1719,16 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes else damage = MakeRandomInt(min_hit, max_hit); - if(!other->CheckHitChance(this, skillinuse, Hand, chance_mod)) { + if(!other->CheckHitChance(this, skillinuse, Hand, chance_mod)) damage = 0; - } else { + else { other->AvoidDamage(this, damage, CanRiposte); other->MeleeMitigation(this, damage, min_hit); if(damage > 0) { - damage += damage*focus/100; + damage += (damage * focus / 100); ApplyMeleeDamageBonus(skillinuse, damage); damage += other->GetFcDamageAmtIncoming(this, 0, true, skillinuse); - damage += (itembonuses.HeroicSTR / 10) + (damage * other->GetSkillDmgTaken(skillinuse) / 100) + GetSkillDmgAmt(skillinuse); + damage += ((itembonuses.HeroicSTR / 10) + (damage * other->GetSkillDmgTaken(skillinuse) / 100) + GetSkillDmgAmt(skillinuse)); TryCriticalHit(other, skillinuse, damage); } } @@ -2170,15 +1743,14 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes else damage = -5; - if(skillinuse == SkillBash){ - if(IsClient()){ + if(skillinuse == SkillBash) { + if(IsClient()) { ItemInst *item = CastToClient()->GetInv().GetItem(SLOT_SECONDARY); - if(item){ - if(item->GetItem()->ItemType == ItemTypeShield) { + if(item) { + if(item->GetItem()->ItemType == ItemTypeShield) hate += item->GetItem()->AC; - } const Item_Struct *itm = item->GetItem(); - hate = hate * (100 + GetFuriousBash(itm->Focus.Effect)) / 100; + hate = (hate * (100 + GetFuriousBash(itm->Focus.Effect)) / 100); } } } @@ -2186,7 +1758,7 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes other->AddToHateList(this, hate); bool CanSkillProc = true; - if (skillinuse == SkillOffense){ //Hack to allow damage to display. + if (skillinuse == SkillOffense) { //Hack to allow damage to display. skillinuse = SkillTigerClaw; //'strike' your opponent - Arbitrary choice for message. CanSkillProc = false; //Disable skill procs } @@ -2200,22 +1772,20 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes if(aabonuses.SpecialAttackKBProc[0] && aabonuses.SpecialAttackKBProc[1] == skillinuse){ int kb_chance = 25; - kb_chance += kb_chance*(100-aabonuses.SpecialAttackKBProc[0])/100; + kb_chance += (kb_chance * (100 - aabonuses.SpecialAttackKBProc[0]) / 100); if (MakeRandomInt(0, 99) < kb_chance) SpellFinished(904, other, 10, 0, -1, spells[904].ResistDiff); } if (CanSkillProc && HasSkillProcs()){ - float chance = 10.0f*RuleR(Combat, AvgProcsPerMinute)/60000.0f; + float chance = (10.0f * RuleR(Combat, AvgProcsPerMinute) / 60000.0f); TrySkillProc(other, skillinuse, chance); } } -bool Mob::CanDoSpecialAttack(Mob *other) -{ - //Make sure everything is valid before doing any attacks. - if (!other) { +bool Mob::CanDoSpecialAttack(Mob *other) { + if (!other) { //Make sure everything is valid before doing any attacks. SetTarget(nullptr); return false; } @@ -2223,10 +1793,8 @@ bool Mob::CanDoSpecialAttack(Mob *other) if(!GetTarget()) SetTarget(other); - if ((other == nullptr || ((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead)) - || HasDied() || (!IsAttackAllowed(other)))) { + if ((other == nullptr || ((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead)) || HasDied() || (!IsAttackAllowed(other)))) return false; - } if(other->GetInvul() || other->GetSpecialAbility(IMMUNE_MELEE)) return false;