Пример #1
0
    void OnLoad()
    {
        if (_unit->IsSummon())
        {
            Summon* s = TO< Summon* >(_unit);
            Unit* owner = s->GetOwner();

            owner->CastSpell(_unit, 45204, true);   // clone me
            owner->CastSpell(_unit, 58838, true);   // inherit threat list

            // Mage mirror image spell
            if (_unit->GetCreatedBySpell() == 58833)
            {
                _unit->SetMaxHealth(2500);
                _unit->SetHealth(2500);
                _unit->SetMaxPower(POWER_TYPE_MANA, owner->GetMaxPower(POWER_TYPE_MANA));
                _unit->SetPower(POWER_TYPE_MANA, owner->GetPower(POWER_TYPE_MANA));

                SpellRange* range = NULL;

                AI_Spell sp1;

                sp1.entryId = 59638;
                sp1.spell = dbcSpell.LookupEntryForced(sp1.entryId);
                sp1.spellType = STYPE_DAMAGE;
                sp1.agent = AGENT_SPELL;
                sp1.spelltargetType = TTYPE_SINGLETARGET;
                sp1.cooldown = 0;
                sp1.cooldowntime = 0;
                sp1.Misc2 = 0;
                sp1.procCount = 0;
                sp1.procChance = 100;
                range = dbcSpellRange.LookupEntry(sp1.spell->rangeIndex);
                sp1.minrange = GetMinRange(range);
                sp1.maxrange = GetMaxRange(range);

                _unit->GetAIInterface()->addSpellToList(&sp1);

                AI_Spell sp2;
                sp2.entryId = 59637;
                sp2.spell = dbcSpell.LookupEntryForced(sp2.entryId);
                sp2.spellType = STYPE_DAMAGE;
                sp2.agent = AGENT_SPELL;
                sp2.spelltargetType = TTYPE_SINGLETARGET;
                sp2.cooldown = 0;
                sp2.cooldowntime = 0;
                sp2.Misc2 = 0;
                sp2.procCount = 0;
                sp2.procChance = 100;
                range = dbcSpellRange.LookupEntry(sp2.spell->rangeIndex);
                sp2.minrange = GetMinRange(range);
                sp2.maxrange = GetMaxRange(range);

                _unit->GetAIInterface()->addSpellToList(&sp2);
            }
        }
    }
