예제 #1
0
파일: PetAI.cpp 프로젝트: Jojo2323/mangos3
uint32 PetAI::GetSpellType(PetAutoSpellType type)
{
    if (type >= PET_SPELL_MAX || m_spellType[type].empty())
        return 0;

    std::vector<uint32> tmpSet;

    for (Unit::SpellIdSet::const_iterator itr = m_spellType[type].begin(); itr != m_spellType[type].end(); ++itr)
    {
        uint32 _spellID = *itr;
        if (!_spellID)
            continue;

        SpellEntry const* spellInfo = sSpellStore.LookupEntry(_spellID);
        if (!spellInfo)
            continue;

        if (m_creature->GetCharmInfo() && m_creature->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
            continue;

        if (m_creature->HasSpellCooldown(spellInfo))
            continue;

        if (IsInCombat() && IsNonCombatSpell(spellInfo))
            continue;

        if (!IsInCombat() && IsPositiveSpell(spellInfo) && !IsNonCombatSpell(spellInfo))
        {
            int32 duration = GetSpellDuration(spellInfo);
//            if ((spellInfo->manaCost || spellInfo->ManaCostPercentage || spellInfo->manaPerSecond) && duration > 0)
//                continue;

            // allow only spell without cooldown > duration
            int32 cooldown = GetSpellRecoveryTime(spellInfo);
            if (cooldown >= 0 && duration >= 0 && cooldown > duration)
                continue;
        }

        tmpSet.push_back(_spellID);
    }

    if (tmpSet.empty())
        return 0;
    else
        return tmpSet[urand(0, tmpSet.size() - 1)];
}
예제 #2
0
	void AIUpdate()
	{
		if (!IsInCombat())
			CastSpellOnTarget(_unit, Target_Self, dbcSpell.LookupEntry(SPELL_SHADOW_CHANNELING), false);
		
		if (timmer == 6 && IsInCombat())
		{
			SpawnCreature(CN_VOLATILE_FELFIRE_FIEND, _unit->GetPositionX()+1, _unit->GetPositionY()+1, _unit->GetPositionZ(), 0, true);
			timmer = 0;
		}

		if(GetHealthPercent()<=25 && infusion == false)
		{
			ApplyAura(SPELL_SHADOW_INFUSION);
			infusion = true;
		}
		timmer++;
		ParentClass::AIUpdate();
	}
예제 #3
0
파일: PetAI.cpp 프로젝트: Kuvaldin/mangos
void PetAI::_stopAttack()
{
    inCombat = false;

    if (IsInCombat())
    {
        m_creature->CastStop();
        m_creature->AttackStop();
        m_creature->GetMotionMaster()->Clear();
        m_creature->GetMotionMaster()->MoveTargetedHome();
    }
}
예제 #4
0
파일: PetAI.cpp 프로젝트: Jojo2323/mangos3
void PetAI::_stopAttack()
{
    if (!IsInCombat())
        return;

    inCombat = false;

    m_creature->CastStop();
    m_creature->AttackStop();
    m_creature->GetMotionMaster()->Clear(); // move idle

    if (!m_savedTargetGuid)
        m_creature->GetMotionMaster()->MoveTargetedHome();
}
예제 #5
0
void TempSummon::Update(uint32 diff)
{
    Creature::Update(diff);

    if (m_deathState == DEAD)
    {
        UnSummon();
        return;
    }
    switch (m_type)
    {
        case TEMPSUMMON_MANUAL_DESPAWN:
            break;
        case TEMPSUMMON_TIMED_DESPAWN:
        {
            if (m_timer <= diff)
            {
                UnSummon();
                return;
            }

            m_timer -= diff;
            break;
        }
        case TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT:
        {
            if (!IsInCombat())
            {
                if (m_timer <= diff)
                {
                    UnSummon();
                    return;
                }

                m_timer -= diff;
            }
            else if (m_timer != m_lifetime)
                m_timer = m_lifetime;

            break;
        }

        case TEMPSUMMON_CORPSE_TIMED_DESPAWN:
        {
            if (m_deathState == CORPSE)
            {
                if (m_timer <= diff)
                {
                    UnSummon();
                    return;
                }

                m_timer -= diff;
            }
            break;
        }
        case TEMPSUMMON_CORPSE_DESPAWN:
        {
            // if m_deathState is DEAD, CORPSE was skipped
            if (m_deathState == CORPSE || m_deathState == DEAD)
            {
                UnSummon();
                return;
            }

            break;
        }
        case TEMPSUMMON_DEAD_DESPAWN:
        {
            if (m_deathState == DEAD)
            {
                UnSummon();
                return;
            }
            break;
        }
        case TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN:
        {
            // if m_deathState is DEAD, CORPSE was skipped
            if (m_deathState == CORPSE || m_deathState == DEAD)
            {
                UnSummon();
                return;
            }

            if (!IsInCombat())
            {
                if (m_timer <= diff)
                {
                    UnSummon();
                    return;
                }
                else
                    m_timer -= diff;
            }
            else if (m_timer != m_lifetime)
                m_timer = m_lifetime;
            break;
        }
        case TEMPSUMMON_TIMED_OR_DEAD_DESPAWN:
        {
            // if m_deathState is DEAD, CORPSE was skipped
            if (m_deathState == DEAD)
            {
                UnSummon();
                return;
            }

            if (!IsInCombat() && IsAlive())
            {
                if (m_timer <= diff)
                {
                    UnSummon();
                    return;
                }
                else
                    m_timer -= diff;
            }
            else if (m_timer != m_lifetime)
                m_timer = m_lifetime;
            break;
        }
        default:
            UnSummon();
            TC_LOG_ERROR("entities.unit", "Temporary summoned creature (entry: %u) have unknown type %u of ", GetEntry(), m_type);
            break;
    }
}
예제 #6
0
파일: PetAI.cpp 프로젝트: Kuvaldin/mangos
void PetAI::UpdateAI(const uint32 diff)
{
    if (!m_creature->isAlive())
        return;

    Unit* owner = m_creature->GetCharmerOrOwner();

    m_updateAlliesTimer.Update(diff);
    if (m_updateAlliesTimer.Passed())
    {
        UpdateAllies();
        m_updateAlliesTimer.Reset();
    }

    if (!inCombat && !m_savedTargetGuid.IsEmpty())
    {
        if (Unit* saved_target = m_creature->GetMap()->GetUnit(m_savedTargetGuid))
        {
            if (!saved_target->isAlive())
                m_savedTargetGuid.Clear();
            else if (!saved_target->IsCrowdControlled())
                AttackStart(saved_target);
        }
        else
            m_savedTargetGuid.Clear();
    }

    if (inCombat &&
        (!m_creature->getVictim() ||
         !m_creature->getVictim()->isAlive() ||
        (m_creature->IsPet() && m_creature->GetCharmInfo()->HasState(CHARM_STATE_ACTION, ACTIONS_DISABLE))))
        _stopAttack();

    if (m_creature->hasUnitState(UNIT_STAT_CAN_NOT_REACT) || m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED))
    {
        UpdateAIType();
        return;
    }

    // i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc.
    if (m_creature->getVictim())
    {
        bool meleeReach = m_creature->CanReachWithMeleeAttack(m_creature->getVictim());

        if (_needToStop())
        {
            DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "PetAI (guid = %u) is stopping attack.", m_creature->GetGUIDLow());
            _stopAttack();
            return;
        }
        else if (!m_creature->getVictim()->isAlive())        // Stop attack if target dead
        {
            m_creature->InterruptNonMeleeSpells(false);
            _stopAttack();
            return;
        }
        else if (sWorld.getConfig(CONFIG_BOOL_PET_ADVANCED_AI) && IsInCombat() && m_creature->getVictim() && m_creature->getVictim()->IsCrowdControlled())  // Stop attack if target under CC effect
        {
            m_savedTargetGuid = m_creature->getVictim()->GetObjectGuid();
            m_creature->InterruptSpell(CURRENT_GENERIC_SPELL, true);
            if (!m_creature->IsNonMeleeSpellCasted(false, false, true))
                _stopAttack();
            return;
        }
        else if (m_creature->IsStopped() || meleeReach)
        {
            // required to be stopped cases
            if (m_creature->IsStopped() && m_creature->IsNonMeleeSpellCasted(false))
            {
                if (m_creature->hasUnitState(UNIT_STAT_FOLLOW_MOVE))
                    m_creature->InterruptNonMeleeSpells(false);
                else
                    return;
            }
            // not required to be stopped case
            else if (DoMeleeAttackIfReady())
            {
                if (!m_creature->getVictim())
                    return;

                //if pet misses its target, it will also be the first in threat list
                m_creature->getVictim()->AddThreat(m_creature);

                if (_needToStop())
                    _stopAttack();
            }
        }

        if (!m_creature->IsNonMeleeSpellCasted(true))
        {
            m_attackDistanceRecheckTimer.Update(diff);
            if (m_attackDistanceRecheckTimer.Passed())
            {
                m_attackDistanceRecheckTimer.Reset();
                if (sWorld.getConfig(CONFIG_BOOL_PET_ADVANCED_AI) && m_AIType == PET_AI_RANGED)
                {
                    float dist = m_creature->GetDistance(m_creature->getVictim());
                    if ((m_creature->CanReachWithMeleeAttack(m_creature->getVictim()) &&
                        m_creature->IsWithinDist(m_creature->GetOwner(), m_creature->GetMap()->GetVisibilityDistance() / 2.0f)) ||
                        dist > (m_attackDistance + 2.0f))
                    {
                        MoveToVictim(m_creature->getVictim());
                        return;
                    }
                }

                if (sWorld.getConfig(CONFIG_BOOL_PET_ADVANCED_AI))
                {
                    // AOE check
                }
            }
        }
    }
    else if (Unit* target = GetPrimaryTarget())
    {
        AttackStart(target);
    }
    else if (owner && owner->IsInCombat())
    {
        switch (m_creature->GetCharmState(CHARM_STATE_REACT))
        {
            case REACT_DEFENSIVE:
            {
                if (!m_creature->getVictim()
                    || !m_creature->getVictim()->isAlive()
                    || (m_primaryTargetGuid.IsEmpty() && owner->getVictim() != m_creature->getVictim() && owner->getVictim()->isAlive()))
                    AttackStart(owner->getAttackerForHelper());
                break;
            }
            case REACT_AGGRESSIVE:
            {
                if (!m_creature->getVictim() || !m_creature->getVictim()->isAlive())
                    AttackStart(owner->getAttackerForHelper());
                break;
            }
            case REACT_PASSIVE:
            default:
                break;
        }
    }

    UpdateAIType();

    if (m_creature->IsNonMeleeSpellCasted(true))
        return;

    // Autocast (casted only in combat or persistent spells in any state)
    if (!sWorld.getConfig(CONFIG_BOOL_PET_ADVANCED_AI) && m_AIType != PET_AI_PASSIVE)
    {
        typedef std::vector<std::pair<ObjectGuid, uint32> > TargetSpellList;
        TargetSpellList targetSpellStore;

        for (uint8 i = 0; i < m_creature->GetPetAutoSpellSize(); ++i)
        {
            uint32 spellID = m_creature->GetPetAutoSpellOnPos(i);
            if (!spellID)
                continue;

            SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellID);
            if (!spellInfo)
                continue;

            if (m_creature->GetCharmInfo() && m_creature->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
                continue;

            if (m_creature->HasSpellCooldown(spellInfo))
                continue;

            // ignore some combinations of combat state and combat/noncombat spells
            if (!inCombat)
            {
                // ignore attacking spells, and allow only self/around spells
                if (!IsPositiveSpell(spellInfo->Id))
                    continue;

                // non combat spells allowed
                // only pet spells have IsNonCombatSpell and not fit this reqs:
                // Consume Shadows, Lesser Invisibility, so ignore checks for its
                if (!IsNonCombatSpell(spellInfo))
                {
                    // allow only spell without spell cost or with spell cost but not duration limit
                    int32 duration = GetSpellDuration(spellInfo);
                    if ((spellInfo->manaCost || spellInfo->ManaCostPercentage || spellInfo->manaPerSecond) && duration > 0)
                        continue;

                    // allow only spell without cooldown > duration
                    int32 cooldown = GetSpellRecoveryTime(spellInfo);
                    if (cooldown >= 0 && duration >= 0 && cooldown > duration)
                        continue;
                }
            }
            else
            {
                // just ignore non-combat spells
                if (IsNonCombatSpell(spellInfo))
                    continue;
            }

            Unit* autoCastTarget = NULL;

            if (inCombat && m_creature->getVictim() && !m_creature->hasUnitState(UNIT_STAT_FOLLOW))
            {
                SpellCastResult result = CanAutoCast(m_creature->getVictim(), spellInfo);
                if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
                    autoCastTarget = m_creature->getVictim();
            }

            if (!autoCastTarget)
            {
                for (GuidSet::const_iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar)
                {
                    Unit* target = m_creature->GetMap()->GetUnit(*tar);

                    // Only buff targets that are in combat, unless the spell can only be cast while out of combat
                    if (!target)
                        continue;

                    SpellCastResult result = CanAutoCast(target, spellInfo);
                    if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
                    {
                        autoCastTarget = target;
                        break;
                    }
                }
            }

            if (autoCastTarget)
                targetSpellStore.push_back(TargetSpellList::value_type(autoCastTarget->GetObjectGuid(), spellInfo->Id));
        }

        // found units to cast on to
        if (!targetSpellStore.empty())
        {
            uint32 index = urand(0, targetSpellStore.size() - 1);
            if (Unit* target = m_creature->GetMap()->GetUnit(targetSpellStore[index].first))
                m_creature->DoPetCastSpell(target, targetSpellStore[index].second);
        }
    }
    else
    {
        AutoSpellList currentSpells;
        switch (m_AIType)
        {
            case PET_AI_PASSIVE:
            {
                currentSpells.push_back(GetSpellType(PET_SPELL_BUFF));
                break;
            }
            case PET_AI_SLACKER:
            {
                if (!IsInCombat())
                    break;

                if (m_creature->IsCrowdControlled() || (owner && owner->IsCrowdControlled()))
                    currentSpells.push_back(GetSpellType(PET_SPELL_FREEACTION));
                currentSpells.push_back(GetSpellType(PET_SPELL_DEFENCE));
                currentSpells.push_back(GetSpellType(PET_SPELL_BUFF));
                currentSpells.push_back(GetSpellType(PET_SPELL_DEBUFF));
                currentSpells.push_back(GetSpellType(PET_SPELL_RANGED));
                break;
            }
            case PET_AI_HEALER:
            {
                if (!IsInCombat())
                    break;

                if (m_creature->IsCrowdControlled() || (owner && owner->IsCrowdControlled()))
                    currentSpells.push_back(GetSpellType(PET_SPELL_FREEACTION));
                if (m_creature->GetHealth() < m_creature->GetMaxHealth() ||
                    (owner && (owner->GetHealth() < owner->GetMaxHealth())))
                    currentSpells.push_back(GetSpellType(PET_SPELL_HEAL));
                currentSpells.push_back(GetSpellType(PET_SPELL_BUFF));
                currentSpells.push_back(GetSpellType(PET_SPELL_RANGED));
                break;
            }
            case PET_AI_RANGED:
            {
                if (!IsInCombat())
                    break;

                if (m_creature->IsCrowdControlled() || (owner && owner->IsCrowdControlled()))
                    currentSpells.push_back(GetSpellType(PET_SPELL_FREEACTION));
                currentSpells.push_back(GetSpellType(PET_SPELL_RANGED));
                currentSpells.push_back(GetSpellType(PET_SPELL_DEBUFF));
                currentSpells.push_back(GetSpellType(PET_SPELL_BUFF));
                break;
            }
            case PET_AI_MELEE:
            case PET_AI_RANGED_NOAMMO:
            {
                if (!IsInCombat())
                    break;

                if (Unit* victim = m_creature->getVictim())
                {
                    if (!victim->getVictim() || (victim->getVictim()->GetObjectGuid() != m_creature->GetObjectGuid()))
                    {
                        currentSpells.push_back(GetSpellType(PET_SPELL_ATTACKSTART));
                        currentSpells.push_back(GetSpellType(PET_SPELL_THREAT));
                    }
                }

                if (m_creature->IsCrowdControlled() || (owner && owner->IsCrowdControlled()))
                    currentSpells.push_back(GetSpellType(PET_SPELL_FREEACTION));
            }
            /* no break here!*/
            default:
            {
                if (!IsInCombat())
                    break;

                currentSpells.push_back(GetSpellType(PET_SPELL_MELEE));
                currentSpells.push_back(GetSpellType(PET_SPELL_DEBUFF));
                currentSpells.push_back(GetSpellType(PET_SPELL_RANGED));
                currentSpells.push_back(GetSpellType(PET_SPELL_BUFF));
                break;
            }
        }

        if (!IsInCombat())
        {
            currentSpells.push_back(GetSpellType(PET_SPELL_NONCOMBAT));
            if (m_creature->GetHealthPercent() < 95.0f)
                currentSpells.push_back(GetSpellType(PET_SPELL_HEAL));
        }
        else
            currentSpells.push_back(GetSpellType(PET_SPELL_SPECIAL));

        for (AutoSpellList::const_iterator itr = currentSpells.begin(); itr != currentSpells.end(); ++itr)
        {
            uint32 spellID = *itr;
            if (!spellID)
                continue;

            SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellID);
            if (!spellInfo)
                continue;

            if (m_creature->GetCharmInfo() && m_creature->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
                continue;

            Unit* pTarget =  m_creature->IsPet() ? ((Pet*)m_creature)->SelectPreferredTargetForSpell(spellInfo) :
                                                   ((Creature*)m_creature)->SelectPreferredTargetForSpell(spellInfo);
            bool b_castOk = false;

            if (pTarget)
            {
                SpellCastResult result = CanAutoCast(pTarget, spellInfo);
                DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS,"PetAI::Update %s, AI %u try cast %u Target %s",
                            m_creature->GetGuidStr().c_str(),
                            m_AIType,
                            spellID,
                            pTarget ? pTarget->GetGuidStr().c_str() : "<none>");
                switch (result)
                {
                    case SPELL_FAILED_UNIT_NOT_INFRONT:
                    {
                        if (DoCastSpellIfCan(pTarget, spellID) == CAST_OK)
                        {
                            b_castOk = true;
                            m_creature->SetInFront(pTarget);
                            if (pTarget->GetTypeId() == TYPEID_PLAYER)
                                m_creature->SendCreateUpdateToPlayer((Player*)pTarget);
                        }
                        break;
                    }
                    case SPELL_CAST_OK:
                    {
                        if (DoCastSpellIfCan(pTarget, spellID) == CAST_OK)
                            b_castOk = true;
                        break;
                    }
                    default:
                    {
                        Player* owner = (Player*)m_creature->GetOwner();
                        if (owner)
                            Spell::SendCastResult(owner,spellInfo,0,result, true);

                        DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS,"PetAI::Update cast %s, AI %u Target %s spell %u result %u",
                            m_creature->GetGuidStr().c_str(),
                            m_AIType,
                            pTarget ? pTarget->GetGuidStr().c_str() : "<none>",
                            spellID,
                            result);
                        break;
                    }
                }
            }
            else
                continue;

            if (b_castOk)
            {
                m_creature->AddSpellAndCategoryCooldowns(spellInfo);
                if (m_creature->IsPet())
                {
                    if(((Pet*)m_creature)->getPetType() == SUMMON_PET && (urand(0, 100) < 10))
                        m_creature->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);
                    else
                        m_creature->SendPetAIReaction();
                }
                break;
            }
        }
    }
}
예제 #7
0
	void NPCComponent::ExecuteAI(Instance *level, int deltaMillis)
	{
		if (!this->IsAlive()) {
			return;
		}

		if (this->IsInCombat()) {
			GameObject *target = this->GetTarget();
			const glm::vec3 &myPosition = this->GetOwner()->GetPosition();
			const glm::vec3 &targetPosition = target->GetPosition();
			glm::vec3 direction = glm::normalize(targetPosition - myPosition);
			double distance = glm::distance(myPosition, targetPosition);
			auto model = this->GetOwner()->FindComponent<ModelComponent>();

			if ((distance > 10 && mMoving) || (distance > 15 && !mMoving)) {
				float movementSpeed = (this->GetStats().GetStat(CharacterStatMovementSpeed) / 100.0f) * kBaseNpcRunSpeed;
				this->GetOwner()->MoveBy(direction * movementSpeed);
				mMoving = true;

				if (model) {
					model->SetAnimation("run");
				}
			}
			else {
				mMoving = false;

				if (model) {
					model->SetAnimation("idle");
				}
			}

			double angle = glm::degrees(atan2(direction.z, direction.x)) + 90;
			this->GetOwner()->RotateTo(glm::vec3(0, -angle, 0));
		}
		else {
			std::vector<GameObject *> objects;
			level->FindObjectsWithinRadius(mAgroShape, objects);

			if (objects.size() > 0) {
				for (GameObject *object : objects) {
					if (object == this->GetOwner()) {
						continue;
					}

					auto character = object->FindComponent<CharacterComponent>();
					if (character) {
						if (character->GetData()->GetHostility() == this->GetData()->GetHostility() && false) {
							// If these 2 objects are on the same side, and one is in combat, enter combat
							if (character->IsInCombat()) {
								this->SetInCombat(true, object);
							}
						}
						else {
							// If these 2 objects aren't on the same side, and we are hostile, enter combat
							if (this->GetData()->GetHostility() == HostilityHostile) {
								this->SetInCombat(true, object);
							}
						}
					}
				}
			}
		}
	}
