本文整理汇总了C++中Mob::CastToClient方法的典型用法代码示例。如果您正苦于以下问题:C++ Mob::CastToClient方法的具体用法?C++ Mob::CastToClient怎么用?C++ Mob::CastToClient使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Mob
的用法示例。
在下文中一共展示了Mob::CastToClient方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: Process
bool Trap::Process()
{
if (chkarea_timer.Enabled() && chkarea_timer.Check() && !reset_timer.Enabled())
{
Mob* trigger = entity_list.GetTrapTrigger(this);
if (trigger && !(trigger->IsClient() && trigger->CastToClient()->GetGM()))
{
Trigger(trigger);
}
}
else if (reset_timer.Enabled() && reset_timer.Check())
{
Log.Out(Logs::General, Logs::Traps, "Reset timer disabled in Reset Check Process for trap %d.", trap_id);
reset_timer.Disable();
charid = 0;
}
if (respawn_timer.Enabled() && respawn_timer.Check())
{
detected = false;
disarmed = false;
chkarea_timer.Enable();
respawn_timer.Disable();
}
return true;
}
示例2: Wipe
void HateList::Wipe()
{
LinkedListIterator<tHateEntry*> iterator(list);
iterator.Reset();
while(iterator.MoreElements())
{
Mob* m = iterator.GetData()->ent;
parse->EventNPC(EVENT_HATE_LIST, owner->CastToNPC(), m, "0", 0);
iterator.RemoveCurrent();
if(m->IsClient())
m->CastToClient()->DecrementAggroCount();
}
}
示例3: Wipe
void HateList::Wipe()
{
auto iterator = list.begin();
while(iterator != list.end())
{
Mob* m = (*iterator)->ent;
parse->EventNPC(EVENT_HATE_LIST, owner->CastToNPC(), m, "0", 0);
//iterator
delete (*iterator);
iterator = list.erase(iterator);
if(m->IsClient())
m->CastToClient()->DecrementAggroCount();
}
}
示例4: Process
bool Trap::Process()
{
if (chkarea_timer.Enabled() && chkarea_timer.Check()
/*&& zone->GetClientCount() > 0*/ )
{
Mob* trigger = entity_list.GetTrapTrigger(this);
if (trigger && !(trigger->IsClient() && trigger->CastToClient()->GetGM()))
{
Trigger(trigger);
}
}
if (respawn_timer.Enabled() && respawn_timer.Check())
{
detected = false;
disarmed = false;
chkarea_timer.Enable();
respawn_timer.Disable();
}
return true;
}
示例5: CheckWillAggro
/*
If you change this function, you should update the above function
to keep the #aggro command accurate.
*/
bool Mob::CheckWillAggro(Mob *mob) {
if(!mob)
return false;
//sometimes if a client has some lag while zoning into a dangerous place while either invis or a GM
//they will aggro mobs even though it's supposed to be impossible, to lets make sure we've finished connecting
if (mob->IsClient()) {
if (!mob->CastToClient()->ClientFinishedLoading() || mob->CastToClient()->IsHoveringForRespawn())
return false;
}
Mob *ownr = mob->GetOwner();
if(ownr && ownr->IsClient() && !ownr->CastToClient()->ClientFinishedLoading())
return false;
float iAggroRange = GetAggroRange();
// Check If it's invisible and if we can see invis
// Check if it's a client, and that the client is connected and not linkdead,
// and that the client isn't Playing an NPC, with thier gm flag on
// Check if it's not a Interactive NPC
// Trumpcard: The 1st 3 checks are low cost calcs to filter out unnessecary distance checks. Leave them at the beginning, they are the most likely occurence.
// Image: I moved this up by itself above faction and distance checks because if one of these return true, theres no reason to go through the other information
float t1, t2, t3;
t1 = mob->GetX() - GetX();
t2 = mob->GetY() - GetY();
t3 = mob->GetZ() - GetZ();
//Cheap ABS()
if(t1 < 0)
t1 = 0 - t1;
if(t2 < 0)
t2 = 0 - t2;
if(t3 < 0)
t3 = 0 - t3;
if(( t1 > iAggroRange)
|| ( t2 > iAggroRange)
|| ( t3 > iAggroRange)
||(mob->IsInvisible(this))
|| (mob->IsClient() &&
(!mob->CastToClient()->Connected()
|| mob->CastToClient()->IsLD()
|| mob->CastToClient()->IsBecomeNPC()
|| mob->CastToClient()->GetGM()
)
))
{
return(false);
}
// Don't aggro new clients if we are already engaged unless PROX_AGGRO is set
if (IsEngaged() && (!GetSpecialAbility(PROX_AGGRO) || (GetSpecialAbility(PROX_AGGRO) && !CombatRange(mob)))) {
Log.Out(Logs::Moderate, Logs::Aggro,
"%s is in combat, and does not have prox_aggro, or does and is out of combat range with %s",
GetName(), mob->GetName());
return false;
}
//im not sure I understand this..
//if I have an owner and it is not this mob, then I cannot
//aggro this mob...???
//changed to be 'if I have an owner and this is it'
if(mob == GetOwner()) {
return(false);
}
float dist2 = DistanceSquared(mob->GetPosition(), m_Position);
float iAggroRange2 = iAggroRange*iAggroRange;
if( dist2 > iAggroRange2 ) {
// Skip it, out of range
return(false);
}
//Image: Get their current target and faction value now that its required
//this function call should seem backwards
FACTION_VALUE fv = mob->GetReverseFactionCon(this);
// Make sure they're still in the zone
// Are they in range?
// Are they kos?
// Are we stupid or are they green
// and they don't have their gm flag on
int heroicCHA_mod = mob->itembonuses.HeroicCHA/25; // 800 Heroic CHA cap
if(heroicCHA_mod > THREATENLY_ARRGO_CHANCE)
heroicCHA_mod = THREATENLY_ARRGO_CHANCE;
if
(
//old InZone check taken care of above by !mob->CastToClient()->Connected()
(
( GetINT() <= RuleI(Aggro, IntAggroThreshold) )
||( mob->IsClient() && mob->CastToClient()->IsSitting() )
||( mob->GetLevelCon(GetLevel()) != CON_GREEN )
)
&&
//.........这里部分代码省略.........
示例6: AESpell
// causes caster to hit every mob within dist range of center with
// spell_id.
// NPC spells will only affect other NPCs with compatible faction
void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster, int16 resist_adjust)
{
Mob *curmob;
float dist = caster->GetAOERange(spell_id);
float dist2 = dist * dist;
float min_range2 = spells[spell_id].min_range * spells[spell_id].min_range;
float dist_targ = 0;
bool bad = IsDetrimentalSpell(spell_id);
bool isnpc = caster->IsNPC();
int MAX_TARGETS_ALLOWED = 4;
if (spells[spell_id].aemaxtargets)
MAX_TARGETS_ALLOWED = spells[spell_id].aemaxtargets;
int iCounter = 0;
for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
curmob = it->second;
// test to fix possible cause of random zone crashes..external methods accessing client properties before they're initialized
if (curmob->IsClient() && !curmob->CastToClient()->ClientFinishedLoading())
continue;
if (curmob == center) //do not affect center
continue;
if (curmob == caster && !affect_caster) //watch for caster too
continue;
if (spells[spell_id].targettype == ST_TargetAENoPlayersPets && curmob->IsPetOwnerClient())
continue;
if (spells[spell_id].targettype == ST_AreaClientOnly && !curmob->IsClient())
continue;
if (spells[spell_id].targettype == ST_AreaNPCOnly && !curmob->IsNPC())
continue;
if (spells[spell_id].targettype == ST_Ring) {
dist_targ = DistanceSquared(static_cast<glm::vec3>(curmob->GetPosition()), caster->GetTargetRingLocation());
}
else if (center) {
dist_targ = DistanceSquared(curmob->GetPosition(), center->GetPosition());
}
if (dist_targ > dist2) //make sure they are in range
continue;
if (dist_targ < min_range2) //make sure they are in range
continue;
if (isnpc && curmob->IsNPC()) { //check npc->npc casting
FACTION_VALUE f = curmob->GetReverseFactionCon(caster);
if (bad) {
//affect mobs that are on our hate list, or
//which have bad faction with us
if (!(caster->CheckAggro(curmob) || f == FACTION_THREATENLY || f == FACTION_SCOWLS) )
continue;
} else {
//only affect mobs we would assist.
if (!(f <= FACTION_AMIABLE))
continue;
}
}
//finally, make sure they are within range
if (bad) {
if (!caster->IsAttackAllowed(curmob, true))
continue;
if (center && !spells[spell_id].npc_no_los && !center->CheckLosFN(curmob))
continue;
if (!center && !spells[spell_id].npc_no_los && !caster->CheckLosFN(caster->GetTargetRingX(), caster->GetTargetRingY(), caster->GetTargetRingZ(), curmob->GetSize()))
continue;
} else { // check to stop casting beneficial ae buffs (to wit: bard songs) on enemies...
// This does not check faction for beneficial AE buffs..only agro and attackable.
// I've tested for spells that I can find without problem, but a faction-based
// check may still be needed. Any changes here should also reflect in BardAEPulse()
if (caster->IsAttackAllowed(curmob, true))
continue;
if (caster->CheckAggro(curmob))
continue;
}
curmob->CalcSpellPowerDistanceMod(spell_id, dist_targ);
//if we get here... cast the spell.
if (IsTargetableAESpell(spell_id) && bad) {
if (iCounter < MAX_TARGETS_ALLOWED) {
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
}
} else {
if (spells[spell_id].aemaxtargets && iCounter < spells[spell_id].aemaxtargets)
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
if (!spells[spell_id].aemaxtargets)
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
}
if (!isnpc || spells[spell_id].aemaxtargets) //npcs are not target limited (unless casting a spell with a target limit)...
iCounter++;
}
}
示例7: AESpell
// solar: causes caster to hit every mob within dist range of center with
// spell_id.
// NPC spells will only affect other NPCs with compatible faction
void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster, int16 resist_adjust)
{
Mob *curmob;
float dist = caster->GetAOERange(spell_id);
float dist2 = dist * dist;
bool bad = IsDetrimentalSpell(spell_id);
bool isnpc = caster->IsNPC();
const int MAX_TARGETS_ALLOWED = 4;
int iCounter = 0;
for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
curmob = it->second;
// test to fix possible cause of random zone crashes..external methods accessing client properties before they're initialized
if (curmob->IsClient() && !curmob->CastToClient()->ClientFinishedLoading())
continue;
if (curmob == center) //do not affect center
continue;
if (curmob == caster && !affect_caster) //watch for caster too
continue;
if (center->DistNoRoot(*curmob) > dist2) //make sure they are in range
continue;
if (isnpc && curmob->IsNPC()) { //check npc->npc casting
FACTION_VALUE f = curmob->GetReverseFactionCon(caster);
if (bad) {
//affect mobs that are on our hate list, or
//which have bad faction with us
if (!(caster->CheckAggro(curmob) || f == FACTION_THREATENLY || f == FACTION_SCOWLS) )
continue;
} else {
//only affect mobs we would assist.
if (!(f <= FACTION_AMIABLE))
continue;
}
}
//finally, make sure they are within range
if (bad) {
if (!caster->IsAttackAllowed(curmob, true))
continue;
if (!center->CheckLosFN(curmob))
continue;
} else { // check to stop casting beneficial ae buffs (to wit: bard songs) on enemies...
// This does not check faction for beneficial AE buffs..only agro and attackable.
// I've tested for spells that I can find without problem, but a faction-based
// check may still be needed. Any changes here should also reflect in BardAEPulse() -U
if (caster->IsAttackAllowed(curmob, true))
continue;
if (caster->CheckAggro(curmob))
continue;
}
//if we get here... cast the spell.
if (IsTargetableAESpell(spell_id) && bad) {
if (iCounter < MAX_TARGETS_ALLOWED) {
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
}
} else {
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
}
if (!isnpc) //npcs are not target limited...
iCounter++;
}
}
示例8: BuffFadeBySlot
//o--------------------------------------------------------------
//| BuffFadeBySlot; Yeahlight, Nov 16, 2008
//o--------------------------------------------------------------
//| Adapted from EQEMU 7.0: Removes the buff in the supplied
//| buff slot 'slot'
//o--------------------------------------------------------------
void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
{
bool debugFlag = true;
if(slot < 0 || slot > BUFF_COUNT)
return;
if(!buffs[slot].spell || !buffs[slot].spell->IsValidSpell())
return;
if(IsClient())
CastToClient()->MakeBuffFadePacket(buffs[slot].spell, slot);
if(debugFlag && this->IsClient() && this->CastToClient()->GetDebugMe())
this->Message(LIGHTEN_BLUE, "Debug: Fading buff %d from slot %d", buffs[slot].spell->GetSpellID(), slot);
for(int i = 0; i < EFFECT_COUNT; i++)
{
if(buffs[slot].spell->IsBlankSpellEffect(i))
continue;
switch(buffs[slot].spell->GetSpellEffectID(i))
{
case SE_WeaponProc:
{
SetBonusProcSpell(0);
break;
}
case SE_Illusion: case SE_IllusionCopy:
{
SendIllusionPacket(GetBaseRace(), GetBaseGender(), GetTexture(), GetHelmTexture());
SendAppearancePacket(this->GetID(), SAT_Size, GetDefaultSize(), true);
break;
}
case SE_Levitate:
{
SendAppearancePacket(this->GetID(), SAT_Levitate, 0, true);
break;
}
case SE_Invisibility:
{
SetInvisible(false);
break;
}
case SE_InvisVsUndead:
{
SetInvisibleUndead(false);
break;
}
case SE_InvisVsAnimals:
{
SetInvisibleAnimal(false);
break;
}
case SE_Silence:
{
break;
}
case SE_DivineAura:
{
SetInvulnerable(false);
break;
}
case SE_Rune:
{
break;
}
case SE_AbsorbMagicAtt:
{
break;
}
case SE_Mez:
{
//Yeahlight: Unfreeze the PC's UI
if(IsClient())
SendAppearancePacket(this->GetID(), SAT_Position_Update, SAPP_Sitting_To_Standing, true);
this->mesmerized = false;
break;
}
case SE_Charm:
{
Mob* charmer = entity_list.GetMob(this->GetOwnerID());
if(charmer && charmer->IsClient())
{
char npcNameSuffix[] = "_CHARM00";
char npcNamePrefix[100] = "";
strcpy(npcNamePrefix, charmer->GetName());
strcat(npcNamePrefix, npcNameSuffix);
Mob* charmPH = entity_list.GetMob(npcNamePrefix);
if(charmPH && charmPH->IsNPC())
{
charmPH->Depop();
}
//Yeahlight: Check for _CHARM01 NPC, too
//.........这里部分代码省略.........
示例9: SpellEffect
///////////////////////////////////////////////////
// Quagmire - that case above getting to long and spells are gonna have a lot of cases of their own
// Cofruben - Reorganised this a little.
void Mob::SpellEffect(Mob* caster, Spell* spell, int8 caster_level, bool partialResist)
{
//Spells not loaded!
if(!spells_handler.SpellsLoaded())
return;
//Spell not loaded!
if(!spell)
return;
//Yeahlight: Caster was not supplied
if(!caster)
return;
int i = 0;
const int16 spell_id = spell->GetSpellID();
const char* teleport_zone = spell->GetSpellTeleportZone();
// 1. Is it a buff? If so, handle its time based effects.
if (spell->IsBuffSpell())
spells_handler.HandleBuffSpellEffects(caster, this, spell);
// 2. Handle its single-time effect.
for (i = 0; i < EFFECT_COUNT; i++)
{
TSpellEffect effect_id = spell->GetSpellEffectID(i);
if(effect_id == SE_Blank || effect_id == 0xFF)
continue;
int8 formula = spell->GetSpellFormula(i);
sint16 base = spell->GetSpellBase(i);
sint16 max = spell->GetSpellMax(i);
sint32 amount = spells_handler.CalcSpellValue(spell, i, caster_level);
//Yeahlight: This is an NPC and had a detremental spell casted upon it
if(this->IsNPC() && (spell->IsDetrimentalSpell() || spell->IsUtilitySpell()))
{
CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): aggroing %s because of the spell effect!", spell->GetSpellName(), this->GetName());
//Yeahlight: Generate hate based on the spells's effect type
sint16 tempHate = GetSpellHate(effect_id, spell->GetMinLevel(), false, amount);
if(tempHate)
{
this->CastToNPC()->AddToHateList(caster, 0, tempHate);
}
}
switch(effect_id)
{
case SE_CurrentHP:
case SE_CurrentHPOnce:
{
sint32 OldHP = this->GetHP();
sint32 damage = amount;
//Yeahlight: Partial resist calculations
if(partialResist)
{
damage = damage / 2;
damage = damage * (float)((float)(rand()%90 + 10) / 100.00f);
if(caster->IsClient() && caster->CastToClient()->GetDebugMe())
caster->Message(YELLOW, "Debug: Your direct damage spell resist has been upgrade to a partial resist.");
}
this->ChangeHP(caster, damage, spell_id);
sint32 NewHP = this->GetHP();
CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You changed %s's hp by %+i.", spell->GetSpellName(), this->GetName(), damage);
break;
}
case SE_MovementSpeed:
{
//Yeahlight: Handled client side
CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a Movement Speed spell, amount: %i.", spell->GetSpellName(), amount);
break;
}
case SE_AttackSpeed:
{
//Yeahlight: There should not be any work to be done here
CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a Attack Speed spell, amount: %i.", spell->GetSpellName(), amount);
break;
}
case SE_Invisibility:
{
this->SetInvisible(true);
//Yeahlight: Castee has a pet; remove it
if(GetPet())
{
Mob* myPet = GetPet();
//Yeahlight: Castee's pet is an NPC
if(myPet->IsNPC())
{
//Yeahlight: Castee's pet is a charmed NPC
if(myPet->CastToNPC()->IsCharmed())
{
myPet->CastToNPC()->BuffFadeByEffect(SE_Charm);
}
//Yeahlight: Castee's pet is a summoned NPC
else
{
myPet->Depop();
}
}
//Yeahlight: Castee's pet is a charmed PC
else if(myPet->IsClient() && myPet->CastToClient()->IsCharmed())
{
//.........这里部分代码省略.........
示例10: GetRewardingGroup
//Yeahlight: Searches for the group that will be rewarded with exp and first loot rights
returnGroup HateList::GetRewardingGroup()
{
groupDamage groupsToConsider[255] = {0};
int16 groupCounter = 0;
int16 groupID = 0;
int16 leadingGroupID = 0;
sint32 highestGroupDamage = 0;
sint32 entityDamage = 0;
Mob* entity = NULL;
returnGroup groupToReward;
Group* group = NULL;
bool groupFound = false;
for(int i = 0; i < 255; i++)
{
groupsToConsider[i].groupID = -1;
groupsToConsider[i].groupDamageTotal = -1;
}
groupToReward.damage = 0;
groupToReward.group = NULL;
LinkedListIterator<tHateEntry*> iterator(list);
iterator.Reset();
while(iterator.MoreElements())
{
entityDamage = 0;
if(iterator.GetData())
entityDamage = iterator.GetData()->damage;
if(entityDamage > 0)
{
entity = iterator.GetData()->ent;
//Yeahlight: Entity exists in the zone
if(entity)
{
//Yeahlight: Entity is a client
if(entity->IsClient())
{
//Yeahlight: PC is grouped
if(entity->CastToClient()->IsGrouped())
{
group = entity_list.GetGroupByClient(entity->CastToClient());
//Yeahlight: Group exists
if(group)
{
groupID = group->GetID();
//Yeahlight: We do not have a group list started yet, so start it off with this group
if(groupCounter == 0)
{
groupsToConsider[0].groupID = groupID;
groupsToConsider[0].groupDamageTotal = iterator.GetData()->damage;
groupsToConsider[0].group = group;
groupCounter++;
}
//Yeahlight: A group list has been created already
else
{
//Yeahlight: Iterate through the group list
for(int i = 0; i < groupCounter; i++)
{
//Yeahlight: Found the group for which this PC resides
if(groupID == groupsToConsider[i].groupID)
{
//Yeahlight: Add the client's damage to the group's total
groupsToConsider[i].groupDamageTotal += iterator.GetData()->damage;
//Yeahlight: Flag the PC as found
groupFound = true;
//Yeahlight: "Break out" of the loop
i = groupCounter;
}
}
//Yeahlight: This grouped PC did not find their group in the list, so we need to add their group
if(!groupFound)
{
groupsToConsider[groupCounter].groupID = groupID;
groupsToConsider[groupCounter].groupDamageTotal = iterator.GetData()->damage;
groupsToConsider[groupCounter].group = group;
groupCounter++;
}
}
}
//Yeahlight: Group does not exist
else
{
}
}
//Yeahlight: PC is not grouped
else
{
}
}
//Yeahlight: Entity is the pet of a client
else if(entity->IsNPC() && entity->GetOwner() && entity->GetOwner()->IsClient())
{
//Yeahlight: Owner of the pet is grouped
if(entity->GetOwner()->CastToClient()->IsGrouped())
{
group = entity_list.GetGroupByClient(entity->GetOwner()->CastToClient());
//.........这里部分代码省略.........
示例11: AESpell
// solar: causes caster to hit every mob within dist range of center with
// spell_id.
// NPC spells will only affect other NPCs with compatible faction
void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster, int16 resist_adjust)
{
Mob *curmob;
float dist = caster->GetAOERange(spell_id);
float dist2 = dist * dist;
float min_range2 = spells[spell_id].min_range * spells[spell_id].min_range;
float dist_targ = 0;
bool detrimental = IsDetrimentalSpell(spell_id);
bool clientcaster = caster->IsClient();
const int MAX_TARGETS_ALLOWED = 4;
int targets_hit = 0;
if(center->IsBeacon())
targets_hit = center->CastToBeacon()->GetTargetsHit();
for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
curmob = it->second;
// test to fix possible cause of random zone crashes..external methods accessing client properties before they're initialized
if (curmob->IsClient() && !curmob->CastToClient()->ClientFinishedLoading())
continue;
if (curmob == center) //do not affect center
continue;
if (curmob == caster && !affect_caster) //watch for caster too
continue;
dist_targ = DistanceSquared(curmob->GetPosition(), center->GetPosition());
if (dist_targ > dist2) //make sure they are in range
continue;
if (dist_targ < min_range2) //make sure they are in range
continue;
if (!clientcaster && curmob->IsNPC()) { //check npc->npc casting
FACTION_VALUE f = curmob->GetReverseFactionCon(caster);
if (detrimental) {
//affect mobs that are on our hate list, or
//which have bad faction with us
if (!(caster->CheckAggro(curmob) || f == FACTION_THREATENLY || f == FACTION_SCOWLS))
continue;
}
else {
//only affect mobs we would assist.
if (!(f <= FACTION_AMIABLE))
continue;
}
}
//finally, make sure they are within range
if (detrimental) {
if (!caster->IsAttackAllowed(curmob, true))
{
Log.Out(Logs::Detail, Logs::Spells, "Attempting to cast a detrimental AE spell/song on a player.");
continue;
}
if (!zone->SkipLoS() && !spells[spell_id].npc_no_los && curmob != caster && !center->CheckLosFN(curmob))
continue;
}
else { // check to stop casting beneficial ae buffs (to wit: bard songs) on enemies...
// This does not check faction for beneficial AE buffs..only agro and attackable.
// I've tested for spells that I can find without problem, but a faction-based
// check may still be needed. Any changes here should also reflect in BardAEPulse() -U
if (caster->IsAttackAllowed(curmob, true))
{
Log.Out(Logs::Detail, Logs::Spells, "Attempting to cast a beneficial AE spell/song on a NPC.");
caster->Message_StringID(MT_SpellFailure, SPELL_NO_HOLD);
continue;
}
if (caster->CheckAggro(curmob))
continue;
}
curmob->CalcSpellPowerDistanceMod(spell_id, dist_targ);
//if we get here... cast the spell.
if (IsTargetableAESpell(spell_id) && detrimental)
{
if (targets_hit < MAX_TARGETS_ALLOWED || (clientcaster && curmob == caster))
{
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
Log.Out(Logs::Detail, Logs::Spells, "AE Rain Spell: %d has hit target #%d: %s", spell_id, targets_hit, curmob->GetCleanName());
if (clientcaster && curmob != caster) //npcs are not target limited, pc caster does not count towards the limit.
++targets_hit;
}
}
else
{
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
}
}
if(center->IsBeacon())
center->CastToBeacon()->SetTargetsHit(targets_hit);
}