예제 #1
0
        void GossipSelectOption(Object* pObject, Player* plr, uint32 Id, uint32 IntId, const char* Code)
        {
            if(!pObject->IsCreature())
                return;
            Creature* pCreature = static_cast<Creature*>(pObject);

            GossipMenu* Menu;
            switch(IntId)
            {
                case 0: // Return to start
                    GossipHello(pCreature, plr);
                    break;

                case 1: //Horde
                    {
                        objmgr.CreateGossipMenuForPlayer(&Menu, pObject->GetGUID(), 4715, plr);
                        Menu->SendTo(plr);

                        QuestLogEntry* qle = plr->GetQuestLogForEntry(6002);
                        if(qle == NULL)
                            return;

                        if(qle->CanBeFinished())
                            return;

                        qle->Complete();
                        qle->SendQuestComplete();
                        qle->UpdatePlayerFields();

                        pCreature->Emote(EMOTE_ONESHOT_WAVE);
                        pCreature->Despawn(240000, 0);
                    }
                    break;

                case 2: //Ally
                    {
                        objmgr.CreateGossipMenuForPlayer(&Menu, pObject->GetGUID(), 4715, plr);
                        Menu->SendTo(plr);

                        QuestLogEntry* qle = plr->GetQuestLogForEntry(6001);
                        if(qle == NULL)
                            return;

                        if(qle->CanBeFinished())
                            return;

                        qle->Complete();
                        qle->SendQuestComplete();
                        qle->UpdatePlayerFields();

                        pCreature->Emote(EMOTE_ONESHOT_WAVE);
                        pCreature->Despawn(240000, 0);
                    }
                    break;

            }
        }
예제 #2
0
uint32 QuestMgr::CalcQuestStatus(Object* quest_giver, Player* plr, Quest* qst, uint8 type)
{
	QuestLogEntry* qle;

	qle = plr->GetQuestLogForEntry(qst->id);

	if (!qle)
	{
		if (type & QUESTGIVER_QUEST_START)
		{
			return PlayerMeetsReqs(plr, qst);
		}
	}
	else
	{		
		if (!qle->CanBeFinished())
		{
			return QMGR_QUEST_NOT_FINISHED;
		}
		else
		{
			if (type & QUESTGIVER_QUEST_END) 
			{
				return QMGR_QUEST_FINISHED;					
			}
			else
			{
				return QMGR_QUEST_NOT_FINISHED;
			}
		}
	}

	return QMGR_QUEST_NOT_AVAILABLE;
}
예제 #3
0
void QuestMgr::OnPlayerExploreArea(Player* plr, uint32 AreaID)
{
	uint32 i, j;
	QuestLogEntry *qle;
	for(i = 0; i < 25; ++i)
	{
		if((qle = plr->GetQuestLogInSlot(i)))
		{
			// dont waste time on quests without mobs
			if(qle->GetQuest()->count_requiredtriggers == 0)
				continue;

			for(j = 0; j < 4; ++j)
			{
				if(qle->GetQuest()->required_triggers[j] == AreaID &&
					!qle->m_explored_areas[j])
				{
					qle->SetTrigger(j);
					CALL_QUESTSCRIPT_EVENT(qle, OnExploreArea)(qle->m_explored_areas[j], plr);
					qle->UpdatePlayerFields();
					if(qle->CanBeFinished())
					{
						plr->UpdateNearbyGameObjects();
						qle->SendQuestComplete();
					}
					break;
				}
			}
		}
	}
}
예제 #4
0
void QuestMgr::OnPlayerItemPickup(Player* plr, Item* item)
{
	uint32 i, j;
	uint32 pcount;
	uint32 entry = item->GetEntry();
	QuestLogEntry *qle;
	for(i = 0; i < 25; ++i)
	{
		if((qle = plr->GetQuestLogInSlot(i)))
		{
			for(j = 0; j < qle->GetQuest()->count_required_item; ++j)
			{
				if(qle->GetQuest()->required_item[j] == entry)
				{
					pcount = plr->GetItemInterface()->GetItemCount(entry, true);
					CALL_QUESTSCRIPT_EVENT(qle, OnPlayerItemPickup)(entry, pcount, plr);
					if(pcount < qle->GetQuest()->required_itemcount[j])
					{
						WorldPacket data(8);
						data.SetOpcode(SMSG_QUESTUPDATE_ADD_ITEM);
						data << qle->GetQuest()->required_item[j] << uint32(1);
						plr->GetSession()->SendPacket(&data);
						if(qle->CanBeFinished())
						{
							plr->UpdateNearbyGameObjects();
							qle->SendQuestComplete();
						}
						break;
					}
				}
			}
		}
	}
}
예제 #5
0
	// public interface for the affray quest
	void OnPlayerEnteredCircle(Player *pPlayer)
	{
		QuestLogEntry *qle = pPlayer->GetQuestLogForEntry(QUEST_THEAFFRAY);
		if(qle->CanBeFinished() || qle->HasFailed())
			return;

		// try to start the affray
		if(Start())
		{
			qle->SetTrigger(0);
			qle->UpdatePlayerFields();
		}
	}
