[11925] Improve interaction checks related to quests

'I see dead people, they are everywhere' - and now you can interact with them for quests.
Also fix aura 10848

Please report any missing issues (could not test all cases)

Signed-off-by: Schmoozerd <schmoozerd@scriptdev2.com>
This commit is contained in:
Schmoozerd 2012-02-08 23:04:05 +01:00
parent 8c912d0ab3
commit b899f97e33
6 changed files with 61 additions and 26 deletions

View file

@ -421,7 +421,7 @@ void PlayerMenu::SendQuestGiverStatus( uint8 questStatus, ObjectGuid npcGUID )
DEBUG_LOG( "WORLD: Sent SMSG_QUESTGIVER_STATUS for %s", npcGUID.GetString().c_str());
}
void PlayerMenu::SendQuestGiverQuestDetails(Quest const *pQuest, ObjectGuid npcGUID, bool ActivateAccept)
void PlayerMenu::SendQuestGiverQuestDetails(Quest const* pQuest, ObjectGuid guid, bool ActivateAccept)
{
std::string Title = pQuest->GetTitle();
std::string Details = pQuest->GetDetails();
@ -442,7 +442,7 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const *pQuest, ObjectGuid npcG
}
WorldPacket data(SMSG_QUESTGIVER_QUEST_DETAILS, 100); // guess size
data << ObjectGuid(npcGUID);
data << guid;
data << uint64(0); // wotlk, something todo with quest sharing?
data << uint32(pQuest->GetQuestId());
data << Title;
@ -540,7 +540,7 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const *pQuest, ObjectGuid npcG
GetMenuSession()->SendPacket( &data );
DEBUG_LOG("WORLD: Sent SMSG_QUESTGIVER_QUEST_DETAILS NPCGuid = %s, questid = %u", npcGUID.GetString().c_str(), pQuest->GetQuestId());
DEBUG_LOG("WORLD: Sent SMSG_QUESTGIVER_QUEST_DETAILS - for %s of %s, questid = %u", GetMenuSession()->GetPlayer()->GetObjectGuid().GetString().c_str(), guid.GetString().c_str(), pQuest->GetQuestId());
}
// send only static data in this packet!

View file

