Example #1
0
void WorldSession::HandleQuestgiverStatusQueryOpcode( WorldPacket & recv_data )
{
    ObjectGuid guid;
    recv_data >> guid;
    uint8 dialogStatus = DIALOG_STATUS_NONE;

    Object* questgiver = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_OR_GAMEOBJECT);
    if(!questgiver)
    {
        DETAIL_LOG("Error in CMSG_QUESTGIVER_STATUS_QUERY, called for not found questgiver %s", guid.GetString().c_str());
        return;
    }

    DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for %s", guid.GetString().c_str());

    switch(questgiver->GetTypeId())
    {
        case TYPEID_UNIT:
        {
            Creature* cr_questgiver=(Creature*)questgiver;

            if (!cr_questgiver->IsHostileTo(_player))       // not show quest status to enemies
            {
                dialogStatus = sScriptMgr.GetDialogStatus(_player, cr_questgiver);

                if (dialogStatus > 6)
                    dialogStatus = getDialogStatus(_player, cr_questgiver, DIALOG_STATUS_NONE);
            }
            break;
        }
        case TYPEID_GAMEOBJECT:
        {
            GameObject* go_questgiver = (GameObject*)questgiver;
            dialogStatus = sScriptMgr.GetDialogStatus(_player, go_questgiver);
            if (dialogStatus > 6)
                dialogStatus = getDialogStatus(_player, go_questgiver, DIALOG_STATUS_NONE);
            break;
        }
        default:
            sLog.outError("QuestGiver called for unexpected type %u", questgiver->GetTypeId());
            break;
    }

    //inform client about status of quest
    _player->PlayerTalkClass->SendQuestGiverStatus(dialogStatus, guid);
}
Example #2
0
void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket & recv_data)
{
    CHECK_PACKET_SIZE(recv_data,8+4+4);

    uint32 quest, reward;
    uint64 guid;
    recv_data >> guid >> quest >> reward;

    if (reward >= QUEST_REWARD_CHOICES_COUNT)
    {
        sLog.outLog(LOG_DEFAULT, "ERROR: Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player %s (guid %d) tried to get invalid reward (%u) (probably packet hacking)", _player->GetName(), _player->GetGUIDLow(), reward);
        return;
    }

    if (!GetPlayer()->isAlive())
        return;

    sLog.outDebug("WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %u, quest = %u, reward = %u",uint32(GUID_LOPART(guid)),quest,reward);

    Object* pObject = _player->GetMap()->GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
    if (!pObject)
        return;

    if (!pObject->hasInvolvedQuest(quest))
        return;

    if (Quest const *pQuest = sObjectMgr.GetQuestTemplate(quest))
    {
        if ((!_player->CanSeeStartQuest(pQuest) &&  _player->GetQuestStatus(quest) == QUEST_STATUS_NONE) ||
                (_player->GetQuestStatus(quest) != QUEST_STATUS_COMPLETE && !pQuest->IsAutoComplete()))
        {
            sLog.outLog(LOG_DEFAULT,"HACK ALERT: Player %s (guid: %u) is trying to complete quest (id: %u) but he has no right to do it!",
                        _player->GetName(), _player->GetGUIDLow(), quest);
            return;
        }

        if (_player->CanRewardQuest(pQuest, reward, true))
        {
            _player->RewardQuest(pQuest, reward, pObject);

            switch (pObject->GetTypeId())
            {
            case TYPEID_UNIT:
                // Send next quest
                if (Quest const* nextquest = _player->GetNextQuest(guid ,pQuest))
                    _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextquest,guid,true);
                break;
            case TYPEID_GAMEOBJECT:
                // Send next quest
                if (Quest const* nextquest = _player->GetNextQuest(guid ,pQuest))
                    _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextquest,guid,true);
                break;
            }
        }
        else
            _player->PlayerTalkClass->SendQuestGiverOfferReward(pQuest, guid, true);
    }
}
Example #3
0
void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket & recv_data)
{
    uint64 guid;
    recv_data >> guid;
    uint32 questStatus = DIALOG_STATUS_NONE;
    uint32 defstatus = DIALOG_STATUS_NONE;

    Object* questgiver = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
    if (!questgiver)
    {
        sLog->outDetail("Error in CMSG_QUESTGIVER_STATUS_QUERY, called for not found questgiver (Typeid: %u GUID: %u)", GuidHigh2TypeId(GUID_HIPART(guid)), GUID_LOPART(guid));
        return;
    }

    switch(questgiver->GetTypeId())
    {
        case TYPEID_UNIT:
        {
            sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for npc, guid = %u", uint32(GUID_LOPART(guid)));
            Creature* cr_questgiver=questgiver->ToCreature();
            if (!cr_questgiver->IsHostileTo(_player))       // do not show quest status to enemies
            {
                questStatus = sScriptMgr->GetDialogStatus(_player, cr_questgiver);
                if (questStatus > 6)
                    questStatus = getDialogStatus(_player, cr_questgiver, defstatus);
            }
            break;
        }
        case TYPEID_GAMEOBJECT:
        {
            sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for GameObject guid = %u", uint32(GUID_LOPART(guid)));
            GameObject* go_questgiver=(GameObject*)questgiver;
            questStatus = sScriptMgr->GetDialogStatus(_player, go_questgiver);
            if (questStatus > 6)
                questStatus = getDialogStatus(_player, go_questgiver, defstatus);
            break;
        }
        default:
            sLog->outError("QuestGiver called for unexpected type %u", questgiver->GetTypeId());
            break;
    }

    //inform client about status of quest
    _player->PlayerTalkClass->SendQuestGiverStatus(questStatus, guid);
}
Example #4
0
void WorldSession::HandleQuestgiverChooseRewardOpcode( WorldPacket & recv_data )
{
    CHECK_PACKET_SIZE(recv_data,8+4+4);

    uint32 quest, reward;
    uint64 guid;
    recv_data >> guid >> quest >> reward;

    if(reward >= QUEST_REWARD_CHOICES_COUNT)
    {
        sLog.outError("Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player %s (guid %d) tried to get invalid reward (%u) (probably packet hacking)", _player->GetName(), _player->GetGUIDLow(), reward);
        return;
    }

    if(!GetPlayer()->isAlive())
        return;

    sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %u, quest = %u, reward = %u",uint32(GUID_LOPART(guid)),quest,reward );

    Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
    if(!pObject)
        return;

    if(!pObject->hasInvolvedQuest(quest))
        return;

    Quest const *pQuest = objmgr.GetQuestTemplate(quest);
    if( pQuest )
    {
        if( _player->CanRewardQuest( pQuest, reward, true ) )
        {
            _player->RewardQuest( pQuest, reward, pObject );

            switch(pObject->GetTypeId())
            {
                case TYPEID_UNIT:
                    if( !(Script->ChooseReward( _player, ((Creature*)pObject), pQuest, reward )) )
                    {
                        // Send next quest
                        if(Quest const* nextquest = _player->GetNextQuest( guid ,pQuest ) )
                            _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextquest,guid,true);
                    }
                    break;
                case TYPEID_GAMEOBJECT:
                    if( !Script->GOChooseReward( _player, ((GameObject*)pObject), pQuest, reward ) )
                    {
                        // Send next quest
                        if(Quest const* nextquest = _player->GetNextQuest( guid ,pQuest ) )
                            _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextquest,guid,true);
                    }
                    break;
            }
        }
        else
            _player->PlayerTalkClass->SendQuestGiverOfferReward( pQuest, guid, true );
    }
}
Example #5
0
void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket& recvData)
{
    uint64 guid;
    recvData >> guid;
    uint32 questStatus = DIALOG_STATUS_NONE;

    Object* questGiver = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT);
    if (!questGiver)
    {
        TC_LOG_INFO("network", "Error in CMSG_QUESTGIVER_STATUS_QUERY, called for non-existing questgiver (Typeid: %u GUID: %u)", GuidHigh2TypeId(GUID_HIPART(guid)), GUID_LOPART(guid));
        return;
    }

    switch (questGiver->GetTypeId())
    {
        case TYPEID_UNIT:
        {
            TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for npc, guid = %u", questGiver->GetGUIDLow());
            if (!questGiver->ToCreature()->IsHostileTo(_player)) // do not show quest status to enemies
                questStatus = _player->GetQuestDialogStatus(questGiver);
            break;
        }
        case TYPEID_GAMEOBJECT:
        {
            TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for GameObject guid = %u", questGiver->GetGUIDLow());
            questStatus = _player->GetQuestDialogStatus(questGiver);
            break;
        }
        default:
            TC_LOG_ERROR("network", "QuestGiver called for unexpected type %u", questGiver->GetTypeId());
            break;
    }

    // inform client about status of quest
    _player->PlayerTalkClass->SendQuestGiverStatus(uint8(questStatus), guid);
}
Example #6
0
void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket & recv_data)
{
    uint32 quest, reward;
    uint64 guid;
    recv_data >> guid >> quest >> reward;

    if (reward >= QUEST_REWARD_CHOICES_COUNT)
    {
        sLog->outError("Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player %s (guid %d) tried to get invalid reward (%u) (probably packet hacking)", _player->GetName(), _player->GetGUIDLow(), reward);
        return;
    }

    if (!GetPlayer()->isAlive())
        return;

    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %u, quest = %u, reward = %u", uint32(GUID_LOPART(guid)), quest, reward);

    Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT|TYPEMASK_PLAYER);
    if (!pObject)
        return;

    if (!IS_PLAYER_GUID(guid))
    {
        if (!pObject->hasInvolvedQuest(quest))
            return;
    }

    Quest const *pQuest = sObjectMgr->GetQuestTemplate(quest);
    if (pQuest)
    {
        if (_player->CanRewardQuest(pQuest, reward, true))
        {
            _player->RewardQuest(pQuest, reward, pObject);

            switch(pObject->GetTypeId())
            {
                case TYPEID_UNIT:
                    if (!(sScriptMgr->OnQuestReward(_player, (pObject->ToCreature()), pQuest, reward)))
                    {
                        // Send next quest
                        if (Quest const* nextquest = _player->GetNextQuest(guid , pQuest))
                            _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextquest, guid, true);

                        (pObject->ToCreature())->AI()->sQuestReward(_player, pQuest, reward);
                    }
                    break;
                case TYPEID_GAMEOBJECT:
                    if (!sScriptMgr->OnQuestReward(_player, ((GameObject*)pObject), pQuest, reward))
                    {
                        // Send next quest
                        if (Quest const* nextquest = _player->GetNextQuest(guid , pQuest))
                            _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextquest, guid, true);
                        pObject->ToGameObject()->AI()->QuestReward(_player, pQuest, reward);
                    }
                    break;
                case TYPEID_PLAYER: break;
                default:
                    break;
            }
        }
        else
            _player->PlayerTalkClass->SendQuestGiverOfferReward(pQuest, guid, true);
    }
}
Example #7
0
void MapCell::RemoveObjects()
{
    ObjectSet::iterator itr;
    uint32 count = 0;
    //uint32 ltime = getMSTime();

    //Zack : we are delaying cell removal so transports can see objects far away. We are waiting for the event to remove us
    if (_unloadpending == true)
        return;

    /* delete objects in pending respawn state */
    for (itr = _respawnObjects.begin(); itr != _respawnObjects.end(); ++itr)
    {
        switch ((*itr)->GetTypeId())
        {
            case TYPEID_UNIT: {
                if (!(*itr)->IsPet())
                {
                    _mapmgr->_reusable_guids_creature.push_back((*itr)->GetUIdFromGUID());
                    static_cast<Creature*>(*itr)->m_respawnCell = NULL;
                    delete static_cast<Creature*>(*itr);
                }
            }break;

            case TYPEID_GAMEOBJECT: {
                _mapmgr->_reusable_guids_gameobject.push_back((*itr)->GetUIdFromGUID());
                static_cast<GameObject*>(*itr)->m_respawnCell = NULL;
                delete static_cast<GameObject*>(*itr);
            }break;
        }
    }
    _respawnObjects.clear();

    //This time it's simpler! We just remove everything :)
    for (itr = _objects.begin(); itr != _objects.end();)
    {
        count++;

        Object *obj = (*itr);

        itr++;

        //zack : we actually never set this to null. Useless check for lucky memory corruption hit.
        if (!obj)
            continue;

        if (_unloadpending)
        {
            if (obj->GetTypeFromGUID() == HIGHGUID_TYPE_TRANSPORTER)
                continue;
            if (obj->GetTypeId() == TYPEID_CORPSE && obj->GetUInt32Value(CORPSE_FIELD_OWNER) != 0)
                continue;
            if (!obj->m_loadedFromDB)
                continue;
        }

        if (obj->Active)
            obj->Deactivate(_mapmgr);

        if (obj->IsInWorld())
            obj->RemoveFromWorld(true);

        delete obj;
    }
    _objects.clear();

    _playerCount = 0;
    _loaded = false;
}
Example #8
0
void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket & recv_data)
{
    uint32 questId, reward;
    uint64 guid;
    recv_data >> guid >> questId >> reward;

    if (reward >= QUEST_REWARD_CHOICES_COUNT)
    {
        sLog->outError("Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player %s (guid %d) tried to get invalid reward (%u) (probably packet hacking)", _player->GetName(), _player->GetGUIDLow(), reward);
        return;
    }

    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %u, quest = %u, reward = %u", uint32(GUID_LOPART(guid)), questId, reward);

    Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
    if (!object || !object->hasInvolvedQuest(questId))
        return;

    // some kind of WPE protection
    if (!_player->CanInteractWithQuestGiver(object))
        return;

    if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
    {
        if ((!_player->CanSeeStartQuest(quest) &&  _player->GetQuestStatus(questId) == QUEST_STATUS_NONE) ||
            (_player->GetQuestStatus(questId) != QUEST_STATUS_COMPLETE && !quest->IsAutoComplete()))
        {
            sLog->outError("HACK ALERT: Player %s (guid: %u) is trying to complete quest (id: %u) but he has no right to do it!",
                           _player->GetName(), _player->GetGUIDLow(), questId);
            return;
        }
        if (_player->CanRewardQuest(quest, reward, true))
        {
            _player->RewardQuest(quest, reward, object);

            switch (object->GetTypeId())
            {
                case TYPEID_UNIT:
                    if (!(sScriptMgr->OnQuestReward(_player, (object->ToCreature()), quest, reward)))
                    {
                        // Send next quest
                        if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))
                        {
                            if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(quest, true))
                            {
                                _player->AddQuest(nextQuest, object);
                                if (_player->CanCompleteQuest(nextQuest->GetQuestId()))
                                    _player->CompleteQuest(nextQuest->GetQuestId());
                            }

                            _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true);
                        }

                        (object->ToCreature())->AI()->sQuestReward(_player, quest, reward);
                    }
                    break;
                case TYPEID_GAMEOBJECT:
                    if (!sScriptMgr->OnQuestReward(_player, ((GameObject*)object), quest, reward))
                    {
                        // Send next quest
                        if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))
                        {
                            if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(quest, true))
                            {
                                _player->AddQuest(nextQuest, object);
                                if (_player->CanCompleteQuest(nextQuest->GetQuestId()))
                                    _player->CompleteQuest(nextQuest->GetQuestId());
                            }

                            _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true);
                        }

                        object->ToGameObject()->AI()->QuestReward(_player, quest, reward);
                    }
                    break;
                default:
                    break;
            }
        }
        else
            _player->PlayerTalkClass->SendQuestGiverOfferReward(quest, guid, true);
    }
}
Example #9
0
void WorldSession::HandleQuestgiverAcceptQuestOpcode( WorldPacket & recv_data )
{
    uint64 guid;
    uint32 quest;
    uint32 unk1;
    recv_data >> guid >> quest >> unk1;

    if(!GetPlayer()->isAlive())
        return;

    sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc = %u, quest = %u, unk1 = %u", uint32(GUID_LOPART(guid)), quest, unk1 );

    Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT|TYPEMASK_ITEM|TYPEMASK_PLAYER);

    // no or incorrect quest giver
    if(!pObject
        || (pObject->GetTypeId()!=TYPEID_PLAYER && !pObject->hasQuest(quest))
        || (pObject->GetTypeId()==TYPEID_PLAYER && !((Player*)pObject)->CanShareQuest(quest))
        )
    {
        _player->PlayerTalkClass->CloseGossip();
        _player->SetDivider( 0 );
        return;
    }

    Quest const* qInfo = objmgr.GetQuestTemplate(quest);
    if ( qInfo )
    {
        // prevent cheating
        if(!GetPlayer()->CanTakeQuest(qInfo,true) )
        {
            _player->PlayerTalkClass->CloseGossip();
            _player->SetDivider( 0 );
            return;
        }

        if( _player->GetDivider() != 0 )
        {
            Player *pPlayer = ObjectAccessor::FindPlayer( _player->GetDivider() );
            if( pPlayer )
            {
                pPlayer->SendPushToPartyResponse( _player, QUEST_PARTY_MSG_ACCEPT_QUEST );
                _player->SetDivider( 0 );
            }
        }

        if( _player->CanAddQuest( qInfo, true ) )
        {
            _player->AddQuest( qInfo, pObject );

            if ( _player->CanCompleteQuest( quest ) )
                _player->CompleteQuest( quest );

            switch(pObject->GetTypeId())
            {
                case TYPEID_UNIT:
                    Script->QuestAccept(_player, ((Creature*)pObject), qInfo );
                    break;
                case TYPEID_ITEM:
                case TYPEID_CONTAINER:
                {
                    Script->ItemQuestAccept(_player, ((Item*)pObject), qInfo );

                    // destroy not required for quest finish quest starting item
                    bool destroyItem = true;
                    for(int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
                    {
                        if ((qInfo->ReqItemId[i] == ((Item*)pObject)->GetEntry()) && (((Item*)pObject)->GetProto()->MaxCount > 0))
                        {
                            destroyItem = false;
                            break;
                        }
                    }

                    if(destroyItem)
                        _player->DestroyItem(((Item*)pObject)->GetBagSlot(),((Item*)pObject)->GetSlot(),true);

                    break;
                }
                case TYPEID_GAMEOBJECT:
                    Script->GOQuestAccept(_player, ((GameObject*)pObject), qInfo );
                    break;
            }
            _player->PlayerTalkClass->CloseGossip();

            if( qInfo->GetSrcSpell() > 0 )
                _player->CastSpell( _player, qInfo->GetSrcSpell(), true);

            return;
        }
    }

    _player->PlayerTalkClass->CloseGossip();
}
Example #10
0
void WorldSession::LogoutPlayer(bool Save)
{
	Player* pPlayer = GetPlayer();

	if( _loggingOut )
		return;

	_loggingOut = true;

	if( _player != NULL )
	{
		sHookInterface.OnLogout( pPlayer );
		if( _player->DuelingWith )
			_player->EndDuel( DUEL_WINNER_RETREAT );

		if( _player->m_currentLoot && _player->IsInWorld() )
		{
			Object* obj = _player->GetMapMgr()->_GetObject( _player->m_currentLoot );
			if( obj != NULL )
			{
				switch( obj->GetTypeId() )
				{
				case TYPEID_UNIT:
					static_cast< Creature* >( obj )->loot.looters.erase( _player->GetGUIDLow() );
					break;
				case TYPEID_GAMEOBJECT:
					static_cast< GameObject* >( obj )->loot.looters.erase( _player->GetGUIDLow() );
					break;
				}
			}
		}

		// part channels
		_player->CleanupChannels();

		if( _player->m_CurrentTransporter != NULL )
			_player->m_CurrentTransporter->RemovePlayer( _player );

		// cancel current spell
		if( _player->m_currentSpell != NULL )
			_player->m_currentSpell->cancel();

		sSocialMgr.LoggedOut( _player );

		if( _player->GetTeam() == 1 )
		{
			if( sWorld.HordePlayers )
				sWorld.HordePlayers--;
		}
		else
		{
			if( sWorld.AlliancePlayers )
				sWorld.AlliancePlayers--;
		}

		if( _player->m_bg )
			_player->m_bg->RemovePlayer( _player, true );

		if( _player->m_bgIsQueued )
			BattlegroundManager.RemovePlayerFromQueues( _player );

		//Duel Cancel on Leave
		if( _player->DuelingWith != NULL )
			_player->EndDuel( DUEL_WINNER_RETREAT );

		//Issue a message telling all guild members that this player signed off
		if( _player->IsInGuild() )
		{
			Guild* pGuild = _player->m_playerInfo->guild;
			if( pGuild != NULL )
				pGuild->LogGuildEvent( GUILD_EVENT_HASGONEOFFLINE, 1, _player->GetName() );
		}

		_player->GetItemInterface()->EmptyBuyBack();
		
		sLfgMgr.RemovePlayerFromLfgQueues( _player );
		
		// Save HP/Mana
		_player->load_health = _player->GetUInt32Value( UNIT_FIELD_HEALTH );
		_player->load_mana = _player->GetUInt32Value( UNIT_FIELD_POWER1 );
		
		objmgr.RemovePlayer( _player );		
		_player->ok_to_remove = true;

		if( _player->GetSummon() != NULL )
			_player->GetSummon()->Remove( false, true, false );

		//_player->SaveAuras();

		if( Save )
			_player->SaveToDB(false);
		
		_player->RemoveAllAuras();
		if( _player->IsInWorld() )
			_player->RemoveFromWorld();
		
		_player->m_playerInfo->m_loggedInPlayer = NULL;

		if( _player->m_playerInfo->m_Group != NULL )
			_player->m_playerInfo->m_Group->Update();
	  
		// Remove the "player locked" flag, to allow movement on next login
		GetPlayer()->RemoveFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_LOCK_PLAYER );

		// Save Honor Points
		//_player->SaveHonorFields();

		// Update any dirty account_data fields.
		bool dirty = false;
		if( sWorld.m_useAccountData )
		{
			std::stringstream ss;
			ss << "UPDATE account_data SET ";
			for(uint32 ui=0;ui<8;ui++)
			{
				if(sAccountData[ui].bIsDirty)
				{
					if(dirty)
						ss <<",";
					ss << "uiconfig"<< ui <<"=\"";
					if(sAccountData[ui].data)
					{
						CharacterDatabase.EscapeLongString(sAccountData[ui].data, sAccountData[ui].sz, ss);
						//ss.write(sAccountData[ui].data,sAccountData[ui].sz);
					}
					ss << "\"";
					dirty = true;
					sAccountData[ui].bIsDirty = false;
				}
			}			
			if(dirty)
			{
				ss	<<" WHERE acct="<< _accountId <<";";
				CharacterDatabase.ExecuteNA(ss.str().c_str());
			}
		}

		delete _player;
		_player = NULL;

		OutPacket(SMSG_LOGOUT_COMPLETE, 0, NULL);
		sLog.outDebug( "SESSION: Sent SMSG_LOGOUT_COMPLETE Message" );
	}
	_loggingOut = false;

	SetLogoutTimer(0);
}
Example #11
0
void WorldSession::HandleQuestgiverAcceptQuestOpcode( WorldPacket & recv_data )
{
    ObjectGuid guid;
    uint32 quest;
    uint32 unk1;
    recv_data >> guid >> quest >> unk1;

    if (!GetPlayer()->isAlive())
    {
        if (Unit * pQuestNPC = GetPlayer()->GetMap()->GetUnit(guid))
            if (!pQuestNPC->isInvisibleForAlive())
                return;
    }

    DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc = %s, quest = %u, unk1 = %u", guid.GetString().c_str(), quest, unk1 );

    Object* pObject = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_GAMEOBJECT_PLAYER_OR_ITEM);

    // no or incorrect quest giver
    if(!pObject
        || (pObject->GetTypeId()!=TYPEID_PLAYER && !pObject->HasQuest(quest))
        || (pObject->GetTypeId()==TYPEID_PLAYER && !((Player*)pObject)->CanShareQuest(quest))
        )
    {
        _player->PlayerTalkClass->CloseGossip();
        _player->ClearDividerGuid();
        return;
    }

    Quest const* qInfo = sObjectMgr.GetQuestTemplate(quest);
    if ( qInfo )
    {
        // prevent cheating
        if(!GetPlayer()->CanTakeQuest(qInfo,true) )
        {
            _player->PlayerTalkClass->CloseGossip();
            _player->ClearDividerGuid();
            return;
        }

        if (Player *pPlayer = ObjectAccessor::FindPlayer(_player->GetDividerGuid()))
        {
            pPlayer->SendPushToPartyResponse(_player, QUEST_PARTY_MSG_ACCEPT_QUEST);
            _player->ClearDividerGuid();
        }

        if( _player->CanAddQuest( qInfo, true ) )
        {
            _player->AddQuest( qInfo, pObject );            // pObject (if it item) can be destroyed at call

            if (qInfo->HasQuestFlag(QUEST_FLAGS_PARTY_ACCEPT))
            {
                if (Group* pGroup = _player->GetGroup())
                {
                    for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
                    {
                        Player* pPlayer = itr->getSource();

                        if (!pPlayer || pPlayer == _player)     // not self
                            continue;

                        if (pPlayer->CanTakeQuest(qInfo, true))
                        {
                            pPlayer->SetDividerGuid(_player->GetObjectGuid());

                            //need confirmation that any gossip window will close
                            pPlayer->PlayerTalkClass->CloseGossip();

                            _player->SendQuestConfirmAccept(qInfo, pPlayer);
                        }
                    }
                }
            }

            if ( _player->CanCompleteQuest( quest ) )
                _player->CompleteQuest( quest );

            _player->GetAchievementMgr().StartTimedAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST, quest);

            _player->PlayerTalkClass->CloseGossip();

            if( qInfo->GetSrcSpell() > 0 )
                _player->CastSpell( _player, qInfo->GetSrcSpell(), true);

            return;
        }
    }

    _player->PlayerTalkClass->CloseGossip();
}
Example #12
0
void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket & recv_data)
{
    CHECK_PACKET_SIZE(recv_data,8+4);

    uint64 guid;
    uint32 quest;
    recv_data >> guid >> quest;

    if (!GetPlayer()->isAlive())
        return;

    sLog.outDebug("WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc = %u, quest = %u",uint32(GUID_LOPART(guid)),quest);

    Object* pObject = _player->GetMap()->GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT|TYPEMASK_ITEM|TYPEMASK_PLAYER);

    // no or incorrect quest giver
    if (!pObject
            || (pObject->GetTypeId()!=TYPEID_PLAYER && !pObject->hasQuest(quest))
            || (pObject->GetTypeId()==TYPEID_PLAYER && !((Player*)pObject)->CanShareQuest(quest))
       )
    {
        _player->PlayerTalkClass->CloseGossip();
        _player->SetDivider(0);
        return;
    }

    Quest const* qInfo = sObjectMgr.GetQuestTemplate(quest);
    if (qInfo)
    {
        // prevent cheating
        if (!GetPlayer()->CanTakeQuest(qInfo,true))
        {
            _player->PlayerTalkClass->CloseGossip();
            _player->SetDivider(0);
            return;
        }

        if (_player->GetDivider() != 0)
        {
            Player *pPlayer = ObjectAccessor::FindPlayer(_player->GetDivider());
            if (pPlayer)
            {
                pPlayer->SendPushToPartyResponse(_player, QUEST_PARTY_MSG_ACCEPT_QUEST);
                _player->SetDivider(0);
            }
        }

        if (_player->CanAddQuest(qInfo, true))
        {
            _player->AddQuest(qInfo, pObject);

            if (qInfo->HasFlag(QUEST_FLAGS_PARTY_ACCEPT))
            {
                if (Group* pGroup = _player->GetGroup())
                {
                    for (GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
                    {
                        Player* pPlayer = itr->getSource();

                        if (!pPlayer || pPlayer == _player)     // not self
                            continue;

                        if (pPlayer->CanTakeQuest(qInfo, true))
                        {
                            pPlayer->SetDivider(_player->GetGUID());

                            //need confirmation that any gossip window will close
                            pPlayer->PlayerTalkClass->CloseGossip();

                            _player->SendQuestConfirmAccept(qInfo, pPlayer);
                        }
                    }
                }
            }

            if (_player->CanCompleteQuest(quest))
                _player->CompleteQuest(quest);

            switch (pObject->GetTypeId())
            {
            case TYPEID_UNIT:
                sScriptMgr.OnQuestAccept(_player, ((Creature*)pObject), qInfo);
                break;
            case TYPEID_ITEM:
            case TYPEID_CONTAINER:
            {
                sScriptMgr.OnQuestAccept(_player, ((Item*)pObject), qInfo);

                // destroy not required for quest finish quest starting item
                bool destroyItem = true;
                for (int i = 0; i < QUEST_OBJECTIVES_COUNT; i++)
                {
                    if ((qInfo->ReqItemId[i] == ((Item*)pObject)->GetEntry()) && (((Item*)pObject)->GetProto()->MaxCount > 0))
                    {
                        destroyItem = false;
                        break;
                    }
                }

                if (destroyItem)
                    _player->DestroyItem(((Item*)pObject)->GetBagSlot(),((Item*)pObject)->GetSlot(),true);

                break;
            }
            case TYPEID_GAMEOBJECT:
                sScriptMgr.OnQuestAccept(_player, ((GameObject*)pObject), qInfo);
                break;
            }
            _player->PlayerTalkClass->CloseGossip();

            if (qInfo->GetSrcSpell() > 0)
                _player->CastSpell(_player, qInfo->GetSrcSpell(), true);

            return;
        }
    }

    _player->PlayerTalkClass->CloseGossip();
}
Example #13
0
void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket& recvData)
{
    uint32 questId, reward;
    uint64 guid;
    recvData >> guid >> questId >> reward;

    if (reward >= QUEST_REWARD_CHOICES_COUNT)
    {
        TC_LOG_ERROR("network", "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player %s (guid %d) tried to get invalid reward (%u) (possible packet-hacking detected)", _player->GetName().c_str(), _player->GetGUIDLow(), reward);
        return;
    }

    TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %u, quest = %u, reward = %u", uint32(GUID_LOPART(guid)), questId, reward);

    Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT);
    if (!object || !object->hasInvolvedQuest(questId))
        return;

    // some kind of WPE protection
    if (!_player->CanInteractWithQuestGiver(object))
        return;

    if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
    {
        if ((!_player->CanSeeStartQuest(quest) &&  _player->GetQuestStatus(questId) == QUEST_STATUS_NONE) ||
            (_player->GetQuestStatus(questId) != QUEST_STATUS_COMPLETE && !quest->IsAutoComplete()))
        {
            TC_LOG_ERROR("network", "Error in QUEST_STATUS_COMPLETE: player %s (guid %u) tried to complete quest %u, but is not allowed to do so (possible packet-hacking or high latency)",
                           _player->GetName().c_str(), _player->GetGUIDLow(), questId);
            return;
        }
        if (_player->CanRewardQuest(quest, reward, true))
        {
            _player->RewardQuest(quest, reward, object);

            switch (object->GetTypeId())
            {
                case TYPEID_UNIT:
                {
                    Creature* questgiver = object->ToCreature();
                    if (!sScriptMgr->OnQuestReward(_player, questgiver, quest, reward))
                    {
                        // Send next quest
                        if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))
                        {
                            // Only send the quest to the player if the conditions are met
                            if (_player->CanTakeQuest(nextQuest, true))
                            {
                                if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true))
                                    _player->AddQuestAndCheckCompletion(nextQuest, object);

                                _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true);
                            }
                        }

                        questgiver->AI()->sQuestReward(_player, quest, reward);
                    }
                    break;
                }
                case TYPEID_GAMEOBJECT:
                {
                    GameObject* questGiver = object->ToGameObject();
                    if (!sScriptMgr->OnQuestReward(_player, questGiver, quest, reward))
                    {
                        // Send next quest
                        if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))
                        {
                            // Only send the quest to the player if the conditions are met
                            if (_player->CanTakeQuest(nextQuest, true))
                            {
                                if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true))
                                    _player->AddQuestAndCheckCompletion(nextQuest, object);

                                _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true);
                            }
                        }

                        questGiver->AI()->QuestReward(_player, quest, reward);
                    }
                    break;
                }
                default:
                    break;
            }
        }
        else
            _player->PlayerTalkClass->SendQuestGiverOfferReward(quest, guid, true);
    }
}
Example #14
0
void WorldSession::_HandleUpdateObjectOpcode(WorldPacket& recvPacket)
{
    uint8 utype;
    //uint8 hasTransport;
    uint32 usize, ublocks, readblocks=0;
    uint64 uguid;
    recvPacket >> ublocks; // >> hasTransport;
    //logdev("UpdateObject: blocks = %u, hasTransport = %u", ublocks, hasTransport);
    logdev("UpdateObject: blocks = %u", ublocks);
    while((recvPacket.rpos() < recvPacket.size())&& (readblocks < ublocks))
    {
        recvPacket >> utype;
        switch(utype)
        {
        case UPDATETYPE_VALUES:
        {
            uguid = recvPacket.GetPackedGuid();
            _ValuesUpdate(uguid,recvPacket);
        }
        break;

        case UPDATETYPE_MOVEMENT:
        {
            recvPacket >> uguid; // the guid is NOT packed here!
            uint8 tyid;
            Object *obj = objmgr.GetObj(uguid, true); // here we update also depleted objects, its just safer
            if(obj)
                tyid = obj->GetTypeId();
            else // sometimes objects get deleted BEFORE a last update packet arrives, this must be handled also
            {
                tyid = GetTypeIdByGuid(uguid);
                logerror("Got UpdateObject_Movement for unknown object "I64FMT". Using typeid %u",uguid,(uint32)tyid);
            }

            if(obj)
                this->_MovementUpdate(tyid,uguid,recvPacket);
        }
        break;

        case UPDATETYPE_CREATE_OBJECT2: // will be sent when our very own character is created
        case UPDATETYPE_CREATE_OBJECT: // will be sent on any other object creation
        {
            uguid = recvPacket.GetPackedGuid();
            uint8 objtypeid;
            recvPacket >> objtypeid;
            logdebug("Create Object type %u with guid "I64FMT,objtypeid,uguid);
            // dont create objects if already present in memory.
            // recreate every object except ourself!
            if(objmgr.GetObj(uguid))
            {
                if(uguid != GetGuid())
                {
                    logdev("- already exists, deleting old, creating new object");
                    objmgr.Remove(uguid, false);
                    // do not call script here, since the object does not really get deleted
                }
                else
                {
                    logdev("- already exists, but not deleted (has our current GUID)");
                }
            }

            // only if the obj didnt exist or was just deleted above, create it....
            if(!objmgr.GetObj(uguid))
            {
                switch(objtypeid)
                {
                case TYPEID_OBJECT: // no data to read
                {
                    logerror("Recieved wrong UPDATETYPE_CREATE_OBJECT to create Object base type!");
                    logerror("%s",toHexDump((uint8*)recvPacket.contents(),recvPacket.size(),true).c_str());
                }
                case TYPEID_ITEM:
                {
                    Item *item = new Item();
                    item->Create(uguid);
                    objmgr.Add(item);
                    break;
                }
                case TYPEID_CONTAINER:
                {
                    Bag *bag = new Bag();
                    bag->Create(uguid);
                    objmgr.Add(bag);
                    break;
                }
                case TYPEID_UNIT:
                {
                    Unit *unit = new Unit();
                    unit->Create(uguid);
                    objmgr.Add(unit);
                    break;
                }
                case TYPEID_PLAYER:
                {
                    if(GetGuid() == uguid) // objmgr.Add() would cause quite some trouble if we added ourself again
                        break;
                    Player *player = new Player();
                    player->Create(uguid);
                    objmgr.Add(player);
                    break;
                }
                case TYPEID_GAMEOBJECT:
                {
                    GameObject *go = new GameObject();
                    go->Create(uguid);
                    objmgr.Add(go);
                    break;
                }
                case TYPEID_CORPSE:
                {
                    Corpse *corpse = new Corpse();
                    corpse->Create(uguid);
                    objmgr.Add(corpse);
                    break;
                }
                case TYPEID_DYNAMICOBJECT:
                {
                    DynamicObject *dobj = new DynamicObject();
                    dobj->Create(uguid);
                    objmgr.Add(dobj);
                    break;
                }
                }
            }
            else
            {
                logdebug("Obj "I64FMT" not created, already exists",uguid);
            }
            // ...regardless if it was freshly created or already present, update its values and stuff now...
            this->_MovementUpdate(objtypeid, uguid, recvPacket);
            this->_ValuesUpdate(uguid, recvPacket);

            // ...and ask the server for eventually missing data.
            _QueryObjectInfo(uguid);


            // call script "_OnObjectCreate"
            if(GetInstance()->GetScripts()->ScriptExists("_onobjectcreate"))
            {
                CmdSet Set;
                Set.defaultarg = toString(uguid);
                Set.arg[0] = toString(objtypeid);
                GetInstance()->GetScripts()->RunScript("_onobjectcreate", &Set);
            }

            // if our own character got finally created, we have successfully entered the world,
            // and should have gotten all info about our char already.
        }
        break;

        case UPDATETYPE_OUT_OF_RANGE_OBJECTS:
        {
            recvPacket >> usize;
            for(uint16 i=0; i<usize; i++)
            {
                uguid = recvPacket.GetPackedGuid(); // not 100% sure if this is correct
                logdebug("GUID "I64FMT" out of range",uguid);

                // call script just before object removal
                if(GetInstance()->GetScripts()->ScriptExists("_onobjectdelete"))
                {
                    Object *del_obj = objmgr.GetObj(uguid);
                    CmdSet Set;
                    Set.defaultarg = toString(uguid);
                    Set.arg[0] = del_obj ? toString(del_obj->GetTypeId()) : "";
                    Set.arg[1] = "true"; // out of range = true
                    GetInstance()->GetScripts()->RunScript("_onobjectdelete", &Set);
                }

                objmgr.Remove(uguid, false);
            }
        }
        break;

        default:
        {
            logerror("UPDATE_OBJECT: Got unk updatetype 0x%X",utype);
            logerror("UPDATE_OBJECT: Read %u / %u bytes, skipped rest",recvPacket.rpos(),recvPacket.size());
            logerror("%s",toHexDump((uint8*)recvPacket.contents(),recvPacket.size(),true).c_str());
            char buf[100];
            sprintf(buf,"Got unk updatetype=0x%X, read %u / %u bytes",utype,recvPacket.rpos(),recvPacket.size());

            if(GetInstance()->GetConf()->dumpPackets)
            {
                char buf[100];
                sprintf(buf,"Got unk updatetype=0x%X, read %u / %u bytes",utype,recvPacket.rpos(),recvPacket.size());
                DumpPacket(recvPacket, recvPacket.rpos(),buf);
            }

            return;
        }
        } // switch
        readblocks++;
    } // while

} // func
Example #15
0
void WorldSession::_MovementUpdate(uint8 objtypeid, uint64 uguid, WorldPacket& recvPacket)
{
    MovementInfo mi; // TODO: use a reference to a MovementInfo in Unit/Player class once implemented
    uint16 flags;
    // uint64 fullguid; // see below
    float speedWalk, speedRun, speedSwimBack, speedSwim, speedWalkBack, speedTurn, speedFly, speedFlyBack, speedPitchRate;
    uint32 unk32;

    Object *obj = (Object*)objmgr.GetObj(uguid, true); // also depleted objects
    Unit *u = NULL;
    if(obj)
    {
        if(obj->IsUnit())
            u = (Unit*)obj; // only use for Unit:: functions!!
        else
            logdev("MovementUpdate: object "I64FMT" is not Unit (typeId=%u)",obj->GetGUID(),obj->GetTypeId());
    }
    else
    {
        logerror("MovementUpdate for unknown object "I64FMT" typeid=%u",uguid,objtypeid);
    }

    recvPacket >> flags;

    mi.flags = 0; // not sure if its correct to set it to 0 (needs some starting flag?)
    if(flags & UPDATEFLAG_LIVING)
    {
        recvPacket >> mi.flags >> mi.unkFlags >> mi.time;

        logdev("MovementUpdate: TypeID=%u GUID="I64FMT" pObj=%X flags=%u mi.flags=%u",objtypeid,uguid,obj,flags,mi.flags);

        recvPacket >> mi.x >> mi.y >> mi.z >> mi.o;
        logdev("FLOATS: x=%f y=%f z=%f o=%f",mi.x, mi.y, mi.z ,mi.o);
        if(obj && obj->IsWorldObject())
            ((WorldObject*)obj)->SetPosition(mi.x, mi.y, mi.z, mi.o);

        if(mi.flags & MOVEMENTFLAG_ONTRANSPORT)
        {
            mi.t_guid = recvPacket.GetPackedGuid();
            recvPacket >> mi.t_x >> mi.t_y >> mi.t_z >> mi.t_o;
            recvPacket >> mi.t_time; // added in 2.0.3
            recvPacket >> mi.t_seat;
            logdev("TRANSPORT @ mi.flags: guid="I64FMT" x=%f y=%f z=%f o=%f", mi.t_guid, mi.t_x, mi.t_y, mi.t_z, mi.t_o);
        }
Example #16
0
void MapCell::RemoveObjects()
{
	ObjectSet::iterator itr;
	uint32 count = 0;
	//uint32 ltime = getMSTime();

	/* delete objects in pending respawn state */
	for(itr = _respawnObjects.begin(); itr != _respawnObjects.end(); ++itr)
	{
		switch((*itr)->GetTypeId())
		{
		case TYPEID_UNIT: {
				if( !(*itr)->IsPet() )
				{
					_mapmgr->_reusable_guids_creature.push_back( (*itr)->GetUIdFromGUID() );
					static_cast< Creature* >( *itr )->m_respawnCell=NULL;
					delete static_cast< Creature* >( *itr );
				}
			}break;

		case TYPEID_GAMEOBJECT: {
			static_cast< GameObject* >( *itr )->m_respawnCell=NULL;
			delete static_cast< GameObject* >( *itr );
			}break;
		}
	}
	_respawnObjects.clear();

	//This time it's simpler! We just remove everything :)
	for(itr = _objects.begin(); itr != _objects.end(); )
	{
		count++;

		Object *obj = (*itr);

		itr++;

		if(!obj)
			continue;

		if( _unloadpending )
		{
			if(obj->GetTypeFromGUID() == HIGHGUID_TYPE_TRANSPORTER)
				continue;

			if(obj->GetTypeId()==TYPEID_CORPSE && obj->GetUInt32Value(CORPSE_FIELD_OWNER) != 0)
				continue;

			if(!obj->m_loadedFromDB)
				continue;
		}



		if( obj->Active )
			obj->Deactivate( _mapmgr );

		if( obj->IsInWorld() )
			obj->RemoveFromWorld( true );

		delete obj;
	}

	_playerCount = 0;
	_loaded = false;
}
Example #17
0
void MapMgr::_UpdateObjects()
{
	if(!_updates.size() && !_processQueue.size())
		return;

	Object *pObj;
	Player *pOwner;
	//std::set<Object*>::iterator it_start, it_end, itr;
	std::set<Player*>::iterator it_start, it_end, itr;
	Player * lplr;
	ByteBuffer update(2500);
	uint32 count = 0;
	
	m_updateMutex.Acquire();
	UpdateQueue::iterator iter = _updates.begin();
	PUpdateQueue::iterator it, eit;

	for(; iter != _updates.end();)
	{
		pObj = *iter;
		++iter;
		if(!pObj) continue;

		if(pObj->GetTypeId() == TYPEID_ITEM || pObj->GetTypeId() == TYPEID_CONTAINER)
		{
			// our update is only sent to the owner here.
			pOwner = static_cast< Item* >(pObj)->GetOwner();
			if( pOwner != NULL )
			{
				count = static_cast< Item* >( pObj )->BuildValuesUpdateBlockForPlayer( &update, pOwner );
				// send update to owner
				if( count )
				{
					pOwner->PushUpdateData( &update, count );
					update.clear();
				}
			}
		}
		else
		{
			if( pObj->IsInWorld() )
			{
				// players have to receive their own updates ;)
				if( pObj->GetTypeId() == TYPEID_PLAYER )
				{
					// need to be different! ;)
					count = pObj->BuildValuesUpdateBlockForPlayer( &update, static_cast< Player* >( pObj ) );
					if( count )
					{
						static_cast< Player* >( pObj )->PushUpdateData( &update, count );
						update.clear();
					}
				}

				if( pObj->IsUnit() && pObj->HasUpdateField( UNIT_FIELD_HEALTH ) )
					static_cast< Unit* >( pObj )->EventHealthChangeSinceLastUpdate();

				// build the update
				count = pObj->BuildValuesUpdateBlockForPlayer( &update, static_cast< Player* >( NULL ) );

				if( count )
				{
					it_start = pObj->GetInRangePlayerSetBegin();
					it_end = pObj->GetInRangePlayerSetEnd();
					for(itr = it_start; itr != it_end;)
					{
						lplr = *itr;
						++itr;
						// Make sure that the target player can see us.
						if( lplr->GetTypeId() == TYPEID_PLAYER && lplr->IsVisible( pObj ) )
							lplr->PushUpdateData( &update, count );
					}
					update.clear();
				}
			}
		}
		pObj->ClearUpdateMask();
	}
	_updates.clear();
	m_updateMutex.Release();
	
	// generate pending a9packets and send to clients.
	Player *plyr;
	for(it = _processQueue.begin(); it != _processQueue.end();)
	{
		plyr = *it;
		eit = it;
		++it;
		_processQueue.erase(eit);
		if(plyr->GetMapMgr() == this)
			plyr->ProcessPendingUpdates();
	}
}
Example #18
0
void MapCell::RemoveEventIdObjects(uint8 eventToRemove)
{
	if(!eventToRemove)
		return;

	ObjectSet::iterator itr;

	/* delete objects in pending respawn state */
	Object* pObject;
	if(_respawnObjects.size())
	{
		for(itr = _respawnObjects.begin(); itr != _respawnObjects.end();)
		{
			pObject = (*itr);
			++itr;

			if(!pObject)
				continue;
			
			switch(pObject->GetTypeId())
			{
				case TYPEID_UNIT: 
				{
					if(!(TO_CREATURE(pObject)->m_spawn->eventinfo->eventchangesflag & EVENTID_FLAG_SPAWN))
						continue;
					if(TO_CREATURE(pObject)->m_spawn->eventid == eventToRemove)
					{
						if( pObject->IsVehicle())
						{
							_mapmgr->_reusable_guids_vehicle.push_back( pObject->GetUIdFromGUID() );
							TO_VEHICLE(pObject)->m_respawnCell=NULL;
							TO_VEHICLE(pObject)->Destructor();
							_respawnObjects.erase(pObject);
						}
						else if( !pObject->IsPet() )
						{
							_mapmgr->_reusable_guids_creature.push_back( pObject->GetUIdFromGUID() );
							TO_CREATURE(pObject)->m_respawnCell=NULL;
							TO_CREATURE(pObject)->Destructor();
							_respawnObjects.erase(pObject);
						}
					}
					}break;

			case TYPEID_GAMEOBJECT:
				{
					if(!(TO_GAMEOBJECT(pObject)->m_spawn->eventinfo->eventchangesflag & EVENTID_FLAG_SPAWN))
						continue;

					if(TO_GAMEOBJECT(pObject)->m_spawn->eventid == eventToRemove)
					{
						TO_GAMEOBJECT(pObject)->m_respawnCell=NULL;
						TO_GAMEOBJECT(pObject)->Destructor();
						_respawnObjects.erase(pObject);
					}break;
				}
			}
		}
	}

	if(_objects.size())
	{
		for(itr = _objects.begin(); itr != _objects.end();)
		{
			pObject = (*itr);
			++itr;

			if(!pObject)
				continue;

			switch(pObject->GetTypeId())
			{
				case TYPEID_UNIT: 
				{
					if( pObject->IsPet() )
						continue;

					if(TO_CREATURE(pObject)->m_spawn->eventid != eventToRemove)
						continue;

				if(!(TO_CREATURE(pObject)->m_spawn->eventinfo->eventchangesflag & EVENTID_FLAG_SPAWN))
						continue;
				}break;
			case TYPEID_GAMEOBJECT:
				{
					if(TO_GAMEOBJECT(pObject)->m_spawn->eventid != eventToRemove)
						continue;

					if(!(TO_GAMEOBJECT(pObject)->m_spawn->eventinfo->eventchangesflag & EVENTID_FLAG_SPAWN))
						continue;
				}break;
			default:
				{
					continue;
	
				}break;
			}

			if( _unloadpending )
			{			
				if(!pObject->m_loadedFromDB)
					continue;
			}

			if( pObject->Active )
				pObject->Deactivate( _mapmgr );

			if( pObject->IsInWorld() )
				pObject->RemoveFromWorld( true );

			pObject->Destructor();
		}
	}
}
Example #19
0
void MapCell::ModifyEventIdSetting(bool active, uint8 eventId)
{
	ObjectSet::iterator itr;
	Object* pObject; //do this outside the loop!
	if(_objects.size())
	{
		for(itr = _objects.begin(); itr != _objects.end();)
		{
			pObject = (*itr);
			++itr;

			if(!pObject)
				continue;

			switch(pObject->GetTypeId())
			{
				case TYPEID_UNIT: 
				{
					if( pObject->IsPet() )
						continue;

					if(!TO_CREATURE(pObject)->m_spawn->eventinfo)
						continue;

					if(TO_CREATURE(pObject)->m_spawn->eventid != eventId)
						continue;

					if(TO_CREATURE(pObject)->m_spawn->eventinfo->eventchangesflag & EVENTID_FLAG_MODELID)
						TO_CREATURE(pObject)->SetUInt32Value(UNIT_FIELD_DISPLAYID, active ? TO_CREATURE(pObject)->m_spawn->eventinfo->eventdisplayid : TO_CREATURE(pObject)->m_spawn->displayid);

					if(TO_CREATURE(pObject)->m_spawn->eventinfo->eventchangesflag & EVENTID_FLAG_PHASE)
						TO_CREATURE(pObject)->SetPhase(active ? TO_CREATURE(pObject)->m_spawn->eventinfo->eventphase : TO_CREATURE(pObject)->m_spawn->phase);

					if(TO_CREATURE(pObject)->m_spawn->eventinfo->eventchangesflag & EVENTID_FLAG_EQUIP)
					{
						if(TO_CREATURE(pObject)->m_spawn->eventinfo->eventitem1)
							TO_CREATURE(pObject)->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, active ? TO_CREATURE(pObject)->m_spawn->eventinfo->eventitem1 : TO_CREATURE(pObject)->proto->Item1);
						if(TO_CREATURE(pObject)->m_spawn->eventinfo->eventitem2)
							TO_CREATURE(pObject)->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID_1, active ? TO_CREATURE(pObject)->m_spawn->eventinfo->eventitem2 : TO_CREATURE(pObject)->proto->Item2);
						if(TO_CREATURE(pObject)->m_spawn->eventinfo->eventitem3)
							TO_CREATURE(pObject)->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID_2, active ? TO_CREATURE(pObject)->m_spawn->eventinfo->eventitem3 : TO_CREATURE(pObject)->proto->Item3);
					}
				}break;
			case TYPEID_GAMEOBJECT:
				{
					if(TO_GAMEOBJECT(pObject)->m_spawn->eventid != eventId)
						continue;

					if(!TO_GAMEOBJECT(pObject)->m_spawn->eventinfo)
						continue;

					if(TO_GAMEOBJECT(pObject)->m_spawn->eventinfo->eventchangesflag & EVENTID_FLAG_MODELID)
					{
						if(active)
						{
							TO_GAMEOBJECT(pObject)->SetUInt32Value(GAMEOBJECT_DISPLAYID, TO_GAMEOBJECT(pObject)->m_spawn->eventinfo->eventdisplayid);
						}
						else
						{
							GameObjectInfo * pInfo = GameObjectNameStorage.LookupEntry(pObject->GetEntry());
							TO_GAMEOBJECT(pObject)->SetUInt32Value(GAMEOBJECT_DISPLAYID, pInfo->DisplayID);
						}
					}
					if(TO_GAMEOBJECT(pObject)->m_spawn->eventinfo->eventchangesflag & EVENTID_FLAG_PHASE)
						TO_CREATURE(pObject)->SetPhase(active ? TO_CREATURE(pObject)->m_spawn->eventinfo->eventphase : TO_CREATURE(pObject)->m_spawn->phase);
				}break;
			default:
				{
					continue;
				}break;
			}
		}
	}
}
Example #20
0
void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPackets::Quest::QuestGiverChooseReward& packet)
{
    if (packet.ItemChoiceID >= QUEST_REWARD_CHOICES_COUNT)
    {
        TC_LOG_ERROR("network", "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player %s (%s) tried to get invalid reward (%u) (possible packet-hacking detected)", _player->GetName().c_str(), _player->GetGUID().ToString().c_str(), packet.ItemChoiceID);
        return;
    }

    TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %s, quest = %u, reward = %u", packet.QuestGiverGUID.ToString().c_str(), packet.QuestID, packet.ItemChoiceID);

    Quest const* quest = sObjectMgr->GetQuestTemplate(packet.QuestID);
    if (!quest)
        return;

    Object* object = _player;

    if (!quest->HasFlag(QUEST_FLAGS_AUTOCOMPLETE))
    {
        object = ObjectAccessor::GetObjectByTypeMask(*_player, packet.QuestGiverGUID, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
        if (!object || !object->hasInvolvedQuest(packet.QuestID))
            return;

        // some kind of WPE protection
        if (!_player->CanInteractWithQuestGiver(object))
            return;
    }

    if ((!_player->CanSeeStartQuest(quest) &&  _player->GetQuestStatus(packet.QuestID) == QUEST_STATUS_NONE) ||
        (_player->GetQuestStatus(packet.QuestID) != QUEST_STATUS_COMPLETE && !quest->IsAutoComplete()))
    {
        TC_LOG_ERROR("network", "Error in QUEST_STATUS_COMPLETE: player %s (%s) tried to complete quest %u, but is not allowed to do so (possible packet-hacking or high latency)",
            _player->GetName().c_str(), _player->GetGUID().ToString().c_str(), packet.QuestID);
        return;
    }

    if (_player->CanRewardQuest(quest, packet.ItemChoiceID, true))
    {
        _player->RewardQuest(quest, packet.ItemChoiceID, object);

        switch (object->GetTypeId())
        {
            case TYPEID_UNIT:
            case TYPEID_PLAYER:
            {
                //For AutoSubmition was added plr case there as it almost same exclute AI script cases.
                Creature* creatureQGiver = object->ToCreature();
                if (!creatureQGiver || !sScriptMgr->OnQuestReward(_player, creatureQGiver, quest, packet.ItemChoiceID))
                {
                    // Send next quest
                    if (Quest const* nextQuest = _player->GetNextQuest(packet.QuestGiverGUID, quest))
                    {
                        // Only send the quest to the player if the conditions are met
                        if (_player->CanTakeQuest(nextQuest, false))
                        {
                            if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true))
                                _player->AddQuestAndCheckCompletion(nextQuest, object);

                            _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, packet.QuestGiverGUID, true);
                        }
                    }

                    if (creatureQGiver)
                        creatureQGiver->AI()->sQuestReward(_player, quest, packet.ItemChoiceID);
                }
                break;
            }
            case TYPEID_GAMEOBJECT:
            {
                GameObject* questGiver = object->ToGameObject();
                if (!sScriptMgr->OnQuestReward(_player, questGiver, quest, packet.ItemChoiceID))
                {
                    // Send next quest
                    if (Quest const* nextQuest = _player->GetNextQuest(packet.QuestGiverGUID, quest))
                    {
                        // Only send the quest to the player if the conditions are met
                        if (_player->CanTakeQuest(nextQuest, false))
                        {
                            if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true))
                                _player->AddQuestAndCheckCompletion(nextQuest, object);

                            _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, packet.QuestGiverGUID, true);
                        }
                    }

                    questGiver->AI()->QuestReward(_player, quest, packet.ItemChoiceID);
                }
                break;
            }
            default:
                break;
        }
    }
    else
        _player->PlayerTalkClass->SendQuestGiverOfferReward(quest, packet.QuestGiverGUID, true);
}
Example #21
0
void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData)
{
    uint64 guid;
    uint32 questId;
    uint32 unk1;
    recvData >> guid >> questId >> unk1;

    TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc = %u, quest = %u, unk1 = %u", uint32(GUID_LOPART(guid)), questId, unk1);

    Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT|TYPEMASK_ITEM|TYPEMASK_PLAYER);