예제 #6
0
bool QuestCast(Player * pPlayer, SpellEntry * pSpell, Spell * spell)
{
    /* Runeforging: Preparation for Battle spell script */
    if( pSpell->Id == 53341 || pSpell->Id == 53343 )
    {
        QuestLogEntry * qle = pPlayer->GetQuestLogForEntry(12842);

        // if can be finished, it means we've already done this
        if( qle == NULL || qle->CanBeFinished() )
            return true;

        // do it blizzlike way :P
        // since hook event is caled when player start casting the spell, we need to make quest finished after 5 seconds
        sEventMgr.AddEvent(TO_UNIT(pPlayer), &Unit::EventCastSpell, TO_UNIT(pPlayer), dbcSpell.LookupEntry(54586), EVENT_CREATURE_UPDATE, 5000, 1, EVENT_FLAG_DO_NOT_EXECUTE_IN_WORLD_CONTEXT);

        return true;
    }

    return true;
}
예제 #7
0
bool QuestMgr::OnGameObjectActivate(Player *plr, GameObject *go)
{
	uint32 i, j;
	QuestLogEntry *qle;
	uint32 entry = go->GetEntry();

	for(i = 0; i < 25; ++i)
	{
		if((qle = plr->GetQuestLogInSlot(i)))
		{
			// dont waste time on quests without mobs
			if(qle->GetQuest()->count_required_mob == 0)
				continue;

			for(j = 0; j < 4; ++j)
			{
				if(qle->GetQuest()->required_mob[j] == entry &&
					qle->GetQuest()->required_mobtype[j] == QUEST_MOB_TYPE_GAMEOBJECT &&
					qle->m_mobcount[j] < qle->GetQuest()->required_mobcount[j])
				{
					// add another kill.
					// (auto-dirtys it)
					qle->SetMobCount(j, qle->m_mobcount[j] + 1);
					qle->SendUpdateAddKill(j);
					CALL_QUESTSCRIPT_EVENT(qle, OnGameObjectActivate)(entry, plr);

					if(qle->CanBeFinished())
						qle->SendQuestComplete();

					qle->UpdatePlayerFields();
					return true;
				}
			}
		}
	}
	return false;
}
예제 #8
0
void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket& recvPacket)
{
	CHECK_INWORLD_RETURN;

	DEBUG_LOG( "WORLD"," Received CMSG_QUESTGIVER_CHOOSE_REWARD." );

	uint64 guid;
	uint32 quest_id;
	uint32 reward_slot;

	recvPacket >> guid;
	recvPacket >> quest_id;
	recvPacket >> reward_slot;

	if( reward_slot >= 6 )
		return;

	bool bValid = false;
	Quest *qst = NULL;
	Object* qst_giver = NULLOBJ;
	uint32 guidtype = GET_TYPE_FROM_GUID(guid);

	if(guidtype == HIGHGUID_TYPE_CREATURE)
	{
		Creature* quest_giver = _player->GetMapMgr()->GetCreature(GET_LOWGUID_PART(guid));
		if(quest_giver)
			qst_giver = quest_giver;
		else
			return;
		bValid = quest_giver->isQuestGiver();
		if(bValid)
			qst = QuestStorage.LookupEntry(quest_id);
	}
	else if(guidtype==HIGHGUID_TYPE_GAMEOBJECT)
	{
		GameObject* quest_giver = _player->GetMapMgr()->GetGameObject(GET_LOWGUID_PART(guid));
		if(quest_giver)
			qst_giver = TO_OBJECT(quest_giver);
		else
			return;
		//bValid = quest_giver->isQuestGiver();
		//if(bValid)
		bValid = true;
		qst = QuestStorage.LookupEntry(quest_id);
	}

	if (!qst_giver)
	{
		OUT_DEBUG("WORLD: Invalid questgiver GUID.");
		return;
	}

	if (!bValid || qst == NULL)
	{
		OUT_DEBUG("WORLD: Creature is not a questgiver.");
		return;
	}

	//FIXME: Some Quest givers talk in the end of the quest.
	//   qst_giver->SendChatMessage(CHAT_MSG_MONSTER_SAY,LANG_UNIVERSAL,qst->GetQuestEndMessage().c_str());
	QuestLogEntry *qle = _player->GetQuestLogForEntry(quest_id);

    if (!qle && !qst->is_repeatable)
	{
		OUT_DEBUG("WORLD: QuestLogEntry not found.");
		return;
	}

	if (qle && !qle->CanBeFinished())
	{
		OUT_DEBUG("WORLD: Quest not finished.");
		return;
	}

	//check for room in inventory for all items
	if(!sQuestMgr.CanStoreReward(_player,qst,reward_slot))
	{
		sQuestMgr.SendQuestFailed(FAILED_REASON_INV_FULL, qst, _player);
		return;
	}

	sQuestMgr.OnQuestFinished(_player, qst, qst_giver, reward_slot);
	//if(qst_giver->GetTypeId() == TYPEID_UNIT) qst->LUA_SendEvent(TO_CREATURE( qst_giver ),GetPlayer(),ON_QUEST_COMPLETEQUEST);

	if(qst->next_quest_id)
	{
        WorldPacket data(12);
		data.Initialize(CMSG_QUESTGIVER_QUERY_QUEST);
		data << guid;
		data << qst->next_quest_id;
		HandleQuestGiverQueryQuestOpcode(data);
	}
	_player->SaveToDB(false);
}
예제 #9
0
void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket& recvPacket)
{
    sLog.outDebug( "WORLD: Recieved CMSG_QUESTGIVER_CHOOSE_REWARD." );

    WorldPacket data;
    uint64 guid;
    uint32 quest_id;
    uint32 reward_slot;

    recvPacket >> guid;
    recvPacket >> quest_id;
    recvPacket >> reward_slot;

    bool bValid = false;
    Quest *qst = NULL;
    Object *qst_giver = NULL;

    if(UINT32_LOPART(GUID_HIPART(guid))==HIGHGUID_UNIT)
    {
        Creature *quest_giver = sObjHolder.GetObject<Creature>(guid);
        if(quest_giver)
            qst_giver = (Object*)quest_giver;
        else
            return;
        bValid = quest_giver->isQuestGiver();
        if(bValid)
            qst = sQuestMgr.FindQuest(quest_id);
    } 
    else if(UINT32_LOPART(GUID_HIPART(guid))==HIGHGUID_GAMEOBJECT)
    {
        GameObject *quest_giver = sObjHolder.GetObject<GameObject>(guid);
        if(quest_giver)
            qst_giver = (Object*)quest_giver;
        else
            return;
        bValid = quest_giver->isQuestGiver();
        if(bValid)
            qst = sQuestMgr.FindQuest(quest_id);
    }

    if (!qst_giver)
    {
        sLog.outDebug("WORLD: Invalid questgiver GUID.");
        return;
    }

    if (!bValid || qst == NULL)
    {
        sLog.outDebug("WORLD: Creature is not a questgiver.");
        return;
    }

    //FIXME: Some Quest givers talk in the end of the quest.
    //   qst_giver->SendChatMessage(CHAT_MSG_MONSTER_SAY,LANG_UNIVERSAL,qst->GetQuestEndMessage().c_str());
    QuestLogEntry *qle = _player->GetQuestLogForEntry(quest_id);

    if (!qle)
    {
        sLog.outDebug("WORLD: QuestLogEntry not found.");
        return;
    }

    if (!qle->CanBeFinished())
    {
        sLog.outDebug("WORLD: Quest not finished.");
        return;
    }

    // remove icon
    if(qst_giver->GetTypeId() == TYPEID_UNIT)
    {
        qst_giver->BuildFieldUpdatePacket(GetPlayer(), UNIT_DYNAMIC_FLAGS, qst_giver->GetUInt32Value(UNIT_DYNAMIC_FLAGS));
    }

    //check for room in inventory for all items
    
    sQuestMgr.OnQuestFinished(GetPlayer(), qst, qst_giver, reward_slot);
    //if(qst_giver->GetTypeId() == TYPEID_UNIT) qst->LUA_SendEvent(((Creature*)qst_giver),GetPlayer(),ON_QUEST_COMPLETEQUEST);

    if(qst->next_quest_id)
    {
        data.Initialize(CMSG_QUESTGIVER_QUERY_QUEST);
        data << guid;
        data << qst->next_quest_id;
        HandleQuestGiverQueryQuestOpcode(data);
    }
    if(qst->time > 0)
    {
        GetPlayer()->timed_quest_slot = 0;
    }
}
예제 #10
0
void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket& recvPacket)
{
    if(!_player) return;
	if(!_player->IsInWorld()) return;
	sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD." );

	uint64 guid;
	uint32 quest_id;
	uint32 reward_slot;

	recvPacket >> guid;
	recvPacket >> quest_id;
	recvPacket >> reward_slot;

	if( reward_slot >= 6 )
		return;

	bool bValid = false;
	Quest *qst = NULL;
	Object *qst_giver = NULL;
	uint32 guidtype = GET_TYPE_FROM_GUID(guid);

	if(guidtype==HIGHGUID_TYPE_UNIT)
	{
		Creature *quest_giver = _player->GetMapMgr()->GetCreature(GET_LOWGUID_PART(guid));
		if(quest_giver)
			qst_giver = (Object*)quest_giver;
		else
			return;
		bValid = quest_giver->isQuestGiver();
		if(bValid)
			qst = QuestStorage.LookupEntry(quest_id);
	} 
	else if(guidtype==HIGHGUID_TYPE_GAMEOBJECT)
	{
		GameObject *quest_giver = _player->GetMapMgr()->GetGameObject(GET_LOWGUID_PART(guid));
		if(quest_giver)
			qst_giver = (Object*)quest_giver;
		else
			return;
		//bValid = quest_giver->isQuestGiver();
		//if(bValid)
		bValid = true;
			qst = QuestStorage.LookupEntry(quest_id);
	}

	if (!qst_giver)
	{
		sLog.outDebug("WORLD: Invalid questgiver GUID.");
		return;
	}

	if (!bValid || qst == NULL)
	{
		sLog.outDebug("WORLD: Creature is not a questgiver.");
		return;
	}

	//FIXME: Some Quest givers talk in the end of the quest.
	//   qst_giver->SendChatMessage(CHAT_MSG_MONSTER_SAY,LANG_UNIVERSAL,qst->GetQuestEndMessage().c_str());
	QuestLogEntry *qle = _player->GetQuestLogForEntry(quest_id);

    if (!qle && !qst->is_repeatable)
	{
		sLog.outDebug("WORLD: QuestLogEntry not found.");
		return;
	}

	if (qle && !qle->CanBeFinished())
	{
		sLog.outDebug("WORLD: Quest not finished.");
		return;
	}

	// remove icon
	/*if(qst_giver->GetTypeId() == TYPEID_UNIT)
	{
		qst_giver->BuildFieldUpdatePacket(GetPlayer(), UNIT_DYNAMIC_FLAGS, qst_giver->GetUInt32Value(UNIT_DYNAMIC_FLAGS));
	}*/

    //check for room in inventory for all items
	if(!sQuestMgr.CanStoreReward(GetPlayer(),qst,reward_slot))
    {
        sQuestMgr.SendQuestFailed(FAILED_REASON_INV_FULL, qst, GetPlayer());
        return;
    }

	
	sQuestMgr.OnQuestFinished(GetPlayer(), qst, qst_giver, reward_slot);
	//if(qst_giver->GetTypeId() == TYPEID_UNIT) qst->LUA_SendEvent(static_cast< Creature* >( qst_giver ),GetPlayer(),ON_QUEST_COMPLETEQUEST);

	if(qst->next_quest_id)
	{
        WorldPacket data(12);
		data.Initialize(CMSG_QUESTGIVER_QUERY_QUEST);
		data << guid;
		data << qst->next_quest_id;
		HandleQuestGiverQueryQuestOpcode(data);
	}
	if(qst->time > 0)
	{
		GetPlayer()->timed_quest_slot = 0;
	}
}
예제 #11
0
void QuestMgr::OnPlayerKill(Player* plr, Creature* victim)
{
	if(!plr)
		return;

	uint32 i, j;
	uint32 entry = victim->GetEntry();
	QuestLogEntry *qle;
	for(i = 0; i < 25; ++i)
	{
		if((qle = plr->GetQuestLogInSlot(i)))
		{
			// dont waste time on quests without mobs
			if(qle->GetQuest()->count_required_mob == 0)
				continue;

			for(j = 0; j < 4; ++j)
			{
				if(qle->GetQuest()->required_mob[j] == entry &&
					qle->GetQuest()->required_mobtype[j] == QUEST_MOB_TYPE_CREATURE &&
					qle->m_mobcount[j] < qle->GetQuest()->required_mobcount[j])
				{
					// add another kill.
					// (auto-dirtys it)
					qle->SetMobCount(j, qle->m_mobcount[j] + 1);
					qle->SendUpdateAddKill(j);
					CALL_QUESTSCRIPT_EVENT(qle, OnCreatureKill)(entry, plr);
					qle->UpdatePlayerFields();
					break;
				}
			}
		}
	}
	
	// Shared kills
	Player *gplr = NULL;

	if(plr->InGroup())
	{
		if(Group* pGroup = plr->GetGroup())
		{
			if(pGroup->GetGroupType() != GROUP_TYPE_PARTY) return;  // Raid's don't get shared kills.

			GroupMembersSet::iterator gitr;
			for(uint32 k = 0; k < pGroup->GetSubGroupCount(); k++)
			{
				for(gitr = pGroup->GetSubGroup(k)->GetGroupMembersBegin(); gitr != pGroup->GetSubGroup(k)->GetGroupMembersEnd(); ++gitr)
				{
					gplr = (*gitr);
					if(gplr && gplr != plr) // dont double kills
					{
						for(i = 0; i < 20; ++i)
						{
							if((qle = gplr->GetQuestLogInSlot(i)))
							{
								// dont waste time on quests without mobs
								if(qle->GetQuest()->count_required_mob == 0)
									continue;

								for(j = 0; j < 4; ++j)
								{
									if(qle->GetQuest()->required_mob[j] == entry &&
										qle->GetQuest()->required_mobtype[j] == QUEST_MOB_TYPE_CREATURE &&
										qle->m_mobcount[j] < qle->GetQuest()->required_mobcount[j])
									{
										// add another kill.
										// (auto-dirtys it)
										qle->SetMobCount(j, qle->m_mobcount[j] + 1);
										qle->SendUpdateAddKill(j);
										CALL_QUESTSCRIPT_EVENT(qle, OnCreatureKill)(entry, plr);
										qle->UpdatePlayerFields();

										// lua stuff
										//QUESTLUA_SendEvent(qst, victim, plr, ON_QUEST_KILLMOB, qle->m_mobcount[j]);
										if(qle->CanBeFinished())
											qle->SendQuestComplete();
										break;
									}
								}
							}
						}
					}
				}
			}
		}
	}
}