Exemple #1
0
bool QuestLogEntry::LoadFromDB(Field *fields)
{
    // playerguid,questid,timeleft,area0,area1,area2,area3,kill0,kill1,kill2,kill3
    int f = 3;
    ASSERT(m_plr && m_quest);
    m_time_left = fields[f].GetUInt32();
    f++;
    for(int i = 0; i < 4; ++i)
    {
        m_explored_areas[i] = fields[f].GetUInt32();
        f++;
        CALL_QUESTSCRIPT_EVENT(this, OnExploreArea)(m_explored_areas[i], m_plr, this);
    }

    for(int i = 0; i < 4; ++i)
    {
        m_mobcount[i] = fields[f].GetUInt32();
        f++;
        if(GetQuest()->required_mobtype[i] == QUEST_MOB_TYPE_CREATURE)
            CALL_QUESTSCRIPT_EVENT(this, OnCreatureKill)(GetQuest()->required_mob[i], m_plr, this);
        else
            CALL_QUESTSCRIPT_EVENT(this, OnGameObjectActivate)(GetQuest()->required_mob[i], m_plr, this);
    }
    mDirty = false;
    return true;
}
Exemple #2
0
bool QuestLogEntry::LoadFromDB(Field* fields)
{
    // playerguid,questid,timeleft,area0,area1,area2,area3,kill0,kill1,kill2,kill3
    int f = 3;
    ARCEMU_ASSERT(m_plr && m_quest);
    expirytime = fields[f].GetUInt32();
    f++;
    /*for (int i = 0; i < 4; ++i)
    {
        m_explored_areas[i] = fields[f].GetUInt32();
        f++;
        CALL_QUESTSCRIPT_EVENT(this, OnExploreArea)(m_explored_areas[i], m_plr, this);
    }*/

    for (int i = 0; i < 4; ++i)
    {
        m_mobcount[i] = fields[f].GetUInt32();
        f++;
        if (GetQuest()->m_reqMobType[i] == QUEST_MOB_TYPE_CREATURE)
        {
            CALL_QUESTSCRIPT_EVENT(this, OnCreatureKill)(GetQuest()->ReqCreatureOrGOId[i], m_plr, this);
        }
        else
        {
            CALL_QUESTSCRIPT_EVENT(this, OnGameObjectActivate)(GetQuest()->ReqCreatureOrGOId[i], m_plr, this);
        }
    }

    completed = fields[f].GetUInt32();

    mDirty = false;
    return true;
}
Exemple #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;
				}
			}
		}
	}
}
Exemple #4
0
void WorldSession::HandleQuestlogRemoveQuestOpcode(WorldPacket& recvPacket)
{
	sLog.outDebug( "WORLD: Received CMSG_QUESTLOG_REMOVE_QUEST" );
    if(!_player) return;
	if(!_player->IsInWorld()) return;

	uint8 quest_slot;
	recvPacket >> quest_slot;
	if(quest_slot >= 25)
		return;

	QuestLogEntry *qEntry = GetPlayer()->GetQuestLogInSlot(quest_slot);
	if (!qEntry)
	{
		sLog.outDebug("WORLD: No quest in slot %d.", quest_slot);
		return;		
	}
	Quest *qPtr = qEntry->GetQuest();
	CALL_QUESTSCRIPT_EVENT(qEntry, OnQuestCancel)(GetPlayer());
	qEntry->Finish();

	// Remove all items given by the questgiver at the beginning
	for(uint32 i = 0; i < 4; ++i)
	{
		if(qPtr->receive_items[i])
			GetPlayer()->GetItemInterface()->RemoveItemAmt( qPtr->receive_items[i], 1 );
	}
	if(qPtr->time > 0)
	{
		GetPlayer()->timed_quest_slot = 0;
	}
	GetPlayer()->UpdateNearbyGameObjects();

	sHookInterface.OnQuestCancelled(_player, qPtr);
}
Exemple #5
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;
					}
				}
			}
		}
	}
}
Exemple #6
0
void WorldSession::HandleQuestlogRemoveQuestOpcode(WorldPacket& recvPacket)
{
	CHECK_INWORLD_RETURN;

	DEBUG_LOG( "QuestHandler","Received CMSG_QUESTLOG_REMOVE_QUEST" );

	uint8 quest_slot;
	recvPacket >> quest_slot;
	if(quest_slot >= 25)
		return;

	QuestLogEntry *qEntry = _player->GetQuestLogInSlot(quest_slot);
	if (!qEntry)
	{
		DEBUG_LOG("QuestHandler","No quest in slot %d.", quest_slot);
		return;
	}
	Quest *qPtr = qEntry->GetQuest();

	if (!qPtr)
	{
		DEBUG_LOG("QuestHandler","Quest %u does not exist in database", qPtr->id);
		return;
	}

	CALL_QUESTSCRIPT_EVENT(qPtr->id, OnQuestCancel)(_player);

	qEntry->Finish();

	// Remove all items given by the questgiver at the beginning
	for(uint32 i = 0; i < 4; i++)
	{
		if(qPtr->receive_items[i])
			_player->GetItemInterface()->RemoveItemAmt( qPtr->receive_items[i], 1 );
	}

	// Remove source item
	if(qPtr->srcitem)
			_player->GetItemInterface()->RemoveItemAmt( qPtr->srcitem, 1 );

	// Reset timed quests, remove timed event
	if(qPtr->time > 0)
	{
		if (sEventMgr.HasEvent(_player,EVENT_TIMED_QUEST_EXPIRE))
			sEventMgr.RemoveEvents(_player, EVENT_TIMED_QUEST_EXPIRE); 
	}

	if(qPtr->start_phase != 0)
	{
		if(_player->GetPhaseMask() == (int32)qPtr->start_phase)
			_player->SetPhaseMask(_player->LastPhase, true);
	}

	_player->UpdateNearbyGameObjects();

	sHookInterface.OnQuestCancelled(_player, qPtr);

	_player->SaveToDB(false);
}
Exemple #7
0
void QuestLogEntry::SendQuestComplete()
{
	WorldPacket data(4);
	data.SetOpcode(SMSG_QUESTUPDATE_COMPLETE);
	data << m_quest->id;
	m_plr->GetSession()->SendPacket(&data);
	CALL_QUESTSCRIPT_EVENT(this, OnQuestComplete)(m_plr, this);
}
string RemoveQuestFromPlayer(Player* plr, Quest *qst)
{
	std::string recout = "|cff00ff00";
	bool has = false;

	if ( plr->HasFinishedQuest(qst->id) )
	{
		if( plr->m_finishedQuests.find(qst->id) != plr->m_finishedQuests.end())
		{
			plr->m_finishedQuests.erase(qst->id);
			recout += "Quest removed from finished quests history.\n\n";
			has = true;
		}
	}

	if ( plr->HasFinishedDailyQuest(qst->id) )
	{
		if( plr->m_finishedDailyQuests.find(qst->id) != plr->m_finishedDailyQuests.end())
		{
			plr->m_finishedDailyQuests.erase(qst->id);
			recout += "Quest removed from finished dailies history.\n\n";
			has = true;
		}
	}

	if (plr->HasQuests())
	{
		QuestLogEntry * qLogEntry = plr->GetQuestLogForEntry(qst->id);
		if (qLogEntry)
		{	
			CALL_QUESTSCRIPT_EVENT(qLogEntry, OnQuestCancel)(plr);
			qLogEntry->Finish();

			// Remove all items given by the questgiver at the beginning
			for(uint32 i = 0; i < 4; ++i)
			{
				if(qst->receive_items[i])
					plr->GetItemInterface()->RemoveItemAmt(qst->receive_items[i], 1 );
			}
			plr->UpdateNearbyGameObjects();
		}
		recout += "Quest removed from current questlog.";
		has = true;
	}
	
	if(!has)
		recout += "Quest not found on player.";

	recout += "\n\n";

	return recout;

}
Exemple #9
0
void WorldSession::HandleQuestlogRemoveQuestOpcode(WorldPacket & recvPacket)
{
	CHECK_INWORLD_RETURN

	LOG_DEBUG("WORLD: Received CMSG_QUESTLOG_REMOVE_QUEST");

	uint8 quest_slot;
	recvPacket >> quest_slot;
	if(quest_slot >= 25)
		return;

	QuestLogEntry* qEntry = GetPlayer()->GetQuestLogInSlot(quest_slot);
	if(!qEntry)
	{
		LOG_DEBUG("WORLD: No quest in slot %d.", quest_slot);
		return;
	}
	Quest* qPtr = qEntry->GetQuest();
	CALL_QUESTSCRIPT_EVENT(qEntry, OnQuestCancel)(GetPlayer());
	qEntry->Finish();

	// Remove all items given by the questgiver at the beginning
	for(uint32 i = 0; i < 4; ++i)
	{
		if(qPtr->receive_items[i])
			GetPlayer()->GetItemInterface()->RemoveItemAmt(qPtr->receive_items[i], 1);
	}

	if( qPtr->srcitem && qPtr->srcitem != qPtr->receive_items[0] )
	{
		ItemPrototype *itemProto = ::ItemPrototypeStorage.LookupEntry( qPtr->srcitem );
		if( itemProto != NULL )
			if( itemProto->QuestId != qPtr->id )
				_player->GetItemInterface()->RemoveItemAmt(qPtr->srcitem, qPtr->srcitemcount ? qPtr->srcitemcount : 1);
	}
	//remove all quest items (but not trade goods) collected and required only by this quest
	for(uint32 i = 0; i < MAX_REQUIRED_QUEST_ITEM; ++i)
	{
		if(qPtr->required_item[i] != 0)
		{
			ItemPrototype* itemProto = ItemPrototypeStorage.LookupEntry(qPtr->required_item[i]);
			if(itemProto != NULL && itemProto->Class == ITEM_CLASS_QUEST)
				GetPlayer()->GetItemInterface()->RemoveItemAmt(qPtr->required_item[i], qPtr->required_itemcount[i]);
		}
	}

	GetPlayer()->UpdateNearbyGameObjects();

	sHookInterface.OnQuestCancelled(_player, qPtr);
}
Exemple #10
0
void QuestLogEntry::Init(Quest* quest, Player* plr, uint32 slot)
{
	ARCEMU_ASSERT(quest != NULL);
	ARCEMU_ASSERT(plr != NULL);

	m_quest = quest;
	m_plr = plr;
	m_slot = slot;

	iscastquest = false;
	isemotequest = false;
	for(uint32 i = 0; i < 4; ++i)
	{
		if(quest->required_spell[i] != 0)
		{
			iscastquest = true;
			if(!plr->HasQuestSpell(quest->required_spell[i]))
				plr->quest_spells.insert(quest->required_spell[i]);
		}
		else if(quest->required_emote[i] != 0)
		{
			isemotequest = true;
		}
		if(quest->required_mob[i] != 0)
		{
			if(!plr->HasQuestMob(quest->required_mob[i]))
				plr->quest_mobs.insert(quest->required_mob[i]);
		}
	}


	// update slot
	plr->SetQuestLogSlot(this, slot);

	mDirty = true;

	memset(m_mobcount, 0, 4 * 4);
	memset(m_explored_areas, 0, 4 * 4);

	if( m_quest->time > 0 )
		expirytime = UNIXTIME + m_quest->time / 1000;
	else
		expirytime = 0;

	if(!plr->GetSession()->m_loggingInPlayer)  //quest script should not be called on login
		CALL_QUESTSCRIPT_EVENT(this, OnQuestStart)(plr, this);
}
Exemple #11
0
void QuestLogEntry::Init(Quest* quest, Player* plr, uint32 slot)
{
	ASSERT(quest);
	ASSERT(plr);

	m_quest = quest;
	m_plr = plr;
	m_slot = slot;

	iscastquest = false;
	for (uint32 i=0;i<4;++i)
	{
		if (quest->required_spell[i]!=0)
		{
			iscastquest=true;
			if (!plr->HasQuestSpell(quest->required_spell[i]))
				plr->quest_spells.insert(quest->required_spell[i]);
		}
		else if (quest->required_mob[i]!=0)
		{
			if (!plr->HasQuestMob(quest->required_mob[i]))
				plr->quest_mobs.insert(quest->required_mob[i]);
		}
	}


	// update slot
	plr->SetQuestLogSlot(this, slot);
	
	mDirty = true;

	memset(m_mobcount, 0, 4*4);
	memset(m_explored_areas, 0, 4*4);

	if(m_quest->time)
		m_time_left = m_quest->time * 1000;
	else
		m_time_left = 0;

	CALL_QUESTSCRIPT_EVENT(this, OnQuestStart)(plr, this);
}
Exemple #12
0
string RemoveQuestFromPlayer(Player *plr, Quest *qst)
{
	std::string recout = "|cff00ff00";

	if (plr->HasQuests())
	{
		if (plr->HasFinishedQuest(qst->id))
			recout += "Player has already completed that quest.\n\n";
		else
		{
			QuestLogEntry * qLogEntry = plr->GetQuestLogForEntry(qst->id);
			if (qLogEntry)
			{	
				CALL_QUESTSCRIPT_EVENT(qLogEntry, OnQuestCancel)(plr);
				qLogEntry->Finish();

				// Remove all items given by the questgiver at the beginning
				for(uint32 i = 0; i < 4; ++i)
				{
					if(qst->receive_items[i])
						plr->GetItemInterface()->RemoveItemAmt(qst->receive_items[i], 1 );
				}
				if(qst->time > 0)
					plr->timed_quest_slot = 0;

				plr->UpdateNearbyGameObjects();
			}
			else
				recout += "No quest log entry found for that player.";
		}
	}
	else
	{
		recout += "Player has no quests to remove.";
	}

	recout += "\n\n";

	return recout;
}
Exemple #13
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;
}
Exemple #14
0
void WorldSession::HandleQuestgiverAcceptQuestOpcode( WorldPacket & recv_data )
{
	DEBUG_LOG( "WORLD"," Received CMSG_QUESTGIVER_ACCEPT_QUEST" );
	CHECK_INWORLD_RETURN;

	//WorldPacket data;

	uint64 guid;
	uint32 quest_id;
	uint32 unk;

	recv_data >> guid;
	recv_data >> quest_id;
	recv_data >> unk;

	bool bValid = false;
	bool hasquest = true;
	bool bSkipLevelCheck = 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 = TO_OBJECT(quest_giver);
		else
			return;
		bValid = quest_giver->isQuestGiver();
		hasquest = quest_giver->HasQuest(quest_id, 1);
		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);
	}
	else if(guidtype==HIGHGUID_TYPE_ITEM)
	{
		Item* quest_giver = GetPlayer()->GetItemInterface()->GetItemByGUID(guid);
		if(quest_giver)
			qst_giver = TO_OBJECT(quest_giver);
		else
			return;
		bValid = true;
		bSkipLevelCheck=true;
		qst = QuestStorage.LookupEntry(quest_id);
		if( qst && qst->id != quest_giver->GetProto()->QuestId )
			return;
	}
	else if(guidtype==HIGHGUID_TYPE_PLAYER)
	{
		Player* quest_giver = _player->GetMapMgr()->GetPlayer((uint32)guid);
		if(quest_giver)
			qst_giver = TO_OBJECT(quest_giver);
		else
			return;
		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;
	}

	if( _player->GetQuestLogForEntry( qst->id ) )
		return;

	if( qst_giver->GetTypeId() == TYPEID_UNIT && TO_CREATURE( qst_giver )->m_escorter != NULL )
	{
		SystemMessage("You cannot accept this quest at this time.");
		return;
	}

	// Check the player hasn't already taken this quest, or
	// it isn't available.
	uint32 status = sQuestMgr.CalcQuestStatus(_player,qst,3, bSkipLevelCheck);

	if((!sQuestMgr.IsQuestRepeatable(qst) && _player->HasFinishedQuest(qst->id)) || ( status != QMGR_QUEST_AVAILABLE && status != QMGR_QUEST_REPEATABLE && status != QMGR_QUEST_CHAT )
		|| !hasquest)
	{
		// We've got a hacker. Disconnect them.
		//sWorld.LogCheater(this, "tried to accept incompatible quest %u from %u.", qst->id, qst_giver->GetEntry());
		//Disconnect();
		return;
	}

	int32 log_slot = _player->GetOpenQuestSlot();

	if (log_slot == -1)
	{
		sQuestMgr.SendQuestLogFull(GetPlayer());
		return;
	}

	//FIXME
	/*if(Player Has Timed quest && qst->HasFlag(QUEST_FLAG_TIMED))
		sQuestMgr.SendQuestInvalid(INVALID_REASON_HAVE_TIMED_QUEST);*/

	if(qst->count_receiveitems || qst->srcitem)
	{
		uint32 slots_required = qst->count_receiveitems;

		if(_player->GetItemInterface()->CalculateFreeSlots(NULL) < slots_required)
		{
			_player->GetItemInterface()->BuildInventoryChangeError(NULLITEM, NULLITEM, INV_ERR_BAG_FULL);
			sQuestMgr.SendQuestFailed(FAILED_REASON_INV_FULL, qst, _player);
			return;
		}
	}