#define CLOSE_GOSSIP_CLEAR_DIVIDER() \
    do { \
        _player->PlayerTalkClass->SendCloseGossip(); \
        _player->SetDivider(0); \
    } while (0)

    // no or incorrect quest giver
    if (!object)
    {
        CLOSE_GOSSIP_CLEAR_DIVIDER();
        return;
    }

    if (Player* playerQuestObject = object->ToPlayer())
    {
        if ((_player->GetDivider() && _player->GetDivider() != guid) ||
           ((object != _player && !playerQuestObject->CanShareQuest(questId))))
        {
            CLOSE_GOSSIP_CLEAR_DIVIDER();
            return;
        }
    }
    else
    {
        if (!object->hasQuest(questId))
        {
            CLOSE_GOSSIP_CLEAR_DIVIDER();
            return;
        }
    }

    // some kind of WPE protection
    if (!_player->CanInteractWithQuestGiver(object))
        return;

    if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
    {
        // prevent cheating
        if (!GetPlayer()->CanTakeQuest(quest, true))
        {
            CLOSE_GOSSIP_CLEAR_DIVIDER();
            return;
        }

        if (_player->GetDivider() != 0)
        {
            Player* player = ObjectAccessor::FindPlayer(_player->GetDivider());
            if (player)
            {
                player->SendPushToPartyResponse(_player, QUEST_PARTY_MSG_ACCEPT_QUEST);
                _player->SetDivider(0);
            }
        }

        if (_player->CanAddQuest(quest, true))
        {
            _player->AddQuest(quest, object);

            if (quest->HasFlag(QUEST_FLAGS_PARTY_ACCEPT))
            {
                if (Group* group = _player->GetGroup())
                {
                    for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
                    {
                        Player* player = itr->GetSource();

                        if (!player || player == _player)     // not self
                            continue;

                        if (player->CanTakeQuest(quest, true))
                        {
                            player->SetDivider(_player->GetGUID());

                            //need confirmation that any gossip window will close
                            player->PlayerTalkClass->SendCloseGossip();

                            _player->SendQuestConfirmAccept(quest, player);
                        }
                    }
                }
            }

            if (_player->CanCompleteQuest(questId))
                _player->CompleteQuest(questId);

            switch (object->GetTypeId())
            {
                case TYPEID_UNIT:
                    sScriptMgr->OnQuestAccept(_player, (object->ToCreature()), quest);
                    object->ToCreature()->AI()->sQuestAccept(_player, quest);
                    break;
                case TYPEID_ITEM:
                case TYPEID_CONTAINER:
                {
                    Item* item = (Item*)object;
                    sScriptMgr->OnQuestAccept(_player, item, quest);

                    // destroy not required for quest finish quest starting item
                    bool destroyItem = true;
                    for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
                    {
                        if (quest->RequiredItemId[i] == item->GetEntry() && item->GetTemplate()->MaxCount > 0)
                        {
                            destroyItem = false;
                            break;
                        }
                    }

                    if (destroyItem)
                        _player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);

                    break;
                }
                case TYPEID_GAMEOBJECT:
                    sScriptMgr->OnQuestAccept(_player, object->ToGameObject(), quest);
                    object->ToGameObject()->AI()->QuestAccept(_player, quest);
                    break;
                default:
                    break;
            }
            _player->PlayerTalkClass->SendCloseGossip();

            if (quest->GetSrcSpell() > 0)
                _player->CastSpell(_player, quest->GetSrcSpell(), true);

            return;
        }
    }

    _player->PlayerTalkClass->SendCloseGossip();

