Beispiel #1
0
void WorldPvPTF::HandleObjectiveComplete(ObjectGuidSet m_sPlayersSet, uint32 uiEventId)
{
    for (uint8 i = 0; i < MAX_TF_TOWERS; ++i)
    {
        for (uint8 j = 0; j < 4; ++j)
        {
            if (uiEventId == aTerokkarTowerEvents[i][j].uiEventEntry)
            {
                for (ObjectGuidSet::iterator itr = m_sPlayersSet.begin(); itr != m_sPlayersSet.end(); ++itr)
                {
                    if (!(*itr))
                        continue;
                    Player* pPlayer = sObjectMgr.GetPlayer(*itr);

                    if (!pPlayer)
                        continue;

                    pPlayer->AreaExploredOrEventHappens(pPlayer->GetTeam() == ALLIANCE ? QUEST_SPIRITS_OF_AUCHINDOUM_ALLY : QUEST_SPIRITS_OF_AUCHINDOUM_HORDE);
                }
            }
        }
    }
}
Beispiel #2
0
/// %Log the player out
void WorldSession::LogoutPlayer(bool Save)
{
    // finish pending transfers before starting the logout
    while(_player && _player->IsBeingTeleportedFar())
        HandleMoveWorldportAckOpcode();

    m_playerLogout = true;
    m_playerSave = Save;

    if (_player)
    {
        // Playerbot mod: log out all player bots owned by this toon
        if (GetPlayer()->GetPlayerbotMgr())
            GetPlayer()->GetPlayerbotMgr()->LogoutAllBots();

        sLog.outChar("Account: %d (IP: %s) Logout Character:[%s] (guid: %u)", GetAccountId(), GetRemoteAddress().c_str(), _player->GetName() ,_player->GetGUIDLow());

        if (ObjectGuid lootGuid = GetPlayer()->GetLootGuid())
            DoLootRelease(lootGuid);

        ///- If the player just died before logging out, make him appear as a ghost
        //FIXME: logout must be delayed in case lost connection with client in time of combat
        if (GetPlayer()->GetDeathTimer())
        {
            GetPlayer()->getHostileRefManager().deleteReferences();
            GetPlayer()->BuildPlayerRepop();
            GetPlayer()->RepopAtGraveyard();
        }
        else if (GetPlayer()->IsInCombat() && GetPlayer()->GetMap())
        {
            GetPlayer()->CombatStop();
            GetPlayer()->getHostileRefManager().setOnlineOfflineState(false);
            GetPlayer()->RemoveAllAurasOnDeath();

            // build set of player who attack _player or who have pet attacking of _player
            std::set<Player*> aset;
            ObjectGuidSet attackers = GetPlayer()->GetMap()->GetAttackersFor(GetPlayer()->GetObjectGuid());

            for (ObjectGuidSet::const_iterator itr = attackers.begin(); itr != attackers.end();)
            {
                Unit* attacker = GetPlayer()->GetMap()->GetUnit(*itr++);
                if (!attacker)
                    continue;

                Unit* owner = attacker->GetOwner();           // including player controlled case
                if(owner)
                {
                    if(owner->GetTypeId() == TYPEID_PLAYER)
                        aset.insert((Player*)owner);
                }
                else
                    if(attacker->GetTypeId() == TYPEID_PLAYER)
                        aset.insert((Player*)(attacker));
            }

            GetPlayer()->SetPvPDeath(!aset.empty());
            GetPlayer()->KillPlayer();
            GetPlayer()->BuildPlayerRepop();
            GetPlayer()->RepopAtGraveyard();

            // give honor to all attackers from set like group case
            for(std::set<Player*>::const_iterator itr = aset.begin(); itr != aset.end(); ++itr)
                (*itr)->RewardHonor(GetPlayer(),aset.size());

            // give bg rewards and update counters like kill by first from attackers
            // this can't be called for all attackers.
            if(!aset.empty())
                if(BattleGround *bg = GetPlayer()->GetBattleGround())
                    bg->HandleKillPlayer(GetPlayer(),*aset.begin());
        }
        else if(GetPlayer()->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION))
        {
            // this will kill character by SPELL_AURA_SPIRIT_OF_REDEMPTION
            GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_MOD_SHAPESHIFT);
            //GetPlayer()->SetDeathPvP(*); set at SPELL_AURA_SPIRIT_OF_REDEMPTION apply time
            GetPlayer()->KillPlayer();
            GetPlayer()->BuildPlayerRepop();
            GetPlayer()->RepopAtGraveyard();
        }
        else if (GetPlayer()->HasPendingBind())
        {
            GetPlayer()->RepopAtGraveyard();
            GetPlayer()->SetPendingBind(NULL, 0);
        }

        //drop a flag if player is carrying it
        if(BattleGround *bg = GetPlayer()->GetBattleGround())
            bg->EventPlayerLoggedOut(GetPlayer());

        ///- Teleport to home if the player is in an invalid instance
        if(!GetPlayer()->m_InstanceValid && !GetPlayer()->isGameMaster())
        {
            GetPlayer()->TeleportToHomebind();
            //this is a bad place to call for far teleport because we need player to be in world for successful logout
            //maybe we should implement delayed far teleport logout?
        }

        // FG: finish pending transfers after starting the logout
        // this should fix players beeing able to logout and login back with full hp at death position
        while(GetPlayer()->IsBeingTeleportedFar())
            HandleMoveWorldportAckOpcode();

        for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
        {
            if(BattleGroundQueueTypeId bgQueueTypeId = GetPlayer()->GetBattleGroundQueueTypeId(i))
            {
                GetPlayer()->RemoveBattleGroundQueueId(bgQueueTypeId);
                sBattleGroundMgr.m_BattleGroundQueues[ bgQueueTypeId ].RemovePlayer(GetPlayer()->GetObjectGuid(), true);
            }
        }

        ///- Reset the online field in the account table
        // no point resetting online in character table here as Player::SaveToDB() will set it to 1 since player has not been removed from world at this stage
        // No SQL injection as AccountID is uint32
        if (!GetPlayer()->GetPlayerbotAI())
        {
            static SqlStatementID id;

            SqlStatement stmt = LoginDatabase.CreateStatement(id, "UPDATE account SET active_realm_id = ? WHERE id = ?");
            stmt.PExecute(uint32(0), GetAccountId());
        }

        ///- If the player is in a guild, update the guild roster and broadcast a logout message to other guild members
        if (Guild* guild = sGuildMgr.GetGuildById(GetPlayer()->GetGuildId()))
        {
            if (MemberSlot* slot = guild->GetMemberSlot(GetPlayer()->GetObjectGuid()))
            {
                slot->SetMemberStats(GetPlayer());
                slot->UpdateLogoutTime();
            }

            guild->BroadcastEvent(GE_SIGNED_OFF, GetPlayer()->GetObjectGuid(), GetPlayer()->GetName());
        }

        ///- Remove pet
        GetPlayer()->RemovePet(PET_SAVE_AS_CURRENT);

        GetPlayer()->InterruptNonMeleeSpells(true);

        ///- empty buyback items and save the player in the database
        // some save parts only correctly work in case player present in map/player_lists (pets, etc)
        if(Save)
            GetPlayer()->SaveToDB();

        ///- Leave all channels before player delete...
        GetPlayer()->CleanupChannels();

        // LFG cleanup
        sLFGMgr.Leave(GetPlayer());

        ///- If the player is in a group (or invited), remove him. If the group if then only 1 person, disband the group.
        GetPlayer()->UninviteFromGroup();

        // remove player from the group if he is:
        // a) in group; b) not in raid group; c) logging out normally (not being kicked or disconnected)
        if(GetPlayer()->GetGroup() && !GetPlayer()->GetGroup()->isRaidGroup() && m_Socket)
            GetPlayer()->RemoveFromGroup();

        ///- Send update to group
        if(GetPlayer()->GetGroup())
            GetPlayer()->GetGroup()->SendUpdate();

        ///- Broadcast a logout message to the player's friends
        sSocialMgr.SendFriendStatus(GetPlayer(), FRIEND_OFFLINE, GetPlayer()->GetObjectGuid(), true);
        sSocialMgr.RemovePlayerSocial (GetPlayer()->GetGUIDLow ());

        // Playerbot - remember player GUID for update SQL below
        uint32 guid = GetPlayer()->GetGUIDLow();

        ///- Remove the player from the world
        // the player may not be in the world when logging out
        // e.g if he got disconnected during a transfer to another map
        // calls to GetMap in this case may cause crashes
        if (GetPlayer()->IsInWorld())
        {
            Map* _map = GetPlayer()->GetMap();
            _map->Remove(GetPlayer(), true);
        }
        else
        {
            GetPlayer()->CleanupsBeforeDelete();
            if (GetPlayer()->GetMap())
                GetPlayer()->GetMap()->DeleteFromWorld(GetPlayer());
            else
            {
                sObjectAccessor.RemoveObject(GetPlayer());
                delete GetPlayer();
            }
        }

        SetPlayer(NULL);                                    // deleted in Remove/DeleteFromWorld call

        ///- Send the 'logout complete' packet to the client
        WorldPacket data( SMSG_LOGOUT_COMPLETE, 0 );
        SendPacket( &data );

        static SqlStatementID updChars;

        // Playerbot mod: commented out above and do this one instead
        SqlStatement stmt = CharacterDatabase.CreateStatement(updChars, "UPDATE characters SET online = 0 WHERE guid = ?");
        stmt.PExecute(guid);

        DEBUG_LOG( "SESSION: Sent SMSG_LOGOUT_COMPLETE Message" );
    }

    m_playerLogout = false;
    m_playerSave = false;
    m_playerRecentlyLogout = true;
    LogoutRequest(0);
}
Beispiel #3
0
void UpdateData::AddOutOfRangeGUID(ObjectGuidSet& guids)
{
    m_outOfRangeGUIDs.insert(guids.begin(),guids.end());
}