/*	if(qst_giver->GetTypeId() == TYPEID_UNIT && !ScriptSystem->OnQuestRequireEvent(qst, TO_CREATURE( qst_giver ), _player, QUEST_EVENT_CAN_ACCEPT))
		return;*/

	QuestLogEntry *qle = new QuestLogEntry();
	qle->Init(qst, _player, log_slot);
	qle->UpdatePlayerFields();

	// If the quest should give any items on begin, give them the items.
	for(uint32 i = 0; i < 4; i++)
	{
		if(qst->receive_items[i])
		{
			Item* item = objmgr.CreateItem( qst->receive_items[i], GetPlayer());
			if(item)
			{
				if(!_player->GetItemInterface()->AddItemToFreeSlot(item))
				{
					item->DeleteMe();
					item = NULLITEM;
				}
				else
					SendItemPushResult(item, false, true, false, true,
					_player->GetItemInterface()->LastSearchItemBagSlot(), _player->GetItemInterface()->LastSearchItemSlot(),
					1);
			}
		}
	}

	if(qst->srcitem && qst->srcitem != qst->receive_items[0])
	{
		Item* item = objmgr.CreateItem( qst->srcitem, _player );
		if(item)
		{
			item->SetUInt32Value(ITEM_FIELD_STACK_COUNT, qst->srcitemcount ? qst->srcitemcount : 1);
			if(!_player->GetItemInterface()->AddItemToFreeSlot(item))
			{
				item->DeleteMe();
				item = NULLITEM;
			}
		}
	}

	if(qst->count_required_item || qst_giver->GetTypeId() == TYPEID_GAMEOBJECT)	// gameobject quests deactivate
		_player->UpdateNearbyGameObjects();

	CALL_QUESTSCRIPT_EVENT(qst->id, OnQuestStart)(_player, qle);

	sQuestMgr.OnQuestAccepted(_player,qst,qst_giver);

	if(qst->start_phase != 0 )
		_player->SetPhaseMask(qst->start_phase, true);

	sHookInterface.OnQuestAccept(_player, qst, qst_giver);
}
bool ChatHandler::HandleQuestStartCommand(const char * args, WorldSession * m_session)
{
	if(!*args) return false;

	Player* plr = getSelectedChar(m_session, true);
	if(!plr)
	{
		plr = m_session->GetPlayer();
		SystemMessage(m_session, "Auto-targeting self.");
	}

	uint32 quest_id = atol(args);
	std::string recout = "|cff00ff00";

	Quest * qst = QuestStorage.LookupEntry(quest_id);
	if(qst)
	{
		if (plr->HasFinishedQuest(quest_id) || plr->HasFinishedDailyQuest(quest_id))
			recout += "Player has already completed that quest.";
		else
		{
			QuestLogEntry * IsPlrOnQuest = plr->GetQuestLogForEntry(quest_id);
			if (IsPlrOnQuest)
				recout += "Player is currently on that quest.";
			else
			{
				int32 open_slot = plr->GetOpenQuestSlot();

				if (open_slot == -1)
				{
					sQuestMgr.SendQuestLogFull(plr);
					recout += "Player's quest log is full.";
				}
				else
				{
					QuestLogEntry *qle = new QuestLogEntry();
					qle->Init(qst, plr, (uint32)open_slot);
					qle->UpdatePlayerFields();

					CALL_QUESTSCRIPT_EVENT(qle, OnQuestStart)(plr, qle);
		
					// If the quest should give any items on begin, give them the items.
					for(uint32 i = 0; i < 4; ++i)
					{
						if(qst->receive_items[i])
						{
							Item* item = objmgr.CreateItem( qst->receive_items[i], plr);
							if(!plr->GetItemInterface()->AddItemToFreeSlot(item))
							{
								if(item)
									item->Destructor();
							}
						}
					}

					if(qst->srcitem && qst->srcitem != qst->receive_items[0])
					{
						Item* item = objmgr.CreateItem( qst->srcitem, plr);
						if(item)
						{
							item->SetUInt32Value(ITEM_FIELD_STACK_COUNT, qst->srcitemcount ? qst->srcitemcount : 1);
							if(!plr->GetItemInterface()->AddItemToFreeSlot(item))
							{
								if(item)
									item->Destructor();
							}
						}
					}
				

					plr->UpdateNearbyGameObjects();
				
					sHookInterface.OnQuestAccept( plr, qst, NULL );

					recout += "Quest has been added to the player's quest log.";
				}
			}
		}
	}
	else
	{
		recout += "Quest Id [";
		recout += args;
		recout += "] was not found and unable to add it to the player's quest log.";
	}

	recout += "\n\n";

	SendMultilineMessage(m_session, recout.c_str());

	return true;
}
Exemple #16
0
void QuestMgr::OnQuestFinished(Player* plr, Quest* qst, Object *qst_giver, uint32 reward_slot)
{
	QuestLogEntry *qle = plr->GetQuestLogForEntry(qst->id);
	if(!qle)
		return;

	BuildQuestComplete(plr, qst);
	CALL_QUESTSCRIPT_EVENT(qle, OnQuestComplete)(plr);

	ScriptSystem->OnQuestEvent(qst, ((Creature*)qst_giver), plr, QUEST_EVENT_ON_COMPLETE);
	qle->Finish();

	if(IsQuestRepeatable(qst))
		return;

	if(qst_giver->GetTypeId() == TYPEID_UNIT)
	{
		if(!((Creature*)qst_giver)->HasQuest(qst->id, 2))
		{
			sCheatLog.writefromsession(plr->GetSession(), "tried to finish quest from invalid npc.");
			plr->GetSession()->Disconnect();
			return;
		}
	}

	plr->ModUInt32Value(PLAYER_FIELD_COINAGE, qst->reward_money);

	
	// Reputation reward
	for(int z = 0; z < 2; z++)
	{
		uint32 fact = 19;   // default to 19 if no factiondbc
		uint32 amt  = uint32(float(GenerateQuestXP(plr, qst)) * 0.1f * sWorld.getRate(RATE_QUESTREPUTATION));   // guess
		if(!qst->reward_repfaction[z])
		{
			if(z == 1)
				break;

			// Let's do this properly. Determine the faction of the creature, and give reputation to his faction.
			if(qst_giver->GetTypeId() == TYPEID_UNIT)
				if(((Creature*)qst_giver)->m_factionDBC != NULL)
					fact = ((Creature*)qst_giver)->m_factionDBC->ID;
			if(qst_giver->GetTypeId() == TYPEID_GAMEOBJECT)
				fact = qst_giver->GetUInt32Value(GAMEOBJECT_FACTION);
		}
		else
		{
			fact = qst->reward_repfaction[z];
			if(qst->reward_repvalue[z])
				amt = qst->reward_repvalue[z];
		}

		if(qst->reward_replimit)
			if(plr->GetStanding(fact) >= (int32)qst->reward_replimit)
				continue;

		plr->ModStanding(fact, amt);
	}

	// Static Item reward
	for(uint32 i = 0; i < 4; ++i)
	{
		if(qst->reward_item[i])
		{
			ItemPrototype *proto = ItemPrototypeStorage.LookupEntry(qst->reward_item[i]);
			if(!proto)
			{
				sLog.outError("Invalid item prototype in quest reward! ID %d, quest %d", qst->reward_item[i], qst->id);
			}
			else
			{   
				Item *itm = objmgr.CreateItem(qst->reward_item[i], plr);
				itm->SetUInt32Value(ITEM_FIELD_STACK_COUNT, uint32(qst->reward_itemcount[i]));
				plr->GetItemInterface()->AddItemToFreeSlot(itm); //possible memleak and no safe check.
			}
		}
	}

	// Choice Rewards
	if(qst->reward_choiceitem[reward_slot])
	{
		ItemPrototype *proto = ItemPrototypeStorage.LookupEntry(qst->reward_choiceitem[reward_slot]);
		if(!proto)
		{
			sLog.outError("Invalid item prototype in quest reward! ID %d, quest %d", qst->reward_choiceitem[reward_slot], qst->id);
		}
		else
		{
			Item *itm = objmgr.CreateItem(qst->reward_choiceitem[reward_slot], plr);
			itm->SetUInt32Value(ITEM_FIELD_STACK_COUNT, qst->reward_choiceitemcount[reward_slot]);
			plr->GetItemInterface()->AddItemToFreeSlot(itm); //possible mem leak and no item check
		}
	}

	// Remove items
	for(uint32 i = 0; i < 4; ++i)
	{
		if(qst->required_item[i]) plr->GetItemInterface()->RemoveItemAmt(qst->required_item[i],qst->required_itemcount[i]);
	}

	// Remove srcitem
	if(qst->srcitem && qst->srcitem != qst->receive_items[0])
		plr->GetItemInterface()->RemoveItemAmt(qst->srcitem, qst->srcitemcount ? qst->srcitemcount : 1);

	// cast learning spell
	if(qst->reward_spell)
	{
		if(!plr->HasSpell(qst->reward_spell))
		{
			// "Teaching" effect
			WorldPacket data(SMSG_SPELL_START, 200);
			data << qst_giver->GetNewGUID() << qst_giver->GetNewGUID();
			data << uint32(7763);
			data << uint16(0);
			data << uint32(0);
			data << uint16(2);
			data << plr->GetGUID();
			plr->GetSession()->SendPacket( &data );

			data.Initialize( SMSG_SPELL_GO );
			data << qst_giver->GetNewGUID() << qst_giver->GetNewGUID();
			data << uint32(7763);		   // spellID
			data << uint8(0) << uint8(1);   // flags
			data << uint8(1);			   // amount of targets
			data << plr->GetGUID();		 // target
			data << uint8(0);
			data << uint16(2);
			data << plr->GetGUID();
			plr->GetSession()->SendPacket( &data );

			// Teach the spell
			plr->addSpell(qst->reward_spell);
		}
	}

	// cast Effect Spell
	if(qst->effect_on_player)
	{
		SpellEntry  * inf =sSpellStore.LookupEntry(qst->effect_on_player);
		if(inf)
		{
			Spell * spe = new Spell(qst_giver,inf,true,NULL);
			SpellCastTargets tgt;
			tgt.m_unitTarget = plr->GetGUID();
			spe->prepare(&tgt);
		}
	}

	//Add to finished quests
	plr->AddToFinishedQuests(qst->id);
}
Exemple #17
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;
									}
								}
							}
						}
					}
				}
			}
		}
	}
}