mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-17 22:51:30 +00:00
Merge pull request #314 from KayenEQ/Development
Support for NPC's to use focus effects.
This commit is contained in:
commit
2a33da248b
@ -325,6 +325,8 @@ RULE_INT ( Spells, AI_IdleBeneficialChance, 100) // Chance while idle to do a be
|
||||
RULE_BOOL ( Spells, SHDProcIDOffByOne, true) // pre June 2009 SHD spell procs were off by 1, they stopped doing this in June 2009 (so UF+ spell files need this false)
|
||||
RULE_BOOL ( Spells, Jun182014HundredHandsRevamp, false) // this should be true for if you import a spell file newer than June 18, 2014
|
||||
RULE_BOOL ( Spells, SwarmPetTargetLock, false) // Use old method of swarm pets target locking till target dies then despawning.
|
||||
RULE_BOOL ( Spells, NPC_UseFocusFromSpells, true) // Allow npcs to use most spell derived focus effects.
|
||||
RULE_BOOL ( Spells, NPC_UseFocusFromItems, false) // Allow npcs to use most item derived focus effects.
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY( Combat )
|
||||
|
||||
@ -519,8 +519,7 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
|
||||
}
|
||||
}
|
||||
|
||||
if(IsClient())
|
||||
pet.duration += (CastToClient()->GetFocusEffect(focusSwarmPetDuration, spell_id) / 1000);
|
||||
pet.duration += GetFocusEffect(focusSwarmPetDuration, spell_id) / 1000;
|
||||
|
||||
pet.npc_id = record.npc_type;
|
||||
|
||||
|
||||
@ -1128,8 +1128,7 @@ int32 Mob::CheckAggroAmount(uint16 spell_id, bool isproc)
|
||||
|
||||
int HateMod = RuleI(Aggro, SpellAggroMod);
|
||||
|
||||
if (IsClient())
|
||||
HateMod += CastToClient()->GetFocusEffect(focusSpellHateMod, spell_id);
|
||||
HateMod += GetFocusEffect(focusSpellHateMod, spell_id);
|
||||
|
||||
AggroAmount = (AggroAmount * HateMod) / 100;
|
||||
|
||||
@ -1178,8 +1177,7 @@ int32 Mob::CheckHealAggroAmount(uint16 spell_id, uint32 heal_possible)
|
||||
if (AggroAmount > 0) {
|
||||
int HateMod = RuleI(Aggro, SpellAggroMod);
|
||||
|
||||
if (IsClient())
|
||||
HateMod += CastToClient()->GetFocusEffect(focusSpellHateMod, spell_id);
|
||||
HateMod += GetFocusEffect(focusSpellHateMod, spell_id);
|
||||
|
||||
//Live AA - Spell casting subtlety
|
||||
HateMod += aabonuses.hatemod + spellbonuses.hatemod + itembonuses.hatemod;
|
||||
|
||||
@ -1386,15 +1386,6 @@ void Client::Damage(Mob* other, int32 damage, uint16 spell_id, SkillUseTypes att
|
||||
if(spell_id==0)
|
||||
spell_id = SPELL_UNKNOWN;
|
||||
|
||||
if(spell_id!=0 && spell_id != SPELL_UNKNOWN && other && damage > 0)
|
||||
{
|
||||
if(other->IsNPC() && !other->IsPet())
|
||||
{
|
||||
float npcspellscale = other->CastToNPC()->GetSpellScale();
|
||||
damage = ((float)damage * npcspellscale) / (float)100;
|
||||
}
|
||||
}
|
||||
|
||||
// cut all PVP spell damage to 2/3 -solar
|
||||
// Blasting ourselfs is considered PvP
|
||||
//Don't do PvP mitigation if the caster is damaging himself
|
||||
@ -3806,13 +3797,6 @@ void Mob::HealDamage(uint32 amount, Mob *caster, uint16 spell_id)
|
||||
int32 curhp = GetHP();
|
||||
uint32 acthealed = 0;
|
||||
|
||||
if (caster && amount > 0) {
|
||||
if (caster->IsNPC() && !caster->IsPet()) {
|
||||
float npchealscale = caster->CastToNPC()->GetHealScale();
|
||||
amount = (static_cast<float>(amount) * npchealscale) / 100.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if (amount > (maxhp - curhp))
|
||||
acthealed = (maxhp - curhp);
|
||||
else
|
||||
|
||||
@ -3050,6 +3050,13 @@ void NPC::CalcItemBonuses(StatBonuses *newbon)
|
||||
if (cur->Worn.Effect>0 && (cur->Worn.Type == ET_WornEffect)) { // latent effects
|
||||
ApplySpellsBonuses(cur->Worn.Effect, cur->Worn.Level, newbon);
|
||||
}
|
||||
|
||||
if (RuleB(Spells, NPC_UseFocusFromItems)){
|
||||
if (cur->Focus.Effect>0 && (cur->Focus.Type == ET_Focus)){ // focus effects
|
||||
ApplySpellsBonuses(cur->Focus.Effect, cur->Focus.Level, newbon, 0, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (cur->Haste > newbon->haste)
|
||||
newbon->haste = cur->Haste;
|
||||
}
|
||||
|
||||
@ -485,14 +485,8 @@ public:
|
||||
|
||||
inline virtual int32 GetDelayDeath() const { return aabonuses.DelayDeath + spellbonuses.DelayDeath + itembonuses.DelayDeath + 11; }
|
||||
|
||||
float GetActSpellRange(uint16 spell_id, float range, bool IsBard = false);
|
||||
int32 GetActSpellDamage(uint16 spell_id, int32 value, Mob* target = nullptr);
|
||||
int32 GetActSpellHealing(uint16 spell_id, int32 value, Mob* target = nullptr);
|
||||
int32 GetActSpellCost(uint16 spell_id, int32);
|
||||
int32 GetActSpellDuration(uint16 spell_id, int32);
|
||||
int32 GetActSpellCasttime(uint16 spell_id, int32);
|
||||
int32 GetDotFocus(uint16 spell_id, int32 value);
|
||||
int32 GetActDoTDamage(uint16 spell_id, int32 value, Mob* target = nullptr);
|
||||
virtual bool CheckFizzle(uint16 spell_id);
|
||||
virtual bool CheckSpellLevelRestriction(uint16 spell_id);
|
||||
virtual int GetCurrentBuffSlots() const;
|
||||
|
||||
145
zone/effects.cpp
145
zone/effects.cpp
@ -30,7 +30,7 @@
|
||||
#include "string_ids.h"
|
||||
#include "npc_ai.h"
|
||||
|
||||
float Client::GetActSpellRange(uint16 spell_id, float range, bool IsBard)
|
||||
float Mob::GetActSpellRange(uint16 spell_id, float range, bool IsBard)
|
||||
{
|
||||
float extrange = 100;
|
||||
|
||||
@ -39,57 +39,17 @@ float Client::GetActSpellRange(uint16 spell_id, float range, bool IsBard)
|
||||
return (range * extrange) / 100;
|
||||
}
|
||||
|
||||
|
||||
int32 NPC::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
|
||||
|
||||
//Quest scale all NPC spell damage via $npc->SetSpellFocusDMG(value)
|
||||
//DoT Damage - Mob::DoBuffTic [spell_effects.cpp] / Direct Damage Mob::SpellEffect [spell_effects.cpp]
|
||||
|
||||
int32 dmg = value;
|
||||
|
||||
if (target) {
|
||||
value += dmg*target->GetVulnerability(this, spell_id, 0)/100;
|
||||
|
||||
if (spells[spell_id].buffduration == 0)
|
||||
value -= target->GetFcDamageAmtIncoming(this, spell_id);
|
||||
else
|
||||
value -= target->GetFcDamageAmtIncoming(this, spell_id)/spells[spell_id].buffduration;
|
||||
}
|
||||
|
||||
value += dmg*GetSpellFocusDMG()/100;
|
||||
|
||||
if (AI_HasSpellsEffects()){
|
||||
int16 chance = 0;
|
||||
int ratio = 0;
|
||||
|
||||
if (spells[spell_id].buffduration == 0) {
|
||||
chance += spellbonuses.CriticalSpellChance + spellbonuses.FrenziedDevastation;
|
||||
|
||||
if (chance && zone->random.Roll(chance)) {
|
||||
ratio += spellbonuses.SpellCritDmgIncrease + spellbonuses.SpellCritDmgIncNoStack;
|
||||
value += (value*ratio)/100;
|
||||
entity_list.MessageClose_StringID(this, true, 100, MT_SpellCrits, OTHER_CRIT_BLAST, GetCleanName(), itoa(-value));
|
||||
}
|
||||
}
|
||||
else {
|
||||
chance += spellbonuses.CriticalDoTChance;
|
||||
if (chance && zone->random.Roll(chance)) {
|
||||
ratio += spellbonuses.DotCritDmgIncrease;
|
||||
value += (value*ratio)/100;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
int32 Client::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
|
||||
int32 Mob::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
|
||||
|
||||
if (spells[spell_id].targettype == ST_Self)
|
||||
return value;
|
||||
|
||||
if (IsNPC())
|
||||
value += value*CastToNPC()->GetSpellFocusDMG()/100;
|
||||
|
||||
bool Critical = false;
|
||||
int32 value_BaseEffect = 0;
|
||||
int chance = 0;
|
||||
|
||||
value_BaseEffect = value + (value*GetFocusEffect(focusFcBaseEffects, spell_id)/100);
|
||||
|
||||
@ -98,20 +58,20 @@ int32 Client::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
|
||||
value -= (GetLevel() - 40) * 20;
|
||||
|
||||
//This adds the extra damage from the AA Unholy Touch, 450 per level to the AA Improved Harm TOuch.
|
||||
if (spell_id == SPELL_IMP_HARM_TOUCH) //Improved Harm Touch
|
||||
if (spell_id == SPELL_IMP_HARM_TOUCH && IsClient()) //Improved Harm Touch
|
||||
value -= GetAA(aaUnholyTouch) * 450; //Unholy Touch
|
||||
|
||||
int chance = RuleI(Spells, BaseCritChance); //Wizard base critical chance is 2% (Does not scale with level)
|
||||
chance = RuleI(Spells, BaseCritChance); //Wizard base critical chance is 2% (Does not scale with level)
|
||||
chance += itembonuses.CriticalSpellChance + spellbonuses.CriticalSpellChance + aabonuses.CriticalSpellChance;
|
||||
|
||||
chance += itembonuses.FrenziedDevastation + spellbonuses.FrenziedDevastation + aabonuses.FrenziedDevastation;
|
||||
|
||||
if (chance > 0 || (GetClass() == WIZARD && GetLevel() >= RuleI(Spells, WizCritLevel))) {
|
||||
//Crtical Hit Calculation pathway
|
||||
if (chance > 0 || (IsClient() && GetClass() == WIZARD && GetLevel() >= RuleI(Spells, WizCritLevel))) {
|
||||
|
||||
int32 ratio = RuleI(Spells, BaseCritRatio); //Critical modifier is applied from spell effects only. Keep at 100 for live like criticals.
|
||||
|
||||
//Improved Harm Touch is a guaranteed crit if you have at least one level of SCF.
|
||||
if (spell_id == SPELL_IMP_HARM_TOUCH && (GetAA(aaSpellCastingFury) > 0) && (GetAA(aaUnholyTouch) > 0))
|
||||
if (spell_id == SPELL_IMP_HARM_TOUCH && IsClient() && (GetAA(aaSpellCastingFury) > 0) && (GetAA(aaUnholyTouch) > 0))
|
||||
chance = 100;
|
||||
|
||||
if (zone->random.Roll(chance)) {
|
||||
@ -120,11 +80,15 @@ int32 Client::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
|
||||
ratio += itembonuses.SpellCritDmgIncNoStack + spellbonuses.SpellCritDmgIncNoStack + aabonuses.SpellCritDmgIncNoStack;
|
||||
}
|
||||
|
||||
else if (GetClass() == WIZARD && (GetLevel() >= RuleI(Spells, WizCritLevel)) && (zone->random.Roll(RuleI(Spells, WizCritChance)))) {
|
||||
ratio += zone->random.Int(20,70); //Wizard innate critical chance is calculated seperately from spell effect and is not a set ratio. (20-70 is parse confirmed)
|
||||
else if ((IsClient() && GetClass() == WIZARD) || (IsMerc() && GetClass() == CASTERDPS)) {
|
||||
if ((GetLevel() >= RuleI(Spells, WizCritLevel)) && zone->random.Roll(RuleI(Spells, WizCritChance))){
|
||||
//Wizard innate critical chance is calculated seperately from spell effect and is not a set ratio. (20-70 is parse confirmed)
|
||||
ratio += zone->random.Int(20,70);
|
||||
Critical = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsClient() && GetClass() == WIZARD)
|
||||
ratio += RuleI(Spells, WizCritRatio); //Default is zero
|
||||
|
||||
if (Critical){
|
||||
@ -147,14 +111,19 @@ int32 Client::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
|
||||
if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
|
||||
value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value)*ratio/100;
|
||||
|
||||
else if (IsNPC() && CastToNPC()->GetSpellScale())
|
||||
value = int(static_cast<float>(value) * CastToNPC()->GetSpellScale() / 100.0f);
|
||||
|
||||
entity_list.MessageClose_StringID(this, true, 100, MT_SpellCrits,
|
||||
OTHER_CRIT_BLAST, GetName(), itoa(-value));
|
||||
|
||||
if (IsClient())
|
||||
Message_StringID(MT_SpellCrits, YOU_CRIT_BLAST, itoa(-value));
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
//Non Crtical Hit Calculation pathway
|
||||
value = value_BaseEffect;
|
||||
|
||||
value += value_BaseEffect*GetFocusEffect(focusImprovedDamage, spell_id)/100;
|
||||
@ -173,14 +142,20 @@ int32 Client::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
|
||||
if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
|
||||
value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value);
|
||||
|
||||
if (IsNPC() && CastToNPC()->GetSpellScale())
|
||||
value = int(static_cast<float>(value) * CastToNPC()->GetSpellScale() / 100.0f);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
int32 Client::GetActDoTDamage(uint16 spell_id, int32 value, Mob* target) {
|
||||
int32 Mob::GetActDoTDamage(uint16 spell_id, int32 value, Mob* target) {
|
||||
|
||||
if (target == nullptr)
|
||||
return value;
|
||||
|
||||
if (IsNPC())
|
||||
value += value*CastToNPC()->GetSpellFocusDMG()/100;
|
||||
|
||||
int32 value_BaseEffect = 0;
|
||||
int32 extra_dmg = 0;
|
||||
int16 chance = 0;
|
||||
@ -209,9 +184,8 @@ int32 Client::GetActDoTDamage(uint16 spell_id, int32 value, Mob* target) {
|
||||
}
|
||||
|
||||
value -= extra_dmg;
|
||||
|
||||
return value;
|
||||
}
|
||||
else {
|
||||
|
||||
value = value_BaseEffect;
|
||||
value += value_BaseEffect*GetFocusEffect(focusImprovedDamage, spell_id)/100;
|
||||
@ -228,6 +202,10 @@ int32 Client::GetActDoTDamage(uint16 spell_id, int32 value, Mob* target) {
|
||||
}
|
||||
|
||||
value -= extra_dmg;
|
||||
}
|
||||
|
||||
if (IsNPC() && CastToNPC()->GetSpellScale())
|
||||
value = int(static_cast<float>(value) * CastToNPC()->GetSpellScale() / 100.0f);
|
||||
|
||||
return value;
|
||||
}
|
||||
@ -254,39 +232,14 @@ int32 Mob::GetExtraSpellAmt(uint16 spell_id, int32 extra_spell_amt, int32 base_s
|
||||
return extra_spell_amt;
|
||||
}
|
||||
|
||||
|
||||
int32 NPC::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
|
||||
|
||||
//Scale all NPC spell healing via SetSpellFocusHeal(value)
|
||||
|
||||
value += value*GetSpellFocusHeal()/100;
|
||||
|
||||
if (target) {
|
||||
value += target->GetFocusIncoming(focusFcHealAmtIncoming, SE_FcHealAmtIncoming, this, spell_id);
|
||||
value += value*target->GetHealRate(spell_id, this)/100;
|
||||
}
|
||||
|
||||
//Allow for critical heal chance if NPC is loading spell effect bonuses.
|
||||
if (AI_HasSpellsEffects()){
|
||||
if(spells[spell_id].buffduration < 1) {
|
||||
if(spellbonuses.CriticalHealChance && (zone->random.Roll(spellbonuses.CriticalHealChance))) {
|
||||
value = value*2;
|
||||
entity_list.MessageClose_StringID(this, true, 100, MT_SpellCrits, OTHER_CRIT_HEAL, GetCleanName(), itoa(value));
|
||||
}
|
||||
}
|
||||
else if(spellbonuses.CriticalHealOverTime && (zone->random.Roll(spellbonuses.CriticalHealOverTime))) {
|
||||
value = value*2;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
int32 Client::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
|
||||
int32 Mob::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
|
||||
|
||||
if (target == nullptr)
|
||||
target = this;
|
||||
|
||||
if (IsNPC())
|
||||
value += value*CastToNPC()->GetSpellFocusHeal()/100;
|
||||
|
||||
int32 value_BaseEffect = 0;
|
||||
int16 chance = 0;
|
||||
int8 modifier = 1;
|
||||
@ -323,9 +276,14 @@ int32 Client::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
|
||||
|
||||
value += value*target->GetHealRate(spell_id, this)/100;
|
||||
|
||||
if (IsNPC() && CastToNPC()->GetHealScale())
|
||||
value = int(static_cast<float>(value) * CastToNPC()->GetHealScale() / 100.0f);
|
||||
|
||||
if (Critical) {
|
||||
entity_list.MessageClose_StringID(this, true, 100, MT_SpellCrits,
|
||||
OTHER_CRIT_HEAL, GetName(), itoa(value));
|
||||
|
||||
if (IsClient())
|
||||
Message_StringID(MT_SpellCrits, YOU_CRIT_HEAL, itoa(value));
|
||||
}
|
||||
|
||||
@ -343,9 +301,12 @@ int32 Client::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
|
||||
chance += GetDecayEffectValue(spell_id, SE_CriticalRegenDecay);
|
||||
|
||||
if(chance && zone->random.Roll(chance))
|
||||
return (value * 2);
|
||||
value *= 2;
|
||||
}
|
||||
|
||||
if (IsNPC() && CastToNPC()->GetHealScale())
|
||||
value = int(static_cast<float>(value) * CastToNPC()->GetHealScale() / 100.0f);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -359,9 +320,9 @@ int32 Client::GetActSpellCost(uint16 spell_id, int32 cost)
|
||||
cost *= 2;
|
||||
|
||||
// Formula = Unknown exact, based off a random percent chance up to mana cost(after focuses) of the cast spell
|
||||
if(this->itembonuses.Clairvoyance && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
|
||||
if(itembonuses.Clairvoyance && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
|
||||
{
|
||||
int16 mana_back = this->itembonuses.Clairvoyance * zone->random.Int(1, 100) / 100;
|
||||
int16 mana_back = itembonuses.Clairvoyance * zone->random.Int(1, 100) / 100;
|
||||
// Doesnt generate mana, so best case is a free spell
|
||||
if(mana_back > cost)
|
||||
mana_back = cost;
|
||||
@ -451,7 +412,7 @@ int32 Client::GetActSpellCost(uint16 spell_id, int32 cost)
|
||||
return cost;
|
||||
}
|
||||
|
||||
int32 Client::GetActSpellDuration(uint16 spell_id, int32 duration)
|
||||
int32 Mob::GetActSpellDuration(uint16 spell_id, int32 duration)
|
||||
{
|
||||
if (spells[spell_id].not_extendable)
|
||||
return duration;
|
||||
@ -463,7 +424,7 @@ int32 Client::GetActSpellDuration(uint16 spell_id, int32 duration)
|
||||
|
||||
// Only need this for clients, since the change was for bard songs, I assume we should keep non bard songs getting +1
|
||||
// However if its bard or not and is mez, charm or fear, we need to add 1 so that client is in sync
|
||||
if (!(IsShortDurationBuff(spell_id) && IsBardSong(spell_id)) ||
|
||||
if (IsClient() && !(IsShortDurationBuff(spell_id) && IsBardSong(spell_id)) ||
|
||||
IsFearSpell(spell_id) ||
|
||||
IsCharmSpell(spell_id) ||
|
||||
IsMezSpell(spell_id) ||
|
||||
@ -664,7 +625,7 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) {
|
||||
if(spell.recast_time > 0)
|
||||
{
|
||||
uint32 reduced_recast = spell.recast_time / 1000;
|
||||
reduced_recast -= CastToClient()->GetFocusEffect(focusReduceRecastTime, spell_id);
|
||||
reduced_recast -= GetFocusEffect(focusReduceRecastTime, spell_id);
|
||||
if(reduced_recast <= 0){
|
||||
reduced_recast = 0;
|
||||
if (GetPTimers().Enabled((uint32)DiscTimer))
|
||||
|
||||
147
zone/merc.cpp
147
zone/merc.cpp
@ -2656,153 +2656,6 @@ int16 Merc::GetFocusEffect(focusType type, uint16 spell_id) {
|
||||
return realTotal + realTotal2 + realTotal3;
|
||||
}
|
||||
|
||||
|
||||
int32 Merc::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
|
||||
|
||||
if (spells[spell_id].targettype == ST_Self)
|
||||
return value;
|
||||
|
||||
bool Critical = false;
|
||||
int32 value_BaseEffect = 0;
|
||||
|
||||
value_BaseEffect = value + (value*GetFocusEffect(focusFcBaseEffects, spell_id)/100);
|
||||
|
||||
int chance = RuleI(Spells, BaseCritChance);
|
||||
chance += itembonuses.CriticalSpellChance + spellbonuses.CriticalSpellChance + aabonuses.CriticalSpellChance;
|
||||
|
||||
if (chance > 0){
|
||||
|
||||
int32 ratio = RuleI(Spells, BaseCritRatio); //Critical modifier is applied from spell effects only. Keep at 100 for live like criticals.
|
||||
|
||||
if (zone->random.Roll(chance)) {
|
||||
Critical = true;
|
||||
ratio += itembonuses.SpellCritDmgIncrease + spellbonuses.SpellCritDmgIncrease + aabonuses.SpellCritDmgIncrease;
|
||||
ratio += itembonuses.SpellCritDmgIncNoStack + spellbonuses.SpellCritDmgIncNoStack + aabonuses.SpellCritDmgIncNoStack;
|
||||
}
|
||||
|
||||
else if (GetClass() == CASTERDPS && (GetLevel() >= RuleI(Spells, WizCritLevel)) && (zone->random.Roll(RuleI(Spells, WizCritChance)))) {
|
||||
ratio = zone->random.Int(1,100); //Wizard innate critical chance is calculated seperately from spell effect and is not a set ratio.
|
||||
Critical = true;
|
||||
}
|
||||
|
||||
ratio += RuleI(Spells, WizCritRatio); //Default is zero
|
||||
|
||||
if (Critical){
|
||||
|
||||
value = value_BaseEffect*ratio/100;
|
||||
|
||||
value += value_BaseEffect*GetFocusEffect(focusImprovedDamage, spell_id)/100;
|
||||
|
||||
value += int(value_BaseEffect*GetFocusEffect(focusFcDamagePctCrit, spell_id)/100)*ratio/100;
|
||||
|
||||
if (target) {
|
||||
value += int(value_BaseEffect*target->GetVulnerability(this, spell_id, 0)/100)*ratio/100;
|
||||
value -= target->GetFcDamageAmtIncoming(this, spell_id);
|
||||
}
|
||||
|
||||
value -= GetFocusEffect(focusFcDamageAmtCrit, spell_id)*ratio/100;
|
||||
|
||||
value -= GetFocusEffect(focusFcDamageAmt, spell_id);
|
||||
|
||||
if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
|
||||
value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value)*ratio/100;
|
||||
|
||||
value = (value * GetSpellScale() / 100);
|
||||
|
||||
entity_list.MessageClose_StringID(this, false, 100, MT_SpellCrits,
|
||||
OTHER_CRIT_BLAST, GetName(), itoa(-value));
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
value = value_BaseEffect;
|
||||
|
||||
value += value_BaseEffect*GetFocusEffect(focusImprovedDamage, spell_id)/100;
|
||||
|
||||
value += value_BaseEffect*GetFocusEffect(focusFcDamagePctCrit, spell_id)/100;
|
||||
|
||||
if (target) {
|
||||
value += value_BaseEffect*target->GetVulnerability(this, spell_id, 0)/100;
|
||||
value -= target->GetFcDamageAmtIncoming(this, spell_id);
|
||||
}
|
||||
|
||||
value -= GetFocusEffect(focusFcDamageAmtCrit, spell_id);
|
||||
|
||||
value -= GetFocusEffect(focusFcDamageAmt, spell_id);
|
||||
|
||||
if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
|
||||
value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value);
|
||||
|
||||
value = (value * GetSpellScale() / 100);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
int32 Merc::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
|
||||
|
||||
if (target == nullptr)
|
||||
target = this;
|
||||
|
||||
int32 value_BaseEffect = 0;
|
||||
int16 chance = 0;
|
||||
int8 modifier = 1;
|
||||
bool Critical = false;
|
||||
|
||||
value_BaseEffect = value + (value*GetFocusEffect(focusFcBaseEffects, spell_id)/100);
|
||||
|
||||
value = value_BaseEffect;
|
||||
|
||||
value += int(value_BaseEffect*GetFocusEffect(focusImprovedHeal, spell_id)/100);
|
||||
|
||||
// Instant Heals
|
||||
if(spells[spell_id].buffduration < 1) {
|
||||
|
||||
chance += itembonuses.CriticalHealChance + spellbonuses.CriticalHealChance + aabonuses.CriticalHealChance;
|
||||
|
||||
chance += target->GetFocusIncoming(focusFcHealPctCritIncoming, SE_FcHealPctCritIncoming, this, spell_id);
|
||||
|
||||
if (spellbonuses.CriticalHealDecay)
|
||||
chance += GetDecayEffectValue(spell_id, SE_CriticalHealDecay);
|
||||
|
||||
if(chance && zone->random.Roll(chance)) {
|
||||
Critical = true;
|
||||
modifier = 2; //At present time no critical heal amount modifier SPA exists.
|
||||
}
|
||||
|
||||
value *= modifier;
|
||||
value += GetFocusEffect(focusFcHealAmtCrit, spell_id) * modifier;
|
||||
value += GetFocusEffect(focusFcHealAmt, spell_id);
|
||||
value += target->GetFocusIncoming(focusFcHealAmtIncoming, SE_FcHealAmtIncoming, this, spell_id);
|
||||
|
||||
if(itembonuses.HealAmt && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
|
||||
value += GetExtraSpellAmt(spell_id, itembonuses.HealAmt, value) * modifier;
|
||||
|
||||
value += value*target->GetHealRate(spell_id, this)/100;
|
||||
|
||||
if (Critical)
|
||||
entity_list.MessageClose(this, false, 100, MT_SpellCrits, "%s performs an exceptional heal! (%d)", GetName(), value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
//Heal over time spells. [Heal Rate and Additional Healing effects do not increase this value]
|
||||
else {
|
||||
|
||||
chance = itembonuses.CriticalHealOverTime + spellbonuses.CriticalHealOverTime + aabonuses.CriticalHealOverTime;
|
||||
|
||||
chance += target->GetFocusIncoming(focusFcHealPctCritIncoming, SE_FcHealPctCritIncoming, this, spell_id);
|
||||
|
||||
if (spellbonuses.CriticalRegenDecay)
|
||||
chance += GetDecayEffectValue(spell_id, SE_CriticalRegenDecay);
|
||||
|
||||
if(chance && zone->random.Roll(chance))
|
||||
return (value * 2);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
int32 Merc::GetActSpellCost(uint16 spell_id, int32 cost)
|
||||
{
|
||||
// Formula = Unknown exact, based off a random percent chance up to mana cost(after focuses) of the cast spell
|
||||
|
||||
@ -83,8 +83,6 @@ public:
|
||||
Corpse* GetGroupMemberCorpse();
|
||||
|
||||
// Merc Spell Casting Methods
|
||||
virtual int32 GetActSpellDamage(uint16 spell_id, int32 value, Mob* target = nullptr);
|
||||
virtual int32 GetActSpellHealing(uint16 spell_id, int32 value, Mob* target = nullptr);
|
||||
virtual int32 GetActSpellCasttime(uint16 spell_id, int32 casttime);
|
||||
virtual int32 GetActSpellCost(uint16 spell_id, int32 cost);
|
||||
int8 GetChanceToCastBySpellType(int16 spellType);
|
||||
|
||||
@ -2926,6 +2926,10 @@ uint32 Mob::GetLevelHP(uint8 tlevel)
|
||||
}
|
||||
|
||||
int32 Mob::GetActSpellCasttime(uint16 spell_id, int32 casttime) {
|
||||
|
||||
int32 cast_reducer = 0;
|
||||
cast_reducer += GetFocusEffect(focusSpellHaste, spell_id);
|
||||
|
||||
if (level >= 60 && casttime > 1000)
|
||||
{
|
||||
casttime = casttime / 2;
|
||||
@ -2938,6 +2942,8 @@ int32 Mob::GetActSpellCasttime(uint16 spell_id, int32 casttime) {
|
||||
else
|
||||
casttime -= cast_deduction;
|
||||
}
|
||||
|
||||
casttime = (casttime*(100 - cast_reducer)/100);
|
||||
return(casttime);
|
||||
}
|
||||
|
||||
@ -2973,8 +2979,7 @@ void Mob::ExecWeaponProc(const ItemInst *inst, uint16 spell_id, Mob *on) {
|
||||
bool twinproc = false;
|
||||
int32 twinproc_chance = 0;
|
||||
|
||||
if(IsClient())
|
||||
twinproc_chance = CastToClient()->GetFocusEffect(focusTwincast, spell_id);
|
||||
twinproc_chance = GetFocusEffect(focusTwincast, spell_id);
|
||||
|
||||
if(twinproc_chance && zone->random.Roll(twinproc_chance))
|
||||
twinproc = true;
|
||||
|
||||
10
zone/mob.h
10
zone/mob.h
@ -198,11 +198,12 @@ public:
|
||||
bool item_bonus = false, uint32 ticsremaining = 0, int buffslot = -1,
|
||||
bool IsAISpellEffect = false, uint16 effect_id = 0, int32 se_base = 0, int32 se_limit = 0, int32 se_max = 0);
|
||||
void NegateSpellsBonuses(uint16 spell_id);
|
||||
virtual float GetActSpellRange(uint16 spell_id, float range, bool IsBard = false) { return range;}
|
||||
virtual int32 GetActSpellDamage(uint16 spell_id, int32 value, Mob* target = nullptr) { return value; }
|
||||
virtual int32 GetActSpellHealing(uint16 spell_id, int32 value, Mob* target = nullptr) { return value; }
|
||||
virtual float GetActSpellRange(uint16 spell_id, float range, bool IsBard = false);
|
||||
virtual int32 GetActSpellDamage(uint16 spell_id, int32 value, Mob* target = nullptr);
|
||||
virtual int32 GetActDoTDamage(uint16 spell_id, int32 value, Mob* target);
|
||||
virtual int32 GetActSpellHealing(uint16 spell_id, int32 value, Mob* target = nullptr);
|
||||
virtual int32 GetActSpellCost(uint16 spell_id, int32 cost){ return cost;}
|
||||
virtual int32 GetActSpellDuration(uint16 spell_id, int32 duration){ return duration;}
|
||||
virtual int32 GetActSpellDuration(uint16 spell_id, int32 duration);
|
||||
virtual int32 GetActSpellCasttime(uint16 spell_id, int32 casttime);
|
||||
float ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use_resist_override = false,
|
||||
int resist_override = 0, bool CharismaCheck = false, bool CharmTick = false, bool IsRoot = false);
|
||||
@ -1044,6 +1045,7 @@ protected:
|
||||
int GetKickDamage();
|
||||
int GetBashDamage();
|
||||
virtual void ApplySpecialAttackMod(SkillUseTypes skill, int32 &dmg, int32 &mindmg);
|
||||
virtual int16 GetFocusEffect(focusType type, uint16 spell_id) { return 0; }
|
||||
void CalculateNewFearpoint();
|
||||
float FindGroundZ(float new_x, float new_y, float z_offset=0.0);
|
||||
Map::Vertex UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &WaypointChange, bool &NodeReached);
|
||||
|
||||
@ -135,9 +135,6 @@ public:
|
||||
void CalcNPCRegen();
|
||||
void CalcNPCDamage();
|
||||
|
||||
int32 GetActSpellDamage(uint16 spell_id, int32 value, Mob* target = nullptr);
|
||||
int32 GetActSpellHealing(uint16 spell_id, int32 value, Mob* target = nullptr);
|
||||
|
||||
virtual void SetTarget(Mob* mob);
|
||||
virtual uint16 GetSkill(SkillUseTypes skill_num) const { if (skill_num <= HIGHEST_SKILL) { return skills[skill_num]; } return 0; }
|
||||
|
||||
@ -445,6 +442,8 @@ protected:
|
||||
virtual bool AICastSpell(Mob* tar, uint8 iChance, uint16 iSpellTypes);
|
||||
virtual bool AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgainBefore = 0);
|
||||
AISpellsVar_Struct AISpellVar;
|
||||
int16 GetFocusEffect(focusType type, uint16 spell_id);
|
||||
|
||||
|
||||
uint32 npc_spells_effects_id;
|
||||
std::vector<AISpellsEffects_Struct> AIspellsEffects;
|
||||
|
||||
@ -230,7 +230,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower,
|
||||
int16 act_power = 0; // The actual pet power we'll use.
|
||||
if (petpower == -1) {
|
||||
if (this->IsClient()) {
|
||||
act_power = CastToClient()->GetFocusEffect(focusPetPower, spell_id);
|
||||
act_power = CastToClient()->GetFocusEffect(focusPetPower, spell_id);//Client only
|
||||
act_power = CastToClient()->mod_pet_power(act_power, spell_id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,11 +179,8 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
|
||||
int numhit = spells[spell_id].numhits;
|
||||
|
||||
if (caster && caster->IsClient()){
|
||||
numhit += numhit*caster->CastToClient()->GetFocusEffect(focusFcLimitUse, spell_id)/100;
|
||||
numhit += caster->CastToClient()->GetFocusEffect(focusIncreaseNumHits, spell_id);
|
||||
}
|
||||
|
||||
numhit += numhit*caster->GetFocusEffect(focusFcLimitUse, spell_id)/100;
|
||||
numhit += caster->GetFocusEffect(focusIncreaseNumHits, spell_id);
|
||||
buffs[buffslot].numhits = numhit;
|
||||
}
|
||||
|
||||
@ -714,7 +711,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
mlog(COMBAT__HITS, "Stunned. We had %d percent resist chance.", stun_resist);
|
||||
|
||||
if (caster->IsClient())
|
||||
effect_value += effect_value*caster->CastToClient()->GetFocusEffect(focusFcStunTimeMod, spell_id)/100;
|
||||
effect_value += effect_value*caster->GetFocusEffect(focusFcStunTimeMod, spell_id)/100;
|
||||
|
||||
Stun(effect_value);
|
||||
} else {
|
||||
@ -2265,8 +2262,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
int16 focus = 0;
|
||||
int ReuseTime = spells[spell_id].recast_time + spells[spell_id].recovery_time;
|
||||
|
||||
if(caster->IsClient())
|
||||
focus = caster->CastToClient()->GetFocusEffect(focusFcBaseEffects, spell_id);
|
||||
focus = caster->GetFocusEffect(focusFcBaseEffects, spell_id);
|
||||
|
||||
switch(spells[spell_id].skill)
|
||||
{
|
||||
@ -3469,30 +3465,18 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste
|
||||
{
|
||||
effect_value = CalcSpellEffectValue(spell_id, i, caster_level, caster, ticsremaining);
|
||||
//Handle client cast DOTs here.
|
||||
if (caster && caster->IsClient() && IsDetrimentalSpell(spell_id) && effect_value < 0) {
|
||||
|
||||
effect_value = caster->CastToClient()->GetActDoTDamage(spell_id, effect_value, this);
|
||||
if (caster && effect_value < 0 && IsDetrimentalSpell(spell_id)){
|
||||
|
||||
if (caster->IsClient()){
|
||||
if (!caster->CastToClient()->GetFeigned())
|
||||
AddToHateList(caster, -effect_value);
|
||||
}
|
||||
|
||||
if(effect_value < 0)
|
||||
{
|
||||
if(caster)
|
||||
{
|
||||
if(!caster->IsClient()){
|
||||
|
||||
if (!IsClient()) //Allow NPC's to generate hate if casted on other NPC's.
|
||||
else if (!IsClient()) //Allow NPC's to generate hate if casted on other NPC's.
|
||||
AddToHateList(caster, -effect_value);
|
||||
}
|
||||
|
||||
if(caster->IsNPC())
|
||||
effect_value = caster->CastToNPC()->GetActSpellDamage(spell_id, effect_value, this);
|
||||
effect_value = caster->GetActDoTDamage(spell_id, effect_value, this);
|
||||
|
||||
caster->ResourceTap(-effect_value, spell_id);
|
||||
}
|
||||
|
||||
effect_value = -effect_value;
|
||||
Damage(caster, effect_value, spell_id, spell.skill, false, i, true);
|
||||
} else if(effect_value > 0) {
|
||||
@ -5318,11 +5302,8 @@ int16 Client::GetFocusEffect(focusType type, uint16 spell_id) {
|
||||
|
||||
//Improved Healing, Damage & Mana Reduction are handled differently in that some are random percentages
|
||||
//In these cases we need to find the most powerful effect, so that each piece of gear wont get its own chance
|
||||
if((type == focusManaCost || type == focusImprovedHeal || type == focusImprovedDamage)
|
||||
&& RuleB(Spells, LiveLikeFocusEffects))
|
||||
{
|
||||
if(RuleB(Spells, LiveLikeFocusEffects) && (type == focusManaCost || type == focusImprovedHeal || type == focusImprovedDamage))
|
||||
rand_effectiveness = true;
|
||||
}
|
||||
|
||||
//Check if item focus effect exists for the client.
|
||||
if (itembonuses.FocusEffects[type]){
|
||||
@ -5540,6 +5521,122 @@ int16 Client::GetFocusEffect(focusType type, uint16 spell_id) {
|
||||
return realTotal + realTotal2 + realTotal3;
|
||||
}
|
||||
|
||||
int16 NPC::GetFocusEffect(focusType type, uint16 spell_id) {
|
||||
|
||||
int16 realTotal = 0;
|
||||
int16 realTotal2 = 0;
|
||||
bool rand_effectiveness = false;
|
||||
|
||||
//Improved Healing, Damage & Mana Reduction are handled differently in that some are random percentages
|
||||
//In these cases we need to find the most powerful effect, so that each piece of gear wont get its own chance
|
||||
if(RuleB(Spells, LiveLikeFocusEffects) && (type == focusManaCost || type == focusImprovedHeal || type == focusImprovedDamage))
|
||||
rand_effectiveness = true;
|
||||
|
||||
if (RuleB(Spells, NPC_UseFocusFromItems) && itembonuses.FocusEffects[type]){
|
||||
|
||||
const Item_Struct* TempItem = 0;
|
||||
const Item_Struct* UsedItem = 0;
|
||||
uint16 UsedFocusID = 0;
|
||||
int16 Total = 0;
|
||||
int16 focus_max = 0;
|
||||
int16 focus_max_real = 0;
|
||||
|
||||
//item focus
|
||||
for(int i = 0; i < EmuConstants::EQUIPMENT_SIZE; i++){
|
||||
const Item_Struct *cur = database.GetItem(equipment[i]);
|
||||
|
||||
if(!cur)
|
||||
continue;
|
||||
|
||||
TempItem = cur;
|
||||
|
||||
if (TempItem && TempItem->Focus.Effect > 0 && TempItem->Focus.Effect != SPELL_UNKNOWN) {
|
||||
if(rand_effectiveness) {
|
||||
focus_max = CalcFocusEffect(type, TempItem->Focus.Effect, spell_id, true);
|
||||
if (focus_max > 0 && focus_max_real >= 0 && focus_max > focus_max_real) {
|
||||
focus_max_real = focus_max;
|
||||
UsedItem = TempItem;
|
||||
UsedFocusID = TempItem->Focus.Effect;
|
||||
} else if (focus_max < 0 && focus_max < focus_max_real) {
|
||||
focus_max_real = focus_max;
|
||||
UsedItem = TempItem;
|
||||
UsedFocusID = TempItem->Focus.Effect;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Total = CalcFocusEffect(type, TempItem->Focus.Effect, spell_id);
|
||||
if (Total > 0 && realTotal >= 0 && Total > realTotal) {
|
||||
realTotal = Total;
|
||||
UsedItem = TempItem;
|
||||
UsedFocusID = TempItem->Focus.Effect;
|
||||
} else if (Total < 0 && Total < realTotal) {
|
||||
realTotal = Total;
|
||||
UsedItem = TempItem;
|
||||
UsedFocusID = TempItem->Focus.Effect;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(UsedItem && rand_effectiveness && focus_max_real != 0)
|
||||
realTotal = CalcFocusEffect(type, UsedFocusID, spell_id);
|
||||
}
|
||||
|
||||
if (RuleB(Spells, NPC_UseFocusFromSpells) && spellbonuses.FocusEffects[type]){
|
||||
|
||||
//Spell Focus
|
||||
int16 Total2 = 0;
|
||||
int16 focus_max2 = 0;
|
||||
int16 focus_max_real2 = 0;
|
||||
|
||||
int buff_tracker = -1;
|
||||
int buff_slot = 0;
|
||||
uint16 focusspellid = 0;
|
||||
uint16 focusspell_tracker = 0;
|
||||
int buff_max = GetMaxTotalSlots();
|
||||
for (buff_slot = 0; buff_slot < buff_max; buff_slot++) {
|
||||
focusspellid = buffs[buff_slot].spellid;
|
||||
if (focusspellid == 0 || focusspellid >= SPDAT_RECORDS)
|
||||
continue;
|
||||
|
||||
if(rand_effectiveness) {
|
||||
focus_max2 = CalcFocusEffect(type, focusspellid, spell_id, true);
|
||||
if (focus_max2 > 0 && focus_max_real2 >= 0 && focus_max2 > focus_max_real2) {
|
||||
focus_max_real2 = focus_max2;
|
||||
buff_tracker = buff_slot;
|
||||
focusspell_tracker = focusspellid;
|
||||
} else if (focus_max2 < 0 && focus_max2 < focus_max_real2) {
|
||||
focus_max_real2 = focus_max2;
|
||||
buff_tracker = buff_slot;
|
||||
focusspell_tracker = focusspellid;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Total2 = CalcFocusEffect(type, focusspellid, spell_id);
|
||||
if (Total2 > 0 && realTotal2 >= 0 && Total2 > realTotal2) {
|
||||
realTotal2 = Total2;
|
||||
buff_tracker = buff_slot;
|
||||
focusspell_tracker = focusspellid;
|
||||
} else if (Total2 < 0 && Total2 < realTotal2) {
|
||||
realTotal2 = Total2;
|
||||
buff_tracker = buff_slot;
|
||||
focusspell_tracker = focusspellid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(focusspell_tracker && rand_effectiveness && focus_max_real2 != 0)
|
||||
realTotal2 = CalcFocusEffect(type, focusspell_tracker, spell_id);
|
||||
|
||||
// For effects like gift of mana that only fire once, save the spellid into an array that consists of all available buff slots.
|
||||
if(buff_tracker >= 0 && buffs[buff_tracker].numhits > 0) {
|
||||
m_spellHitsLeft[buff_tracker] = focusspell_tracker;
|
||||
}
|
||||
}
|
||||
|
||||
return realTotal + realTotal2;
|
||||
}
|
||||
|
||||
void Mob::CheckNumHitsRemaining(uint8 type, int32 buff_slot, uint16 spell_id)
|
||||
{
|
||||
/*
|
||||
@ -5946,15 +6043,13 @@ int32 Mob::ApplySpellEffectiveness(Mob* caster, int16 spell_id, int32 value, boo
|
||||
if (!caster)
|
||||
return value;
|
||||
|
||||
if (caster->IsClient()){
|
||||
int16 focus = caster->CastToClient()->GetFocusEffect(focusFcBaseEffects, spell_id);
|
||||
int16 focus = GetFocusEffect(focusFcBaseEffects, spell_id);
|
||||
|
||||
if (IsBard)
|
||||
value += focus;
|
||||
|
||||
else
|
||||
value += value*focus/100;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@ -176,7 +176,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
|
||||
BuffFadeByEffect(SE_Sanctuary);
|
||||
|
||||
if(IsClient()){
|
||||
int chance = CastToClient()->GetFocusEffect(focusFcMute, spell_id);
|
||||
int chance = CastToClient()->GetFocusEffect(focusFcMute, spell_id);//Client only
|
||||
|
||||
if (zone->random.Roll(chance)) {
|
||||
Message_StringID(13, SILENCED_STRING);
|
||||
@ -1043,7 +1043,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot,
|
||||
// Check for consumables and Reagent focus items
|
||||
// first check for component reduction
|
||||
if(IsClient()) {
|
||||
int reg_focus = CastToClient()->GetFocusEffect(focusReagentCost,spell_id);
|
||||
int reg_focus = CastToClient()->GetFocusEffect(focusReagentCost,spell_id);//Client only
|
||||
if(zone->random.Roll(reg_focus)) {
|
||||
mlog(SPELLS__CASTING, "Spell %d: Reagent focus item prevented reagent consumption (%d chance)", spell_id, reg_focus);
|
||||
} else {
|
||||
@ -2237,7 +2237,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
|
||||
{
|
||||
recast -= GetAA(aaTouchoftheWicked) * 420;
|
||||
}
|
||||
int reduction = CastToClient()->GetFocusEffect(focusReduceRecastTime, spell_id);
|
||||
int reduction = CastToClient()->GetFocusEffect(focusReduceRecastTime, spell_id);//Client only
|
||||
if(reduction)
|
||||
recast -= reduction;
|
||||
|
||||
@ -4189,14 +4189,8 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use
|
||||
|
||||
//Get resist modifier and adjust it based on focus 2 resist about eq to 1% resist chance
|
||||
int resist_modifier = (use_resist_override) ? resist_override : spells[spell_id].ResistDiff;
|
||||
if(caster->IsClient())
|
||||
{
|
||||
if(IsValidSpell(spell_id))
|
||||
{
|
||||
int focus_resist = caster->CastToClient()->GetFocusEffect(focusResistRate, spell_id);
|
||||
int focus_resist = caster->GetFocusEffect(focusResistRate, spell_id);
|
||||
resist_modifier -= 2 * focus_resist;
|
||||
}
|
||||
}
|
||||
|
||||
//Check for fear resist
|
||||
bool IsFear = false;
|
||||
@ -4580,16 +4574,13 @@ float Mob::GetAOERange(uint16 spell_id) {
|
||||
if(range == 0)
|
||||
range = 10; //something....
|
||||
|
||||
if (IsClient()) {
|
||||
|
||||
if(IsBardSong(spell_id) && IsBeneficialSpell(spell_id)) {
|
||||
//Live AA - Extended Notes, SionachiesCrescendo
|
||||
float song_bonus = static_cast<float>(aabonuses.SongRange + spellbonuses.SongRange + itembonuses.SongRange);
|
||||
range += range*song_bonus /100.0f;
|
||||
}
|
||||
|
||||
range = CastToClient()->GetActSpellRange(spell_id, range);
|
||||
}
|
||||
range = GetActSpellRange(spell_id, range);
|
||||
|
||||
return(range);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user