Пример #2
0
SpellDesc* ArcScriptCreatureAI::AddSpell(uint32 pSpellId, TargetType pTargetType, float pChance, float pCastTime, int32 pCooldown, float pMinRange, float pMaxRange, bool pStrictRange, char* pText, TextType pTextType, uint32 pSoundId)
{
	//Cannot add twice same spell id
	SpellDesc* NewSpell = FindSpellById(pSpellId);
	if( NewSpell ) return NewSpell;

	//Find spell info from spell id
	SpellEntry* Info = dbcSpell.LookupEntry(pSpellId);

#ifdef USE_DBC_SPELL_INFO
	float CastTime = ( Info->CastingTimeIndex ) ? GetCastTime(dbcSpellCastTime.LookupEntry(Info->CastingTimeIndex)) : pCastTime;
	int32 Cooldown = Info->RecoveryTime;
	float MinRange = ( Info->rangeIndex ) ? GetMinRange(dbcSpellRange.LookupEntry(Info->rangeIndex)) : pMinRange;
	float MaxRange = ( Info->rangeIndex ) ? GetMaxRange(dbcSpellRange.LookupEntry(Info->rangeIndex)) : pMaxRange;
	sLog.outColor(TYELLOW, "ArcScriptCreatureAI::AddSpell(%u) : casttime=%.1f cooldown=%d minrange=%.1f maxrange=%.1f\n", pSpellId, CastTime, Cooldown, MinRange, MaxRange);
#else
	float CastTime = pCastTime;
	int32 Cooldown = pCooldown;
	float MinRange = pMinRange;
	float MaxRange = pMaxRange;
#endif

	//Create new spell
	NewSpell = new SpellDesc(Info, NULL, pTargetType, pChance, CastTime, Cooldown, MinRange, MaxRange, pStrictRange, pText, pTextType, pSoundId);
	mSpells.push_back(NewSpell);
	return NewSpell;
}
Пример #3
0
bool DemonicCircleSummon(uint8_t /*effectIndex*/, Aura* a, bool apply)
{
    Unit* m_target = a->GetTarget();

    if (m_target->GetMapMgr() == nullptr)
        return true;

    if (apply)
    {

        GameObject* circle = m_target->GetMapMgr()->GetGameObject(a->GetTarget()->m_ObjectSlots[0]);
        SpellInfo const* sp = sSpellMgr.getSpellInfo(48020);

        if (circle != NULL && sp != NULL && m_target->CalcDistance(circle) <= GetMaxRange(sSpellRangeStore.LookupEntry(sp->getRangeIndex())))
        {
            if (!m_target->HasAura(62388))
                m_target->castSpell(m_target, 62388, true);
        }
        else
            m_target->RemoveAura(62388);
    }
    else
    {
        m_target->removeAllAurasById(62388);
    }

    return true;
}
Пример #4
0
bool DemonicCircleSummon(uint32 i, Aura* a, bool apply)
{
    Unit* m_target = a->GetTarget();

    if(m_target->GetMapMgr() == NULL)
        return true;

    if(apply)
    {

        GameObject* circle = m_target->GetMapMgr()->GetGameObject(a->GetTarget()->m_ObjectSlots[ 0 ]);
        SpellEntry* sp = dbcSpell.LookupEntryForced(48020);

        if(circle != NULL && sp != NULL && m_target->CalcDistance(circle) <= GetMaxRange(sSpellRangeStore.LookupEntry(sp->rangeIndex)))
        {
            if(!m_target->HasAura(62388))
                m_target->CastSpell(m_target, 62388, true);
        }
        else
            m_target->RemoveAura(62388);
    }
    else
    {
        m_target->RemoveAllAuraById(62388);
    }

    return true;
}
Пример #5
0
void Pet::CreateAISpell(SpellEntry * info)
{
    // Create an AI_Spell
    AI_Spell *sp = new AI_Spell;
    sp->agent = AGENT_SPELL;
    sp->entryId = GetEntry();
    sp->floatMisc1 = 0;
    sp->maxrange = GetMaxRange(sSpellRange.LookupEntry(info->rangeIndex));
    sp->minrange = GetMinRange(sSpellRange.LookupEntry(info->rangeIndex));
    sp->Misc2 = 0;
    sp->procChance = 0;
    sp->procCount = 0;
    sp->procCounter = 0;
    sp->procEvent = 0;
    sp->spellCooldown = 0;
    sp->spellCooldownTimer = 0;
    sp->spellId = info->Id;
    sp->spellType = STYPE_DAMAGE;
    sp->spelltargetType = TTYPE_SINGLETARGET;
    if(info->Effect[0] == SPELL_EFFECT_APPLY_AURA)
        sp->agent = STYPE_BUFF;

    if(info->EffectImplicitTargetA[0] == 24)
    {
        float radius = ::GetRadius(sSpellRadius.LookupEntry(info->EffectRadiusIndex[0]));
        sp->maxrange = radius;
        sp->spelltargetType = TTYPE_SOURCE;
    }

    m_AISpellStore[info->Id] = sp;
}
Пример #6
0
void
TotemAI::UpdateAI(const uint32 diff)
{
    if (i_totem.GetTotemType() != TOTEM_ACTIVE)
        return;

    if (!i_totem.isAlive() || i_totem.IsNonMeleeSpellCasted(false))
        return;

    // Search spell
    SpellEntry const *spellInfo = sSpellStore.LookupEntry(i_totem.GetSpell());
    if (!spellInfo) 
        return;

    // Get spell rangy
    SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex);
    float max_range = GetMaxRange(srange);

    // SPELLMOD_RANGE not applied in this place just because not existence range mods for attacking totems

    Unit* victim = NULL;                                    // pointer to appropriate target if found any

    // Search victim if no, not attackable, or out of range, or friendly (possible in case duel end)
    if( !i_victimGuid || !(victim = ObjectAccessor::GetUnit(i_totem, i_victimGuid)) ||
        !victim->isTargetableForAttack() || !i_totem.IsWithinDistInMap(victim, max_range) ||
        i_totem.IsFriendlyTo(victim) || !victim->isVisibleForOrDetect(&i_totem,false) )
    {
        CellPair p(MaNGOS::ComputeCellPair(i_totem.GetPositionX(),i_totem.GetPositionY()));
        Cell cell = RedZone::GetZone(p);
        cell.data.Part.reserved = ALL_DISTRICT;

        victim = NULL;

        MaNGOS::NearestAttackableUnitInObjectRangeCheck u_check(&i_totem, &i_totem, max_range);
        MaNGOS::UnitLastSearcher<MaNGOS::NearestAttackableUnitInObjectRangeCheck> checker(victim, u_check);

        TypeContainerVisitor<MaNGOS::UnitLastSearcher<MaNGOS::NearestAttackableUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker);
        TypeContainerVisitor<MaNGOS::UnitLastSearcher<MaNGOS::NearestAttackableUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);

        CellLock<GridReadGuard> cell_lock(cell, p);
        cell_lock->Visit(cell_lock, grid_object_checker,  *MapManager::Instance().GetMap(i_totem.GetMapId(), &i_totem));
        cell_lock->Visit(cell_lock, world_object_checker, *MapManager::Instance().GetMap(i_totem.GetMapId(), &i_totem));
    }

    // If have target
    if (victim)
    {
        // remember
        i_victimGuid = victim->GetGUID(); 

        // attack
        i_totem.SetInFront(victim);                         // client change orientation by self
        i_totem.CastSpell(victim, i_totem.GetSpell(), false);
    }
    else
        i_victimGuid = 0;
}
Пример #7
0
// Spell Target Handling for type 35: Single Target Party Member (if not in party then the target can not be himself)
// this one requeres more research
void Spell::SpellTargetSingleTargetPartyMember(uint32 i, uint32 j)
{
	if(!m_caster->IsInWorld())
		return;

	Unit* Target = m_caster->GetMapMgr()->GetPlayer((uint32)m_targets.m_unitTarget);
	if(!Target)
		return;
	float r=GetMaxRange(dbcSpellRange.LookupEntry(m_spellInfo->rangeIndex));
	if(IsInrange(m_caster->GetPositionX(),m_caster->GetPositionY(),m_caster->GetPositionZ(),Target,r*r))
		_AddTargetForced(m_targets.m_unitTarget, i);
}
Пример #8
0
/// Spell Target Handling for type 21: Single Target Friend
void Spell::SpellTargetSingleTargetFriend(uint32 i, uint32 j)
{
	Unit* Target;
	if(m_targets.m_unitTarget == m_caster->GetGUID())
		Target = u_caster;
	else
		Target = m_caster->GetMapMgr() ? m_caster->GetMapMgr()->GetUnit(m_targets.m_unitTarget) : NULL;
	if(!Target)
		return;

	float r= GetMaxRange(dbcSpellRange.LookupEntry(m_spellInfo->rangeIndex));
	if(IsInrange (m_caster->GetPositionX(),m_caster->GetPositionY(),m_caster->GetPositionZ(),Target, r*r))
		_AddTargetForced(Target->GetGUID(), i);
}
Пример #9
0
SpellEntry const *Creature::reachWithSpellAttack(Unit *pVictim)
{
    if(!pVictim)
        return NULL;

    for(uint32 i=0; i < CREATURE_MAX_SPELLS; i++)
    {
        if(!m_spells[i])
            continue;
        SpellEntry const *spellInfo = sSpellStore.LookupEntry(m_spells[i] );
        if(!spellInfo)
        {
            sLog.outError("WORLD: unknown spell id %i\n", m_spells[i]);
            continue;
        }

        bool bcontinue = true;
        for(uint32 j=0;j<3;j++)
        {
            if( (spellInfo->Effect[j] == SPELL_EFFECT_SCHOOL_DAMAGE )       ||
                (spellInfo->Effect[j] == SPELL_EFFECT_INSTAKILL)            ||
                (spellInfo->Effect[j] == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE) ||
                (spellInfo->Effect[j] == SPELL_EFFECT_HEALTH_LEECH )
                )
            {
                bcontinue = false;
                break;
            }
        }
        if(bcontinue) continue;

        if(spellInfo->manaCost > GetPower(POWER_MANA))
            continue;
        SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex);
        float range = GetMaxRange(srange);
        float minrange = GetMinRange(srange);
        float dist = GetDistanceSq(pVictim);
        //if(!isInFront( pVictim, range ) && spellInfo->AttributesEx )
        //    continue;
        if( dist > range * range || dist < minrange * minrange )
            continue;
        if(m_silenced)
            continue;
        return spellInfo;
    }
    return NULL;
}
Пример #10
0
/// Spell Target Handling for type 57: Targeted Party Member
void Spell::SpellTargetTargetPartyMember(uint32 i, uint32 j)
{
	if(!m_caster->IsInWorld())
		return;

	if (!m_caster->IsPet() && !m_caster->IsPlayer())
		return;

	TargetsList* tmpMap=&m_targetUnits[i];
	Unit* Target = m_caster->GetMapMgr()->GetUnit(m_targets.m_unitTarget);
	Unit* Caster = static_cast<Unit*>(m_caster);

	if(!Target || !Caster)
		return;

	if (!Target->IsPet() && !Target->IsPlayer())
		return;

	if (Caster->IsPet() && static_cast<Pet*>(Caster)->GetPetOwner() != NULL)
		Caster = static_cast<Pet*>(Caster)->GetPetOwner();

	if(Target->IsPet() && static_cast<Pet*>(Target)->GetPetOwner() != NULL)
		Target = static_cast<Pet*>(Target)->GetPetOwner();

		

	if (Caster != Target)
	{
		Group *c_group = static_cast<Player*>(Caster)->GetGroup();

		if( !c_group )
			return; //caster or caster master are not in group, cannot cast spell on this target

		Group *t_group = static_cast<Player*>(Target)->GetGroup();

		if( !t_group )
			return; //target does not have a group

		if( t_group != c_group )
			return; //caster and target are not in same group

	}
	float r=GetMaxRange(dbcSpellRange.LookupEntry(GetProto()->rangeIndex));
	if(IsInrange(m_caster->GetPositionX(),m_caster->GetPositionY(),m_caster->GetPositionZ(),Target,r*r))
		SafeAddTarget(tmpMap,m_targets.m_unitTarget);
}
Пример #11
0
// FIXME: Scale objects according to distance and ignore those below a given threshold (which improves with better sensors)
const Sensor::TrackCollection& Sensor::FindTracksInRange() const
{
    assert(player);

    collection.clear();

    // Find all units within range
    static float maxUnitRadius =
        XMLSupport::parse_float(vs_config->getVariable("graphics", "hud", "radar_search_extra_radius", "1000"));
    static bool allGravUnits =
        XMLSupport::parse_bool(vs_config->getVariable("graphics", "hud", "draw_gravitational_objects", "true"));

    UnitWithinRangeLocator<CollectRadarTracks> unitLocator(GetMaxRange(), maxUnitRadius);
    unitLocator.action.init(this, &collection, player);
    if (! is_null(player->location[Unit::UNIT_ONLY]))
    {
        findObjects(_Universe->activeStarSystem()->collidemap[Unit::UNIT_ONLY],
                    player->location[Unit::UNIT_ONLY],
                    &unitLocator);
    }
    if (allGravUnits)
    {
        Unit *target = player->Target();
        Unit *gravUnit;
        bool foundtarget = false;
        for (un_kiter i = _Universe->activeStarSystem()->gravitationalUnits().constIterator();
             (gravUnit = *i) != NULL;
             ++i)
        {
            unitLocator.action.acquire(gravUnit, UnitUtil::getDistance(player, gravUnit));
            if (gravUnit == target)
                foundtarget = true;
        }
        if (target && !foundtarget)
            unitLocator.action.acquire(target, UnitUtil::getDistance(player, target));
    }
    return collection;
}
Пример #12
0
void
TotemAI::UpdateAI(const uint32 diff)
{
    if (!i_totem.isTotem() || !i_totem.isAlive() || i_totem.m_currentSpell)
        return;
    if (((Totem*)&i_totem)->GetTotemType() != TOTEM_ACTIVE)
        return;

    SpellEntry const *spellInfo = sSpellStore.LookupEntry(((Totem*)&i_totem)->GetSpell());
    if (!spellInfo) return;
    SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex);
    float max_range = GetMaxRange(srange);

    Unit *victim = ObjectAccessor::Instance().GetUnit(*(Unit*)&i_totem, i_victimGuid);
    // stop attacking dead or out of range victims
    if (victim && victim->isAlive() && i_totem.IsWithinDistInMap(victim, max_range))
    {
        // if totem is not casting and it has a victim .. cast again
        AttackStart(victim);
        return;
    }
    else
        i_victimGuid = 0;
}
Пример #13
0
void
TotemAI::MoveInLineOfSight(Unit *u)
{
    if (!i_totem.isTotem() || ((Totem*)&i_totem)->GetTotemType() != TOTEM_ACTIVE)
        return;

    if(i_totem.getVictim() || i_totem.IsFriendlyTo(u) || i_totem.IsNeutralToAll() || u->IsNeutralToAll())
        return;

    if(!u->isTargetableForAttack()|| !IsVisible(u))
        return;

    SpellEntry const *spellInfo = sSpellStore.LookupEntry(((Totem*)&i_totem)->GetSpell());
    if (!spellInfo) return;
    SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex);
    float attackRadius = GetMaxRange(srange);

    if(i_totem.IsWithinDistInMap(u, attackRadius))
    {
        AttackStart(u);
        if(u->HasStealthAura())
            u->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
    }
}
Пример #14
0
/// Spell Target Handling for type 45: Chain,!!only for healing!! for chain lightning =6 
void Spell::SpellTargetChainTargeting(uint32 i, uint32 j)
{
	if( !m_caster->IsInWorld() )
		return;

	TargetsList* tmpMap=&m_targetUnits[i];
	//if selected target is party member, then jumps on party
	Unit* firstTarget;

	bool PartyOnly = false;
	float range = GetMaxRange(dbcSpellRange.LookupEntry(m_spellInfo->rangeIndex));//this is probably wrong,
	//this is cast distance, not searching distance
	range *= range;

	firstTarget = m_caster->GetMapMgr()->GetPlayer((uint32)m_targets.m_unitTarget);
	if( firstTarget && p_caster != NULL )
	{
		if( p_caster->InGroup() )
			if( p_caster->GetSubGroup() == static_cast< Player* >( firstTarget )->GetSubGroup() )
				PartyOnly=true;					
	}
	else
	{
		firstTarget = m_caster->GetMapMgr()->GetUnit(m_targets.m_unitTarget);
		if(!firstTarget) 
			return;
	}

	uint32 jumps=m_spellInfo->EffectChainTarget[i];
	if(m_spellInfo->SpellGroupType && u_caster)
	{
		SM_FIValue(u_caster->SM_FAdditionalTargets,(int32*)&jumps,m_spellInfo->SpellGroupType);
	}
	SafeAddTarget(tmpMap,firstTarget->GetGUID());
	if(!jumps)
		return;
	jumps--;
	if(PartyOnly)
	{
		GroupMembersSet::iterator itr;
		SubGroup * pGroup = p_caster->GetGroup() ?
			p_caster->GetGroup()->GetSubGroup(p_caster->GetSubGroup()) : 0;

		if(pGroup)
		{
			p_caster->GetGroup()->Lock();
			for(itr = pGroup->GetGroupMembersBegin();
				itr != pGroup->GetGroupMembersEnd(); ++itr)
			{
				if(!(*itr)->m_loggedInPlayer || (*itr)->m_loggedInPlayer==u_caster || !(*itr)->m_loggedInPlayer->isAlive() )
					continue;

				//we target stuff that has no full health. No idea if we must fill target list or not :(
				if( (*itr)->m_loggedInPlayer->GetUInt32Value( UNIT_FIELD_HEALTH ) == (*itr)->m_loggedInPlayer->GetUInt32Value( UNIT_FIELD_MAXHEALTH ) )
					continue;

				if( sWorld.Collision && u_caster != NULL )
				{
					if (u_caster->GetMapId() == (*itr)->m_loggedInPlayer->GetMapId() && !CollideInterface.CheckLOS(u_caster->GetMapId(),u_caster->GetPositionNC(),(*itr)->m_loggedInPlayer->GetPositionNC()))
						continue;
				}

				if( IsInrange(u_caster,(*itr)->m_loggedInPlayer, range) )
				{
					SafeAddTarget(tmpMap,(*itr)->m_loggedInPlayer->GetGUID());
					if(!--jumps)
					{
						p_caster->GetGroup()->Unlock();
						return;
					}
				}
			}
			p_caster->GetGroup()->Unlock();
		}
	}//find nearby friendly target
	else
	{
		std::set<Object*>::iterator itr;
		firstTarget->AquireInrangeLock(); //make sure to release lock before exit function !
		for( itr = firstTarget->GetInRangeSetBegin(); itr != firstTarget->GetInRangeSetEnd(); itr++ )
		{
			if( !(*itr)->IsUnit() || !((Unit*)(*itr))->isAlive())
				continue;

			//we target stuff that has no full health. No idea if we must fill target list or not :(
			if( (*itr)->GetUInt32Value( UNIT_FIELD_HEALTH ) == (*itr)->GetUInt32Value( UNIT_FIELD_MAXHEALTH ) )
				continue;

			if (sWorld.Collision) {
				if (u_caster->GetMapId() == (*itr)->GetMapId() && !CollideInterface.CheckLOS(u_caster->GetMapId(),u_caster->GetPositionNC(),(*itr)->GetPositionNC()))
					continue;
			}

			if(IsInrange(firstTarget,*itr, range))
			{
				if(!isAttackable(u_caster,(Unit*)(*itr)))
				{
					SafeAddTarget(tmpMap,(*itr)->GetGUID());
					if(!--jumps)
					{
						firstTarget->ReleaseInrangeLock();
						return;
					}
				}
			}
		}
		firstTarget->ReleaseInrangeLock();
	}
}
Пример #15
0
/// Spell Target Handling for type 31: related to scripted effects
void Spell::SpellTargetScriptedEffects( uint32 i, uint32 j )
{
	// Circle of healing or Wild Growth
	// - target top 5 hp deficient raid members around target.
	if( GetProto()->NameHash == SPELL_HASH_CIRCLE_OF_HEALING || GetProto()->NameHash == SPELL_HASH_WILD_GROWTH )
	{
		if( p_caster == NULL || !p_caster->IsInWorld() )
			return;

		TargetsList* tmpMap = &m_targetUnits[i];
		Unit * pTarget = p_caster->GetMapMgr()->GetUnit( m_targets.m_unitTarget );

		if( !pTarget )
			return;
		
		if( p_caster == pTarget ||
			IsInrange( p_caster->GetPositionX(), p_caster->GetPositionY(), p_caster->GetPositionZ(), pTarget, GetMaxRange( dbcSpellRange.LookupEntry( GetProto()->rangeIndex ) ) ) )
			SafeAddTarget( tmpMap, pTarget->GetGUID() );	 
		else
		{
			cancastresult = SPELL_FAILED_OUT_OF_RANGE;
			return; // No point targeting others if the target is not in casting range.
		}

		Group * group = p_caster->GetGroup(); 
		if( group == NULL )
			return;

		std::vector<Player*> raidList;
		std::vector<Player*>::iterator itr;

		uint32 count = group->GetSubGroupCount();

		group->Lock();
		for( uint32 k = 0; k < count; k++ )
		{
			SubGroup * subgroup = group->GetSubGroup( k );
			if( subgroup )
			{
				for( GroupMembersSet::iterator itr = subgroup->GetGroupMembersBegin(); itr != subgroup->GetGroupMembersEnd(); ++itr )
				{
					if( (*itr)->m_loggedInPlayer && m_caster != (*itr)->m_loggedInPlayer && 
						IsInrange( pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), (*itr)->m_loggedInPlayer, GetRadius(i) ) )
						raidList.push_back( (*itr)->m_loggedInPlayer );
				}
			}
		}
		group->Unlock();

		std::sort( raidList.begin(), raidList.end(), hpLessThan );

		uint32 maxTargets = 4;
		if( GetProto()->NameHash == SPELL_HASH_CIRCLE_OF_HEALING && p_caster->HasSpell( 55675 ) ) // Glyph of circle of healing
			maxTargets++;

		for( itr = raidList.begin(); itr != raidList.end() && maxTargets > 0; ++itr, maxTargets-- )
		{
			SafeAddTarget( tmpMap, (*itr)->GetGUID() );
		}
	}
	else
		FillAllTargetsInArea( i, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, GetRadius(i) );
}
Пример #16
0
/// Spell Target Handling for type 6 and 77: Single Target Enemy (grep thinks 77 fits in 6)
void Spell::SpellTargetSingleTargetEnemy(uint32 i, uint32 j)
{
	if(!m_caster->IsInWorld())
		return;
	Unit * pTarget = m_caster->GetMapMgr()->GetUnit(m_targets.m_unitTarget);
	if(!pTarget)
		return;

	if(p_caster && p_caster == pTarget) // spell bug: target is supposed to be a single enemy, not self
	{
		if(GetProto())
			sLog.outDebug("Spell %lu has target single enemy, but is targeting the caster.", GetProto()->Id);
	}

	TargetsList* tmpMap=&m_targetUnits[i];
	if(m_spellInfo->TargetCreatureType && pTarget->GetTypeId()==TYPEID_UNIT)
	{		
		Creature* cr = static_cast< Creature* >( pTarget );
		
		if( cr == NULL )
			return;

		if( cr->GetCreatureInfo() )
			if(!(1<<(cr->GetCreatureInfo()->Type-1) & m_spellInfo->TargetCreatureType))
				return;
	}

	if(p_caster && pTarget != p_caster)
	{
		// this is mostly used for things like duels
		if(pTarget->IsPlayer() && !isAttackable(p_caster, pTarget, false))
		{
			cancastresult = SPELL_FAILED_BAD_TARGETS;
			return;
		}

		/* HACK FIX */
		/* Please replace if found correct way */
		/* SPELL_AURA_SPELL_MAGNET */
		int x;
		for( x = 0; x < 3; ++x )
			if( m_spellInfo->EffectApplyAuraName[x] == SPELL_AURA_MOD_POSSESS ||
				m_spellInfo->is_melee_spell )
				break;		

		if( pTarget && x == 3 && pTarget->m_magnetcaster != 0)
		{	
			Unit *MagnetTarget = pTarget->GetMapMgr()->GetUnit(pTarget->m_magnetcaster);
			if ( MagnetTarget && m_spellInfo->School )
			{
				m_magnetTarget = pTarget->m_magnetcaster;	
				pTarget = MagnetTarget; // Redirected
			}
		}
	}

	uint8 did_hit_result = DidHit(i,pTarget);
	if(did_hit_result != SPELL_DID_HIT_SUCCESS)
		SafeAddModeratedTarget(pTarget->GetGUID(), did_hit_result);
	else
		SafeAddTarget(tmpMap, pTarget->GetGUID());

	if( m_spellInfo->EffectChainTarget[i] )
	{
		//number of additional targets
		uint32 jumps = m_spellInfo->EffectChainTarget[i] - 1;

		// extra targets by auras
		if( u_caster )
			SM_FIValue( u_caster->SM_FAdditionalTargets,(int32*)&jumps, m_spellInfo->SpellGroupType );

		float range = GetMaxRange( dbcSpellRange.LookupEntry( m_spellInfo->rangeIndex ) );//this is probably wrong
		range *= range;
		std::set<Object*>::iterator itr,itr2;
		m_caster->AquireInrangeLock(); //make sure to release lock before exit function !
		for( itr2 = m_caster->GetInRangeSetBegin(); itr2 != m_caster->GetInRangeSetEnd(); )
		{
			itr = itr2;
			itr2++;
			if((*itr)->GetGUID()==m_targets.m_unitTarget)
				continue;
			if( !((*itr)->IsUnit()) || !((Unit*)(*itr))->isAlive() || 
				((*itr)->IsCreature() && ((Creature*)(*itr))->IsTotem()))
				continue;

			if( sWorld.Collision && u_caster != NULL )
			{
				if (u_caster->GetMapId() == (*itr)->GetMapId() && !CollideInterface.CheckLOS(u_caster->GetMapId(),u_caster->GetPositionNC(),(*itr)->GetPositionNC()))
					continue;
			}

			if(IsInrange(m_caster->GetPositionX(),m_caster->GetPositionY(),m_caster->GetPositionZ(),(*itr),range))
			{
				if(isAttackable(u_caster,(Unit*)(*itr)))
				{
					did_hit_result = DidHit(i,((Unit*)*itr));
					if(did_hit_result==SPELL_DID_HIT_SUCCESS)
						SafeAddTarget(tmpMap, (*itr)->GetGUID());
					else
						SafeAddModeratedTarget((*itr)->GetGUID(), did_hit_result);

					if(!--jumps)
					{
						m_caster->ReleaseInrangeLock();
						return;
					}
				}
			}
		}
		m_caster->ReleaseInrangeLock();
	}
}
Пример #17
0
void GameObject::InitAI()
{	
	if(pInfo == NULL)
		return;
	
	// this fixes those fuckers in booty bay
	if(pInfo->SpellFocus == 0 &&
		pInfo->sound1 == 0 &&
		pInfo->sound2 == 0 &&
		pInfo->sound3 != 0 &&
		pInfo->sound5 != 3 &&
		pInfo->sound9 == 1)
		return;

	uint32 spellid = 0;
	switch(pInfo->Type)
	{
		case GAMEOBJECT_TYPE_TRAP:
		{	
			spellid = pInfo->sound3;
		}break;
		case GAMEOBJECT_TYPE_SPELL_FOCUS://redirect to properties of another go
		{
			uint32 new_entry = pInfo->sound2;
			if(new_entry)
			{
				pInfo = GameObjectNameStorage.LookupEntry( new_entry );
				if(pInfo == NULL)
				{
					Log.Warning("GameObject","Redirected gameobject %u doesn't seem to exists in database, skipping",new_entry);
					return;
				}
				if(pInfo->sound3)
					spellid = pInfo->sound3;
			}
		}break;
		case GAMEOBJECT_TYPE_RITUAL:
		{	
			m_ritualmembers = new uint32[pInfo->SpellFocus];
			memset(m_ritualmembers,0,sizeof(uint32)*pInfo->SpellFocus);
		}break;
		case GAMEOBJECT_TYPE_CHEST:
 		{
			Lock *pLock = dbcLock.LookupEntry(GetInfo()->SpellFocus);
			if(pLock)
			{
				for(uint32 i = 0; i < 5; i++)
				{
					if(pLock->locktype[i])
					{
						if(pLock->locktype[i] == 2) //locktype;
						{
							//herbalism and mining;
							if(pLock->lockmisc[i] == LOCKTYPE_MINING || pLock->lockmisc[i] == LOCKTYPE_HERBALISM)
							{
								CalcMineRemaining(true);
							}
						}
					}
				}
			}
			else if(pInfo->Type == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
			{
				Health = pInfo->SpellFocus + pInfo->sound5;
			}
		}
}
	//Null out gossip_script here, will be set with sScriptMgr.register_go_gossip_script (if any).
	pInfo->gossip_script = NULL;
	myScript = sScriptMgr.CreateAIScriptClassForGameObject(GetEntry(), this);

	// hackfix for bad spell in BWL
	if(!spellid || spellid == 22247)
		return;

	SpellEntry *sp= dbcSpell.LookupEntry(spellid);
	if(!sp)
	{
		spell = NULL;
		return;
	}
	else
	{
		spell = sp;
	}
	//ok got valid spell that will be casted on target when it comes close enough
	//get the range for that 
	
	float r = 0;

	for(uint32 i = 0; i < 3; i++)
	{
		if(sp->Effect[i])
		{
			float t = GetDBCCastTime(dbcSpellRadius.LookupEntry(sp->EffectRadiusIndex[i]));
			if(t > r)
				r = t;
		}
	}

	if(r < 0.1)//no range
		r = GetMaxRange(dbcSpellRange.LookupEntry(sp->rangeIndex));

	range = r*r;//square to make code faster
	checkrate = 20;//once in 2 seconds
	
}
Пример #18
0
/// Spell Target Handling for type 45: Chain,!!only for healing!! for chain lightning =6
void Spell::SpellTargetChainTargeting(uint32 i, uint32 j)
{
	if( !m_caster->IsInWorld() )
		return;

	//if selected target is party member, then jumps on party
	Unit* firstTarget;

	bool PartyOnly = false;
	float range = GetMaxRange(dbcSpellRange.LookupEntry(m_spellInfo->rangeIndex));//this is probably wrong,
	//this is cast distance, not searching distance
	range *= range;

	firstTarget = m_caster->GetMapMgr()->GetPlayer((uint32)m_targets.m_unitTarget);
	if( firstTarget && p_caster != NULL )
	{
		if( p_caster->InGroup() )
			if( p_caster->GetSubGroup() == TO_PLAYER( firstTarget )->GetSubGroup() )
				PartyOnly=true;
	}
	else
	{
		firstTarget = m_caster->GetMapMgr()->GetUnit(m_targets.m_unitTarget);
		if(!firstTarget)
			return;
	}

	uint32 jumps=m_spellInfo->EffectChainTarget[i];
	if(m_spellInfo->SpellGroupType && u_caster)
	{
		SM_FIValue(u_caster->SM[SMT_ADDITIONAL_TARGET][0],(int32*)&jumps,m_spellInfo->SpellGroupType);
	}

	_AddTargetForced(firstTarget->GetGUID(), i);
	if(!jumps)
		return;
	jumps--;
	if(PartyOnly)
	{
		GroupMembersSet::iterator itr;
		SubGroup * pGroup = p_caster->GetGroup() ?
			p_caster->GetGroup()->GetSubGroup(p_caster->GetSubGroup()) : 0;

		if(pGroup)
		{
			p_caster->GetGroup()->Lock();
			for(itr = pGroup->GetGroupMembersBegin();
				itr != pGroup->GetGroupMembersEnd(); itr++)
			{
				if(!(*itr)->m_loggedInPlayer || (*itr)->m_loggedInPlayer == u_caster || (*itr)->m_loggedInPlayer->GetUInt32Value(UNIT_FIELD_HEALTH) == (*itr)->m_loggedInPlayer->GetUInt32Value(UNIT_FIELD_MAXHEALTH))
					continue;
				if(IsInrange(u_caster->GetPositionX(),u_caster->GetPositionY(),u_caster->GetPositionZ(),(*itr)->m_loggedInPlayer, range))
				{
					_AddTargetForced((*itr)->m_loggedInPlayer->GetGUID(), i);
					if(!--jumps)
					{
						p_caster->GetGroup()->Unlock();
						return;
					}
				}
			}
			p_caster->GetGroup()->Unlock();
		}
	}//find nearby friendly target
	else
	{
		unordered_set<Object*>::iterator itr;
		for( itr = firstTarget->GetInRangeSetBegin(); itr != firstTarget->GetInRangeSetEnd(); ++itr )
		{
			if( !(*itr)->IsUnit() || !TO_UNIT(*itr)->isAlive())
				continue;

			if(IsInrange(firstTarget->GetPositionX(),firstTarget->GetPositionY(),firstTarget->GetPositionZ(),*itr, range))
			{
				if(!isAttackable(u_caster,TO_UNIT(*itr)) && (*itr)->GetUInt32Value(UNIT_FIELD_HEALTH) != (*itr)->GetUInt32Value(UNIT_FIELD_MAXHEALTH))
				{
					_AddTargetForced((*itr)->GetGUID(), i);
					if(!--jumps)
						return;
				}
			}
		}
	}
}
Пример #19
0
void GameObject::InitAI()
{
	
	if(!pInfo)
		return;
	
	// this fixes those fuckers in booty bay
	if(pInfo->SpellFocus == 0 &&
		pInfo->sound1 == 0 &&
		pInfo->sound2 == 0 &&
		pInfo->sound3 != 0 &&
		pInfo->sound5 != 3 &&
		pInfo->sound9 == 1)
		return;

	if(pInfo->DisplayID == 1027)//Shaman Shrine
	{
		if(pInfo->ID != 177964 && pInfo->ID != 153556)
		{
			//Deactivate
			//SetUInt32Value(GAMEOBJECT_DYN_FLAGS, 0);
		}
	}


	uint32 spellid = 0;
	if(pInfo->Type==GAMEOBJECT_TYPE_TRAP)
	{	
		spellid = pInfo->sound3;
	}
	else if(pInfo->Type == GAMEOBJECT_TYPE_SPELL_FOCUS)
	{
		// get spellid from attached gameobject - by sound2 field
		if( pInfo->sound2 == 0 )
			return;
		if( GameObjectNameStorage.LookupEntry( pInfo->sound2 ) == NULL )
			return;
		spellid = GameObjectNameStorage.LookupEntry( pInfo->sound2 )->sound3;
	}
	else if(pInfo->Type == GAMEOBJECT_TYPE_RITUAL)
	{	
		m_ritualmembers = new uint32[pInfo->SpellFocus];
		memset(m_ritualmembers,0,sizeof(uint32)*pInfo->SpellFocus);
	}
    else if(pInfo->Type == GAMEOBJECT_TYPE_CHEST)
    {
        Lock *pLock = dbcLock.LookupEntry(GetInfo()->SpellFocus);
        if(pLock)
        {
            for(uint32 i=0; i < 5; i++)
            {
                if(pLock->locktype[i])
                {
                    if(pLock->locktype[i] == 2) //locktype;
                    {
                        //herbalism and mining;
                        if(pLock->lockmisc[i] == LOCKTYPE_MINING || pLock->lockmisc[i] == LOCKTYPE_HERBALISM)
                        {
							CalcMineRemaining(true);
                        }
                    }
                }
            }
        }

    }
	else if ( pInfo->Type == GAMEOBJECT_TYPE_FISHINGHOLE )
	{
		CalcFishRemaining( true );
	}

	myScript = sScriptMgr.CreateAIScriptClassForGameObject(GetEntry(), this);

	// hackfix for bad spell in BWL
	if(!spellid || spellid == 22247)
		return;

	SpellEntry *sp= dbcSpell.LookupEntry(spellid);
	if(!sp)
	{
		spell = NULL;
		return;
	}
	else
	{
		spell = sp;
	}
	//ok got valid spell that will be casted on target when it comes close enough
	//get the range for that 
	
	float r = 0;

	for(uint32 i=0;i<3;i++)
	{
		if(sp->Effect[i])
		{
			float t = GetRadius(dbcSpellRadius.LookupEntry(sp->EffectRadiusIndex[i]));
			if(t > r)
				r = t;
		}
	}

	if(r < 0.1)//no range
		r = GetMaxRange(dbcSpellRange.LookupEntry(sp->rangeIndex));

	range = r*r;//square to make code faster
	checkrate = 20;//once in 2 seconds
	
}
Пример #20
0
// Spell Target Handling for type 6 and 77: Single Target Enemy (grep thinks 77 fits in 6)
void Spell::SpellTargetSingleTargetEnemy(uint32 i, uint32 j)
{
	if(!m_caster->IsInWorld())
		return;

	Unit* pTarget = m_caster->GetMapMgr()->GetUnit(m_targets.m_unitTarget);
	if(!pTarget)
		return;

	if(m_spellInfo->TargetCreatureType && pTarget->GetTypeId()==TYPEID_UNIT)
	{
		Creature* cr = TO_CREATURE( pTarget );

		if( cr == NULL )
			return;

		if( cr->GetCreatureInfo() )
			if(!(1<<(cr->GetCreatureInfo()->Type-1) & m_spellInfo->TargetCreatureType))
				return;
	}

	if(p_caster && pTarget != p_caster)
	{
		// this is mostly used for things like duels
		if(pTarget->IsPlayer() && !isAttackable(p_caster, pTarget, false))
		{
			cancastresult = SPELL_FAILED_BAD_TARGETS;
			return;
		}
	}

	// magnet!!!!!
	if( pTarget->IsPlayer() && TO_PLAYER(pTarget)->m_magnetAura != NULL && m_magnetTarget == NULL )
	{
		if(!m_spellInfo->is_melee_spell && GetType() == SPELL_DMG_TYPE_MAGIC )
		{
			// redirect it to the magnet
			m_magnetTarget = TO_PLAYER(pTarget)->m_magnetAura->GetUnitCaster();

			// clear the magnet aura
			TO_PLAYER(pTarget)->m_magnetAura->Remove();
		}
	}

	if( m_magnetTarget != NULL )
	{
		// if the target exists, shoot it at him.
		if( m_magnetTarget != NULL && m_magnetTarget->IsInWorld() && !m_magnetTarget->isDead() )
			pTarget = m_magnetTarget;
	}

	_AddTarget(pTarget, i);

	if(m_spellInfo->EffectChainTarget[i])
	{
		uint32 jumps=m_spellInfo->EffectChainTarget[i]-1;
		float range=GetMaxRange(dbcSpellRange.LookupEntry(m_spellInfo->rangeIndex));//this is probably wrong
		range*=range;
		unordered_set<Object*>::iterator itr;
		for( itr = m_caster->GetInRangeSetBegin(); itr != m_caster->GetInRangeSetEnd(); ++itr )
		{
			if((*itr)->GetGUID()==m_targets.m_unitTarget)
				continue;
			if( !((*itr)->IsUnit()) || !TO_UNIT(*itr)->isAlive())
				continue;

			if(IsInrange(m_caster->GetPositionX(),m_caster->GetPositionY(),m_caster->GetPositionZ(),(*itr),range))
			{
				if(isAttackable(u_caster,TO_UNIT(*itr)))
				{
					_AddTarget(TO_UNIT(*itr), i);
					if(!--jumps)
						return;
				}
			}
		}
	}
}
Пример #21
0
void CPageDisplay::Update()
{
	int				max_rate[NUM_STATUS_BARS];
	CString			max_range_text;
	double			stat_double;
	CString			stat_string;

	// Setting ranges on status bar display based on selections.
	for ( int i = 0; i < NUM_STATUS_BARS; i++ )
	{
		max_rate[i] = GetMaxRange( &(barcharts[i].results[GetWhichPerf()]), barcharts[i].result_to_display );
	}

	// If the results to display are the same, giving them the same ranges for easier comparisons.
	for ( i = 0; i < NUM_STATUS_BARS - 1; i++)
	{
		for ( int j = i; j < NUM_STATUS_BARS; j++ )
		{
			if ( barcharts[i].result_to_display == barcharts[j].result_to_display )
			{
				if ( max_rate[i] > max_rate[j] )
					max_rate[j] = max_rate[i];
				else
					max_rate[i] = max_rate[j];
			}
		}
	}

	// Setting ranges on status bar and displaying range value.
	for ( i = 0; i < NUM_STATUS_BARS; i++ )
	{
		( (CProgressCtrl*)GetDlgItem( PRate1 + i ) )->SetRange( 0, max_rate[i] );

		// See if results are displaying a percentage.
		if ( ( barcharts[i].result_to_display >= CPU_UTILIZATION_RESULT ) && 
			( barcharts[i].result_to_display <= IRQ_UTILIZATION_RESULT ) )
		{
			max_range_text.Format( "%d %%", max_rate[i] );		// display % sign
			( (CStatic*)GetDlgItem( TRate1MAX + i ) )->SetWindowText( max_range_text );
		}
		else
		{
			max_range_text.Format( "%d", max_rate[i] );			// displaying a rate
			( (CStatic*)GetDlgItem( TRate1MAX + i ) )->SetWindowText( max_range_text );
		}

		// Update the name.
		SetDlgItemText( TWorker1 + i, barcharts[i].name );

		// Get the performance data to display (a number and a string)
		GetDisplayData(	&(barcharts[i].results[GetWhichPerf()]), 
			barcharts[i].result_to_display, &stat_double, &stat_string );

		// Update the appropriate progress bar
		((CProgressCtrl *) GetDlgItem( PRate1 + i ))->SetPos( (int) stat_double );

		// Display the new value to the user
		((CStatic *) GetDlgItem( TRate1 + i ))->SetWindowText( stat_string );
	}

	// Update the data.
	UpdateWindow();

	// Update the big meter dialog, if it exists.
	if ( m_dlgBigMeter.is_displayed )
		m_dlgBigMeter.UpdateDisplay();
}
Пример #22
0
	BlueDragonAI(Creature* pCreature) : MoonScriptCreatureAI( pCreature )
	{	
		AI_Spell* NewSpell = new AI_Spell;
		NewSpell->spell = dbcSpell.LookupEntry( 45848 );
		NewSpell->agent = AGENT_SPELL;
		NewSpell->entryId = _unit->GetEntry();
		NewSpell->maxrange = GetMaxRange( dbcSpellRange.LookupEntry( NewSpell->spell->rangeIndex ) );
		NewSpell->minrange = GetMinRange( dbcSpellRange.LookupEntry( NewSpell->spell->rangeIndex ) );
		NewSpell->spelltargetType = TTYPE_SINGLETARGET;
		NewSpell->spellType = STYPE_DAMAGE;
		NewSpell->cooldown = objmgr.GetPetSpellCooldown( NewSpell->spell->Id );
		NewSpell->cooldowntime = 0;
		NewSpell->autocast_type = AUTOCAST_EVENT_NONE;
		NewSpell->floatMisc1 = 0;
		NewSpell->Misc2 = 0;
		NewSpell->procChance = 0;
		NewSpell->procCount=0;
		_unit->GetAIInterface()->addSpellToList( NewSpell );

		NewSpell = new AI_Spell;
		NewSpell->spell = dbcSpell.LookupEntry( 45856 );
		NewSpell->agent = AGENT_SPELL;
		NewSpell->entryId = _unit->GetEntry();
		NewSpell->maxrange = GetMaxRange( dbcSpellRange.LookupEntry( NewSpell->spell->rangeIndex ) );
		NewSpell->minrange = GetMinRange( dbcSpellRange.LookupEntry( NewSpell->spell->rangeIndex ) );
		NewSpell->spelltargetType = TTYPE_CASTER;
		NewSpell->spellType = STYPE_BUFF;
		NewSpell->cooldown = objmgr.GetPetSpellCooldown( NewSpell->spell->Id );
		NewSpell->cooldowntime = 0;
		NewSpell->autocast_type = AUTOCAST_EVENT_NONE;
		NewSpell->floatMisc1 = 0;
		NewSpell->Misc2 = 0;
		NewSpell->procChance = 0;
		NewSpell->procCount=0;
		_unit->GetAIInterface()->addSpellToList( NewSpell );
	
		NewSpell = new AI_Spell;
		NewSpell->spell = dbcSpell.LookupEntry( 45860 );
		NewSpell->agent = AGENT_SPELL;
		NewSpell->entryId = _unit->GetEntry();
		NewSpell->maxrange = GetMaxRange( dbcSpellRange.LookupEntry( NewSpell->spell->rangeIndex ) );		
		NewSpell->minrange = GetMinRange( dbcSpellRange.LookupEntry( NewSpell->spell->rangeIndex ) );
		NewSpell->spelltargetType = TTYPE_SINGLETARGET;
		NewSpell->spellType = STYPE_BUFF;
		NewSpell->cooldown = objmgr.GetPetSpellCooldown( NewSpell->spell->Id );
		NewSpell->cooldowntime = 0;
		NewSpell->autocast_type = AUTOCAST_EVENT_NONE;
		NewSpell->floatMisc1 = 0;
		NewSpell->Misc2 = 0;
		NewSpell->procChance = 0;
		NewSpell->procCount=0;
		_unit->GetAIInterface()->addSpellToList( NewSpell );

		NewSpell = new AI_Spell;
		NewSpell->spell = dbcSpell.LookupEntry( 45862 );
		NewSpell->agent = AGENT_SPELL;
		NewSpell->entryId = _unit->GetEntry();
		NewSpell->maxrange = GetMaxRange( dbcSpellRange.LookupEntry( NewSpell->spell->rangeIndex ) );		
		NewSpell->minrange = GetMinRange( dbcSpellRange.LookupEntry( NewSpell->spell->rangeIndex ) );
		NewSpell->spelltargetType = TTYPE_SINGLETARGET;
		NewSpell->spellType = STYPE_BUFF;
		NewSpell->cooldown = objmgr.GetPetSpellCooldown( NewSpell->spell->Id );
		NewSpell->cooldowntime = 0;
		NewSpell->autocast_type = AUTOCAST_EVENT_NONE;
		NewSpell->floatMisc1 = 0;
		NewSpell->Misc2 = 0;
		NewSpell->procChance = 0;
		NewSpell->procCount=0;
		_unit->GetAIInterface()->addSpellToList( NewSpell );

		RegisterAIUpdateEvent( 500 );
	};
Пример #23
0
void GameObject::InitAI()
{
	
	if(!pInfo)
		return;
	
	// this fixes those fuckers in booty bay
	if(pInfo->SpellFocus == 0 &&
		pInfo->sound1 == 0 &&
		pInfo->sound2 == 0 &&
		pInfo->sound3 != 0 &&
		pInfo->sound5 != 3 &&
		pInfo->sound9 == 1)
		return;

	if(pInfo->DisplayID == 1027)//Shaman Shrine
	{
		if(pInfo->ID != 177964 || pInfo->ID != 153556)
		{
			//Deactivate
			//SetUInt32Value(GAMEOBJECT_DYN_FLAGS, 0);
		}
	}


	uint32 spellid = 0;
	if(pInfo->Type==GAMEOBJECT_TYPE_TRAP)
	{	
		spellid = pInfo->sound3;
	}
	else if(pInfo->Type == GAMEOBJECT_TYPE_SPELL_FOCUS)//redirect to properties of another go
	{
		uint32 new_entry = pInfo->sound2;
		if(!new_entry)
			return;
		pInfo = GameObjectNameStorage.LookupEntry( new_entry );
		if(!pInfo)
			return;
		spellid = pInfo->sound3;
	}
	else if(pInfo->Type == GAMEOBJECT_TYPE_RITUAL)
	{	
		m_ritualmembers = new uint32[pInfo->SpellFocus];
		memset(m_ritualmembers,0,sizeof(uint32)*pInfo->SpellFocus);
	}

	myScript = sScriptMgr.CreateAIScriptClassForGameObject(GetEntry(), this);

	// hackfix for bad spell in BWL
	if(!spellid || spellid == 22247)
		return;

	SpellEntry *sp= sSpellStore.LookupEntry(spellid);
	if(!sp)
	{
		spell = NULL;
		return;
	}
	else
	{
		spell = sp;
	}
	//ok got valid spell that will be casted on target when it comes close enough
	//get the range for that 
	
	float r = 0;

	for(uint32 i=0;i<3;i++)
	{
		if(sp->Effect[i])
		{
			float t = GetRadius(sSpellRadius.LookupEntry(sp->EffectRadiusIndex[i]));
			if(t > r)
				r = t;
		}
	}

	if(r < 0.1)//no range
		r = GetMaxRange(sSpellRange.LookupEntry(sp->rangeIndex));

	range = r*r;//square to make code faster
	checkrate = 20;//once in 2 seconds
	
}
Пример #24
0
bool Sensor::InRange(const Track& track) const
{
    return (track.GetDistance() <= GetMaxRange());
}
Пример #25
0
void ObjectMgr::LoadExtraCreatureProtoStuff()
{
	{
		StorageContainerIterator<CreatureProto> * itr = CreatureProtoStorage.MakeIterator();
		CreatureProto* cn;
		while(!itr->AtEnd())
		{
			cn = itr->Get();

			// Process spell fields
			for( uint32 i = 0; i < MAX_CREATURE_PROTO_SPELLS; i++ ){
				if( cn->AISpells[ i ] == 0 )
					continue;

				SpellEntry *sp = dbcSpell.LookupEntryForced( cn->AISpells[ i ] );
				if( sp == NULL )
					continue;

				if( ( sp->Attributes & ATTRIBUTES_PASSIVE ) == 0 )
					cn->castable_spells.push_back( sp->Id );
				else
					cn->start_auras.insert( sp->Id );

			}

			// process creature spells from creaturespelldata.dbc
			if( cn->spelldataid != 0 ){
				CreatureSpellDataEntry* spe = dbcCreatureSpellData.LookupEntry( cn->spelldataid );
				for( uint32 i = 0; i < 3; i++ ){
					if( spe->Spells[ i ] == 0 )
						continue;

					SpellEntry *sp = dbcSpell.LookupEntryForced( spe->Spells[ i ] );
					if( sp == NULL )
						continue;

					if( ( sp->Attributes & ATTRIBUTES_PASSIVE ) == 0 )
						cn->castable_spells.push_back( sp->Id );
					else
						cn->start_auras.insert( sp->Id );
				}
			}

			if(cn->aura_string)
			{
				string auras = string(cn->aura_string);
				vector<string> aurs = StrSplit(auras, " ");
				for(vector<string>::iterator it = aurs.begin(); it != aurs.end(); ++it)
				{
					uint32 id = atol((*it).c_str());
					if(id)
						cn->start_auras.insert(id);
				}
			}

			if(!cn->MinHealth)
				cn->MinHealth = 1;
			if(!cn->MaxHealth)
				cn->MaxHealth = 1;
			if(cn->AttackType > SCHOOL_ARCANE)
				cn->AttackType = SCHOOL_NORMAL;

			cn->m_canFlee = cn->m_canRangedAttack = cn->m_canCallForHelp = false;
			cn->m_fleeHealth = 0.0f;
			// please.... m_fleeDuration is a uint32...
			//cn->m_fleeDuration = 0.0f;
			cn->m_fleeDuration = 0;

			if(!itr->Inc())
				break;
		}

		itr->Destruct();
	}

	{
		StorageContainerIterator<CreatureInfo> * itr = CreatureNameStorage.MakeIterator();
		CreatureInfo* ci;
		while(!itr->AtEnd())
		{
			ci = itr->Get();

			ci->lowercase_name = string(ci->Name);
			for(uint32 j = 0; j < ci->lowercase_name.length(); ++j)
				ci->lowercase_name[j] = static_cast<char>(tolower(ci->lowercase_name[j]));   // Darvaleo 2008/08/15 - Copied lowercase conversion logic from ItemPrototype task

			for(int i = 0; i < NUM_MONSTER_SAY_EVENTS; i++)
				ci->MonsterSay[i] = objmgr.HasMonsterSay(ci->Id, MONSTER_SAY_EVENTS(i));

			if(!itr->Inc())
				break;
		}
		itr->Destruct();
	}

	// Load AI Agents
	if(Config.MainConfig.GetBoolDefault("Server", "LoadAIAgents", true))
	{
		QueryResult* result = WorldDatabase.Query("SELECT * FROM ai_agents");
		CreatureProto* cn;

		if(result != NULL)
		{
			AI_Spell* sp;
			SpellEntry* spe;
			uint32 entry;

			do
			{
				Field* fields = result->Fetch();
				entry = fields[0].GetUInt32();
				cn = CreatureProtoStorage.LookupEntry(entry);
				spe = dbcSpell.LookupEntryForced(fields[6].GetUInt32());
				if(spe == NULL)
				{
					Log.Error("AIAgent", "For %u has nonexistent spell %u.", fields[0].GetUInt32(), fields[6].GetUInt32());
					continue;
				}
				if(!cn)
					continue;

				sp = new AI_Spell;
				sp->entryId = fields[0].GetUInt32();
				sp->instance_mode = fields[1].GetUInt32();
				sp->agent = fields[2].GetUInt16();
				sp->procChance = fields[4].GetUInt32();
				sp->procCount = fields[5].GetUInt32();
				sp->spell = spe;
				sp->spellType = static_cast<uint8>(fields[7].GetUInt32());

				int32  targettype = fields[8].GetInt32();
				if(targettype == -1)
					sp->spelltargetType = static_cast<uint8>(GetAiTargetType(spe));
				else sp->spelltargetType = static_cast<uint8>(targettype);

				sp->cooldown = fields[9].GetInt32();
				sp->floatMisc1 = fields[10].GetFloat();
				sp->autocast_type = (uint32) - 1;
				sp->cooldowntime = getMSTime();
				sp->procCounter = 0;
				sp->Misc2 = fields[11].GetUInt32();
				if(sp->agent == AGENT_SPELL)
				{
					if(!sp->spell)
					{
						LOG_DEBUG("SpellId %u in ai_agent for %u is invalid.", (unsigned int)fields[6].GetUInt32(), (unsigned int)sp->entryId);
						delete sp;
						sp = NULL;
						continue;
					}

					if(sp->spell->Effect[0] == SPELL_EFFECT_LEARN_SPELL || sp->spell->Effect[1] == SPELL_EFFECT_LEARN_SPELL ||
					        sp->spell->Effect[2] == SPELL_EFFECT_LEARN_SPELL)
					{
						LOG_DEBUG("Teaching spell %u in ai_agent for %u", (unsigned int)fields[6].GetUInt32(), (unsigned int)sp->entryId);
						delete sp;
						sp = NULL;
						continue;
					}

					sp->minrange = GetMinRange(dbcSpellRange.LookupEntry(sp->spell->rangeIndex));
					sp->maxrange = GetMaxRange(dbcSpellRange.LookupEntry(sp->spell->rangeIndex));

					//omg the poor darling has no clue about making ai_agents
					if(sp->cooldown == (uint32) - 1)
					{
						//now this will not be exact cooldown but maybe a bigger one to not make him spam spells to often
						int cooldown;
						SpellDuration* sd = dbcSpellDuration.LookupEntry(sp->spell->DurationIndex);
						int Dur = 0;
						int Casttime = 0; //most of the time 0
						int RecoveryTime = sp->spell->RecoveryTime;
						if(sp->spell->DurationIndex)
							Dur =::GetDuration(sd);
						Casttime = GetCastTime(dbcSpellCastTime.LookupEntry(sp->spell->CastingTimeIndex));
						cooldown = Dur + Casttime + RecoveryTime;
						if(cooldown < 0)
							sp->cooldown = 2000; //huge value that should not loop while adding some timestamp to it
						else sp->cooldown = cooldown;
					}

					/*
					//now apply the moron filter
					if(sp->procChance== 0)
					{
						//printf("SpellId %u in ai_agent for %u is invalid.\n", (unsigned int)fields[5].GetUInt32(), (unsigned int)sp->entryId);
						delete sp;
						sp = NULL;
						continue;
					}
					if(sp->spellType== 0)
					{
						//right now only these 2 are used
						if(IsBeneficSpell(sp->spell))
							sp->spellType==STYPE_HEAL;
						else sp->spellType==STYPE_BUFF;
					}
					if(sp->spelltargetType== 0)
						sp->spelltargetType = RecommandAISpellTargetType(sp->spell);
						*/
				}

				if(sp->agent == AGENT_RANGED)
				{
					cn->m_canRangedAttack = true;
					delete sp;
					sp = NULL;
				}
				else if(sp->agent == AGENT_FLEE)
				{
					cn->m_canFlee = true;
					if(sp->floatMisc1)
						cn->m_canFlee = (sp->floatMisc1 > 0.0f ? true : false);
					else
						cn->m_fleeHealth = 0.2f;

					if(sp->Misc2)
						cn->m_fleeDuration = sp->Misc2;
					else
						cn->m_fleeDuration = 10000;

					delete sp;
					sp = NULL;
				}
				else if(sp->agent == AGENT_CALLFORHELP)
				{
					cn->m_canCallForHelp = true;
					if(sp->floatMisc1)
						cn->m_callForHelpHealth = 0.2f;
					delete sp;
					sp = NULL;
				}
				else
				{
					cn->spells.push_back(sp);
				}
			}
			while(result->NextRow());

			delete result;
		}
	}
}
Пример #26
0
float CUnitTable::GetScore(const UnitDef* udef, UnitCategory cat) {
	const int m = (ai->uh->AllUnitsByType[udef->id]).size();
	const int n = udef->maxThisUnit;

	if (m >= n) {
		// if we've hit the build-limit for this
		// type of unit, make sure GetUnitByScore()
		// won't pick it for construction anyway
		return 0.0f;
	}

	if (udef->minWaterDepth > 0) {
		// we can't swim yet
		return 0.0f;
	}

	const int frame = ai->cb->GetCurrentFrame();
	const float cost =
		((udef->metalCost * METAL2ENERGY) +
		udef->energyCost) + 0.1f;
	const float currentIncome =
		INCOMEMULTIPLIER *
		(ai->cb->GetEnergyIncome() + (ai->cb->GetMetalIncome() * METAL2ENERGY)) +
		frame / 2;
	const float Hitpoints = udef->health;
	const float buildTime = udef->buildTime + 0.1f;
	const float RandNum = ai->math->RandNormal(4, 3, 1) + 1;

	float benefit = 0.0f;
	float aoe = 0.0f;
	float dps = 0.0f;
	int unitcounter = 0;
	bool candevelop = false;

	switch (cat) {
		case CAT_ENERGY: {
			// KLOOTNOTE: factor build-time into this as well?
			// (so benefit values generally lie closer together)
			float baseBenefit = udef->energyMake - udef->energyUpkeep;

			if (udef->windGenerator > 0.0f) {
				const float minWind = ai->cb->GetMinWind();
				const float maxWind = ai->cb->GetMaxWind();
				const float avgWind = (minWind + maxWind) * 0.5f;
				const float avgEffi = std::min(avgWind / udef->windGenerator, 1.0f);

				if (avgEffi >= 0.4f) {
					baseBenefit += avgWind;
				}
			}
			if (udef->tidalGenerator > 0.0f) {
				baseBenefit += ai->cb->GetTidalStrength();
			}

			// filter geothermals
			if (udef->needGeo) {
				baseBenefit = 0.0f;
			}

			// KLOOTNOTE: dividing by cost here as well means
			// benefit is inversely proportional to square of
			// cost, so expensive generators are quadratically
			// less likely to be built if original calculation
			// of score is used
			// benefit /= cost;
			benefit = (baseBenefit / buildTime) * float((rand() % 2) + 1);
		} break;

		case CAT_MEX: {
			benefit = pow(udef->extractsMetal, 4.0f);
		} break;
		case CAT_MMAKER: {
			// benefit = ((udef->metalMake - udef->metalUpkeep) / udef->energyUpkeep) + 0.01f;
			benefit = (udef->metalMake - udef->metalUpkeep) / (udef->energyUpkeep + 0.01f);
		} break;

		case CAT_G_ATTACK: {
			dps = GetCurrentDamageScore(udef);
			aoe = ((udef->weapons.size())? ((udef->weapons.front()).def)->areaOfEffect: 0.0f);

			if (udef->canfly && !udef->hoverAttack) {
				// TODO: improve to set reload-time to the bomber's
				// turnspeed vs. movespeed (eg. time taken for a run)
				dps /= 6;
			}

			benefit =
				pow((aoe + 80), 1.5f) *
				pow(GetMaxRange(udef) + 200, 1.5f) *
				pow(dps, 1.0f) *
				pow(udef->speed + 40, 1.0f) *
				pow(Hitpoints, 1.0f) *
				pow(RandNum, 2.5f) *
				pow(cost, -0.5f);

			if (udef->canfly || udef->canhover) {
				// general hack: reduce feasibility of aircraft for 20 mins
				// and that of hovercraft permanently, should mostly prefer
				// real L2 units to hovers
				benefit = (udef->canfly && frame >= (30 * 60 * 20))? benefit: benefit * 0.01f;
			}
		} break;

		case CAT_DEFENCE: {
			aoe = ((udef->weapons.size())? ((udef->weapons.front()).def)->areaOfEffect: 0.0f);
			benefit =
				pow((aoe + 80), 1.5f) *
				pow(GetMaxRange(udef), 2.0f) *
				pow(GetCurrentDamageScore(udef), 1.5f) *
				pow(Hitpoints, 0.5f) *
				pow(RandNum, 2.5f) *
				pow(cost, -1.0f);
		} break;

		case CAT_BUILDER: {
			for (unsigned int i = 0; i != unitTypes[udef->id].canBuildList.size(); i++) {
				if (unitTypes[unitTypes[udef->id].canBuildList[i]].category == CAT_FACTORY) {
					candevelop = true;
				}
			}

			// builder units that cannot construct any
			// factories are worthless, prevent them
			// from being chosen via GetUnitByScore()
			// (they might have other uses though, eg.
			// nano-towers)
			if (!candevelop) {
				benefit = 0.0f;
			} else {
				benefit =
					pow(udef->buildSpeed, 1.0f) *
					pow(udef->speed, 0.5f) *
					pow(Hitpoints, 0.3f) *
					pow(RandNum, 0.4f);
			}
		} break;

		case CAT_FACTORY: {
			// benefit of a factory is dependant on the kind of
			// offensive units it can build, but EE-hubs are only
			// capable of building other buildings
			for (unsigned int i = 0; i != unitTypes[udef->id].canBuildList.size(); i++) {
				const int          buildOpt    = unitTypes[udef->id].canBuildList[i];
				const UnitCategory buildOptCat = unitTypes[buildOpt].category;

				if (buildOptCat == CAT_G_ATTACK || buildOptCat == CAT_FACTORY) {
					if (unitTypes[buildOpt].def != udef) {
						// KLOOTNOTE: guard against infinite recursion (BuildTowers in
						// PURE trigger this since they are able to build themselves)
						benefit += GetScore(unitTypes[buildOpt].def, buildOptCat);
						unitcounter++;
					}
				}
			}

			if (unitcounter > 0) {
				benefit /= (unitcounter * pow(float(ai->uh->AllUnitsByType[udef->id].size() + 1), 3.0f));
				benefit /= ((m > 0)? (m * 2.0f): 1.0f);
			} else {
				benefit = 0.0f;
			}
		} break;

		case CAT_MSTOR: {
			benefit = pow((udef->metalStorage), 1.0f) * pow(Hitpoints, 1.0f);
		} break;
		case CAT_ESTOR: {
			benefit = pow((udef->energyStorage), 1.0f) * pow(Hitpoints, 1.0f);
		} break;
		case CAT_NUKE: {
			// KLOOTNOTE: should factor damage into this as well
			float metalCost = udef->stockpileWeaponDef->metalcost;
			float energyCost = udef->stockpileWeaponDef->energycost;
			float supplyCost = udef->stockpileWeaponDef->supplycost;
			float denom = metalCost + energyCost + supplyCost + 1.0f;
			float range = udef->stockpileWeaponDef->range;
			benefit = (udef->stockpileWeaponDef->areaOfEffect + range) / denom;
		} break;
		/*
		case CAT_ANTINUKE: {
			benefit = udef->stockpileWeaponDef->coverageRange;
		} break;
		case CAT_SHIELD: {
			benefit = udef->shieldWeaponDef->shieldRadius;
		} break;
		*/
		default:
			benefit = 0.0f;
	}

	benefit *= unitTypes[udef->id].costMultiplier;
	// return (benefit / (currentIncome + cost));
	// return ((benefit / cost) * currentIncome);
	return ((currentIncome / cost) * benefit);
}
Пример #27
0
bool ChatHandler::HandleAddAIAgentCommand(const char* args, WorldSession *m_session)
{
	char* agent = strtok((char*)args, " ");
	if(!agent)
		return false;
	char* procEvent = strtok(NULL, " ");
	if(!procEvent)
		return false;
	char* procChance = strtok(NULL, " ");
	if(!procChance)
		return false;
	char* procCount = strtok(NULL, " ");
	if(!procCount)
		return false;
	char* spellId = strtok(NULL, " ");
	if(!spellId)
		return false;
	char* spellType = strtok(NULL, " ");
	if(!spellType)
		return false;
	char* spelltargetType = strtok(NULL, " ");
	if(!spelltargetType)
		return false;
	char* spellCooldown = strtok(NULL, " ");
	if(!spellCooldown)
		return false;
	char* floatMisc1 = strtok(NULL, " ");
	if(!floatMisc1)
		return false;
	char* Misc2 = strtok(NULL, " ");
	if(!Misc2)
		return false;

	Creature* target = m_session->GetPlayer()->GetMapMgr()->GetCreature(GET_LOWGUID_PART(m_session->GetPlayer()->GetSelection()));
	if(!target)
	{
		RedSystemMessage(m_session, "You have to select a Creature!");
		return false;
	}

	std::stringstream qry;
	qry << "INSERT INTO ai_agents SET entry = '" << target->GetUInt32Value(OBJECT_FIELD_ENTRY) << "', type = '" << atoi(agent) << "', event = '" << atoi(procEvent)<< "', chance = '" << atoi(procChance)<< "', maxcount = '" << atoi(procCount)<< "', spell = '" << atoi(spellId)<< "', spelltype = '" << atoi(spellType)<< "', targettype_overwrite = '" << atoi(spelltargetType)<< "', cooldown_overwrite = '" << atoi(spellCooldown)<< "', floatMisc1 = '" << atof(floatMisc1)<< "', Misc2  ='" << atoi(Misc2)<< "'";
	WorldDatabase.Execute( qry.str().c_str( ) );

	AI_Spell * sp = new AI_Spell;
	sp->agent = atoi(agent);
	sp->procChance = atoi(procChance);
/*	sp->procCount = atoi(procCount);*/
	sp->spell = dbcSpell.LookupEntry(atoi(spellId));
	sp->spellType = atoi(spellType);
//	sp->spelltargetType = atoi(spelltargetType);
	sp->floatMisc1 = (float)atof(floatMisc1);
	sp->Misc2 = (uint32)atof(Misc2);
	sp->cooldown = (uint32)atoi(spellCooldown);
	sp->procCount=0;
	sp->procCounter=0;
	sp->cooldowntime=0;
	sp->minrange = GetMinRange(dbcSpellRange.LookupEntry(dbcSpell.LookupEntry(atoi(spellId))->rangeIndex));
	sp->maxrange = GetMaxRange(dbcSpellRange.LookupEntry(dbcSpell.LookupEntry(atoi(spellId))->rangeIndex));

	target->GetProto()->spells.push_back(sp);

	if(sp->agent == AGENT_CALLFORHELP)
		target->GetAIInterface()->m_canCallForHelp = true;
	else if(sp->agent == AGENT_FLEE)
		target->GetAIInterface()->m_canFlee = true;
	else if(sp->agent == AGENT_RANGED)
		target->GetAIInterface()->m_canRangedAttack = true;
	else
		target->GetAIInterface()->addSpellToList(sp);

	return true;
}
Пример #28
0
void Spell::AddChainTargets(uint32 i, uint32 TargetType, float r, uint32 maxtargets)
{
	if(!m_caster->IsInWorld())
		return;

	Object* targ = m_caster->GetMapMgr()->_GetObject(m_targets.m_unitTarget);

	if(targ == NULL)
		return;

	TargetsList* list = &m_targetUnits[i];

	//if selected target is party member, then jumps on party
	Unit* firstTarget = NULL;

	if(targ->IsUnit())
		firstTarget = TO_UNIT(targ);
	else
		firstTarget = u_caster;

	bool RaidOnly = false;
	float range = GetMaxRange(dbcSpellRange.LookupEntry(m_spellInfo->rangeIndex));//this is probably wrong,
	//this is cast distance, not searching distance
	range *= range;

	//is this party only?
	Player* casterFrom = TO< Player* >(u_caster->GetPlayerOwner());
	Player* pfirstTargetFrom = TO< Player* >(firstTarget->GetPlayerOwner());

	if(casterFrom != NULL && pfirstTargetFrom != NULL && casterFrom->GetGroup() == pfirstTargetFrom->GetGroup())
		RaidOnly = true;

	uint32 jumps = m_spellInfo->EffectChainTarget[i];

	//range
	range /= jumps; //hacky, needs better implementation!

	if(m_spellInfo->SpellGroupType && u_caster != NULL)
		SM_FIValue(u_caster->SM_FAdditionalTargets, (int32*)&jumps, m_spellInfo->SpellGroupType);

	AddTarget(i, TargetType, firstTarget);

	if(jumps <= 1 || list->size() == 0) //1 because we've added the first target, 0 size if spell is resisted
		return;

	ObjectSet::iterator itr;
	for(itr = firstTarget->GetInRangeSetBegin(); itr != firstTarget->GetInRangeSetEnd(); itr++)
	{
		if(!(*itr)->IsUnit() || !TO_UNIT((*itr))->isAlive())
			continue;

		if(RaidOnly && !pfirstTargetFrom->InRaid(TO_UNIT(*itr)))
			continue;

		//healing spell, full health target = NONO
		if(IsHealingSpell(m_spellInfo) && TO_UNIT(*itr)->GetHealthPct() == 100)
			continue;

		size_t oldsize;

		if(IsInrange(firstTarget->GetPositionX(), firstTarget->GetPositionY(), firstTarget->GetPositionZ(), (*itr), range))
		{
			oldsize = list->size();
			AddTarget(i, TargetType, (*itr));
			if(list->size() == oldsize || list->size() >= jumps) //either out of jumps or a resist
				return;
		}
	}
}
Пример #29
0
void ObjectMgr::LoadExtraCreatureProtoStuff()
{
	{
		StorageContainerIterator<CreatureProto> * itr = CreatureProtoStorage.MakeIterator();
		CreatureProto * cn;
		while(!itr->AtEnd())
		{
			cn = itr->Get();
			if(itr->Get()->aura_string)
			{
				string auras = string(itr->Get()->aura_string);
				vector<string> aurs = StrSplit(auras, " ");
				for(vector<string>::iterator it = aurs.begin(); it != aurs.end(); ++it)
				{
					uint32 id = atol((*it).c_str());
					if(id)
						itr->Get()->start_auras.insert( id );
				}
			}

			if(!itr->Get()->MinHealth)
				itr->Get()->MinHealth = 1;
			if(!itr->Get()->MaxHealth)
				itr->Get()->MaxHealth = 1;
			if (itr->Get()->AttackType > SCHOOL_ARCANE)
				itr->Get()->AttackType = SCHOOL_NORMAL;

			cn->m_canFlee = cn->m_canRangedAttack = cn->m_canCallForHelp = false;
			cn->m_fleeHealth = 0.0f;
			// please.... m_fleeDuration is a uint32...
			//cn->m_fleeDuration = 0.0f;
			cn->m_fleeDuration = 0;

			if(!itr->Inc())
				break;
		}

		itr->Destruct();
	}

	{
		StorageContainerIterator<CreatureInfo> * itr = CreatureNameStorage.MakeIterator();
		CreatureInfo * ci;
		while(!itr->AtEnd())
		{
			ci = itr->Get();

			ci->lowercase_name = string(ci->Name);
			for(uint32 j = 0; j < ci->lowercase_name.length(); ++j)
				ci->lowercase_name[j] = tolower(ci->lowercase_name[j]); // Darvaleo 2008/08/15 - Copied lowercase conversion logic from ItemPrototype task

			ci->gossip_script = sScriptMgr.GetDefaultGossipScript();

			if(!itr->Inc())
				break;
		}
		itr->Destruct();
	}

	{
		StorageContainerIterator<Quest> * itr = QuestStorage.MakeIterator();
		Quest * qst;
		while(!itr->AtEnd())
		{
			qst = itr->Get();
			qst->pQuestScript = NULL;

			if( !itr->Inc() )
				break;
		}
		itr->Destruct();
	}

	// Load AI Agents
	QueryResult * result = WorldDatabase.Query( "SELECT * FROM ai_agents" );
	CreatureProto * cn;

	if( result != NULL )
	{
		AI_Spell *sp;
		SpellEntry * spe;
		uint32 entry;

		if(Config.OptionsConfig.GetBoolDefault("Server", "LoadAIAgents", true))
		{
			do
			{
				Field *fields = result->Fetch();
				entry = fields[0].GetUInt32();
				cn = CreatureProtoStorage.LookupEntry(entry);
				spe = dbcSpell.LookupEntryForced(fields[5].GetUInt32());
				if( spe == NULL )
				{
					Log.Warning("AIAgent", "For %u has nonexistant spell %u.", fields[0].GetUInt32(), fields[5].GetUInt32());
				}
				if(!cn)
					continue;

				sp = new AI_Spell;
				sp->entryId = fields[0].GetUInt32();
				sp->agent = fields[1].GetUInt16();
				sp->procChance = fields[3].GetUInt32();
				sp->procCount = fields[4].GetUInt32();
				sp->spell = spe;
				sp->spellType = fields[6].GetUInt32();
				sp->spelltargetType = fields[7].GetUInt32();
				sp->cooldown = fields[8].GetUInt32();
				sp->floatMisc1 = fields[9].GetFloat();
				sp->autocast_type=(uint32)-1;
				sp->custom_pointer=false;
				sp->cooldowntime=getMSTime();
				sp->procCounter=0;

		/*		if (!sp->procCountDB) 
					sp->procCount = uint32(-1);
				else sp->procCount = sp->procCountDB;*/
				sp->Misc2 = fields[10].GetUInt32();
				if(sp->agent == AGENT_SPELL)
				{
					if(!sp->spell)
					{
						//printf("SpellId %u in ai_agent for %u is invalid.\n", (unsigned int)fields[5].GetUInt32(), (unsigned int)sp->entryId);
						delete sp;
						continue;
					}
					
					if(sp->spell->Effect[0] == SPELL_EFFECT_LEARN_SPELL || sp->spell->Effect[1] == SPELL_EFFECT_LEARN_SPELL ||
						sp->spell->Effect[2] == SPELL_EFFECT_LEARN_SPELL)
					{
						//printf("Teaching spell %u in ai_agent for %u\n", (unsigned int)fields[5].GetUInt32(), (unsigned int)sp->entryId);
						delete sp;
						continue;
					}

					sp->minrange = GetMinRange(dbcSpellRange.LookupEntry(sp->spell->rangeIndex));
					sp->maxrange = GetMaxRange(dbcSpellRange.LookupEntry(sp->spell->rangeIndex));

					//omg the poor darling has no clue about making ai_agents
					if(sp->cooldown==0xffffffff)
					{
						//now this will not be exact cooldown but maybe a bigger one to not make him spam spells to often
						int cooldown;
						SpellDuration *sd=dbcSpellDuration.LookupEntry(sp->spell->DurationIndex);
						int Dur=0;
						int Casttime=0;//most of the time 0
						int RecoveryTime=sp->spell->RecoveryTime;
						if(sp->spell->DurationIndex)
							Dur =::GetDuration(sd);
						Casttime=GetCastTime(dbcSpellCastTime.LookupEntry(sp->spell->CastingTimeIndex));
						cooldown=Dur+Casttime+RecoveryTime;
						if(cooldown<0)
							sp->cooldown=0;//huge value that should not loop while adding some timestamp to it
						else sp->cooldown=cooldown;
					}

					/*
					//now apply the morron filter
					if(sp->procChance==0)
					{
						//printf("SpellId %u in ai_agent for %u is invalid.\n", (unsigned int)fields[5].GetUInt32(), (unsigned int)sp->entryId);
						delete sp;
						continue;
					}
					if(sp->spellType==0)
					{
						//right now only these 2 are used
						if(IsBeneficSpell(sp->spell))
							sp->spellType==STYPE_HEAL;
						else sp->spellType==STYPE_BUFF;
					}
					if(sp->spelltargetType==0)
						sp->spelltargetType = RecommandAISpellTargetType(sp->spell);
						*/
				}

				if(sp->agent == AGENT_RANGED)
				{
					cn->m_canRangedAttack = true;
					delete sp;
				}
				else if(sp->agent == AGENT_FLEE)
				{
					cn->m_canFlee = true;
					if(sp->floatMisc1)
						cn->m_canFlee = (sp->floatMisc1>0.0f ? true : false);
					else
						cn->m_fleeHealth = 0.2f;

					if(sp->Misc2)
						cn->m_fleeDuration = sp->Misc2;
					else
						cn->m_fleeDuration = 10000;

					delete sp;
				}
				else if(sp->agent == AGENT_CALLFORHELP)
				{
					cn->m_canCallForHelp = true;
					if(sp->floatMisc1)
						cn->m_callForHelpHealth = 0.2f;
					delete sp;
				}
				else
				{
					cn->spells.push_back(sp);
				}
			} while( result->NextRow() );
		}

		delete result;
	}
}