Пример #1
0
// 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)
{
    LinkedListIterator<Mob*> iterator(mob_list);
    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(iterator.Reset(); iterator.MoreElements(); iterator.Advance())
    {
        curmob = iterator.GetData();
        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;
        }

        //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++;
    }
}
Пример #2
0
bool IsPoisonSpell(int16 spell_id) {
	if (IsDetrimentalSpell(spell_id) && IsEffectInSpell(spell_id, SE_PoisonCounter)){
		return true;
	}
	else {
		return false;
	}
}
Пример #3
0
bool IsMaloSpell(int16 spell_id) {
	if (IsDetrimentalSpell(spell_id) && IsEffectInSpell(spell_id, SE_ResistFire) && IsEffectInSpell(spell_id, SE_ResistCold) && IsEffectInSpell(spell_id, SE_ResistPoison) && IsEffectInSpell(spell_id, SE_ResistMagic)){
		return true;
	}
	else {
		return false;
	}
}
Пример #4
0
bool IsSnareSpell(int16 spell_id) {
	if (IsDetrimentalSpell(spell_id) && IsEffectInSpell(spell_id, SE_MovementSpeed)){
		return true;
	}
	else {
		return false;
	}
}
Пример #5
0
// checks if this spell can be targeted
bool IsTGBCompatibleSpell(uint16 spell_id)
{
	if (IsValidSpell(spell_id) &&
			(!IsDetrimentalSpell(spell_id) && spells[spell_id].buffduration != 0 &&
			 !IsBardSong(spell_id) && !IsEffectInSpell(spell_id, SE_Illusion)))
		return true;

	return false;
}
Пример #6
0
bool IsResistableSpell(uint16 spell_id)
{
	// for now only detrimental spells are resistable. later on i will
	// add specific exceptions for the beneficial spells that are resistable
	if (IsDetrimentalSpell(spell_id))
		return true;

	return false;
}
Пример #7
0
// solar: causes caster to hit every mob within dist range of center with
// a bard pulse of spell_id.
// NPC spells will only affect other NPCs with compatible faction
void EntityList::AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster)
{
    Mob *curmob;

    float dist = caster->GetAOERange(spell_id);
    float dist2 = dist * dist;

    bool bad = IsDetrimentalSpell(spell_id);
    bool isnpc = caster->IsNPC();

    for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
        curmob = it->second;
        if (curmob == center)	//do not affect center
            continue;
        if (curmob == caster && !affect_caster)	//watch for caster too
            continue;
        if (DistanceSquared(center->GetPosition(), curmob->GetPosition()) > 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 (!center->CheckLosFN(curmob))
                continue;
        } else { // check to stop casting beneficial ae buffs (to wit: bard songs) on enemies...
            // See notes in AESpell() above for more info.
            if (caster->IsAttackAllowed(curmob, true))
                continue;
            if (caster->CheckAggro(curmob))
                continue;

            AddHealAggro(curmob, caster, caster->CheckHealAggroAmount(spell_id, curmob));
        }

        //if we get here... cast the spell.
        curmob->BardPulse(spell_id, caster);
    }
    if (caster->IsClient())
        caster->CastToClient()->CheckSongSkillIncrease(spell_id);
}
Пример #8
0
void EntityList::MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster)
{
    LinkedListIterator<Mob*> iterator(mob_list);
    Mob *curmob;

    float dist = caster->GetAOERange(spell_id);
    float dist2 = dist * dist;

    bool bad = IsDetrimentalSpell(spell_id);

    for(iterator.Reset(); iterator.MoreElements(); iterator.Advance())
    {
        curmob = iterator.GetData();
        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;

        //Only npcs mgb should hit are client pets...
        if(curmob->IsNPC())
        {
            Mob *owner = curmob->GetOwner();
            if(owner)
            {
                if(!owner->IsClient())
                {
                    continue;
                }
            }
            else
            {
                continue;
            }
        }

        if(bad)
        {
            continue;
        }

        caster->SpellOnTarget(spell_id, curmob);
    }
}
Пример #9
0
// solar: causes caster to hit every mob within dist range of center with
// a bard pulse of spell_id.
// NPC spells will only affect other NPCs with compatible faction
void EntityList::AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster)
{
    LinkedListIterator<Mob*> iterator(mob_list);
    Mob *curmob;

    float dist = caster->GetAOERange(spell_id);
    float dist2 = dist * dist;

    bool bad = IsDetrimentalSpell(spell_id);
    bool isnpc = caster->IsNPC();

    for(iterator.Reset(); iterator.MoreElements(); iterator.Advance())
    {
        curmob = iterator.GetData();
        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(!center->CheckLosFN(curmob))
                continue;
        }
        //if we get here... cast the spell.
        curmob->BardPulse(spell_id, caster);
    }
    if(caster->IsClient())
        caster->CastToClient()->CheckSongSkillIncrease(spell_id);
}
Пример #10
0
void EntityList::MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster)
{
	Mob *curmob;

	float dist = caster->GetAOERange(spell_id);
	float dist2 = dist * dist;

	bool bad = IsDetrimentalSpell(spell_id);

	for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
		curmob = it->second;
		if (curmob == center)	//do not affect center
			continue;
		if (curmob == caster && !affect_caster)	//watch for caster too
			continue;
		if (DistanceSquared(center->GetPosition(), curmob->GetPosition()) > dist2)	//make sure they are in range
			continue;

		//Only npcs mgb should hit are client pets...
		if (curmob->IsNPC()) {
			Mob *owner = curmob->GetOwner();
			if (owner) {
				if (!owner->IsClient()) {
					continue;
				}
			} else {
				continue;
			}
		}

		if (bad) {
			continue;
		}

		caster->SpellOnTarget(spell_id, curmob);
	}
}
Пример #11
0
// 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++;
	}
}
Пример #12
0
// 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++;
	}
}
Пример #13
0
// 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);
}