Esempio n. 1
0
/////////////////////////////////////////////////
/// Cooperation: Unit can cooperate with another unit
///
/// @note Relations API Tier 1
///
/// Client-side counterpart: <tt>CGUnit_C::CanCooperate(const CGUnit_C *this, const CGUnit_C *unit)</tt>
/////////////////////////////////////////////////
bool Unit::CanCooperate(const Unit* unit) const
{
    // Simple sanity check
    if (!unit)
        return false;

    // Original logic

    // Can't cooperate with yourself
    if (this == unit)
        return false;

    // We can't cooperate while being charmed or with charmed unit
    if (GetCharmerGuid() || unit->GetCharmerGuid())
        return false;

    if (const FactionTemplateEntry* thisFactionTemplate = GetFactionTemplateEntry())
    {
        if (const FactionTemplateEntry* unitFactionTemplate = unit->GetFactionTemplateEntry())
        {
            if (thisFactionTemplate->factionGroupMask == unitFactionTemplate->factionGroupMask)
                // Pre-TBC: CanAttack check is not present clientside (always true), but potentially can be useful serverside to resolve some corner cases (e.g. duels). TODO: research needed
                return (!CanAttack(unit));
        }
    }
    return false;
}
Esempio n. 2
0
/////////////////////////////////////////////////
/// Interaction: Unit can interact with another unit (immediate response)
///
/// @note Relations API Tier 1
///
/// Client-side counterpart: <tt>CGUnit_C::CanInteractNow(const CGUnit_C *this, const CGUnit_C *unit)</tt>
/////////////////////////////////////////////////
bool Unit::CanInteractNow(const Unit* unit) const
{
    // Simple sanity check
    if (!unit)
        return false;

    // Original logic

    // We can't intract while on taxi
    if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_TAXI_FLIGHT))
        return false;

    // We can't interact while being charmed
    if (GetCharmerGuid())
        return false;

    // We can't interact with anyone while being dead (this does not apply to player ghosts, which allow very limited interactions)
    if (!isAlive() && (GetTypeId() == TYPEID_UNIT || !(static_cast<const Player*>(this)->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))))
        return false;

    // We can't interact with anyone while being shapeshifted, unless form flags allow us to do so
    if (IsShapeShifted())
    {
        if (SpellShapeshiftFormEntry const* formEntry = sSpellShapeshiftFormStore.LookupEntry(GetShapeshiftForm()))
        {
            if (!(formEntry->flags1 & SHAPESHIFT_FORM_FLAG_ALLOW_NPC_INTERACT))
                return false;
        }
    }

    // We can't interact with dead units, unless it's a creature with special flag
    if (!unit->isAlive())
    {
        if (GetTypeId() != TYPEID_UNIT || !(static_cast<const Creature*>(unit)->GetCreatureInfo()->CreatureTypeFlags & CREATURE_TYPEFLAGS_INTERACT_DEAD))
            return false;
    }

    // We can't interact with charmed units
    if (unit->GetCharmerGuid())
        return false;

    // We can't interact with units who are currently fighting
    if (unit->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PET_IN_COMBAT) ||  unit->getVictim())
        return false;

    return CanInteract(unit);
}
Esempio n. 3
0
void TemporarySpawn::Update(uint32 update_diff,  uint32 diff)
{
    switch (m_type)
    {
        case TEMPSPAWN_MANUAL_DESPAWN:
            break;

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

            m_timer -= update_diff;
            break;
        }

        case TEMPSPAWN_TIMED_OOC_DESPAWN:
        {
            if (isAlive())
            {
                if (!isInCombat())
                {
                    if (m_timer <= update_diff)
                    {
                        UnSummon();
                        return;
                    }

                    m_timer -= update_diff;
                }
                else if (m_timer != m_lifetime)
                    m_timer = m_lifetime;
            }
            else if (IsDespawned())
            {
                UnSummon();
                return;
            }
            break;
        }

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

                m_timer -= update_diff;
            }
            if (IsDespawned())
            {
                UnSummon();
                return;
            }
            break;
        }

        case TEMPSPAWN_CORPSE_DESPAWN:
        {
            // if m_deathState is DEAD, CORPSE was skipped
            if (isDead())
            {
                UnSummon();
                return;
            }

            break;
        }

        case TEMPSPAWN_DEAD_DESPAWN:
        {
            if (IsDespawned())
            {
                UnSummon();
                return;
            }
            break;
        }

        case TEMPSPAWN_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 TEMPSPAWN_TIMED_OOC_OR_DEAD_DESPAWN:
        {
            // if m_deathState is DEAD, CORPSE was skipped
            if (IsDespawned())
            {
                UnSummon();
                return;
            }

            if (!isInCombat() && isAlive() && !GetCharmerGuid())
            {
                if (m_timer <= update_diff)
                {
                    UnSummon();
                    return;
                }
                else
                    m_timer -= update_diff;
            }
            else if (m_timer != m_lifetime)
                m_timer = m_lifetime;
            break;
        }

        case TEMPSPAWN_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 TEMPSPAWN_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 & TEMPSPAWN_LINKED_AURA_OWNER_CHECK)
            {
                if (!CheckAuraOnOwner())
                    UnSummon();
            }
            break;

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

        default:
            break;
    }

    Creature::Update(update_diff, diff);
}