예제 #8
0
void TemporarySummon::Update(uint32 update_diff,  uint32 diff)
{
    switch (m_type)
    {
        case TEMPSUMMON_MANUAL_DESPAWN:
            break;
        case TEMPSUMMON_TIMED_DESPAWN:
        {
            if (m_timer <= update_diff)
            {
                UnSummon();
                return;
            }

            m_timer -= update_diff;
            break;
        }
        case TEMPSUMMON_TIMED_OOC_DESPAWN:
        {
            if (!IsInCombat())
            {
                if (m_timer <= update_diff)
                {
                    UnSummon();
                    return;
                }

                m_timer -= update_diff;
            }
            else if (m_timer != m_lifetime)
                m_timer = m_lifetime;

            break;
        }

        case TEMPSUMMON_CORPSE_TIMED_DESPAWN:
        {
            if (IsCorpse())
            {
                if (m_timer <= update_diff)
                {
                    UnSummon();
                    return;
                }

                m_timer -= update_diff;
            }
            if (IsDespawned())
            {
                UnSummon();
                return;
            }
            break;
        }
        case TEMPSUMMON_CORPSE_DESPAWN:
        {
            // if m_deathState is DEAD, CORPSE was skipped
            if (IsDead())
            {
                UnSummon();
                return;
            }

            break;
        }
        case TEMPSUMMON_DEAD_DESPAWN:
        {
            if (IsDespawned())
            {
                UnSummon();
                return;
            }
            break;
        }
        case TEMPSUMMON_TIMED_OOC_OR_CORPSE_DESPAWN:
        {
            // if m_deathState is DEAD, CORPSE was skipped
            if (IsDead())
            {
                UnSummon();
                return;
            }

            if (!IsInCombat())
            {
                if (m_timer <= update_diff)
                {
                    UnSummon();
                    return;
                }
                else
                    m_timer -= update_diff;
            }
            else if (m_timer != m_lifetime)
                m_timer = m_lifetime;
            break;
        }
        case TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN:
        {
            // if m_deathState is DEAD, CORPSE was skipped
            if (IsDespawned())
            {
                UnSummon();
                return;
            }

            if (!IsInCombat() && IsAlive())
            {
                if (m_timer <= update_diff)
                {
                    UnSummon();
                    return;
                }
                else
                    m_timer -= update_diff;
            }
            else if (m_timer != m_lifetime)
                m_timer = m_lifetime;
            break;
        }
        case TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN:
        {
            // if m_deathState is DEAD, CORPSE was skipped
            if (IsDead())
            {
                UnSummon();
                return;
            }
            if (m_timer <= update_diff)
            {
                UnSummon();
                return;
            }
            m_timer -= update_diff;
            break;
        }
        case TEMPSUMMON_TIMED_OR_DEAD_DESPAWN:
        {
            // if m_deathState is DEAD, CORPSE was skipped
            if (IsDespawned())
            {
                UnSummon();
                return;
            }
            if (m_timer <= update_diff)
            {
                UnSummon();
                return;
            }
            m_timer -= update_diff;
            break;
        }
        default:
            UnSummon();
            sLog.outError("Temporary summoned creature (entry: %u) have unknown type %u of ", GetEntry(), m_type);
            break;
    }

    switch (m_deathState)
    {
        case ALIVE:
            if (m_linkedToOwnerAura & TEMPSUMMON_LINKED_AURA_OWNER_CHECK)
            {
                // we have to check if owner still have the required aura
                Unit* owner = GetCharmerOrOwner();
                uint32 const& spellId = GetUInt32Value(UNIT_CREATED_BY_SPELL);
                if (!owner || !spellId || !owner->HasAura(spellId))
                    UnSummon();
            }
            break;

        case DEAD:
        case CORPSE:
            if (m_linkedToOwnerAura & TEMPSUMMON_LINKED_AURA_REMOVE_OWNER)
            {
                RemoveAuraFromOwner();
                m_linkedToOwnerAura = 0;                    // we dont need to recheck
            }

        default:
            break;
    }
    
    Creature::Update(update_diff, diff);
}
예제 #9
0
	void AIUpdate()
	{
		if ( _unit->CalcDistance(BoomTarget) < 5 && IsInCombat())
			_unit->CastSpell(_unit, dbcSpell.LookupEntry(SPELL_FELFIRE_FISSION), true);
		ParentClass::AIUpdate();
	}
