[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()); 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 Title = pQuest->GetTitle();
std::string Details = pQuest->GetDetails(); 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 WorldPacket data(SMSG_QUESTGIVER_QUEST_DETAILS, 100); // guess size
data << ObjectGuid(npcGUID); data << guid;
data << uint64(0); // wotlk, something todo with quest sharing? data << uint64(0); // wotlk, something todo with quest sharing?
data << uint32(pQuest->GetQuestId()); data << uint32(pQuest->GetQuestId());
data << Title; data << Title;
@ -540,7 +540,7 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const *pQuest, ObjectGuid npcG
GetMenuSession()->SendPacket( &data ); 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! // send only static data in this packet!

View file

@ -44,7 +44,7 @@ void WorldSession::HandleQuestgiverStatusQueryOpcode( WorldPacket & recv_data )
return; 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()) switch(questgiver->GetTypeId())
{ {
@ -85,13 +85,12 @@ void WorldSession::HandleQuestgiverHelloOpcode(WorldPacket & recv_data)
ObjectGuid guid; ObjectGuid guid;
recv_data >> guid; recv_data >> guid;
DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_HELLO npc: %s", guid.GetString().c_str()); 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); Creature* pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE);
if (!pCreature) 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; return;
} }
@ -117,10 +116,10 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode( WorldPacket & recv_data )
uint32 unk1; uint32 unk1;
recv_data >> guid >> quest >> unk1; recv_data >> guid >> quest >> unk1;
if (!GetPlayer()->isAlive()) if (!CanInteractWithQuestGiver(guid, "CMSG_QUESTGIVER_ACCEPT_QUEST"))
return; 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); Object* pObject = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_GAMEOBJECT_PLAYER_OR_ITEM);
@ -204,7 +203,7 @@ void WorldSession::HandleQuestgiverQueryQuestOpcode( WorldPacket & recv_data )
uint8 unk1; uint8 unk1;
recv_data >> guid >> quest >> 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 // 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); Object* pObject = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_GAMEOBJECT_OR_ITEM);
@ -239,14 +238,14 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode( WorldPacket & recv_data )
if(reward >= QUEST_REWARD_CHOICES_COUNT) 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; return;
} }
if(!GetPlayer()->isAlive()) if (!CanInteractWithQuestGiver(guid, "CMSG_QUESTGIVER_CHOOSE_REWARD"))
return; 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); Object* pObject = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_OR_GAMEOBJECT);
if(!pObject) if(!pObject)
@ -277,10 +276,10 @@ void WorldSession::HandleQuestgiverRequestRewardOpcode( WorldPacket & recv_data
ObjectGuid guid; ObjectGuid guid;
recv_data >> guid >> quest; recv_data >> guid >> quest;
if (!GetPlayer()->isAlive()) if (!CanInteractWithQuestGiver(guid, "CMSG_QUESTGIVER_REQUEST_REWARD"))
return; 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); Object* pObject = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_OR_GAMEOBJECT);
if (!pObject||!pObject->HasInvolvedQuest(quest)) if (!pObject||!pObject->HasInvolvedQuest(quest))
@ -386,10 +385,11 @@ void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recv_data)
ObjectGuid guid; ObjectGuid guid;
recv_data >> guid >> quest; recv_data >> guid >> quest;
if (!GetPlayer()->isAlive()) if (!CanInteractWithQuestGiver(guid, "CMSG_QUESTGIVER_COMPLETE_QUEST"))
return; 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))
{ {
@ -643,3 +643,32 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket
data.put<uint32>(0, count); // write real count data.put<uint32>(0, count); // write real count
SendPacket(&data); 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); target->PlayDirectSound(14972, (Player *)target);
} }
return; return;
case 40131: case 10848:
case 27978: case 27978:
case 40131:
if (apply) if (apply)
target->m_AuraFlags |= UNIT_AURAFLAG_ALIVE_INVISIBLE; target->m_AuraFlags |= UNIT_AURAFLAG_ALIVE_INVISIBLE;
else else

View file

@ -158,6 +158,9 @@ enum UnitStandFlags
UNIT_STAND_FLAGS_ALL = 0xFF 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) // byte flags value (UNIT_FIELD_BYTES_1,3)
enum UnitBytes1_Flags enum UnitBytes1_Flags
{ {

View file

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

View file

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