Core/Entities: allow interaction with gameobject questgivers if player can take or return quests
Closes #11269 Closes #8898 Closes #10204 Closes #11410 Closes #7053 Closes #6189 Closes #9474
This commit is contained in:
@@ -986,9 +986,17 @@ bool GameObject::ActivateToQuest(Player* target) const
|
||||
|
||||
switch (GetGoType())
|
||||
{
|
||||
// scan GO chest with loot including quest items
|
||||
case GAMEOBJECT_TYPE_QUESTGIVER:
|
||||
{
|
||||
GameObject* go = const_cast<GameObject*>(this);
|
||||
QuestGiverStatus questStatus = target->GetQuestDialogStatus(go);
|
||||
if (questStatus > DIALOG_STATUS_UNAVAILABLE)
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
case GAMEOBJECT_TYPE_CHEST:
|
||||
{
|
||||
// scan GO chest with loot including quest items
|
||||
if (LootTemplates_Gameobject.HaveQuestLootForPlayer(GetGOInfo()->GetLootId(), target))
|
||||
{
|
||||
if (Battleground const* bg = target->GetBattleground())
|
||||
@@ -2148,6 +2156,10 @@ void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* t
|
||||
int16 pathProgress = -1;
|
||||
switch (GetGoType())
|
||||
{
|
||||
case GAMEOBJECT_TYPE_QUESTGIVER:
|
||||
if (ActivateToQuest(target))
|
||||
dynFlags |= GO_DYNFLAG_LO_ACTIVATE;
|
||||
break;
|
||||
case GAMEOBJECT_TYPE_CHEST:
|
||||
case GAMEOBJECT_TYPE_GOOBER:
|
||||
if (ActivateToQuest(target))
|
||||
|
||||
@@ -15034,7 +15034,7 @@ void Player::AddQuestAndCheckCompletion(Quest const* quest, Object* questGiver)
|
||||
switch (questGiver->GetTypeId())
|
||||
{
|
||||
case TYPEID_UNIT:
|
||||
sScriptMgr->OnQuestAccept(this, (questGiver->ToCreature()), quest);
|
||||
sScriptMgr->OnQuestAccept(this, questGiver->ToCreature(), quest);
|
||||
questGiver->ToCreature()->AI()->sQuestAccept(this, quest);
|
||||
break;
|
||||
case TYPEID_ITEM:
|
||||
@@ -15177,7 +15177,7 @@ void Player::AddQuest(Quest const* quest, Object* questGiver)
|
||||
|
||||
StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_QUEST, quest_id);
|
||||
|
||||
UpdateForQuestWorldObjects();
|
||||
SendQuestUpdate(quest_id);
|
||||
}
|
||||
|
||||
void Player::CompleteQuest(uint32 quest_id)
|
||||
@@ -15343,7 +15343,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
|
||||
else if (quest->IsSeasonal())
|
||||
SetSeasonalQuestStatus(quest_id);
|
||||
|
||||
RemoveActiveQuest(quest_id);
|
||||
RemoveActiveQuest(quest_id, false);
|
||||
m_RewardedQuests.insert(quest_id);
|
||||
m_RewardedQuestsSave[quest_id] = true;
|
||||
|
||||
@@ -15391,6 +15391,8 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
|
||||
UpdatePvPState();
|
||||
}
|
||||
|
||||
SendQuestUpdate(quest_id);
|
||||
|
||||
//lets remove flag for delayed teleports
|
||||
SetCanDelayTeleport(false);
|
||||
}
|
||||
@@ -15984,17 +15986,49 @@ bool Player::CanShareQuest(uint32 quest_id) const
|
||||
return false;
|
||||
}
|
||||
|
||||
void Player::SetQuestStatus(uint32 quest_id, QuestStatus status)
|
||||
void Player::SetQuestStatus(uint32 questId, QuestStatus status, bool update /*= true*/)
|
||||
{
|
||||
if (sObjectMgr->GetQuestTemplate(quest_id))
|
||||
if (sObjectMgr->GetQuestTemplate(questId))
|
||||
{
|
||||
m_QuestStatus[quest_id].Status = status;
|
||||
m_QuestStatusSave[quest_id] = true;
|
||||
m_QuestStatus[questId].Status = status;
|
||||
m_QuestStatusSave[questId] = true;
|
||||
}
|
||||
|
||||
if (update)
|
||||
SendQuestUpdate(questId);
|
||||
}
|
||||
|
||||
void Player::RemoveActiveQuest(uint32 questId, bool update /*= true*/)
|
||||
{
|
||||
QuestStatusMap::iterator itr = m_QuestStatus.find(questId);
|
||||
if (itr != m_QuestStatus.end())
|
||||
{
|
||||
m_QuestStatus.erase(itr);
|
||||
m_QuestStatusSave[questId] = false;
|
||||
}
|
||||
|
||||
if (update)
|
||||
SendQuestUpdate(questId);
|
||||
}
|
||||
|
||||
void Player::RemoveRewardedQuest(uint32 questId, bool update /*= true*/)
|
||||
{
|
||||
RewardedQuestSet::iterator rewItr = m_RewardedQuests.find(questId);
|
||||
if (rewItr != m_RewardedQuests.end())
|
||||
{
|
||||
m_RewardedQuests.erase(rewItr);
|
||||
m_RewardedQuestsSave[questId] = false;
|
||||
}
|
||||
|
||||
if (update)
|
||||
SendQuestUpdate(questId);
|
||||
}
|
||||
|
||||
void Player::SendQuestUpdate(uint32 questId)
|
||||
{
|
||||
uint32 zone = 0, area = 0;
|
||||
|
||||
SpellAreaForQuestMapBounds saBounds = sSpellMgr->GetSpellAreaForQuestMapBounds(quest_id);
|
||||
SpellAreaForQuestMapBounds saBounds = sSpellMgr->GetSpellAreaForQuestMapBounds(questId);
|
||||
if (saBounds.first != saBounds.second)
|
||||
{
|
||||
GetZoneAndAreaId(zone, area);
|
||||
@@ -16005,7 +16039,7 @@ void Player::SetQuestStatus(uint32 quest_id, QuestStatus status)
|
||||
CastSpell(this, itr->second->spellId, true);
|
||||
}
|
||||
|
||||
saBounds = sSpellMgr->GetSpellAreaForQuestEndMapBounds(quest_id);
|
||||
saBounds = sSpellMgr->GetSpellAreaForQuestEndMapBounds(questId);
|
||||
if (saBounds.first != saBounds.second)
|
||||
{
|
||||
if (!zone || !area)
|
||||
@@ -16019,25 +16053,108 @@ void Player::SetQuestStatus(uint32 quest_id, QuestStatus status)
|
||||
UpdateForQuestWorldObjects();
|
||||
}
|
||||
|
||||
void Player::RemoveActiveQuest(uint32 quest_id)
|
||||
QuestGiverStatus Player::GetQuestDialogStatus(Object* questgiver)
|
||||
{
|
||||
QuestStatusMap::iterator itr = m_QuestStatus.find(quest_id);
|
||||
if (itr != m_QuestStatus.end())
|
||||
{
|
||||
m_QuestStatus.erase(itr);
|
||||
m_QuestStatusSave[quest_id] = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
QuestRelationBounds qr;
|
||||
QuestRelationBounds qir;
|
||||
|
||||
void Player::RemoveRewardedQuest(uint32 quest_id)
|
||||
{
|
||||
RewardedQuestSet::iterator rewItr = m_RewardedQuests.find(quest_id);
|
||||
if (rewItr != m_RewardedQuests.end())
|
||||
switch (questgiver->GetTypeId())
|
||||
{
|
||||
m_RewardedQuests.erase(rewItr);
|
||||
m_RewardedQuestsSave[quest_id] = false;
|
||||
case TYPEID_GAMEOBJECT:
|
||||
{
|
||||
QuestGiverStatus questStatus = QuestGiverStatus(sScriptMgr->GetDialogStatus(this, questgiver->ToGameObject()));
|
||||
if (questStatus != DIALOG_STATUS_SCRIPTED_NO_STATUS)
|
||||
return questStatus;
|
||||
qr = sObjectMgr->GetGOQuestRelationBounds(questgiver->GetEntry());
|
||||
qir = sObjectMgr->GetGOQuestInvolvedRelationBounds(questgiver->GetEntry());
|
||||
break;
|
||||
}
|
||||
case TYPEID_UNIT:
|
||||
{
|
||||
QuestGiverStatus questStatus = QuestGiverStatus(sScriptMgr->GetDialogStatus(this, questgiver->ToCreature()));
|
||||
if (questStatus != DIALOG_STATUS_SCRIPTED_NO_STATUS)
|
||||
return questStatus;
|
||||
qr = sObjectMgr->GetCreatureQuestRelationBounds(questgiver->GetEntry());
|
||||
qir = sObjectMgr->GetCreatureQuestInvolvedRelationBounds(questgiver->GetEntry());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// it's impossible, but check
|
||||
TC_LOG_ERROR("entities.player.quest", "GetQuestDialogStatus called for unexpected type %u", questgiver->GetTypeId());
|
||||
return DIALOG_STATUS_NONE;
|
||||
}
|
||||
|
||||
QuestGiverStatus result = DIALOG_STATUS_NONE;
|
||||
|
||||
for (QuestRelations::const_iterator i = qir.first; i != qir.second; ++i)
|
||||
{
|
||||
QuestGiverStatus result2 = DIALOG_STATUS_NONE;
|
||||
uint32 questId = i->second;
|
||||
Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
|
||||
if (!quest)
|
||||
continue;
|
||||
|
||||
ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK, quest->GetQuestId());
|
||||
if (!sConditionMgr->IsObjectMeetToConditions(this, conditions))
|
||||
continue;
|
||||
|
||||
QuestStatus status = GetQuestStatus(questId);
|
||||
if ((status == QUEST_STATUS_COMPLETE && !GetQuestRewardStatus(questId)) ||
|
||||
(quest->IsAutoComplete() && CanTakeQuest(quest, false)))
|
||||
{
|
||||
if (quest->IsAutoComplete() && quest->IsRepeatable() && !quest->IsDailyOrWeekly())
|
||||
result2 = DIALOG_STATUS_REWARD_REP;
|
||||
else
|
||||
result2 = DIALOG_STATUS_REWARD;
|
||||
}
|
||||
else if (status == QUEST_STATUS_INCOMPLETE)
|
||||
result2 = DIALOG_STATUS_INCOMPLETE;
|
||||
|
||||
if (result2 > result)
|
||||
result = result2;
|
||||
}
|
||||
|
||||
for (QuestRelations::const_iterator i = qr.first; i != qr.second; ++i)
|
||||
{
|
||||
QuestGiverStatus result2 = DIALOG_STATUS_NONE;
|
||||
uint32 questId = i->second;
|
||||
Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
|
||||
if (!quest)
|
||||
continue;
|
||||
|
||||
ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK, quest->GetQuestId());
|
||||
if (!sConditionMgr->IsObjectMeetToConditions(this, conditions))
|
||||
continue;
|
||||
|
||||
QuestStatus status = GetQuestStatus(questId);
|
||||
if (status == QUEST_STATUS_NONE)
|
||||
{
|
||||
if (CanSeeStartQuest(quest))
|
||||
{
|
||||
if (SatisfyQuestLevel(quest, false))
|
||||
{
|
||||
if (quest->IsAutoComplete())
|
||||
result2 = DIALOG_STATUS_REWARD_REP;
|
||||
else if (getLevel() <= (GetQuestLevel(quest) + sWorld->getIntConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF)))
|
||||
{
|
||||
if (quest->IsDaily())
|
||||
result2 = DIALOG_STATUS_AVAILABLE_REP;
|
||||
else
|
||||
result2 = DIALOG_STATUS_AVAILABLE;
|
||||
}
|
||||
else
|
||||
result2 = DIALOG_STATUS_LOW_LEVEL_AVAILABLE;
|
||||
}
|
||||
else
|
||||
result2 = DIALOG_STATUS_UNAVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
if (result2 > result)
|
||||
result = result2;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// not used in Trinity, but used in scripting code
|
||||
@@ -23356,7 +23473,7 @@ void Player::UpdateForQuestWorldObjects()
|
||||
|
||||
UpdateData udata;
|
||||
WorldPacket packet;
|
||||
for (ClientGUIDs::iterator itr=m_clientGUIDs.begin(); itr != m_clientGUIDs.end(); ++itr)
|
||||
for (ClientGUIDs::iterator itr = m_clientGUIDs.begin(); itr != m_clientGUIDs.end(); ++itr)
|
||||
{
|
||||
if (IS_GAMEOBJECT_GUID(*itr))
|
||||
{
|
||||
|
||||
@@ -1383,9 +1383,11 @@ class Player : public Unit, public GridObject<Player>
|
||||
bool TakeQuestSourceItem(uint32 questId, bool msg);
|
||||
bool GetQuestRewardStatus(uint32 quest_id) const;
|
||||
QuestStatus GetQuestStatus(uint32 quest_id) const;
|
||||
void SetQuestStatus(uint32 quest_id, QuestStatus status);
|
||||
void RemoveActiveQuest(uint32 quest_id);
|
||||
void RemoveRewardedQuest(uint32 quest_id);
|
||||
void SetQuestStatus(uint32 questId, QuestStatus status, bool update = true);
|
||||
void RemoveActiveQuest(uint32 questId, bool update = true);
|
||||
void RemoveRewardedQuest(uint32 questId, bool update = true);
|
||||
void SendQuestUpdate(uint32 questId);
|
||||
QuestGiverStatus GetQuestDialogStatus(Object* questGiver);
|
||||
|
||||
void SetDailyQuestStatus(uint32 quest_id);
|
||||
void SetWeeklyQuestStatus(uint32 quest_id);
|
||||
|
||||
@@ -7506,6 +7506,10 @@ void ObjectMgr::LoadGameObjectForQuests()
|
||||
{
|
||||
switch (itr->second.type)
|
||||
{
|
||||
case GAMEOBJECT_TYPE_QUESTGIVER:
|
||||
_gameObjectForQuestStore.insert(itr->second.entry);
|
||||
++count;
|
||||
break;
|
||||
case GAMEOBJECT_TYPE_CHEST:
|
||||
{
|
||||
// scan GO chest with loot including quest items
|
||||
|
||||
@@ -38,42 +38,34 @@ void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket& recvData)
|
||||
recvData >> guid;
|
||||
uint32 questStatus = DIALOG_STATUS_NONE;
|
||||
|
||||
Object* questgiver = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
|
||||
if (!questgiver)
|
||||
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())
|
||||
switch (questGiver->GetTypeId())
|
||||
{
|
||||
case TYPEID_UNIT:
|
||||
{
|
||||
TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for npc, guid = %u", questgiver->GetGUIDLow());
|
||||
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 == DIALOG_STATUS_SCRIPTED_NO_STATUS)
|
||||
questStatus = getDialogStatus(_player, cr_questgiver);
|
||||
}
|
||||
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());
|
||||
GameObject* go_questgiver = questgiver->ToGameObject();
|
||||
questStatus = sScriptMgr->GetDialogStatus(_player, go_questgiver);
|
||||
if (questStatus == DIALOG_STATUS_SCRIPTED_NO_STATUS)
|
||||
questStatus = getDialogStatus(_player, go_questgiver);
|
||||
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());
|
||||
TC_LOG_ERROR("network", "QuestGiver called for unexpected type %u", questGiver->GetTypeId());
|
||||
break;
|
||||
}
|
||||
|
||||
//inform client about status of quest
|
||||
// inform client about status of quest
|
||||
_player->PlayerTalkClass->SendQuestGiverStatus(uint8(questStatus), guid);
|
||||
}
|
||||
|
||||
@@ -174,7 +166,7 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData)
|
||||
|
||||
if (_player->CanAddQuest(quest, true))
|
||||
{
|
||||
_player->AddQuest(quest, object);
|
||||
_player->AddQuestAndCheckCompletion(quest, object);
|
||||
|
||||
if (quest->HasFlag(QUEST_FLAGS_PARTY_ACCEPT))
|
||||
{
|
||||
@@ -191,7 +183,7 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData)
|
||||
{
|
||||
player->SetDivider(_player->GetGUID());
|
||||
|
||||
//need confirmation that any gossip window will close
|
||||
// need confirmation that any gossip window will close
|
||||
player->PlayerTalkClass->SendCloseGossip();
|
||||
|
||||
_player->SendQuestConfirmAccept(quest, player);
|
||||
@@ -200,45 +192,6 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -314,7 +267,7 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket& recvData)
|
||||
|
||||
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);
|
||||
Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT);
|
||||
if (!object || !object->hasInvolvedQuest(questId))
|
||||
return;
|
||||
|
||||
@@ -338,7 +291,9 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket& recvData)
|
||||
switch (object->GetTypeId())
|
||||
{
|
||||
case TYPEID_UNIT:
|
||||
if (!(sScriptMgr->OnQuestReward(_player, (object->ToCreature()), quest, reward)))
|
||||
{
|
||||
Creature* questgiver = object->ToCreature();
|
||||
if (!sScriptMgr->OnQuestReward(_player, questgiver, quest, reward))
|
||||
{
|
||||
// Send next quest
|
||||
if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))
|
||||
@@ -349,11 +304,14 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket& recvData)
|
||||
_player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true);
|
||||
}
|
||||
|
||||
(object->ToCreature())->AI()->sQuestReward(_player, quest, reward);
|
||||
questgiver->AI()->sQuestReward(_player, quest, reward);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TYPEID_GAMEOBJECT:
|
||||
if (!sScriptMgr->OnQuestReward(_player, ((GameObject*)object), quest, reward))
|
||||
{
|
||||
GameObject* questGiver = object->ToGameObject();
|
||||
if (!sScriptMgr->OnQuestReward(_player, questGiver, quest, reward))
|
||||
{
|
||||
// Send next quest
|
||||
if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))
|
||||
@@ -364,9 +322,10 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket& recvData)
|
||||
_player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true);
|
||||
}
|
||||
|
||||
object->ToGameObject()->AI()->QuestReward(_player, quest, reward);
|
||||
questGiver->AI()->QuestReward(_player, quest, reward);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -384,7 +343,7 @@ void WorldSession::HandleQuestgiverRequestRewardOpcode(WorldPacket& recvData)
|
||||
|
||||
TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_REQUEST_REWARD npc = %u, quest = %u", uint32(GUID_LOPART(guid)), questId);
|
||||
|
||||
Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
|
||||
Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT);
|
||||
if (!object || !object->hasInvolvedQuest(questId))
|
||||
return;
|
||||
|
||||
@@ -468,17 +427,16 @@ void WorldSession::HandleQuestConfirmAccept(WorldPacket& recvData)
|
||||
|
||||
TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUEST_CONFIRM_ACCEPT quest = %u", questId);
|
||||
|
||||
if (const Quest* quest = sObjectMgr->GetQuestTemplate(questId))
|
||||
if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
|
||||
{
|
||||
if (!quest->HasFlag(QUEST_FLAGS_PARTY_ACCEPT))
|
||||
return;
|
||||
|
||||
Player* pOriginalPlayer = ObjectAccessor::FindPlayer(_player->GetDivider());
|
||||
|
||||
if (!pOriginalPlayer)
|
||||
Player* originalPlayer = ObjectAccessor::FindPlayer(_player->GetDivider());
|
||||
if (!originalPlayer)
|
||||
return;
|
||||
|
||||
if (!_player->IsInSameRaidWith(pOriginalPlayer))
|
||||
if (!_player->IsInSameRaidWith(originalPlayer))
|
||||
return;
|
||||
|
||||
if (_player->CanAddQuest(quest, true))
|
||||
@@ -501,7 +459,7 @@ void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recvData)
|
||||
if (!quest)
|
||||
return;
|
||||
|
||||
Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
|
||||
Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT);
|
||||
if (!object || !object->hasInvolvedQuest(questId))
|
||||
return;
|
||||
|
||||
@@ -638,104 +596,6 @@ void WorldSession::HandleQuestPushResult(WorldPacket& recvPacket)
|
||||
}
|
||||
}
|
||||
|
||||
uint32 WorldSession::getDialogStatus(Player* player, Object* questgiver)
|
||||
{
|
||||
uint32 result = DIALOG_STATUS_NONE;
|
||||
|
||||
QuestRelationBounds qr;
|
||||
QuestRelationBounds qir;
|
||||
|
||||
switch (questgiver->GetTypeId())
|
||||
{
|
||||
case TYPEID_GAMEOBJECT:
|
||||
{
|
||||
qr = sObjectMgr->GetGOQuestRelationBounds(questgiver->GetEntry());
|
||||
qir = sObjectMgr->GetGOQuestInvolvedRelationBounds(questgiver->GetEntry());
|
||||
break;
|
||||
}
|
||||
case TYPEID_UNIT:
|
||||
{
|
||||
qr = sObjectMgr->GetCreatureQuestRelationBounds(questgiver->GetEntry());
|
||||
qir = sObjectMgr->GetCreatureQuestInvolvedRelationBounds(questgiver->GetEntry());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
//its imposible, but check ^)
|
||||
TC_LOG_ERROR("network", "Warning: GetDialogStatus called for unexpected type %u", questgiver->GetTypeId());
|
||||
return DIALOG_STATUS_NONE;
|
||||
}
|
||||
|
||||
for (QuestRelations::const_iterator i = qir.first; i != qir.second; ++i)
|
||||
{
|
||||
uint32 result2 = 0;
|
||||
uint32 quest_id = i->second;
|
||||
Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
|
||||
if (!quest)
|
||||
continue;
|
||||
|
||||
ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK, quest->GetQuestId());
|
||||
if (!sConditionMgr->IsObjectMeetToConditions(player, conditions))
|
||||
continue;
|
||||
|
||||
QuestStatus status = player->GetQuestStatus(quest_id);
|
||||
if ((status == QUEST_STATUS_COMPLETE && !player->GetQuestRewardStatus(quest_id)) ||
|
||||
(quest->IsAutoComplete() && player->CanTakeQuest(quest, false)))
|
||||
{
|
||||
if (quest->IsAutoComplete() && quest->IsRepeatable() && !quest->IsDailyOrWeekly())
|
||||
result2 = DIALOG_STATUS_REWARD_REP;
|
||||
else
|
||||
result2 = DIALOG_STATUS_REWARD;
|
||||
}
|
||||
else if (status == QUEST_STATUS_INCOMPLETE)
|
||||
result2 = DIALOG_STATUS_INCOMPLETE;
|
||||
|
||||
if (result2 > result)
|
||||
result = result2;
|
||||
}
|
||||
|
||||
for (QuestRelations::const_iterator i = qr.first; i != qr.second; ++i)
|
||||
{
|
||||
uint32 result2 = 0;
|
||||
uint32 quest_id = i->second;
|
||||
Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
|
||||
if (!quest)
|
||||
continue;
|
||||
|
||||
ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK, quest->GetQuestId());
|
||||
if (!sConditionMgr->IsObjectMeetToConditions(player, conditions))
|
||||
continue;
|
||||
|
||||
QuestStatus status = player->GetQuestStatus(quest_id);
|
||||
if (status == QUEST_STATUS_NONE)
|
||||
{
|
||||
if (player->CanSeeStartQuest(quest))
|
||||
{
|
||||
if (player->SatisfyQuestLevel(quest, false))
|
||||
{
|
||||
if (quest->IsAutoComplete())
|
||||
result2 = DIALOG_STATUS_REWARD_REP;
|
||||
else if (player->getLevel() <= ((player->GetQuestLevel(quest) == -1) ? player->getLevel() : player->GetQuestLevel(quest) + sWorld->getIntConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF)))
|
||||
{
|
||||
if (quest->IsDaily())
|
||||
result2 = DIALOG_STATUS_AVAILABLE_REP;
|
||||
else
|
||||
result2 = DIALOG_STATUS_AVAILABLE;
|
||||
}
|
||||
else
|
||||
result2 = DIALOG_STATUS_LOW_LEVEL_AVAILABLE;
|
||||
}
|
||||
else
|
||||
result2 = DIALOG_STATUS_UNAVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
if (result2 > result)
|
||||
result = result2;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket*/)
|
||||
{
|
||||
TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY");
|
||||
@@ -758,9 +618,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket
|
||||
if (!questgiver->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER))
|
||||
continue;
|
||||
|
||||
questStatus = sScriptMgr->GetDialogStatus(_player, questgiver);
|
||||
if (questStatus == DIALOG_STATUS_SCRIPTED_NO_STATUS)
|
||||
questStatus = getDialogStatus(_player, questgiver);
|
||||
questStatus = _player->GetQuestDialogStatus(questgiver);
|
||||
|
||||
data << uint64(questgiver->GetGUID());
|
||||
data << uint8(questStatus);
|
||||
@@ -772,9 +630,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket
|
||||
if (!questgiver || questgiver->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER)
|
||||
continue;
|
||||
|
||||
questStatus = sScriptMgr->GetDialogStatus(_player, questgiver);
|
||||
if (questStatus == DIALOG_STATUS_SCRIPTED_NO_STATUS)
|
||||
questStatus = getDialogStatus(_player, questgiver);
|
||||
questStatus = _player->GetQuestDialogStatus(questgiver);
|
||||
|
||||
data << uint64(questgiver->GetGUID());
|
||||
data << uint8(questStatus);
|
||||
|
||||
@@ -359,7 +359,6 @@ class WorldSession
|
||||
uint32 GetLatency() const { return m_latency; }
|
||||
void SetLatency(uint32 latency) { m_latency = latency; }
|
||||
void ResetClientTimeDelay() { m_clientTimeDelay = 0; }
|
||||
uint32 getDialogStatus(Player* player, Object* questgiver);
|
||||
|
||||
ACE_Atomic_Op<ACE_Thread_Mutex, time_t> m_timeOutTime;
|
||||
void UpdateTimeOutTime(uint32 diff)
|
||||
|
||||
@@ -4864,7 +4864,7 @@ void Spell::EffectQuestClear(SpellEffIndex effIndex)
|
||||
}
|
||||
}
|
||||
|
||||
player->RemoveActiveQuest(quest_id);
|
||||
player->RemoveActiveQuest(quest_id, false);
|
||||
player->RemoveRewardedQuest(quest_id);
|
||||
}
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
player->RemoveActiveQuest(entry);
|
||||
player->RemoveActiveQuest(entry, false);
|
||||
player->RemoveRewardedQuest(entry);
|
||||
|
||||
handler->SendSysMessage(LANG_COMMAND_QUEST_REMOVED);
|
||||
|
||||
Reference in New Issue
Block a user