Core/Gossips: added some sanity checks to prevent duplicate interaction

(cherry picked from commit 8b6954e81b76f8d7c6700eaf1a8b942bebaa85a0)

Scripts: addition to 8b6954e81b76f8d7c6700eaf1a8b942bebaa85a0

Closes #16466

(cherry picked from commit b259d5c2bc41a545aad978c286f21347c0ba51a2)
This commit is contained in:
joschiwald
2016-02-06 18:16:11 +01:00
parent bc6326d71f
commit 3ac2ba721d
8 changed files with 42 additions and 27 deletions
+18 -4
View File
@@ -2124,7 +2124,7 @@ bool Player::CanInteractWithQuestGiver(Object* questGiver) const
return false;
}
Creature* Player::GetNPCIfCanInteractWith(ObjectGuid guid, uint64 npcflagmask) const
Creature* Player::GetNPCIfCanInteractWith(ObjectGuid const& guid, uint64 npcflagmask) const
{
// unit checks
if (!guid)
@@ -2168,7 +2168,21 @@ Creature* Player::GetNPCIfCanInteractWith(ObjectGuid guid, uint64 npcflagmask) c
return creature;
}
GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid guid, GameobjectTypes type) const
GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid const& guid) const
{
if (GameObject* go = GetMap()->GetGameObject(guid))
{
if (go->IsWithinDistInMap(this, go->GetInteractionDistance()))
return go;
TC_LOG_DEBUG("maps", "Player::GetGameObjectIfCanInteractWith: GameObject '%s' (%s) is too far away from player '%s' (%s) to be used by him (Distance: %f, maximal %f is allowed)",
go->GetGOInfo()->name.c_str(), go->GetGUID().ToString().c_str(), GetName().c_str(), GetGUID().ToString().c_str(), go->GetDistance(this), go->GetInteractionDistance());
}
return nullptr;
}
GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid const& guid, GameobjectTypes type) const
{
if (GameObject* go = GetMap()->GetGameObject(guid))
{
@@ -2177,8 +2191,8 @@ GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid guid, GameobjectTy
if (go->IsWithinDistInMap(this, go->GetInteractionDistance()))
return go;
TC_LOG_DEBUG("maps", "Player::GetGameObjectIfCanInteractWith: GameObject '%s' (%s) is too far away from player '%s' (%s) to be used by him (Distance: %f, maximal 10 is allowed)",
go->GetGOInfo()->name.c_str(), go->GetGUID().ToString().c_str(), GetName().c_str(), GetGUID().ToString().c_str(), go->GetDistance(this));
TC_LOG_DEBUG("maps", "Player::GetGameObjectIfCanInteractWith: GameObject '%s' (%s) is too far away from player '%s' (%s) to be used by him (Distance: %f, maximal %f is allowed)",
go->GetGOInfo()->name.c_str(), go->GetGUID().ToString().c_str(), GetName().c_str(), GetGUID().ToString().c_str(), go->GetDistance(this), go->GetInteractionDistance());
}
}
+3 -2
View File
@@ -1229,8 +1229,9 @@ class Player : public Unit, public GridObject<Player>
void SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time, bool welcome) const;
bool CanInteractWithQuestGiver(Object* questGiver) const;
Creature* GetNPCIfCanInteractWith(ObjectGuid guid, uint64 npcflagmask) const;
GameObject* GetGameObjectIfCanInteractWith(ObjectGuid guid, GameobjectTypes type) const;
Creature* GetNPCIfCanInteractWith(ObjectGuid const& guid, uint64 npcflagmask) const;
GameObject* GetGameObjectIfCanInteractWith(ObjectGuid const& guid) const;
GameObject* GetGameObjectIfCanInteractWith(ObjectGuid const& guid, GameobjectTypes type) const;
void ToggleAFK();
void ToggleDND();
+4 -6
View File
@@ -256,7 +256,7 @@ void WorldSession::SendTrainerBuyFailed(ObjectGuid trainerGUID, uint32 spellID,
void WorldSession::HandleGossipHelloOpcode(WorldPackets::NPC::Hello& packet)
{
Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(packet.Unit, UNIT_NPC_FLAG_NONE);
Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(packet.Unit, UNIT_NPC_FLAG_GOSSIP);
if (!unit)
{
TC_LOG_DEBUG("network", "WORLD: HandleGossipHelloOpcode - %s not found or you can not interact with him.", packet.Unit.ToString().c_str());
@@ -296,7 +296,6 @@ void WorldSession::HandleGossipHelloOpcode(WorldPackets::NPC::Hello& packet)
unit->AI()->sGossipHello(_player);
}
void WorldSession::HandleGossipSelectOptionOpcode(WorldPackets::NPC::GossipSelectOption& packet)
{
if (!_player->PlayerTalkClass->GetGossipMenu().GetItem(packet.GossipIndex))
@@ -310,20 +309,19 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPackets::NPC::GossipSelec
GameObject* go = nullptr;
if (packet.GossipUnit.IsCreatureOrVehicle())
{
unit = GetPlayer()->GetNPCIfCanInteractWith(packet.GossipUnit, UNIT_NPC_FLAG_NONE);
unit = GetPlayer()->GetNPCIfCanInteractWith(packet.GossipUnit, UNIT_NPC_FLAG_GOSSIP);
if (!unit)
{
TC_LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - %s not found or you can't interact with him.", packet.GossipUnit.ToString().c_str());
return;
}
}
else if (packet.GossipUnit.IsGameObject())
{
go = _player->GetMap()->GetGameObject(packet.GossipUnit);
go = _player->GetGameObjectIfCanInteractWith(packet.GossipUnit);
if (!go)
{
TC_LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - %s not found.", packet.GossipUnit.ToString().c_str());
TC_LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - %s not found or you can't interact with it.", packet.GossipUnit.ToString().c_str());
return;
}
}
+1 -1
View File
@@ -71,7 +71,7 @@ void WorldSession::HandleQuestgiverHelloOpcode(WorldPackets::Quest::QuestGiverHe
{
TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_HELLO %s", packet.QuestGiverGUID.ToString().c_str());
Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(packet.QuestGiverGUID, UNIT_NPC_FLAG_NONE);
Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(packet.QuestGiverGUID, UNIT_NPC_FLAG_QUESTGIVER);
if (!creature)
{
TC_LOG_DEBUG("network", "WORLD: HandleQuestgiverHelloOpcode - %s not found or you can't interact with him.",
+7 -14
View File
@@ -216,11 +216,8 @@ void WorldSession::HandleOpenItemOpcode(WorldPackets::Spells::OpenItem& packet)
void WorldSession::HandleGameObjectUseOpcode(WorldPackets::GameObject::GameObjUse& packet)
{
if (GameObject* obj = GetPlayer()->GetMap()->GetGameObject(packet.Guid))
if (GameObject* obj = GetPlayer()->GetGameObjectIfCanInteractWith(packet.Guid))
{
if (!obj->IsWithinDistInMap(GetPlayer(), obj->GetInteractionDistance()))
return;
// ignore for remote control state
if (GetPlayer()->m_mover != GetPlayer())
if (!(GetPlayer()->IsOnVehicle(GetPlayer()->m_mover) || GetPlayer()->IsMounted()) && !obj->GetGOInfo()->IsUsableMounted())
@@ -236,17 +233,13 @@ void WorldSession::HandleGameobjectReportUse(WorldPackets::GameObject::GameObjRe
if (_player->m_mover != _player)
return;
GameObject* go = GetPlayer()->GetMap()->GetGameObject(packet.Guid);
if (!go)
return;
if (GameObject* go = GetPlayer()->GetGameObjectIfCanInteractWith(packet.Guid))
{
if (go->AI()->GossipHello(_player))
return;
if (!go->IsWithinDistInMap(_player, INTERACTION_DISTANCE))
return;
if (go->AI()->GossipHello(_player))
return;
_player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT, go->GetEntry());
_player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT, go->GetEntry());
}
}
void WorldSession::HandleCastSpellOpcode(WorldPackets::Spells::CastSpell& cast)
@@ -979,6 +979,9 @@ class go_celestial_planetarium_access : public GameObjectScript
bool GossipHello(Player* player) override
{
if (go->HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE))
return true;
bool hasKey = true;
if (LockEntry const* lock = sLockStore.LookupEntry(go->GetGOInfo()->GetLockId()))
{
@@ -1186,6 +1186,7 @@ class npc_brann_bronzebeard_ulduar_intro : public CreatureScript
{
if (menuId == GOSSIP_MENU_BRANN_BRONZEBEARD && gossipListId == GOSSIP_OPTION_BRANN_BRONZEBEARD)
{
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
player->PlayerTalkClass->SendCloseGossip();
if (Creature* loreKeeper = _instance->GetCreature(DATA_LORE_KEEPER_OF_NORGANNON))
loreKeeper->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
@@ -1238,6 +1239,7 @@ class npc_lorekeeper : public CreatureScript
{
if (menuId == GOSSIP_MENU_LORE_KEEPER && gossipListId == GOSSIP_OPTION_LORE_KEEPER)
{
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
player->PlayerTalkClass->SendCloseGossip();
_instance->instance->LoadGrid(364, -16); // make sure leviathan is loaded
@@ -1250,6 +1252,7 @@ class npc_lorekeeper : public CreatureScript
{
if (Creature* brann = _instance->GetCreature(DATA_BRANN_BRONZEBEARD_INTRO))
{
brann->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
delorah->GetMotionMaster()->MovePoint(0, brann->GetPositionX() - 4, brann->GetPositionY(), brann->GetPositionZ());
/// @todo delorah->AI()->Talk(xxxx, brann->GetGUID()); when reached at branz
}
@@ -1636,6 +1636,9 @@ class go_mimiron_hardmode_button : public GameObjectScript
bool OnGossipHello(Player* /*player*/, GameObject* go) override
{
if (go->HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE))
return true;
InstanceScript* instance = go->GetInstanceScript();
if (!instance)
return false;