#undef CLOSE_GOSSIP_CLEAR_DIVIDER
}
Example #22
0
/// Process queued scripts
void Map::ScriptsProcess()
{
    if (m_scriptSchedule.empty())
        return;

    ///- Process overdue queued scripts
    ScriptScheduleMap::iterator iter = m_scriptSchedule.begin();
    // ok as multimap is a *sorted* associative container
    while (!m_scriptSchedule.empty() && (iter->first <= sWorld->GetGameTime()))
    {
        ScriptAction const& step = iter->second;

        Object* source = NULL;
        if (step.sourceGUID)
        {
            switch (GUID_HIPART(step.sourceGUID))
            {
                case HIGHGUID_ITEM: // as well as HIGHGUID_CONTAINER
                    if (Player* player = HashMapHolder<Player>::Find(step.ownerGUID))
                        source = player->GetItemByGuid(step.sourceGUID);
                    break;
                case HIGHGUID_UNIT:
                case HIGHGUID_VEHICLE:
                    source = HashMapHolder<Creature>::Find(step.sourceGUID);
                    break;
                case HIGHGUID_PET:
                    source = HashMapHolder<Pet>::Find(step.sourceGUID);
                    break;
                case HIGHGUID_PLAYER:
                    source = HashMapHolder<Player>::Find(step.sourceGUID);
                    break;
                case HIGHGUID_GAMEOBJECT:
                    source = HashMapHolder<GameObject>::Find(step.sourceGUID);
                    break;
                case HIGHGUID_CORPSE:
                    source = HashMapHolder<Corpse>::Find(step.sourceGUID);
                    break;
                case HIGHGUID_MO_TRANSPORT:
                    for (MapManager::TransportSet::iterator itr2 = sMapMgr->m_Transports.begin(); itr2 != sMapMgr->m_Transports.end(); ++itr2)
                    {
                        if ((*itr2)->GetGUID() == step.sourceGUID)
                        {
                            source = *itr2;
                            break;
                        }
                    }
                    break;
                default:
                    sLog->outError(LOG_FILTER_TSCR, "%s source with unsupported high guid (GUID: " UI64FMTD ", high guid: %u).",
                        step.script->GetDebugInfo().c_str(), step.sourceGUID, GUID_HIPART(step.sourceGUID));
                    break;
            }
        }

        Object* target = NULL;
        if (step.targetGUID)
        {
            switch (GUID_HIPART(step.targetGUID))
            {
                case HIGHGUID_UNIT:
                case HIGHGUID_VEHICLE:
                    target = HashMapHolder<Creature>::Find(step.targetGUID);
                    break;
                case HIGHGUID_PET:
                    target = HashMapHolder<Pet>::Find(step.targetGUID);
                    break;
                case HIGHGUID_PLAYER:                       // empty GUID case also
                    target = HashMapHolder<Player>::Find(step.targetGUID);
                    break;
                case HIGHGUID_GAMEOBJECT:
                    target = HashMapHolder<GameObject>::Find(step.targetGUID);
                    break;
                case HIGHGUID_CORPSE:
                    target = HashMapHolder<Corpse>::Find(step.targetGUID);
                    break;
                default:
                    sLog->outError(LOG_FILTER_TSCR, "%s target with unsupported high guid (GUID: " UI64FMTD ", high guid: %u).",
                        step.script->GetDebugInfo().c_str(), step.targetGUID, GUID_HIPART(step.targetGUID));
                    break;
            }
        }

        switch (step.script->command)
        {
            case SCRIPT_COMMAND_TALK:
                if (step.script->Talk.ChatType > CHAT_TYPE_WHISPER && step.script->Talk.ChatType != CHAT_MSG_RAID_BOSS_WHISPER)
                {
                    sLog->outError(LOG_FILTER_TSCR, "%s invalid chat type (%u) specified, skipping.", step.script->GetDebugInfo().c_str(), step.script->Talk.ChatType);
                    break;
                }
                if (step.script->Talk.Flags & SF_TALK_USE_PLAYER)
                {
                    if (Player* player = _GetScriptPlayerSourceOrTarget(source, target, step.script))
                    {
                        LocaleConstant loc_idx = player->GetSession()->GetSessionDbLocaleIndex();
                        std::string text(sObjectMgr->GetTrinityString(step.script->Talk.TextID, loc_idx));

                        switch (step.script->Talk.ChatType)
                        {
                            case CHAT_TYPE_SAY:
                                player->Say(text, LANG_UNIVERSAL);
                                break;
                            case CHAT_TYPE_YELL:
                                player->Yell(text, LANG_UNIVERSAL);
                                break;
                            case CHAT_TYPE_TEXT_EMOTE:
                            case CHAT_TYPE_BOSS_EMOTE:
                                player->TextEmote(text);
                                break;
                            case CHAT_TYPE_WHISPER:
                            case CHAT_MSG_RAID_BOSS_WHISPER:
                            {
                                uint64 targetGUID = target ? target->GetGUID() : 0;
                                if (!targetGUID || !IS_PLAYER_GUID(targetGUID))
                                    sLog->outError(LOG_FILTER_TSCR, "%s attempt to whisper to non-player unit, skipping.", step.script->GetDebugInfo().c_str());
                                else
                                    player->Whisper(text, LANG_UNIVERSAL, targetGUID);
                                break;
                            }
                            default:
                                break;                              // must be already checked at load
                        }
                    }
                }
                else
                {
                    // Source or target must be Creature.
                    if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script))
                    {
                        uint64 targetGUID = target ? target->GetGUID() : 0;
                        switch (step.script->Talk.ChatType)
                        {
                            case CHAT_TYPE_SAY:
                                cSource->Say(step.script->Talk.TextID, LANG_UNIVERSAL, targetGUID);
                                break;
                            case CHAT_TYPE_YELL:
                                cSource->Yell(step.script->Talk.TextID, LANG_UNIVERSAL, targetGUID);
                                break;
                            case CHAT_TYPE_TEXT_EMOTE:
                                cSource->TextEmote(step.script->Talk.TextID, targetGUID);
                                break;
                            case CHAT_TYPE_BOSS_EMOTE:
                                cSource->MonsterTextEmote(step.script->Talk.TextID, targetGUID, true);
                                break;
                            case CHAT_TYPE_WHISPER:
                                if (!targetGUID || !IS_PLAYER_GUID(targetGUID))
                                    sLog->outError(LOG_FILTER_TSCR, "%s attempt to whisper to non-player unit, skipping.", step.script->GetDebugInfo().c_str());
                                else
                                    cSource->Whisper(step.script->Talk.TextID, targetGUID);
                                break;
                            case CHAT_MSG_RAID_BOSS_WHISPER:
                                if (!targetGUID || !IS_PLAYER_GUID(targetGUID))
                                    sLog->outError(LOG_FILTER_TSCR, "%s attempt to raidbosswhisper to non-player unit, skipping.", step.script->GetDebugInfo().c_str());
                                else
                                    cSource->MonsterWhisper(step.script->Talk.TextID, targetGUID, true);
                                break;
                            default:
                                break;                              // must be already checked at load
                        }
                    }
                }
                break;

            case SCRIPT_COMMAND_EMOTE:
                // Source or target must be Creature.
                if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script))
                {
                    if (step.script->Emote.Flags & SF_EMOTE_USE_STATE)
                        cSource->SetUInt32Value(UNIT_NPC_EMOTESTATE, step.script->Emote.EmoteID);
                    else
                        cSource->HandleEmoteCommand(step.script->Emote.EmoteID);
                }
                break;

            case SCRIPT_COMMAND_FIELD_SET:
                // Source or target must be Creature.
                if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script))
                {
                    // Validate field number.
                    if (step.script->FieldSet.FieldID <= OBJECT_FIELD_ENTRY || step.script->FieldSet.FieldID >= cSource->GetValuesCount())
                        sLog->outError(LOG_FILTER_TSCR, "%s wrong field %u (max count: %u) in object (TypeId: %u, Entry: %u, GUID: %u) specified, skipping.",
                            step.script->GetDebugInfo().c_str(), step.script->FieldSet.FieldID,
                            cSource->GetValuesCount(), cSource->GetTypeId(), cSource->GetEntry(), cSource->GetGUIDLow());
                    else
                        cSource->SetUInt32Value(step.script->FieldSet.FieldID, step.script->FieldSet.FieldValue);
                }
                break;

            case SCRIPT_COMMAND_MOVE_TO:
                // Source or target must be Creature.
                if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script))
                {
                    Unit * unit = (Unit*)cSource;
                    if (step.script->MoveTo.TravelTime != 0)
                    {
                        float speed = unit->GetDistance(step.script->MoveTo.DestX, step.script->MoveTo.DestY, step.script->MoveTo.DestZ) / ((float)step.script->MoveTo.TravelTime * 0.001f);
                        unit->MonsterMoveWithSpeed(step.script->MoveTo.DestX, step.script->MoveTo.DestY, step.script->MoveTo.DestZ, speed);
                    }
                    else
                        unit->NearTeleportTo(step.script->MoveTo.DestX, step.script->MoveTo.DestY, step.script->MoveTo.DestZ, unit->GetOrientation());
                }
                break;

            case SCRIPT_COMMAND_FLAG_SET:
                // Source or target must be Creature.
                if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script))
                {
                    // Validate field number.
                    if (step.script->FlagToggle.FieldID <= OBJECT_FIELD_ENTRY || step.script->FlagToggle.FieldID >= cSource->GetValuesCount())
                        sLog->outError(LOG_FILTER_TSCR, "%s wrong field %u (max count: %u) in object (TypeId: %u, Entry: %u, GUID: %u) specified, skipping.",
                            step.script->GetDebugInfo().c_str(), step.script->FlagToggle.FieldID,
                            source->GetValuesCount(), source->GetTypeId(), source->GetEntry(), source->GetGUIDLow());
                    else
                        cSource->SetFlag(step.script->FlagToggle.FieldID, step.script->FlagToggle.FieldValue);
                }
                break;

            case SCRIPT_COMMAND_FLAG_REMOVE:
                // Source or target must be Creature.
                if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script))
                {
                    // Validate field number.
                    if (step.script->FlagToggle.FieldID <= OBJECT_FIELD_ENTRY || step.script->FlagToggle.FieldID >= cSource->GetValuesCount())
                        sLog->outError(LOG_FILTER_TSCR, "%s wrong field %u (max count: %u) in object (TypeId: %u, Entry: %u, GUID: %u) specified, skipping.",
                            step.script->GetDebugInfo().c_str(), step.script->FlagToggle.FieldID,
                            source->GetValuesCount(), source->GetTypeId(), source->GetEntry(), source->GetGUIDLow());
                    else
                        cSource->RemoveFlag(step.script->FlagToggle.FieldID, step.script->FlagToggle.FieldValue);
                }
                break;

            case SCRIPT_COMMAND_TELEPORT_TO:
                if (step.script->TeleportTo.Flags & SF_TELEPORT_USE_CREATURE)
                {
                    // Source or target must be Creature.
                    if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script, true))
                        cSource->NearTeleportTo(step.script->TeleportTo.DestX, step.script->TeleportTo.DestY, step.script->TeleportTo.DestZ, step.script->TeleportTo.Orientation);
                }
                else
                {
                    // Source or target must be Player.
                    if (Player* player = _GetScriptPlayerSourceOrTarget(source, target, step.script))
                        player->TeleportTo(step.script->TeleportTo.MapID, step.script->TeleportTo.DestX, step.script->TeleportTo.DestY, step.script->TeleportTo.DestZ, step.script->TeleportTo.Orientation);
                }
                break;

            case SCRIPT_COMMAND_QUEST_EXPLORED:
            {
                if (!source)
                {
                    sLog->outError(LOG_FILTER_TSCR, "%s source object is NULL.", step.script->GetDebugInfo().c_str());
                    break;
                }
                if (!target)
                {
                    sLog->outError(LOG_FILTER_TSCR, "%s target object is NULL.", step.script->GetDebugInfo().c_str());
                    break;
                }

                // when script called for item spell casting then target == (unit or GO) and source is player
                WorldObject* worldObject;
                Player* player = target->ToPlayer();
                if (player)
                {
                    if (source->GetTypeId() != TYPEID_UNIT && source->GetTypeId() != TYPEID_GAMEOBJECT && source->GetTypeId() != TYPEID_PLAYER)
                    {
                        sLog->outError(LOG_FILTER_TSCR, "%s source is not unit, gameobject or player (TypeId: %u, Entry: %u, GUID: %u), skipping.",
                            step.script->GetDebugInfo().c_str(), source->GetTypeId(), source->GetEntry(), source->GetGUIDLow());
                        break;
                    }
                    worldObject = dynamic_cast<WorldObject*>(source);
                }
                else
                {
                    player = source->ToPlayer();
                    if (player)
                    {
                        if (target->GetTypeId() != TYPEID_UNIT && target->GetTypeId() != TYPEID_GAMEOBJECT && target->GetTypeId() != TYPEID_PLAYER)
                        {
                            sLog->outError(LOG_FILTER_TSCR, "%s target is not unit, gameobject or player (TypeId: %u, Entry: %u, GUID: %u), skipping.",
                                step.script->GetDebugInfo().c_str(), target->GetTypeId(), target->GetEntry(), target->GetGUIDLow());
                            break;
                        }
                        worldObject = dynamic_cast<WorldObject*>(target);
                    }
                    else
                    {
                        sLog->outError(LOG_FILTER_TSCR, "%s neither source nor target is player (source: TypeId: %u, Entry: %u, GUID: %u; target: TypeId: %u, Entry: %u, GUID: %u), skipping.",
                            step.script->GetDebugInfo().c_str(), source->GetTypeId(), source->GetEntry(), source->GetGUIDLow(),
                            target->GetTypeId(), target->GetEntry(), target->GetGUIDLow());
                        break;
                    }
                }

                // quest id and flags checked at script loading
                if ((worldObject->GetTypeId() != TYPEID_UNIT || ((Unit*)worldObject)->isAlive()) &&
                    (step.script->QuestExplored.Distance == 0 || worldObject->IsWithinDistInMap(player, float(step.script->QuestExplored.Distance))))
                    player->AreaExploredOrEventHappens(step.script->QuestExplored.QuestID);
                else
                    player->FailQuest(step.script->QuestExplored.QuestID);

                break;
            }

            case SCRIPT_COMMAND_KILL_CREDIT:
                // Source or target must be Player.
                if (Player* player = _GetScriptPlayerSourceOrTarget(source, target, step.script))
                {
                    if (step.script->KillCredit.Flags & SF_KILLCREDIT_REWARD_GROUP)
                        player->RewardPlayerAndGroupAtEvent(step.script->KillCredit.CreatureEntry, player);
                    else
                        player->KilledMonsterCredit(step.script->KillCredit.CreatureEntry, 0);
                }
                break;

            case SCRIPT_COMMAND_RESPAWN_GAMEOBJECT:
                if (!step.script->RespawnGameobject.GOGuid)
                {
                    sLog->outError(LOG_FILTER_TSCR, "%s gameobject guid (datalong) is not specified.", step.script->GetDebugInfo().c_str());
                    break;
                }

                // Source or target must be WorldObject.
                if (WorldObject* pSummoner = _GetScriptWorldObject(source, true, step.script))
                {
                    GameObject* pGO = _FindGameObject(pSummoner, step.script->RespawnGameobject.GOGuid);
                    if (!pGO)
                    {
                        sLog->outError(LOG_FILTER_TSCR, "%s gameobject was not found (guid: %u).", step.script->GetDebugInfo().c_str(), step.script->RespawnGameobject.GOGuid);
                        break;
                    }

                    if (pGO->GetGoType() == GAMEOBJECT_TYPE_FISHINGNODE ||
                        pGO->GetGoType() == GAMEOBJECT_TYPE_DOOR        ||
                        pGO->GetGoType() == GAMEOBJECT_TYPE_BUTTON      ||
                        pGO->GetGoType() == GAMEOBJECT_TYPE_TRAP)
                    {
                        sLog->outError(LOG_FILTER_TSCR, "%s can not be used with gameobject of type %u (guid: %u).",
                            step.script->GetDebugInfo().c_str(), uint32(pGO->GetGoType()), step.script->RespawnGameobject.GOGuid);
                        break;
                    }

                    // Check that GO is not spawned
                    if (!pGO->isSpawned())
                    {
                        int32 nTimeToDespawn = std::max(5, int32(step.script->RespawnGameobject.DespawnDelay));
                        pGO->SetLootState(GO_READY);
                        pGO->SetRespawnTime(nTimeToDespawn);

                        pGO->GetMap()->AddToMap(pGO);
                    }
                }
                break;

            case SCRIPT_COMMAND_TEMP_SUMMON_CREATURE:
            {
                // Source must be WorldObject.
                if (WorldObject* pSummoner = _GetScriptWorldObject(source, true, step.script))
                {
                    if (!step.script->TempSummonCreature.CreatureEntry)
                        sLog->outError(LOG_FILTER_TSCR, "%s creature entry (datalong) is not specified.", step.script->GetDebugInfo().c_str());
                    else
                    {
                        float x = step.script->TempSummonCreature.PosX;
                        float y = step.script->TempSummonCreature.PosY;
                        float z = step.script->TempSummonCreature.PosZ;
                        float o = step.script->TempSummonCreature.Orientation;

                        if (!pSummoner->SummonCreature(step.script->TempSummonCreature.CreatureEntry, x, y, z, o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, step.script->TempSummonCreature.DespawnDelay))
                            sLog->outError(LOG_FILTER_TSCR, "%s creature was not spawned (entry: %u).", step.script->GetDebugInfo().c_str(), step.script->TempSummonCreature.CreatureEntry);
                    }
                }
                break;
            }

            case SCRIPT_COMMAND_OPEN_DOOR:
            case SCRIPT_COMMAND_CLOSE_DOOR:
                _ScriptProcessDoor(source, target, step.script);
                break;

            case SCRIPT_COMMAND_ACTIVATE_OBJECT:
                // Source must be Unit.
                if (Unit* unit = _GetScriptUnit(source, true, step.script))
                {
                    // Target must be GameObject.
                    if (!target)
                    {
                        sLog->outError(LOG_FILTER_TSCR, "%s target object is NULL.", step.script->GetDebugInfo().c_str());
                        break;
                    }

                    if (target->GetTypeId() != TYPEID_GAMEOBJECT)
                    {
                        sLog->outError(LOG_FILTER_TSCR, "%s target object is not gameobject (TypeId: %u, Entry: %u, GUID: %u), skipping.",
                            step.script->GetDebugInfo().c_str(), target->GetTypeId(), target->GetEntry(), target->GetGUIDLow());
                        break;
                    }

                    if (GameObject* pGO = target->ToGameObject())
                        pGO->Use(unit);
                }
                break;

            case SCRIPT_COMMAND_REMOVE_AURA:
            {
                // Source (datalong2 != 0) or target (datalong2 == 0) must be Unit.
                bool bReverse = step.script->RemoveAura.Flags & SF_REMOVEAURA_REVERSE;
                if (Unit* unit = _GetScriptUnit(bReverse ? source : target, bReverse, step.script))
                    unit->RemoveAurasDueToSpell(step.script->RemoveAura.SpellID);
                break;
            }

            case SCRIPT_COMMAND_CAST_SPELL:
            {
                // TODO: Allow gameobjects to be targets and casters
                if (!source && !target)
                {
                    sLog->outError(LOG_FILTER_TSCR, "%s source and target objects are NULL.", step.script->GetDebugInfo().c_str());
                    break;
                }

                Unit* uSource = NULL;
                Unit* uTarget = NULL;
                // source/target cast spell at target/source (script->datalong2: 0: s->t 1: s->s 2: t->t 3: t->s
                switch (step.script->CastSpell.Flags)
                {
                    case SF_CASTSPELL_SOURCE_TO_TARGET: // source -> target
                        uSource = source ? source->ToUnit() : NULL;
                        uTarget = target ? target->ToUnit() : NULL;
                        break;
                    case SF_CASTSPELL_SOURCE_TO_SOURCE: // source -> source
                        uSource = source ? source->ToUnit() : NULL;
                        uTarget = uSource;
                        break;
                    case SF_CASTSPELL_TARGET_TO_TARGET: // target -> target
                        uSource = target ? target->ToUnit() : NULL;
                        uTarget = uSource;
                        break;
                    case SF_CASTSPELL_TARGET_TO_SOURCE: // target -> source
                        uSource = target ? target->ToUnit() : NULL;
                        uTarget = source ? source->ToUnit() : NULL;
                        break;
                    case SF_CASTSPELL_SEARCH_CREATURE: // source -> creature with entry
                        uSource = source ? source->ToUnit() : NULL;
                        uTarget = uSource ? GetClosestCreatureWithEntry(uSource, abs(step.script->CastSpell.CreatureEntry), step.script->CastSpell.SearchRadius) : NULL;
                        break;
                }

                if (!uSource || !uSource->isType(TYPEMASK_UNIT))
                {
                    sLog->outError(LOG_FILTER_TSCR, "%s no source unit found for spell %u", step.script->GetDebugInfo().c_str(), step.script->CastSpell.SpellID);
                    break;
                }

                if (!uTarget || !uTarget->isType(TYPEMASK_UNIT))
                {
                    sLog->outError(LOG_FILTER_TSCR, "%s no target unit found for spell %u", step.script->GetDebugInfo().c_str(), step.script->CastSpell.SpellID);
                    break;
                }

                bool triggered = (step.script->CastSpell.Flags != 4) ?
                    step.script->CastSpell.CreatureEntry & SF_CASTSPELL_TRIGGERED :
                    step.script->CastSpell.CreatureEntry < 0;
                uSource->CastSpell(uTarget, step.script->CastSpell.SpellID, triggered);
                break;
            }

            case SCRIPT_COMMAND_PLAY_SOUND:
                // Source must be WorldObject.
                if (WorldObject* object = _GetScriptWorldObject(source, true, step.script))
                {
                    // PlaySound.Flags bitmask: 0/1=anyone/target
                    Player* player = NULL;
                    if (step.script->PlaySound.Flags & SF_PLAYSOUND_TARGET_PLAYER)
                    {
                        // Target must be Player.
                        player = _GetScriptPlayer(target, false, step.script);
                        if (!target)
                            break;
                    }

                    // PlaySound.Flags bitmask: 0/2=without/with distance dependent
                    if (step.script->PlaySound.Flags & SF_PLAYSOUND_DISTANCE_SOUND)
                        object->PlayDistanceSound(step.script->PlaySound.SoundID, player);
                    else
                        object->PlayDirectSound(step.script->PlaySound.SoundID, player);
                }
                break;

            case SCRIPT_COMMAND_CREATE_ITEM:
                // Target or source must be Player.
                if (Player* pReceiver = _GetScriptPlayerSourceOrTarget(source, target, step.script))
                {
                    ItemPosCountVec dest;
                    InventoryResult msg = pReceiver->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, step.script->CreateItem.ItemEntry, step.script->CreateItem.Amount);
                    if (msg == EQUIP_ERR_OK)
                    {
                        if (Item* item = pReceiver->StoreNewItem(dest, step.script->CreateItem.ItemEntry, true))
                            pReceiver->SendNewItem(item, step.script->CreateItem.Amount, false, true);
                    }
                    else
                        pReceiver->SendEquipError(msg, NULL, NULL, step.script->CreateItem.ItemEntry);
                }
                break;

            case SCRIPT_COMMAND_DESPAWN_SELF:
                // Target or source must be Creature.
                if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script, true))
                    cSource->DespawnOrUnsummon(step.script->DespawnSelf.DespawnDelay);
                break;

            case SCRIPT_COMMAND_LOAD_PATH:
                // Source must be Unit.
                if (Unit* unit = _GetScriptUnit(source, true, step.script))
                {
                    if (!sWaypointMgr->GetPath(step.script->LoadPath.PathID))
                        sLog->outError(LOG_FILTER_TSCR, "%s source object has an invalid path (%u), skipping.", step.script->GetDebugInfo().c_str(), step.script->LoadPath.PathID);
                    else
                        unit->GetMotionMaster()->MovePath(step.script->LoadPath.PathID, step.script->LoadPath.IsRepeatable);
                }
                break;

            case SCRIPT_COMMAND_CALLSCRIPT_TO_UNIT:
            {
                if (!step.script->CallScript.CreatureEntry)
                {
                    sLog->outError(LOG_FILTER_TSCR, "%s creature entry is not specified, skipping.", step.script->GetDebugInfo().c_str());
                    break;
                }
                if (!step.script->CallScript.ScriptID)
                {
                    sLog->outError(LOG_FILTER_TSCR, "%s script id is not specified, skipping.", step.script->GetDebugInfo().c_str());
                    break;
                }

                Creature* cTarget = NULL;
                if (source) //using grid searcher
                {
                    WorldObject* wSource = dynamic_cast <WorldObject*> (source);

                    CellCoord p(MistCore::ComputeCellCoord(wSource->GetPositionX(), wSource->GetPositionY()));
                    Cell cell(p);

                    MistCore::CreatureWithDbGUIDCheck target_check(wSource, step.script->CallScript.CreatureEntry);
                    MistCore::CreatureSearcher<MistCore::CreatureWithDbGUIDCheck> checker(wSource, cTarget, target_check);

                    TypeContainerVisitor<MistCore::CreatureSearcher <MistCore::CreatureWithDbGUIDCheck>, GridTypeMapContainer > unit_checker(checker);
                    cell.Visit(p, unit_checker, *wSource->GetMap(), *wSource, wSource->GetGridActivationRange());
                }
                else //check hashmap holders
                {
                    if (CreatureData const* data = sObjectMgr->GetCreatureData(step.script->CallScript.CreatureEntry))
                        cTarget = ObjectAccessor::GetObjectInWorld<Creature>(data->mapid, data->posX, data->posY, MAKE_NEW_GUID(step.script->CallScript.CreatureEntry, data->id, HIGHGUID_UNIT), cTarget);
                }

                if (!cTarget)
                {
                    sLog->outError(LOG_FILTER_TSCR, "%s target was not found (entry: %u)", step.script->GetDebugInfo().c_str(), step.script->CallScript.CreatureEntry);
                    break;
                }

                //Lets choose our ScriptMap map
                ScriptMapMap* datamap = GetScriptsMapByType(ScriptsType(step.script->CallScript.ScriptType));
                //if no scriptmap present...
                if (!datamap)
                {
                    sLog->outError(LOG_FILTER_TSCR, "%s unknown scriptmap (%u) specified, skipping.", step.script->GetDebugInfo().c_str(), step.script->CallScript.ScriptType);
                    break;
                }

                // Insert script into schedule but do not start it
                ScriptsStart(*datamap, step.script->CallScript.ScriptID, cTarget, NULL);
                break;
            }

            case SCRIPT_COMMAND_KILL:
                // Source or target must be Creature.
                if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script))
                {
                    if (cSource->isDead())
                        sLog->outError(LOG_FILTER_TSCR, "%s creature is already dead (Entry: %u, GUID: %u)",
                            step.script->GetDebugInfo().c_str(), cSource->GetEntry(), cSource->GetGUIDLow());
                    else
                    {
                        cSource->setDeathState(JUST_DIED);
                        if (step.script->Kill.RemoveCorpse == 1)
                            cSource->RemoveCorpse();
                    }
                }
                break;

            case SCRIPT_COMMAND_ORIENTATION:
                // Source must be Unit.
                if (Unit* sourceUnit = _GetScriptUnit(source, true, step.script))
                {
                    if (step.script->Orientation.Flags & SF_ORIENTATION_FACE_TARGET)
                    {
                        // Target must be Unit.
                        Unit* targetUnit = _GetScriptUnit(target, false, step.script);
                        if (!targetUnit)
                            break;

                        sourceUnit->SetInFront(targetUnit);
                    }
                    else
                        sourceUnit->SetOrientation(step.script->Orientation.Orientation);

                    sourceUnit->SendMovementFlagUpdate();
                }
                break;

            case SCRIPT_COMMAND_EQUIP:
                // Source must be Creature.
                if (Creature* cSource = _GetScriptCreature(source, true, step.script))
                    cSource->LoadEquipment(step.script->Equip.EquipmentID);
                break;

            case SCRIPT_COMMAND_MODEL:
                // Source must be Creature.
                if (Creature* cSource = _GetScriptCreature(source, true, step.script))
                    cSource->SetDisplayId(step.script->Model.ModelID);
                break;

            case SCRIPT_COMMAND_CLOSE_GOSSIP:
                // Source must be Player.
                if (Player* player = _GetScriptPlayer(source, true, step.script))
                    player->PlayerTalkClass->SendCloseGossip();
                break;

            case SCRIPT_COMMAND_PLAYMOVIE:
                // Source must be Player.
                if (Player* player = _GetScriptPlayer(source, true, step.script))
                    player->SendMovieStart(step.script->PlayMovie.MovieID);
                break;

            default:
                sLog->outError(LOG_FILTER_TSCR, "Unknown script command %s.", step.script->GetDebugInfo().c_str());
                break;
        }

        m_scriptSchedule.erase(iter);
        iter = m_scriptSchedule.begin();
        sScriptMgr->DecreaseScheduledScriptCount();
    }
}
Example #23
0
void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPackets::Quest::QuestGiverChooseReward& packet)
{
    TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %s, quest = %u, reward = %u", packet.QuestGiverGUID.ToString().c_str(), packet.QuestID, packet.ItemChoiceID);

    Quest const* quest = sObjectMgr->GetQuestTemplate(packet.QuestID);
    if (!quest)
        return;

    // This is Real Item Entry, not slot id as pre 5.x
    if (packet.ItemChoiceID)
    {
        ItemTemplate const* rewardProto = sObjectMgr->GetItemTemplate(packet.ItemChoiceID);
        if (!rewardProto)
        {
            TC_LOG_ERROR("network", "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player %s (%s) tried to get invalid reward item (Item Entry: %u) for quest %u (possible packet-hacking detected)", _player->GetName().c_str(), _player->GetGUID().ToString().c_str(), packet.ItemChoiceID, packet.QuestID);
            return;
        }

        bool itemValid = false;
        for (uint32 i = 0; i < quest->GetRewChoiceItemsCount(); ++i)
        {
            if (quest->RewardChoiceItemId[i] && quest->RewardChoiceItemId[i] == uint32(packet.ItemChoiceID))
            {
                itemValid = true;
                break;
            }
        }

        if (!itemValid && quest->GetQuestPackageID())
        {
            if (std::vector<QuestPackageItemEntry const*> const* questPackageItems = sDB2Manager.GetQuestPackageItems(quest->GetQuestPackageID()))
            {
                for (QuestPackageItemEntry const* questPackageItem : *questPackageItems)
                {
                    if (questPackageItem->ItemID != uint32(packet.ItemChoiceID))
                        continue;

                    rewardProto = sObjectMgr->GetItemTemplate(questPackageItem->ItemID);
                    if (rewardProto)
                    {
                        if (rewardProto->CanWinForPlayer(_player))
                        {
                            itemValid = true;
                            break;
                        }
                    }
                }
            }
        }

        if (!itemValid)
        {
            TC_LOG_ERROR("network", "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player %s (%s) tried to get reward item (Item Entry: %u) wich is not a reward for quest %u (possible packet-hacking detected)", _player->GetName().c_str(), _player->GetGUID().ToString().c_str(), packet.ItemChoiceID, packet.QuestID);
            return;
        }
    }

    Object* object = _player;

    if (!quest->HasFlag(QUEST_FLAGS_AUTOCOMPLETE))
    {
        object = ObjectAccessor::GetObjectByTypeMask(*_player, packet.QuestGiverGUID, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
        if (!object || !object->hasInvolvedQuest(packet.QuestID))
            return;

        // some kind of WPE protection
        if (!_player->CanInteractWithQuestGiver(object))
            return;
    }

    if ((!_player->CanSeeStartQuest(quest) &&  _player->GetQuestStatus(packet.QuestID) == QUEST_STATUS_NONE) ||
        (_player->GetQuestStatus(packet.QuestID) != QUEST_STATUS_COMPLETE && !quest->IsAutoComplete()))
    {
        TC_LOG_ERROR("network", "Error in QUEST_STATUS_COMPLETE: player %s (%s) tried to complete quest %u, but is not allowed to do so (possible packet-hacking or high latency)",
            _player->GetName().c_str(), _player->GetGUID().ToString().c_str(), packet.QuestID);
        return;
    }

    if (_player->CanRewardQuest(quest, packet.ItemChoiceID, true))
    {
        _player->RewardQuest(quest, packet.ItemChoiceID, object);

        switch (object->GetTypeId())
        {
            case TYPEID_UNIT:
            case TYPEID_PLAYER:
            {
                //For AutoSubmition was added plr case there as it almost same exclute AI script cases.
                Creature* creatureQGiver = object->ToCreature();
                if (!creatureQGiver || !sScriptMgr->OnQuestReward(_player, creatureQGiver, quest, packet.ItemChoiceID))
                {
                    // Send next quest
                    if (Quest const* nextQuest = _player->GetNextQuest(packet.QuestGiverGUID, quest))
                    {
                        // Only send the quest to the player if the conditions are met
                        if (_player->CanTakeQuest(nextQuest, false))
                        {
                            if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true))
                                _player->AddQuestAndCheckCompletion(nextQuest, object);

                            _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, packet.QuestGiverGUID, true);
                        }
                    }

                    if (creatureQGiver)
                        creatureQGiver->AI()->sQuestReward(_player, quest, packet.ItemChoiceID);
                }
                break;
            }
            case TYPEID_GAMEOBJECT:
            {
                GameObject* questGiver = object->ToGameObject();
                if (!sScriptMgr->OnQuestReward(_player, questGiver, quest, packet.ItemChoiceID))
                {
                    // Send next quest
                    if (Quest const* nextQuest = _player->GetNextQuest(packet.QuestGiverGUID, quest))
                    {
                        // Only send the quest to the player if the conditions are met
                        if (_player->CanTakeQuest(nextQuest, false))
                        {
                            if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true))
                                _player->AddQuestAndCheckCompletion(nextQuest, object);

                            _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, packet.QuestGiverGUID, true);
                        }
                    }

                    questGiver->AI()->QuestReward(_player, quest, packet.ItemChoiceID);
                }
                break;
            }
            default:
                break;
        }
    }
    else
        _player->PlayerTalkClass->SendQuestGiverOfferReward(quest, packet.QuestGiverGUID, true);
}
Example #24
0
void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket & recv_data)
{
    uint32 quest, reward;
    uint64 guid;
    recv_data >> guid >> quest >> reward;

    if (reward >= QUEST_REWARD_CHOICES_COUNT)
    {
        sLog.outError("Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player %s (guid %d) tried to get invalid reward (%u) (probably packet hacking)", _player->GetName(), _player->GetGUIDLow(), reward);
        return;
    }

    if (!GetPlayer()->isAlive())
        return;

    sLog.outDebug("WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %u, quest = %u, reward = %u",uint32(GUID_LOPART(guid)),quest,reward);

    Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
    if (!pObject)
        return;

    if (!pObject->hasInvolvedQuest(quest))
        return;

    Quest const *pQuest = sObjectMgr.GetQuestTemplate(quest);
    if (pQuest)
    {
        if ((!_player->CanSeeStartQuest(pQuest) && _player->GetQuestStatus(quest)==QUEST_STATUS_NONE) || (_player->GetQuestStatus(quest) != QUEST_STATUS_COMPLETE && !pQuest->IsAutoComplete()))
        {
            sLog.outError("Player with guid %u trying to Complete quest (id %u) when he can't - cheat?", _player->GetGUID(), quest);
            return;
        }
        if (_player->CanRewardQuest(pQuest, reward, true))
        {
            _player->RewardQuest(pQuest, reward, pObject);

            switch(pObject->GetTypeId())
            {
                case TYPEID_UNIT:
                    if (!(sScriptMgr.OnQuestReward(_player, (pObject->ToCreature()), pQuest, reward)))
                    {
                        // Send next quest
                        if (Quest const* nextquest = _player->GetNextQuest(guid ,pQuest))
                            _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextquest,guid,true);

                        (pObject->ToCreature())->AI()->sQuestReward(_player, pQuest, reward);
                    }
                    break;
                case TYPEID_GAMEOBJECT:
                    if (!sScriptMgr.OnQuestReward(_player, ((GameObject*)pObject), pQuest, reward))
                    {
                        // Send next quest
                        if (Quest const* nextquest = _player->GetNextQuest(guid ,pQuest))
                            _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextquest,guid,true);
                        pObject->ToGameObject()->AI()->QuestReward(_player, pQuest, reward);
                    }
                    break;
                default:
                    break;
            }
        }
        else
            _player->PlayerTalkClass->SendQuestGiverOfferReward(pQuest, guid, true);
    }
}
Example #25
0
void WorldSession::HandleQuestgiverAcceptQuestOpcode( WorldPacket & recv_data )
{
    ObjectGuid guid;
    uint32 quest;
    uint32 unk1;
    recv_data >> guid >> quest >> unk1;

    if (!GetPlayer()->isAlive())
        return;

    DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc = %s, quest = %u, unk1 = %u", guid.GetString().c_str(), quest, unk1 );

    Object* pObject = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_GAMEOBJECT_PLAYER_OR_ITEM);

    // no or incorrect quest giver
    if(!pObject
        || (pObject->GetTypeId()!=TYPEID_PLAYER && !pObject->HasQuest(quest))
        || (pObject->GetTypeId()==TYPEID_PLAYER && !((Player*)pObject)->CanShareQuest(quest))
        )
    {
        _player->PlayerTalkClass->CloseGossip();
        _player->SetDivider( 0 );
        return;
    }

    Quest const* qInfo = sObjectMgr.GetQuestTemplate(quest);
    if ( qInfo )
    {
        // prevent cheating
        if(!GetPlayer()->CanTakeQuest(qInfo,true) )
        {
            _player->PlayerTalkClass->CloseGossip();
            _player->SetDivider( 0 );
            return;
        }

        if( _player->GetDivider() != 0 )
        {
            Player *pPlayer = ObjectAccessor::FindPlayer( _player->GetDivider() );
            if( pPlayer )
            {
                pPlayer->SendPushToPartyResponse( _player, QUEST_PARTY_MSG_ACCEPT_QUEST );
                _player->SetDivider( 0 );
            }
        }

        if( _player->CanAddQuest( qInfo, true ) )
        {
            _player->AddQuest( qInfo, pObject );

            if (qInfo->HasQuestFlag(QUEST_FLAGS_PARTY_ACCEPT))
            {
                if (Group* pGroup = _player->GetGroup())
                {
                    for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
                    {
                        Player* pPlayer = itr->getSource();

                        if (!pPlayer || pPlayer == _player)     // not self
                            continue;

                        if (pPlayer->CanTakeQuest(qInfo, true))
                        {
                            pPlayer->SetDivider(_player->GetGUID());

                            //need confirmation that any gossip window will close
                            pPlayer->PlayerTalkClass->CloseGossip();

                            _player->SendQuestConfirmAccept(qInfo, pPlayer);
                        }
                    }
                }
            }

            if ( _player->CanCompleteQuest( quest ) )
                _player->CompleteQuest( quest );

            _player->GetAchievementMgr().StartTimedAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST, quest);

            switch(pObject->GetTypeId())
            {
                case TYPEID_UNIT:
                    sScriptMgr.OnQuestAccept(_player, (Creature*)pObject, qInfo);
                    break;
                case TYPEID_ITEM:
                case TYPEID_CONTAINER:
                {
                    sScriptMgr.OnQuestAccept(_player, (Item*)pObject, qInfo);

                    // destroy not required for quest finish quest starting item
                    bool destroyItem = true;
                    for(int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
                    {
                        if ((qInfo->ReqItemId[i] == ((Item*)pObject)->GetEntry()) && (((Item*)pObject)->GetProto()->MaxCount > 0))
                        {
                            destroyItem = false;
                            break;
                        }
                    }

                    if(destroyItem)
                        _player->DestroyItem(((Item*)pObject)->GetBagSlot(), ((Item*)pObject)->GetSlot(), true);

                    break;
                }
                case TYPEID_GAMEOBJECT:
                    sScriptMgr.OnQuestAccept(_player, (GameObject*)pObject, qInfo);
                    break;
            }
            _player->PlayerTalkClass->CloseGossip();

            if( qInfo->GetSrcSpell() > 0 )
                _player->CastSpell( _player, qInfo->GetSrcSpell(), true);

            return;
        }
    }

    _player->PlayerTalkClass->CloseGossip();
}
Example #26
0
void MapCell::RemoveObjects()
{
	ObjectSet::iterator itr;
	//uint32 ltime = getMSTime();

	/* delete objects in pending respawn state */
	Object* pObject;
	for(itr = _respawnObjects.begin(); itr != _respawnObjects.end(); ++itr)
	{
		pObject = *itr;
		if(!pObject)
			continue;
		
		switch(pObject->GetTypeId())
		{
		case TYPEID_UNIT: {
				if( pObject->IsVehicle() )
				{
					_mapmgr->_reusable_guids_vehicle.push_back( pObject->GetUIdFromGUID() );
					TO_VEHICLE(pObject)->m_respawnCell=NULL;
					TO_VEHICLE(pObject)->Destructor();
				}
				else if( !pObject->IsPet() )
				{
					_mapmgr->_reusable_guids_creature.push_back( pObject->GetUIdFromGUID() );
					TO_CREATURE(pObject)->m_respawnCell=NULL;
					TO_CREATURE(pObject)->Destructor();
				}
			}break;

		case TYPEID_GAMEOBJECT: {
			TO_GAMEOBJECT(pObject)->m_respawnCell=NULL;
			TO_GAMEOBJECT(pObject)->Destructor();
			}break;
		default:
			pObject->Destructor();
			break;

		}
	}
	_respawnObjects.clear();

	//This time it's simpler! We just remove everything :)
	Object* obj; //do this outside the loop!
	for(itr = _objects.begin(); itr != _objects.end();)
	{
		obj = (*itr);
		itr++;

		if(!obj)
			continue;

		if( _unloadpending )
		{
			if(obj->GetTypeFromGUID() == HIGHGUID_TYPE_TRANSPORTER)
				continue;

			if(obj->GetTypeId()==TYPEID_CORPSE && obj->GetUInt32Value(CORPSE_FIELD_OWNER) != 0)
				continue;

			if(!obj->m_loadedFromDB)
				continue;
		}



		if( obj->Active )
			obj->Deactivate( _mapmgr );

		if( obj->IsInWorld())
			obj->RemoveFromWorld( true );

		obj->Destructor();
	}

	_playerCount = 0;
	_loaded = false;
}
Example #27
0
/// Process queued scripts
void Map::ScriptsProcess()
{
    if (m_scriptSchedule.empty())
        return;

    ///- Process overdue queued scripts
    ScriptScheduleMap::iterator iter = m_scriptSchedule.begin();
    // ok as multimap is a *sorted* associative container
    while (!m_scriptSchedule.empty() && (iter->first <= sWorld->GetGameTime()))
    {
        ScriptAction const& step = iter->second;

        Object* source = NULL;
        if (!step.sourceGUID.IsEmpty())
        {
            switch (step.sourceGUID.GetHigh())
            {
                case HighGuid::Item: // as well as HIGHGUID_CONTAINER
                    if (Player* player = HashMapHolder<Player>::Find(step.ownerGUID))
                        source = player->GetItemByGuid(step.sourceGUID);
                    break;
                case HighGuid::Creature:
                case HighGuid::Vehicle:
                    source = GetCreature(step.sourceGUID);
                    break;
                case HighGuid::Pet:
                    source = GetPet(step.sourceGUID);
                    break;
                case HighGuid::Player:
                    source = HashMapHolder<Player>::Find(step.sourceGUID);
                    break;
                case HighGuid::GameObject:
                case HighGuid::Transport:
                    source = GetGameObject(step.sourceGUID);
                    break;
                case HighGuid::Corpse:
                    source = GetCorpse(step.sourceGUID);
                    break;
                default:
                    TC_LOG_ERROR("scripts", "%s source with unsupported high guid %s.",
                        step.script->GetDebugInfo().c_str(), step.sourceGUID.ToString().c_str());
                    break;
            }
        }

        WorldObject* target = NULL;
        if (!step.targetGUID.IsEmpty())
        {
            switch (step.targetGUID.GetHigh())
            {
                case HighGuid::Creature:
                case HighGuid::Vehicle:
                    target = GetCreature(step.targetGUID);
                    break;
                case HighGuid::Pet:
                    target = GetPet(step.targetGUID);
                    break;
                case HighGuid::Player:
                    target = HashMapHolder<Player>::Find(step.targetGUID);
                    break;
                case HighGuid::GameObject:
                case HighGuid::Transport:
                    target = GetGameObject(step.targetGUID);
                    break;
                case HighGuid::Corpse:
                    target = GetCorpse(step.targetGUID);
                    break;
                default:
                    TC_LOG_ERROR("scripts", "%s target with unsupported high guid %s.",
                        step.script->GetDebugInfo().c_str(), step.targetGUID.ToString().c_str());
                    break;
            }
        }

        switch (step.script->command)
        {
            case SCRIPT_COMMAND_TALK:
            {
                if (step.script->Talk.ChatType > CHAT_TYPE_BOSS_WHISPER)
                {
                    TC_LOG_ERROR("scripts", "%s invalid chat type (%u) specified, skipping.", step.script->GetDebugInfo().c_str(), step.script->Talk.ChatType);
                    break;
                }

                if (step.script->Talk.Flags & SF_TALK_USE_PLAYER)
                    source = _GetScriptPlayerSourceOrTarget(source, target, step.script);
                else
                    source = _GetScriptCreatureSourceOrTarget(source, target, step.script);

                if (source)
                {
                    Unit* sourceUnit = source->ToUnit();
                    if (!sourceUnit)
                    {
                        TC_LOG_ERROR("scripts", "%s source object (%s) is not an unit, skipping.", step.script->GetDebugInfo().c_str(), source->GetGUID().ToString().c_str());
                        break;
                    }

                    switch (step.script->Talk.ChatType)
                    {
                        case CHAT_TYPE_SAY:
                            sourceUnit->Say(step.script->Talk.TextID, target);
                            break;
                        case CHAT_TYPE_YELL:
                            sourceUnit->Yell(step.script->Talk.TextID, target);
                            break;
                        case CHAT_TYPE_TEXT_EMOTE:
                        case CHAT_TYPE_BOSS_EMOTE:
                            sourceUnit->TextEmote(step.script->Talk.TextID, target, step.script->Talk.ChatType == CHAT_TYPE_BOSS_EMOTE);
                            break;
                        case CHAT_TYPE_WHISPER:
                        case CHAT_TYPE_BOSS_WHISPER:
                        {
                            Player* receiver = target ? target->ToPlayer() : nullptr;
                            if (!receiver)
                                TC_LOG_ERROR("scripts", "%s attempt to whisper to non-player unit, skipping.", step.script->GetDebugInfo().c_str());
                            else
                                sourceUnit->Whisper(step.script->Talk.TextID, receiver, step.script->Talk.ChatType == CHAT_TYPE_BOSS_WHISPER);
                            break;
                        }
                        default:
                            break;                              // must be already checked at load
                    }
                }
                break;
            }

            case SCRIPT_COMMAND_EMOTE:
                // Source or target must be Creature.
                if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script))
                {
                    if (step.script->Emote.Flags & SF_EMOTE_USE_STATE)
                        cSource->SetUInt32Value(UNIT_NPC_EMOTESTATE, step.script->Emote.EmoteID);
                    else
                        cSource->HandleEmoteCommand(step.script->Emote.EmoteID);
                }
                break;

            case SCRIPT_COMMAND_FIELD_SET:
                // Source or target must be Creature.
                if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script))
                {
                    // Validate field number.
                    if (step.script->FieldSet.FieldID <= OBJECT_FIELD_ENTRY || step.script->FieldSet.FieldID >= cSource->GetValuesCount())
                        TC_LOG_ERROR("scripts", "%s wrong field %u (max count: %u) in object (TypeId: %u, %s) specified, skipping.",
                            step.script->GetDebugInfo().c_str(), step.script->FieldSet.FieldID,
                            cSource->GetValuesCount(), cSource->GetTypeId(), cSource->GetGUID().ToString().c_str());
                    else
                        cSource->SetUInt32Value(step.script->FieldSet.FieldID, step.script->FieldSet.FieldValue);
                }
                break;

            case SCRIPT_COMMAND_MOVE_TO:
                // Source or target must be Creature.
                if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script))
                {
                    Unit* unit = (Unit*)cSource;
                    if (step.script->MoveTo.TravelTime != 0)
                    {
                        float speed = unit->GetDistance(step.script->MoveTo.DestX, step.script->MoveTo.DestY, step.script->MoveTo.DestZ) / ((float)step.script->MoveTo.TravelTime * 0.001f);
                        unit->MonsterMoveWithSpeed(step.script->MoveTo.DestX, step.script->MoveTo.DestY, step.script->MoveTo.DestZ, speed);
                    }
                    else
                        unit->NearTeleportTo(step.script->MoveTo.DestX, step.script->MoveTo.DestY, step.script->MoveTo.DestZ, unit->GetOrientation());
                }
                break;

            case SCRIPT_COMMAND_FLAG_SET:
                // Source or target must be Creature.
                if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script))
                {
                    // Validate field number.
                    if (step.script->FlagToggle.FieldID <= OBJECT_FIELD_ENTRY || step.script->FlagToggle.FieldID >= cSource->GetValuesCount())
                    {
                        TC_LOG_ERROR("scripts", "%s wrong field %u (max count: %u) in object (TypeId: %u, Entry: %u, %s) specified, skipping.",
                            step.script->GetDebugInfo().c_str(), step.script->FlagToggle.FieldID,
                            cSource->GetValuesCount(), cSource->GetTypeId(), cSource->GetEntry(), cSource->GetGUID().ToString().c_str());
                    }
                    else
                        cSource->SetFlag(step.script->FlagToggle.FieldID, step.script->FlagToggle.FieldValue);
                }
                break;

            case SCRIPT_COMMAND_FLAG_REMOVE:
                // Source or target must be Creature.
                if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script))
                {
                    // Validate field number.
                    if (step.script->FlagToggle.FieldID <= OBJECT_FIELD_ENTRY || step.script->FlagToggle.FieldID >= cSource->GetValuesCount())
                    {
                        TC_LOG_ERROR("scripts", "%s wrong field %u (max count: %u) in object (TypeId: %u, Entry: %u, %s) specified, skipping.",
                            step.script->GetDebugInfo().c_str(), step.script->FlagToggle.FieldID,
                            cSource->GetValuesCount(), cSource->GetTypeId(), cSource->GetEntry(), cSource->GetGUID().ToString().c_str());
                    }
                    else
                        cSource->RemoveFlag(step.script->FlagToggle.FieldID, step.script->FlagToggle.FieldValue);
                }
                break;

            case SCRIPT_COMMAND_TELEPORT_TO:
                if (step.script->TeleportTo.Flags & SF_TELEPORT_USE_CREATURE)
                {
                    // Source or target must be Creature.
                    if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script, true))
                        cSource->NearTeleportTo(step.script->TeleportTo.DestX, step.script->TeleportTo.DestY, step.script->TeleportTo.DestZ, step.script->TeleportTo.Orientation);
                }
                else
                {
                    // Source or target must be Player.
                    if (Player* player = _GetScriptPlayerSourceOrTarget(source, target, step.script))
                        player->TeleportTo(step.script->TeleportTo.MapID, step.script->TeleportTo.DestX, step.script->TeleportTo.DestY, step.script->TeleportTo.DestZ, step.script->TeleportTo.Orientation);
                }
                break;

            case SCRIPT_COMMAND_QUEST_EXPLORED:
            {
                if (!source)
                {
                    TC_LOG_ERROR("scripts", "%s source object is NULL.", step.script->GetDebugInfo().c_str());
                    break;
                }
                if (!target)
                {
                    TC_LOG_ERROR("scripts", "%s target object is NULL.", step.script->GetDebugInfo().c_str());
                    break;
                }

                // when script called for item spell casting then target == (unit or GO) and source is player
                WorldObject* worldObject;
                Player* player = target->ToPlayer();
                if (player)
                {
                    if (source->GetTypeId() != TYPEID_UNIT && source->GetTypeId() != TYPEID_GAMEOBJECT && source->GetTypeId() != TYPEID_PLAYER)
                    {
                        TC_LOG_ERROR("scripts", "%s source is not unit, gameobject or player (TypeId: %u, Entry: %u, %s), skipping.",
                            step.script->GetDebugInfo().c_str(), source->GetTypeId(), source->GetEntry(), source->GetGUID().ToString().c_str());
                        break;
                    }
                    worldObject = dynamic_cast<WorldObject*>(source);
                }
                else
                {
                    player = source->ToPlayer();
                    if (player)
                    {
                        if (target->GetTypeId() != TYPEID_UNIT && target->GetTypeId() != TYPEID_GAMEOBJECT && target->GetTypeId() != TYPEID_PLAYER)
                        {
                            TC_LOG_ERROR("scripts", "%s target is not unit, gameobject or player (TypeId: %u, Entry: %u, %s), skipping.",
                                step.script->GetDebugInfo().c_str(), target->GetTypeId(), target->GetEntry(), target->GetGUID().ToString().c_str());
                            break;
                        }
                        worldObject = dynamic_cast<WorldObject*>(target);
                    }
                    else
                    {
                        TC_LOG_ERROR("scripts", "%s neither source nor target is player (Entry: %u, GUID: %s; target: Entry: %u, GUID: %s), skipping.",
                            step.script->GetDebugInfo().c_str(), source->GetEntry(), source->GetGUID().ToString().c_str(),
                            target->GetEntry(), target->GetGUID().ToString().c_str());
                        break;
                    }
                }

                // quest id and flags checked at script loading
                if ((worldObject->GetTypeId() != TYPEID_UNIT || ((Unit*)worldObject)->IsAlive()) &&
                    (step.script->QuestExplored.Distance == 0 || worldObject->IsWithinDistInMap(player, float(step.script->QuestExplored.Distance))))
                    player->AreaExploredOrEventHappens(step.script->QuestExplored.QuestID);
                else
                    player->FailQuest(step.script->QuestExplored.QuestID);

                break;
            }

            case SCRIPT_COMMAND_KILL_CREDIT:
                // Source or target must be Player.
                if (Player* player = _GetScriptPlayerSourceOrTarget(source, target, step.script))
                {
                    if (step.script->KillCredit.Flags & SF_KILLCREDIT_REWARD_GROUP)
                        player->RewardPlayerAndGroupAtEvent(step.script->KillCredit.CreatureEntry, player);
                    else
                        player->KilledMonsterCredit(step.script->KillCredit.CreatureEntry);
                }
                break;

            case SCRIPT_COMMAND_RESPAWN_GAMEOBJECT:
                if (!step.script->RespawnGameobject.GOGuid)
                {
                    TC_LOG_ERROR("scripts", "%s gameobject guid (datalong) is not specified.", step.script->GetDebugInfo().c_str());
                    break;
                }

                // Source or target must be WorldObject.
                if (WorldObject* pSummoner = _GetScriptWorldObject(source, true, step.script))
                {
                    GameObject* pGO = _FindGameObject(pSummoner, step.script->RespawnGameobject.GOGuid);
                    if (!pGO)
                    {
                        TC_LOG_ERROR("scripts", "%s gameobject was not found (guid: %u).", step.script->GetDebugInfo().c_str(), step.script->RespawnGameobject.GOGuid);
                        break;
                    }

                    if (pGO->GetGoType() == GAMEOBJECT_TYPE_FISHINGNODE ||
                        pGO->GetGoType() == GAMEOBJECT_TYPE_DOOR        ||
                        pGO->GetGoType() == GAMEOBJECT_TYPE_BUTTON      ||
                        pGO->GetGoType() == GAMEOBJECT_TYPE_TRAP)
                    {
                        TC_LOG_ERROR("scripts", "%s can not be used with gameobject of type %u (guid: %u).",
                            step.script->GetDebugInfo().c_str(), uint32(pGO->GetGoType()), step.script->RespawnGameobject.GOGuid);
                        break;
                    }

                    // Check that GO is not spawned
                    if (!pGO->isSpawned())
                    {
                        int32 nTimeToDespawn = std::max(5, int32(step.script->RespawnGameobject.DespawnDelay));
                        pGO->SetLootState(GO_READY);
                        pGO->SetRespawnTime(nTimeToDespawn);

                        pGO->GetMap()->AddToMap(pGO);
                    }
                }
                break;

            case SCRIPT_COMMAND_TEMP_SUMMON_CREATURE:
            {
                // Source must be WorldObject.
                if (WorldObject* pSummoner = _GetScriptWorldObject(source, true, step.script))
                {
                    if (!step.script->TempSummonCreature.CreatureEntry)
                        TC_LOG_ERROR("scripts", "%s creature entry (datalong) is not specified.", step.script->GetDebugInfo().c_str());
                    else
                    {
                        float x = step.script->TempSummonCreature.PosX;
                        float y = step.script->TempSummonCreature.PosY;
                        float z = step.script->TempSummonCreature.PosZ;
                        float o = step.script->TempSummonCreature.Orientation;

                        if (!pSummoner->SummonCreature(step.script->TempSummonCreature.CreatureEntry, x, y, z, o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, step.script->TempSummonCreature.DespawnDelay))
                            TC_LOG_ERROR("scripts", "%s creature was not spawned (entry: %u).", step.script->GetDebugInfo().c_str(), step.script->TempSummonCreature.CreatureEntry);
                    }
                }
                break;
            }

            case SCRIPT_COMMAND_OPEN_DOOR:
            case SCRIPT_COMMAND_CLOSE_DOOR:
                _ScriptProcessDoor(source, target, step.script);
                break;

            case SCRIPT_COMMAND_ACTIVATE_OBJECT:
                // Source must be Unit.
                if (Unit* unit = _GetScriptUnit(source, true, step.script))
                {
                    // Target must be GameObject.
                    if (!target)
                    {
                        TC_LOG_ERROR("scripts", "%s target object is NULL.", step.script->GetDebugInfo().c_str());
                        break;
                    }

                    if (target->GetTypeId() != TYPEID_GAMEOBJECT)
                    {
                        TC_LOG_ERROR("scripts", "%s target object is not gameobject (TypeId: %u, Entry: %u, %s), skipping.",
                            step.script->GetDebugInfo().c_str(), target->GetTypeId(), target->GetEntry(), target->GetGUID().ToString().c_str());
                        break;
                    }

                    if (GameObject* pGO = target->ToGameObject())
                        pGO->Use(unit);
                }
                break;

            case SCRIPT_COMMAND_REMOVE_AURA:
            {
                // Source (datalong2 != 0) or target (datalong2 == 0) must be Unit.
                bool bReverse = step.script->RemoveAura.Flags & SF_REMOVEAURA_REVERSE;
                if (Unit* unit = _GetScriptUnit(bReverse ? source : target, bReverse, step.script))
                    unit->RemoveAurasDueToSpell(step.script->RemoveAura.SpellID);
                break;
            }

            case SCRIPT_COMMAND_CAST_SPELL:
            {
                /// @todo Allow gameobjects to be targets and casters
                if (!source && !target)
                {
                    TC_LOG_ERROR("scripts", "%s source and target objects are NULL.", step.script->GetDebugInfo().c_str());
                    break;
                }

                Unit* uSource = NULL;
                Unit* uTarget = NULL;
                // source/target cast spell at target/source (script->datalong2: 0: s->t 1: s->s 2: t->t 3: t->s
                switch (step.script->CastSpell.Flags)
                {
                    case SF_CASTSPELL_SOURCE_TO_TARGET: // source -> target
                        uSource = source ? source->ToUnit() : NULL;
                        uTarget = target ? target->ToUnit() : NULL;
                        break;
                    case SF_CASTSPELL_SOURCE_TO_SOURCE: // source -> source
                        uSource = source ? source->ToUnit() : NULL;
                        uTarget = uSource;
                        break;
                    case SF_CASTSPELL_TARGET_TO_TARGET: // target -> target
                        uSource = target ? target->ToUnit() : NULL;
                        uTarget = uSource;
                        break;
                    case SF_CASTSPELL_TARGET_TO_SOURCE: // target -> source
                        uSource = target ? target->ToUnit() : NULL;
                        uTarget = source ? source->ToUnit() : NULL;
                        break;
                    case SF_CASTSPELL_SEARCH_CREATURE: // source -> creature with entry
                        uSource = source ? source->ToUnit() : NULL;
                        uTarget = uSource ? uSource->FindNearestCreature(abs(step.script->CastSpell.CreatureEntry), step.script->CastSpell.SearchRadius) : NULL;
                        break;
                }

                if (!uSource || !uSource->isType(TYPEMASK_UNIT))
                {
                    TC_LOG_ERROR("scripts", "%s no source unit found for spell %u", step.script->GetDebugInfo().c_str(), step.script->CastSpell.SpellID);
                    break;
                }

                if (!uTarget || !uTarget->isType(TYPEMASK_UNIT))
                {
                    TC_LOG_ERROR("scripts", "%s no target unit found for spell %u", step.script->GetDebugInfo().c_str(), step.script->CastSpell.SpellID);
                    break;
                }

                bool triggered = (step.script->CastSpell.Flags != 4) ?
                    step.script->CastSpell.CreatureEntry & SF_CASTSPELL_TRIGGERED :
                    step.script->CastSpell.CreatureEntry < 0;
                uSource->CastSpell(uTarget, step.script->CastSpell.SpellID, triggered);
                break;
            }

            case SCRIPT_COMMAND_PLAY_SOUND:
                // Source must be WorldObject.
                if (WorldObject* object = _GetScriptWorldObject(source, true, step.script))
                {
                    // PlaySound.Flags bitmask: 0/1=anyone/target
                    Player* player = NULL;
                    if (step.script->PlaySound.Flags & SF_PLAYSOUND_TARGET_PLAYER)
                    {
                        // Target must be Player.
                        player = _GetScriptPlayer(target, false, step.script);
                        if (!target)
                            break;
                    }

                    // PlaySound.Flags bitmask: 0/2=without/with distance dependent
                    if (step.script->PlaySound.Flags & SF_PLAYSOUND_DISTANCE_SOUND)
                        object->PlayDistanceSound(step.script->PlaySound.SoundID, player);
                    else
                        object->PlayDirectSound(step.script->PlaySound.SoundID, player);
                }
                break;

            case SCRIPT_COMMAND_CREATE_ITEM:
                // Target or source must be Player.
                if (Player* pReceiver = _GetScriptPlayerSourceOrTarget(source, target, step.script))
                {
                    ItemPosCountVec dest;
                    InventoryResult msg = pReceiver->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, step.script->CreateItem.ItemEntry, step.script->CreateItem.Amount);
                    if (msg == EQUIP_ERR_OK)
                    {
                        if (Item* item = pReceiver->StoreNewItem(dest, step.script->CreateItem.ItemEntry, true))
                            pReceiver->SendNewItem(item, step.script->CreateItem.Amount, false, true);
                    }
                    else
                        pReceiver->SendEquipError(msg, NULL, NULL, step.script->CreateItem.ItemEntry);
                }
                break;

            case SCRIPT_COMMAND_DESPAWN_SELF:
                // Target or source must be Creature.
                if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script, true))
                    cSource->DespawnOrUnsummon(step.script->DespawnSelf.DespawnDelay);
                break;

            case SCRIPT_COMMAND_LOAD_PATH:
                // Source must be Unit.
                if (Unit* unit = _GetScriptUnit(source, true, step.script))
                {
                    if (!sWaypointMgr->GetPath(step.script->LoadPath.PathID))
                        TC_LOG_ERROR("scripts", "%s source object has an invalid path (%u), skipping.", step.script->GetDebugInfo().c_str(), step.script->LoadPath.PathID);
                    else
                        unit->GetMotionMaster()->MovePath(step.script->LoadPath.PathID, step.script->LoadPath.IsRepeatable != 0);
                }
                break;

            case SCRIPT_COMMAND_CALLSCRIPT_TO_UNIT:
            {
                if (!step.script->CallScript.CreatureEntry)
                {
                    TC_LOG_ERROR("scripts", "%s creature entry is not specified, skipping.", step.script->GetDebugInfo().c_str());
                    break;
                }
                if (!step.script->CallScript.ScriptID)
                {
                    TC_LOG_ERROR("scripts", "%s script id is not specified, skipping.", step.script->GetDebugInfo().c_str());
                    break;
                }

                Creature* cTarget = NULL;
                auto creatureBounds = _creatureBySpawnIdStore.equal_range(step.script->CallScript.CreatureEntry);
                if (creatureBounds.first != creatureBounds.second)
                {
                    // Prefer alive (last respawned) creature
                    auto creatureItr = std::find_if(creatureBounds.first, creatureBounds.second, [](Map::CreatureBySpawnIdContainer::value_type const& pair)
                    {
                        return pair.second->IsAlive();
                    });

                    cTarget = creatureItr != creatureBounds.second ? creatureItr->second : creatureBounds.first->second;
                }

                if (!cTarget)
                {
                    TC_LOG_ERROR("scripts", "%s target was not found (entry: %u)", step.script->GetDebugInfo().c_str(), step.script->CallScript.CreatureEntry);
                    break;
                }

                //Lets choose our ScriptMap map
                ScriptMapMap* datamap = GetScriptsMapByType(ScriptsType(step.script->CallScript.ScriptType));
                //if no scriptmap present...
                if (!datamap)
                {
                    TC_LOG_ERROR("scripts", "%s unknown scriptmap (%u) specified, skipping.", step.script->GetDebugInfo().c_str(), step.script->CallScript.ScriptType);
                    break;
                }

                // Insert script into schedule but do not start it
                ScriptsStart(*datamap, step.script->CallScript.ScriptID, cTarget, NULL);
                break;
            }

            case SCRIPT_COMMAND_KILL:
                // Source or target must be Creature.
                if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script))
                {
                    if (cSource->isDead())
                    {
                        TC_LOG_ERROR("scripts", "%s creature is already dead (Entry: %u, %s)",
                            step.script->GetDebugInfo().c_str(), cSource->GetEntry(), cSource->GetGUID().ToString().c_str());
                    }
                    else
                    {
                        cSource->setDeathState(JUST_DIED);
                        if (step.script->Kill.RemoveCorpse == 1)
                            cSource->RemoveCorpse();
                    }
                }
                break;

            case SCRIPT_COMMAND_ORIENTATION:
                // Source must be Unit.
                if (Unit* sourceUnit = _GetScriptUnit(source, true, step.script))
                {
                    if (step.script->Orientation.Flags & SF_ORIENTATION_FACE_TARGET)
                    {
                        // Target must be Unit.
                        Unit* targetUnit = _GetScriptUnit(target, false, step.script);
                        if (!targetUnit)
                            break;

                        sourceUnit->SetFacingToObject(targetUnit);
                    }
                    else
                        sourceUnit->SetFacingTo(step.script->Orientation.Orientation);
                }
                break;

            case SCRIPT_COMMAND_EQUIP:
                // Source must be Creature.
                if (Creature* cSource = _GetScriptCreature(source, true, step.script))
                    cSource->LoadEquipment(step.script->Equip.EquipmentID);
                break;

            case SCRIPT_COMMAND_MODEL:
                // Source must be Creature.
                if (Creature* cSource = _GetScriptCreature(source, true, step.script))
                    cSource->SetDisplayId(step.script->Model.ModelID);
                break;

            case SCRIPT_COMMAND_CLOSE_GOSSIP:
                // Source must be Player.
                if (Player* player = _GetScriptPlayer(source, true, step.script))
                    player->PlayerTalkClass->SendCloseGossip();
                break;

            case SCRIPT_COMMAND_PLAYMOVIE:
                // Source must be Player.
                if (Player* player = _GetScriptPlayer(source, true, step.script))
                    player->SendMovieStart(step.script->PlayMovie.MovieID);
                break;

            case SCRIPT_COMMAND_MOVEMENT:
                // Source must be Creature.
                if (Creature* cSource = _GetScriptCreature(source, true, step.script))
                {
                    if (!cSource->IsAlive())
                        return;

                    cSource->GetMotionMaster()->MovementExpired();
                    cSource->GetMotionMaster()->MoveIdle();

                    switch (step.script->Movement.MovementType)
                    {
                        case RANDOM_MOTION_TYPE:
                            cSource->GetMotionMaster()->MoveRandom((float)step.script->Movement.MovementDistance);
                            break;
                        case WAYPOINT_MOTION_TYPE:
                            cSource->GetMotionMaster()->MovePath(step.script->Movement.Path, false);
                            break;
                    }
                }
                break;

            case SCRIPT_COMMAND_PLAY_ANIMKIT:
                // Source must be Creature.
                if (Creature* cSource = _GetScriptCreature(source, true, step.script))
                    cSource->PlayOneShotAnimKitId(step.script->PlayAnimKit.AnimKitID);
                break;

            default:
                TC_LOG_ERROR("scripts", "Unknown script command %s.", step.script->GetDebugInfo().c_str());
                break;
        }

        m_scriptSchedule.erase(iter);
        iter = m_scriptSchedule.begin();
        sMapMgr->DecreaseScheduledScriptCount();
    }
}
Example #28
0
void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket& recvData)
{
    uint32 questId, reward;
    uint64 guid;
    recvData >> guid >> questId >> reward;

    if (reward >= QUEST_REWARD_CHOICES_COUNT)
    {
        sLog->outError(LOG_FILTER_NETWORKIO, "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player %s (guid %d) tried to get invalid reward (%u) (possible packet-hacking detected)", _player->GetName().c_str(), _player->GetGUIDLow(), reward);
        return;
    }

    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %u, quest = %u, reward = %u", uint32(GUID_LOPART(guid)), questId, reward);

    Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
    if (!quest)
        return;

    Object* object = _player;

    if (!quest->HasFlag(QUEST_FLAGS_AUTO_SUBMIT))
    {
        object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
        if (!object || !object->hasInvolvedQuest(questId))
            return;

        // some kind of WPE protection
        if (!_player->CanInteractWithQuestGiver(object))
            return;
    }

    if ((!_player->CanSeeStartQuest(quest) &&  _player->GetQuestStatus(questId) == QUEST_STATUS_NONE) ||
        (_player->GetQuestStatus(questId) != QUEST_STATUS_COMPLETE && !quest->IsAutoComplete()))
    {
        sLog->outError(LOG_FILTER_NETWORKIO, "Error in QUEST_STATUS_COMPLETE: player %s (guid %u) tried to complete quest %u, but is not allowed to do so (possible packet-hacking or high latency)",
                        _player->GetName().c_str(), _player->GetGUIDLow(), questId);
        return;
    }

    if (_player->CanRewardQuest(quest, reward, true))
    {
        _player->RewardQuest(quest, reward, object);

        switch (object->GetTypeId())
        {
            case TYPEID_UNIT:
            case TYPEID_PLAYER:
            {
                //For AutoSubmition was added plr case there as it almost same exclute AI script cases.
                Creature* creatureQGiver = object->ToCreature();
                if (!creatureQGiver || !(sScriptMgr->OnQuestReward(_player, creatureQGiver, quest, reward)))
                {
                    // Send next quest
                    if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))
                    {
                        if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(nextQuest, true))
                        {
                            _player->AddQuest(nextQuest, object);
                            if (_player->CanCompleteQuest(nextQuest->GetQuestId()))
                                _player->CompleteQuest(nextQuest->GetQuestId());
                        }

                        _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true);
                    }

                    if (creatureQGiver)
                        creatureQGiver->AI()->sQuestReward(_player, quest, reward);
                }
                break;
            }
            case TYPEID_GAMEOBJECT:
                if (!sScriptMgr->OnQuestReward(_player, ((GameObject*)object), quest, reward))
                {
                    // Send next quest
                    if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))
                    {
                        if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(nextQuest, true))
                        {
                            _player->AddQuest(nextQuest, object);
                            if (_player->CanCompleteQuest(nextQuest->GetQuestId()))
                                _player->CompleteQuest(nextQuest->GetQuestId());
                        }

                        _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true);
                    }

                    object->ToGameObject()->AI()->QuestReward(_player, quest, reward);
                }
                break;
            default:
                break;
        }
    }
    else
        _player->PlayerTalkClass->SendQuestGiverOfferReward(quest, guid, true);
}
Example #29
0
void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recv_data)
{
    ObjectGuid guid;
    uint32 quest;
    recv_data >> guid >> quest;

    if (!CanInteractWithQuestGiver(guid, "CMSG_QUESTGIVER_ACCEPT_QUEST"))
        return;

    DEBUG_LOG("WORLD: Received opcode CMSG_QUESTGIVER_ACCEPT_QUEST - for %s to %s, quest = %u", _player->GetGuidStr().c_str(), guid.GetString().c_str(), quest);

    Object* pObject = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_GAMEOBJECT_PLAYER_OR_ITEM);

    // no or incorrect quest giver
    if (!pObject
            || (pObject->GetTypeId() != TYPEID_PLAYER && !pObject->HasQuest(quest))
            || (pObject->GetTypeId() == TYPEID_PLAYER && !((Player*)pObject)->CanShareQuest(quest))
       )
    {
        _player->PlayerTalkClass->CloseGossip();
        _player->ClearDividerGuid();
        return;
    }

    Quest const* qInfo = sObjectMgr.GetQuestTemplate(quest);
    if (qInfo)
    {
        // prevent cheating
        if (!GetPlayer()->CanTakeQuest(qInfo, true))
        {
            _player->PlayerTalkClass->CloseGossip();
            _player->ClearDividerGuid();
            return;
        }

        if (Player* pPlayer = ObjectAccessor::FindPlayer(_player->GetDividerGuid()))
        {
            pPlayer->SendPushToPartyResponse(_player, QUEST_PARTY_MSG_ACCEPT_QUEST);
            _player->ClearDividerGuid();
        }

        if (_player->CanAddQuest(qInfo, true))
        {
            _player->AddQuest(qInfo, pObject);              // pObject (if it item) can be destroyed at call

            if (qInfo->HasQuestFlag(QUEST_FLAGS_PARTY_ACCEPT))
            {
                if (Group* pGroup = _player->GetGroup())
                {
                    for (GroupReference* itr = pGroup->GetFirstMember(); itr != nullptr; itr = itr->next())
                    {
                        Player* pPlayer = itr->getSource();

                        if (!pPlayer || pPlayer == _player) // not self
                            continue;

                        if (pPlayer->CanTakeQuest(qInfo, true))
                        {
                            pPlayer->SetDividerGuid(_player->GetObjectGuid());

                            // need confirmation that any gossip window will close
                            pPlayer->PlayerTalkClass->CloseGossip();

                            _player->SendQuestConfirmAccept(qInfo, pPlayer);
                        }
                    }
                }
            }

            if (_player->CanCompleteQuest(quest))
                _player->CompleteQuest(quest);

            _player->PlayerTalkClass->CloseGossip();

            if (qInfo->GetSrcSpell() > 0)
                _player->CastSpell(_player, qInfo->GetSrcSpell(), TRIGGERED_OLD_TRIGGERED);

            return;
        }
    }

    _player->PlayerTalkClass->CloseGossip();
}
Example #30
0
void MapMgr::ChangeObjectLocation(Object *obj)
{
    ASSERT(obj);
    ASSERT(obj->GetMapId() == _mapId);
    ASSERT(_cells);

    if(obj->GetTypeId() == TYPEID_ITEM || obj->GetTypeId() == TYPEID_CONTAINER)
        return;

    WorldPacket packet;
    UpdateData data;
    UpdateData playerData;

    Object* curObj;

    for (Object::InRangeSet::iterator iter = obj->GetInRangeSetBegin();
        iter != obj->GetInRangeSetEnd();)
    {
        curObj = *iter;
        iter++;

        if (curObj->GetDistance2dSq(obj) > UPDATE_DISTANCE*UPDATE_DISTANCE)
        {
            sLog.outDetail("Object "I64FMT" no longer in field of view of object "I64FMT".",
                obj->GetGUID(), (curObj)->GetGUID());

            if( obj->GetTypeId() == TYPEID_PLAYER )
                curObj->BuildOutOfRangeUpdateBlock( &playerData );

            obj->RemoveInRangeObject(curObj);

            if( curObj->GetTypeId() == TYPEID_PLAYER )
            {
                data.Clear();
                obj->BuildOutOfRangeUpdateBlock( &data );
                data.BuildPacket(&packet);
                ((Player*)curObj)->GetSession()->SendPacket( &packet );
            }

            curObj->RemoveInRangeObject(obj);
        }
    }

    uint32 cellX = (uint32)(obj->GetPositionX() > 0 ? abs(_minX) + obj->GetPositionX() :
    abs(_minX) - abs(obj->GetPositionX()));
    uint32 cellY = (uint32)(obj->GetPositionY() > 0 ? abs(_minY) + obj->GetPositionY() :
    abs(_minY) - abs(obj->GetPositionY()));
    cellX /= _sizeX;
    cellY /= _sizeY;

/*
    sLog.outDetail("Obj position: %f %f Cell position: %u %u",
    obj->GetPositionX(), obj->GetPositionY(), cellX, cellY);
*/

    MapCell *objCell = &(_cells[cellX][cellY]);

    if (objCell != obj->GetMapCell())
    {
        obj->GetMapCell()->RemoveObject(obj);
        objCell->AddObject(obj);
        obj->SetMapCell(objCell);
    }

    uint32 endX = cellX < _sizeX ? cellX + 1 : _sizeX;
    uint32 endY = cellY < _sizeY ? cellY + 1 : _sizeY;
    uint32 startX = cellX > 0 ? cellX - 1 : 0;
    uint32 startY = cellY > 0 ? cellY - 1 : 0;
    uint32 posX, posY;
    MapCell *cell;
    MapCell::ObjectSet::iterator iter;

    for (posX = startX; posX <= endX; posX++ )
    {
        for (posY = startY; posY <= endY; posY++ )
        {
            cell = &(_cells[posX][posY]);
            ASSERT(cell);

            for (iter = cell->Begin(); iter != cell->End(); iter++)
            {
                curObj = *iter;
                if (curObj != obj &&
                    (curObj)->GetDistance2dSq(obj) <= UPDATE_DISTANCE*UPDATE_DISTANCE &&
                    !obj->IsInRangeSet(curObj))
                {
                    // Object in range, add to set
                    if((curObj)->GetTypeId() == TYPEID_PLAYER)
                    {
                        sLog.outDetail("Creating object "I64FMT" for player "I64FMT".",
                            obj->GetGUID(), (curObj)->GetGUID());

                        data.Clear();
                        obj->BuildCreateUpdateBlockForPlayer( &data, (Player*)curObj );
                        data.BuildPacket(&packet);

                        ((Player*)curObj)->GetSession()->SendPacket( &packet );
                    }

                    (curObj)->AddInRangeObject(obj);

                    if(obj->GetTypeId() == TYPEID_PLAYER)
                    {
                        sLog.outDetail("Creating object "I64FMT" for player "I64FMT".",
                            (curObj)->GetGUID(), obj->GetGUID());

                        (curObj)->BuildCreateUpdateBlockForPlayer( &playerData, (Player*)obj );
                    }

                    obj->AddInRangeObject(curObj);
                }
            }
        }
    }

    if (obj->GetTypeId() == TYPEID_PLAYER)
    {
        playerData.BuildPacket(&packet);
        ((Player*)obj)->GetSession()->SendPacket( &packet );
    }
}