@ -30,7 +30,7 @@
#include "ScriptMgr.h"
#include "Group.h"
void WorldSession::HandleQuestgiverStatusQueryOpcode( WorldPacket & recv_data )
void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket & recv_data)
{
ObjectGuid guid;
recv_data >> guid;
@ -44,7 +44,7 @@ void WorldSession::HandleQuestgiverStatusQueryOpcode( WorldPacket & recv_data )
return;
}
DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for %s", guid.GetString().c_str());
DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY - for %s to %s", _player->GetObjectGuid().GetString().c_str(), guid.GetString().c_str());
switch(questgiver->GetTypeId())
{
@ -85,13 +85,12 @@ void WorldSession::HandleQuestgiverHelloOpcode(WorldPacket & recv_data)
ObjectGuid guid;
recv_data >> guid;
DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_HELLO npc: %s", guid.GetString().c_str());
Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE);
DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_HELLO - for %s to %s", _player->GetObjectGuid().GetString().c_str(), guid.GetString().c_str());
Creature* pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE);
if (!pCreature)
{
DEBUG_LOG ("WORLD: HandleQuestgiverHelloOpcode - %s not found or you can't interact with him.", guid.GetString().c_str());
DEBUG_LOG ("WORLD: HandleQuestgiverHelloOpcode - for %s to %s not found or you can't interact with him.", _player->GetObjectGuid().GetString().c_str(), guid.GetString().c_str());
return;
}
@ -110,17 +109,17 @@ void WorldSession::HandleQuestgiverHelloOpcode(WorldPacket & recv_data)
_player->SendPreparedGossip(pCreature);
}
void WorldSession::HandleQuestgiverAcceptQuestOpcode( WorldPacket & recv_data )
void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket & recv_data)
{
ObjectGuid guid;
uint32 quest;
uint32 unk1;
recv_data >> guid >> quest >> unk1;
if (!GetPlayer()->isAlive())
if (!CanInteractWithQuestGiver(guid, "CMSG_QUESTGIVER_ACCEPT_QUEST"))
return;
DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc = %s, quest = %u, unk1 = %u", guid.GetString().c_str(), quest, unk1 );
DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST - for %s to %s, quest = %u, unk1 = %u", _player->GetObjectGuid().GetString().c_str(), guid.GetString().c_str(), quest, unk1 );
Object* pObject = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_GAMEOBJECT_PLAYER_OR_ITEM);
@ -204,7 +203,7 @@ void WorldSession::HandleQuestgiverQueryQuestOpcode( WorldPacket & recv_data )
uint8 unk1;
recv_data >> guid >> quest >> unk1;
DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_QUERY_QUEST npc = %s, quest = %u, unk1 = %u", guid.GetString().c_str(), quest, unk1 );
DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_QUERY_QUEST - for %s to %s, quest = %u, unk1 = %u", _player->GetObjectGuid().GetString().c_str(), guid.GetString().c_str(), quest, unk1);
// Verify that the guid is valid and is a questgiver or involved in the requested quest
Object* pObject = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_GAMEOBJECT_OR_ITEM);
@ -231,7 +230,7 @@ void WorldSession::HandleQuestQueryOpcode( WorldPacket & recv_data )
}
}
void WorldSession::HandleQuestgiverChooseRewardOpcode( WorldPacket & recv_data )
void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket & recv_data)
{
uint32 quest, reward;
ObjectGuid guid;
@ -239,14 +238,14 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode( WorldPacket & recv_data )
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);
sLog.outError("Error in CMSG_QUESTGIVER_CHOOSE_REWARD - %s tried to get invalid reward (%u) (probably packet hacking)", _player->GetObjectGuid().GetString().c_str(), _player->GetGUIDLow(), reward);
return;
}
if(!GetPlayer()->isAlive())
if (!CanInteractWithQuestGiver(guid, "CMSG_QUESTGIVER_CHOOSE_REWARD"))
return;
DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %s, quest = %u, reward = %u", guid.GetString().c_str(), quest, reward);
DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD - for %s to %s, quest = %u, reward = %u", _player->GetObjectGuid().GetString().c_str(), guid.GetString().c_str(), quest, reward);
Object* pObject = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_OR_GAMEOBJECT);
if(!pObject)
@ -277,10 +276,10 @@ void WorldSession::HandleQuestgiverRequestRewardOpcode( WorldPacket & recv_data
ObjectGuid guid;
recv_data >> guid >> quest;
if (!GetPlayer()->isAlive())
if (!CanInteractWithQuestGiver(guid, "CMSG_QUESTGIVER_REQUEST_REWARD"))
return;
DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_REQUEST_REWARD npc = %s, quest = %u", guid.GetString().c_str(), quest);
DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_REQUEST_REWARD - for %s to %s, quest = %u", _player->GetObjectGuid().GetString().c_str(), guid.GetString().c_str(), quest);
Object* pObject = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_OR_GAMEOBJECT);
if (!pObject||!pObject->HasInvolvedQuest(quest))
@ -386,19 +385,20 @@ void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recv_data)
ObjectGuid guid;
recv_data >> guid >> quest;
if (!GetPlayer()->isAlive())
if (!CanInteractWithQuestGiver(guid, "CMSG_QUESTGIVER_COMPLETE_QUEST"))
return;
DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_COMPLETE_QUEST npc = %s, quest = %u", guid.GetString().c_str(), quest);
// All ok, continue
DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_COMPLETE_QUEST - for %s to %s, quest = %u", _player->GetObjectGuid().GetString().c_str(), guid.GetString().c_str(), quest);
if (Quest const *pQuest = sObjectMgr.GetQuestTemplate(quest))
if (Quest const* pQuest = sObjectMgr.GetQuestTemplate(quest))
{
if (_player->GetQuestStatus( quest ) != QUEST_STATUS_COMPLETE)
if (_player->GetQuestStatus(quest) != QUEST_STATUS_COMPLETE)
{
if (pQuest->IsRepeatable())
_player->PlayerTalkClass->SendQuestGiverRequestItems(pQuest, guid, _player->CanCompleteRepeatableQuest(pQuest), false);
else
_player->PlayerTalkClass->SendQuestGiverRequestItems(pQuest, guid, _player->CanRewardQuest(pQuest,false), false);
_player->PlayerTalkClass->SendQuestGiverRequestItems(pQuest, guid, _player->CanRewardQuest(pQuest, false), false);
}
else
{
@ -643,3 +643,32 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket
data.put<uint32>(0, count); // write real count
SendPacket(&data);
}
bool WorldSession::CanInteractWithQuestGiver(ObjectGuid& guid, char const* descr)
{
if (guid.IsCreatureOrVehicle())
{
Creature* pCreature = _player->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_QUESTGIVER);
if (!pCreature)
{
DEBUG_LOG("WORLD: %s - %s cannot interact with %s.", descr, _player->GetObjectGuid().GetString().c_str(), guid.GetString().c_str());
return false;
}
}
else if (guid.IsGameObject())
{
GameObject* pGo = _player->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_QUESTGIVER);
if (!pGo)
{
DEBUG_LOG("WORLD: %s - %s cannot interact with %s.", descr, _player->GetObjectGuid().GetString().c_str(), guid.GetString().c_str());
return false;
}
}
else if (!_player->isAlive())
{
DEBUG_LOG("WORLD: $s - %s is dead, requested guid was %s", descr, _player->GetObjectGuid().GetString().c_str(), guid.GetString().c_str());
return false;
}
return true;
}

View file

@ -2874,8 +2874,9 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
target->PlayDirectSound(14972, (Player *)target);
}
return;
case 40131:
case 10848:
case 27978:
case 40131:
if (apply)
target->m_AuraFlags |= UNIT_AURAFLAG_ALIVE_INVISIBLE;
else

View file

@ -158,6 +158,9 @@ enum UnitStandFlags
UNIT_STAND_FLAGS_ALL = 0xFF
};
// byte flags value (UNIT_FIELD_BYTES_1,2)
// This corresponds to free talent points (pet case)
// byte flags value (UNIT_FIELD_BYTES_1,3)
enum UnitBytes1_Flags
{

View file

@ -679,6 +679,8 @@ class MANGOS_DLL_SPEC WorldSession
void HandleQuestLogRemoveQuest(WorldPacket& recv_data);
void HandleQuestConfirmAccept(WorldPacket& recv_data);
void HandleQuestgiverCompleteQuest(WorldPacket& recv_data);
bool CanInteractWithQuestGiver(ObjectGuid& guid, char const* descr);
void HandleQuestgiverQuestAutoLaunch(WorldPacket& recvPacket);
void HandlePushQuestToParty(WorldPacket& recvPacket);
void HandleQuestPushResult(WorldPacket& recvPacket);

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "11924"
#define REVISION_NR "11925"
#endif // __REVISION_NR_H__