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

This commit is contained in:
joschiwald committed 2016-02-04 20:43:28 +01:00
1 parent fe2a0fda44
commit 8b6954e81b
9 files changed
+44 -68

No files matched your search

+19 -5
View File
@@ -2406,7 +2406,7 @@ bool Player::CanInteractWithQuestGiver(Object* questGiver)
return false;
}
Creature* Player::GetNPCIfCanInteractWith(ObjectGuid guid, uint32 npcflagmask)
Creature* Player::GetNPCIfCanInteractWith(ObjectGuid const& guid, uint32 npcflagmask)
{
// unit checks
if (!guid)
@@ -2450,7 +2450,21 @@ Creature* Player::GetNPCIfCanInteractWith(ObjectGuid guid, uint32 npcflagmask)
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", "GetGameObjectIfCanInteractWith: GameObject '%s' [GUID: %u] is too far away from player %s [GUID: %u] to be used by him (distance=%f, maximal %f is allowed)", go->GetGOInfo()->name.c_str(),
go->GetGUID().GetCounter(), GetName().c_str(), GetGUID().GetCounter(), go->GetDistance(this), go->GetInteractionDistance());
}
return nullptr;
}
GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid const& guid, GameobjectTypes type) const
{
if (GameObject* go = GetMap()->GetGameObject(guid))
{
@@ -2459,12 +2473,12 @@ GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid guid, GameobjectTy
if (go->IsWithinDistInMap(this, go->GetInteractionDistance()))
return go;
TC_LOG_DEBUG("maps", "GetGameObjectIfCanInteractWith: GameObject '%s' [GUID: %u] is too far away from player %s [GUID: %u] to be used by him (distance=%f, maximal 10 is allowed)", go->GetGOInfo()->name.c_str(),
go->GetGUID().GetCounter(), GetName().c_str(), GetGUID().GetCounter(), go->GetDistance(this));
TC_LOG_DEBUG("maps", "GetGameObjectIfCanInteractWith: GameObject '%s' [GUID: %u] is too far away from player %s [GUID: %u] to be used by him (distance=%f, maximal %f is allowed)", go->GetGOInfo()->name.c_str(),
go->GetGUID().GetCounter(), GetName().c_str(), GetGUID().GetCounter(), go->GetDistance(this), go->GetInteractionDistance());
}
}
return NULL;
return nullptr;
}
bool Player::IsUnderWater() const
+3 -2
View File
@@ -1050,8 +1050,9 @@ class Player : public Unit, public GridObject<Player>
void SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time, bool welcome);
bool CanInteractWithQuestGiver(Object* questGiver);
Creature* GetNPCIfCanInteractWith(ObjectGuid guid, uint32 npcflagmask);
GameObject* GetGameObjectIfCanInteractWith(ObjectGuid guid, GameobjectTypes type) const;
Creature* GetNPCIfCanInteractWith(ObjectGuid const& guid, uint32 npcflagmask);
GameObject* GetGameObjectIfCanInteractWith(ObjectGuid const& guid) const;
GameObject* GetGameObjectIfCanInteractWith(ObjectGuid const& guid, GameobjectTypes type) const;
void ToggleAFK();
void ToggleDND();
+3 -3
View File
@@ -105,7 +105,7 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket& recvData)
GameObject* go = NULL;
if (guid.IsCreatureOrVehicle())
{
unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE);
unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_GOSSIP);
if (!unit)
{
TC_LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - %s not found or you can't interact with him.", guid.ToString().c_str());
@@ -114,10 +114,10 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket& recvData)
}
else if (guid.IsGameObject())
{
go = _player->GetMap()->GetGameObject(guid);
go = _player->GetGameObjectIfCanInteractWith(guid);
if (!go)
{
TC_LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - %s not found.", guid.ToString().c_str());
TC_LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - %s not found or you can't interact with it.", guid.ToString().c_str());
return;
}
}
+1 -42
View File
@@ -292,7 +292,7 @@ void WorldSession::HandleGossipHelloOpcode(WorldPacket& recvData)
ObjectGuid guid;
recvData >> guid;
Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE);
Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_GOSSIP);
if (!unit)
{
TC_LOG_DEBUG("network", "WORLD: HandleGossipHelloOpcode - %s not found or you can not interact with him.", guid.ToString().c_str());
@@ -334,47 +334,6 @@ void WorldSession::HandleGossipHelloOpcode(WorldPacket& recvData)
unit->AI()->sGossipHello(_player);
}
/*void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket& recvData)
{
TC_LOG_DEBUG("network", "WORLD: CMSG_GOSSIP_SELECT_OPTION");
uint32 option;
uint32 unk;
uint64 guid;
std::string code = "";
recvData >> guid >> unk >> option;
if (_player->PlayerTalkClass->GossipOptionCoded(option))
{
TC_LOG_DEBUG("network", "reading string");
recvData >> code;
TC_LOG_DEBUG("network", "string read: %s", code.c_str());
}
Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE);
if (!unit)
{
TC_LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)));
return;
}
// remove fake death
if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
if (!code.empty())
{
if (!Script->GossipSelectWithCode(_player, unit, _player->PlayerTalkClass->GossipOptionSender (option), _player->PlayerTalkClass->GossipOptionAction(option), code.c_str()))
unit->OnGossipSelect (_player, option);
}
else
{
if (!Script->OnGossipSelect (_player, unit, _player->PlayerTalkClass->GossipOptionSender (option), _player->PlayerTalkClass->GossipOptionAction (option)))
unit->OnGossipSelect (_player, option);
}
}*/
void WorldSession::HandleSpiritHealerActivateOpcode(WorldPacket& recvData)
{
TC_LOG_DEBUG("network", "WORLD: CMSG_SPIRIT_HEALER_ACTIVATE");
+1 -1
View File
@@ -75,7 +75,7 @@ void WorldSession::HandleQuestgiverHelloOpcode(WorldPacket& recvData)
TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_HELLO %s", guid.ToString().c_str());
Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE);
Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(guid, 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
@@ -268,11 +268,8 @@ void WorldSession::HandleGameObjectUseOpcode(WorldPacket& recvData)
TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_GAMEOBJ_USE Message [%s]", guid.ToString().c_str());
if (GameObject* obj = GetPlayer()->GetMap()->GetGameObject(guid))
if (GameObject* obj = GetPlayer()->GetGameObjectIfCanInteractWith(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())
@@ -293,17 +290,13 @@ void WorldSession::HandleGameobjectReportUse(WorldPacket& recvPacket)
if (_player->m_mover != _player)
return;
GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid);
if (!go)
return;
if (GameObject* go = GetPlayer()->GetGameObjectIfCanInteractWith(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(WorldPacket& recvPacket)
@@ -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 false;
bool hasKey = true;
if (LockEntry const* lock = sLockStore.LookupEntry(go->GetGOInfo()->goober.lockId))
{
@@ -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
}
@@ -1634,8 +1634,11 @@ class go_mimiron_hardmode_button : public GameObjectScript
public:
go_mimiron_hardmode_button() : GameObjectScript("go_mimiron_hardmode_button") { }
bool OnGossipHello(Player* /*player*/, GameObject* go)
bool OnGossipHello(Player* /*player*/, GameObject* go) override
{
if (go->HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE))
return false;
InstanceScript* instance = go->GetInstanceScript();
if (!instance)
return false;