예제 #10
0
void TemporarySummon::Update(uint32 update_diff,  uint32 diff)
{
    switch (m_type)
    {
        case TEMPSUMMON_MANUAL_DESPAWN:
            break;
        case TEMPSUMMON_TIMED_DESPAWN:
        {
            if (m_timer <= update_diff)
            {
                UnSummon();
                return;
            }

            m_timer -= update_diff;
            break;
        }
        case TEMPSUMMON_TIMED_OOC_DESPAWN:
        {
            if (!IsInCombat())
            {
                if (m_timer <= update_diff)
                {
                    UnSummon();
                    return;
                }

                m_timer -= update_diff;
            }
            else if (m_timer != m_lifetime)
                { m_timer = m_lifetime; }

            break;
        }

        case TEMPSUMMON_CORPSE_TIMED_DESPAWN:
        {
            if (IsCorpse())
            {
                if (m_timer <= update_diff)
                {
                    UnSummon();
                    return;
                }

                m_timer -= update_diff;
            }
            if (IsDespawned())
            {
                UnSummon();
                return;
            }
            break;
        }
        case TEMPSUMMON_CORPSE_DESPAWN:
        {
            // if m_deathState is DEAD, CORPSE was skipped
            if (IsDead())
            {
                UnSummon();
                return;
            }

            break;
        }
        case TEMPSUMMON_DEAD_DESPAWN:
        {
            if (IsDespawned())
            {
                UnSummon();
                return;
            }
            break;
        }
        case TEMPSUMMON_TIMED_OOC_OR_CORPSE_DESPAWN:
        {
            // if m_deathState is DEAD, CORPSE was skipped
            if (IsDead())
            {
                UnSummon();
                return;
            }

            if (!IsInCombat())
            {
                if (m_timer <= update_diff)
                {
                    UnSummon();
                    return;
                }
                else
                    { m_timer -= update_diff; }
            }
            else if (m_timer != m_lifetime)
                { m_timer = m_lifetime; }
            break;
        }
        case TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN:
        {
            // if m_deathState is DEAD, CORPSE was skipped
            if (IsDespawned())
            {
                UnSummon();
                return;
            }

            if (!IsInCombat() && IsAlive())
            {
                if (m_timer <= update_diff)
                {
                    UnSummon();
                    return;
                }
                else
                    { m_timer -= update_diff; }
            }
            else if (m_timer != m_lifetime)
                { m_timer = m_lifetime; }
            break;
        }
        case TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN:
        {
            // if m_deathState is DEAD, CORPSE was skipped
            if (IsDead())
            {
                UnSummon();
                return;
            }
            if (m_timer <= update_diff)
            {
                UnSummon();
                return;
            }
            m_timer -= update_diff;
            break;
        }
        case TEMPSUMMON_TIMED_OR_DEAD_DESPAWN:
        {
            // if m_deathState is DEAD, CORPSE was skipped
            if (IsDespawned())
            {
                UnSummon();
                return;
            }
            if (m_timer <= update_diff)
            {
                UnSummon();
                return;
            }
            m_timer -= update_diff;
            break;
        }
        default:
            UnSummon();
            sLog.outError("Temporary summoned creature (entry: %u) have unknown type %u of ", GetEntry(), m_type);
            break;
    }

    Creature::Update(update_diff, diff);
}