diff --git a/src/bindings/universal/ScriptMgr.cpp b/src/bindings/universal/ScriptMgr.cpp index ab8f5ed18..634cc8a9f 100644 --- a/src/bindings/universal/ScriptMgr.cpp +++ b/src/bindings/universal/ScriptMgr.cpp @@ -79,6 +79,18 @@ bool GossipHello ( Player * player, Creature *_Creature ) return tmpscript->pGossipHello(player,_Creature); } +MANGOS_DLL_EXPORT +bool GOGossipHello(Player *pPlayer, GameObject *pGo) +{ + Script *tmpscript = m_scripts[pGo->GetGOInfo()->ScriptId]; + if (!tmpscript || !tmpscript->pGOGossipHello) + return false; + + pPlayer->PlayerTalkClass->ClearMenus(); + + return tmpscript->pGOGossipHello(pPlayer, pGo); +} + MANGOS_DLL_EXPORT bool GossipSelect( Player *player, Creature *_Creature,uint32 sender, uint32 action ) { @@ -93,6 +105,20 @@ bool GossipSelect( Player *player, Creature *_Creature,uint32 sender, uint32 act return tmpscript->pGossipSelect(player,_Creature,sender,action); } +MANGOS_DLL_EXPORT +bool GOGossipSelect(Player *pPlayer, GameObject *pGo, uint32 sender, uint32 action) +{ + debug_log("DEBUG: GO Gossip selection, sender: %u, action: %u", sender, action); + + Script *tmpscript = m_scripts[pGo->GetGOInfo()->ScriptId]; + if (!tmpscript || !tmpscript->pGOGossipSelect) + return false; + + pPlayer->PlayerTalkClass->ClearMenus(); + + return tmpscript->pGOGossipSelect(pPlayer, pGo, sender, action); +} + MANGOS_DLL_EXPORT bool GossipSelectWithCode( Player *player, Creature *_Creature, uint32 sender, uint32 action, const char* sCode ) { @@ -107,6 +133,20 @@ bool GossipSelectWithCode( Player *player, Creature *_Creature, uint32 sender, u return tmpscript->pGossipSelectWithCode(player,_Creature,sender,action,sCode); } +MANGOS_DLL_EXPORT +bool GOGossipSelectWithCode(Player *pPlayer, GameObject *pGo, uint32 sender, uint32 action, const char* sCode) +{ + debug_log("DEBUG: GO Gossip selection, sender: %u, action: %u", sender, action); + + Script *tmpscript = m_scripts[pGo->GetGOInfo()->ScriptId]; + if (!tmpscript || !tmpscript->pGOGossipSelectWithCode) + return false; + + pPlayer->PlayerTalkClass->ClearMenus(); + + return tmpscript->pGOGossipSelectWithCode(pPlayer, pGo, sender, action, sCode); +} + MANGOS_DLL_EXPORT bool QuestAccept( Player *player, Creature *_Creature, Quest *_Quest ) { diff --git a/src/bindings/universal/ScriptMgr.h b/src/bindings/universal/ScriptMgr.h index c18bc5265..e5e27f216 100644 --- a/src/bindings/universal/ScriptMgr.h +++ b/src/bindings/universal/ScriptMgr.h @@ -39,7 +39,8 @@ class Aura; struct Script { Script() : - pGossipHello(NULL), pQuestAccept(NULL), pGossipSelect(NULL), pGossipSelectWithCode(NULL), + pGossipHello(NULL), pGOGossipHello(NULL), pQuestAccept(NULL), pGossipSelect(NULL), pGOGossipSelect(NULL), + pGossipSelectWithCode(NULL), pGOGossipSelectWithCode(NULL), pQuestSelect(NULL), pQuestComplete(NULL), pNPCDialogStatus(NULL), pGODialogStatus(NULL), pChooseReward(NULL), pItemHello(NULL), pGOHello(NULL), pAreaTrigger(NULL), pItemQuestAccept(NULL), pGOQuestAccept(NULL), pGOChooseReward(NULL), pItemUse(NULL), pEffectDummyGameObj(NULL), pEffectDummyCreature(NULL), @@ -50,9 +51,12 @@ struct Script // -- Quest/gossip Methods to be scripted -- bool (*pGossipHello )(Player *player, Creature *_Creature); + bool (*pGOGossipHello )(Player *player, GameObject *_GO); bool (*pQuestAccept )(Player *player, Creature *_Creature, Quest const*_Quest ); bool (*pGossipSelect )(Player *player, Creature *_Creature, uint32 sender, uint32 action ); + bool (*pGOGossipSelect )(Player *player, GameObject *_GO, uint32 sender, uint32 action ); bool (*pGossipSelectWithCode)(Player *player, Creature *_Creature, uint32 sender, uint32 action, const char* sCode ); + bool (*pGOGossipSelectWithCode)(Player *player, GameObject *_GO, uint32 sender, uint32 action, const char* sCode ); bool (*pQuestSelect )(Player *player, Creature *_Creature, Quest const*_Quest ); bool (*pQuestComplete )(Player *player, Creature *_Creature, Quest const*_Quest ); uint32 (*pNPCDialogStatus )(Player *player, Creature *_Creature ); diff --git a/src/framework/GameSystem/TypeContainer.h b/src/framework/GameSystem/TypeContainer.h index 8b7bcdea7..eb3f8984d 100644 --- a/src/framework/GameSystem/TypeContainer.h +++ b/src/framework/GameSystem/TypeContainer.h @@ -67,7 +67,7 @@ class TypeUnorderedMapContainer // Insert helpers template static bool insert(ContainerUnorderedMap& elements, KEY_TYPE handle, SPECIFIC_TYPE* obj) { - typename UNORDERED_MAP::iterator i = elements._element.find(handle); + typename UNORDERED_MAP::iterator i = elements._element.find(handle); if (i == elements._element.end()) { elements._element[handle] = obj; @@ -95,7 +95,7 @@ class TypeUnorderedMapContainer // Find helpers template static SPECIFIC_TYPE* find(ContainerUnorderedMap& elements, KEY_TYPE hdl, SPECIFIC_TYPE* /*obj*/) { - typename UNORDERED_MAP::iterator i = elements._element.find(hdl); + typename UNORDERED_MAP::iterator i = elements._element.find(hdl); if (i == elements._element.end()) return NULL; else diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index f30d223a8..7bc403df5 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -201,7 +201,7 @@ template void BattleGround::BroadcastWorker(Do& _do) { for(BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) - if (Player *plr = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER))) + if (Player *plr = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first))) _do(plr); } diff --git a/src/game/GameEventMgr.cpp b/src/game/GameEventMgr.cpp index 0d58740ae..2efaa0853 100644 --- a/src/game/GameEventMgr.cpp +++ b/src/game/GameEventMgr.cpp @@ -594,7 +594,7 @@ void GameEventMgr::GameEventUnspawn(int16 event_id) { sObjectMgr.RemoveCreatureFromGrid(*itr, data); - if( Creature* pCreature = ObjectAccessor::GetCreatureInWorld(MAKE_NEW_GUID(*itr, data->id, HIGHGUID_UNIT)) ) + if (Creature* pCreature = ObjectAccessor::GetCreatureInWorld(ObjectGuid(HIGHGUID_UNIT, data->id, *itr))) pCreature->AddObjectToRemoveList(); } } @@ -612,7 +612,7 @@ void GameEventMgr::GameEventUnspawn(int16 event_id) { sObjectMgr.RemoveGameobjectFromGrid(*itr, data); - if( GameObject* pGameobject = ObjectAccessor::GetGameObjectInWorld(MAKE_NEW_GUID(*itr, data->id, HIGHGUID_GAMEOBJECT)) ) + if( GameObject* pGameobject = ObjectAccessor::GetGameObjectInWorld(ObjectGuid(HIGHGUID_GAMEOBJECT, data->id, *itr)) ) pGameobject->AddObjectToRemoveList(); } } @@ -638,8 +638,7 @@ void GameEventMgr::ChangeEquipOrModel(int16 event_id, bool activate) continue; // Update if spawned - Creature* pCreature = ObjectAccessor::GetCreatureInWorld(MAKE_NEW_GUID(itr->first, data->id,HIGHGUID_UNIT)); - if (pCreature) + if (Creature* pCreature = ObjectAccessor::GetCreatureInWorld(ObjectGuid(HIGHGUID_UNIT, data->id, itr->first))) { if (activate) { diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index e146a0aa6..217690f84 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -930,8 +930,12 @@ void GameObject::Use(Unit* user) Player* player = (Player*)user; - player->PrepareGossipMenu(this, GetGOInfo()->questgiver.gossipID); - player->SendPreparedGossip(this); + if (!Script->GOGossipHello(player, this)) + { + player->PrepareGossipMenu(this, GetGOInfo()->questgiver.gossipID); + player->SendPreparedGossip(this); + } + return; } case GAMEOBJECT_TYPE_CHEST: @@ -1037,8 +1041,11 @@ void GameObject::Use(Unit* user) } else if (info->goober.gossipID) // ...or gossip, if page does not exist { - player->PrepareGossipMenu(this, info->goober.gossipID); - player->SendPreparedGossip(this); + if (!Script->GOGossipHello(player, this)) + { + player->PrepareGossipMenu(this, info->goober.gossipID); + player->SendPreparedGossip(this); + } } if (info->goober.eventId) diff --git a/src/game/GridNotifiers.cpp b/src/game/GridNotifiers.cpp index e654cc7f3..d25078b83 100644 --- a/src/game/GridNotifiers.cpp +++ b/src/game/GridNotifiers.cpp @@ -100,7 +100,7 @@ VisibleNotifier::Notify() #ifdef MANGOS_DEBUG if((sLog.getLogFilter() & LOG_FILTER_VISIBILITY_CHANGES)==0) - sLog.outDebug("Object %u (Type: %u) is out of range (no in active cells set) now for player %u",GUID_LOPART(*itr),GuidHigh2TypeId(GUID_HIPART(*itr)),i_player.GetGUIDLow()); + sLog.outDebug("%s is out of range (no in active cells set) now for player %u",itr->GetString().c_str(),i_player.GetGUIDLow()); #endif } @@ -123,10 +123,10 @@ VisibleNotifier::Notify() i_player.GetSession()->SendPacket(&packet); // send out of range to other players if need - std::set const& oor = i_data.GetOutOfRangeGUIDs(); - for(std::set::const_iterator iter = oor.begin(); iter != oor.end(); ++iter) + std::set const& oor = i_data.GetOutOfRangeGUIDs(); + for(std::set::const_iterator iter = oor.begin(); iter != oor.end(); ++iter) { - if(!IS_PLAYER_GUID(*iter)) + if(!iter->IsPlayer()) continue; if (Player* plr = ObjectAccessor::FindPlayer(*iter)) diff --git a/src/game/Guild.cpp b/src/game/Guild.cpp index 7df4a49fe..9a06194fe 100644 --- a/src/game/Guild.cpp +++ b/src/game/Guild.cpp @@ -551,7 +551,7 @@ void Guild::BroadcastToGuild(WorldSession *session, const std::string& msg, uint for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr) { - Player *pl = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)); + Player *pl = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first)); if (pl && pl->GetSession() && HasRankRight(pl->GetRank(),GR_RIGHT_GCHATLISTEN) && !pl->GetSocial()->HasIgnore(session->GetPlayer()->GetGUIDLow()) ) pl->GetSession()->SendPacket(&data); @@ -568,7 +568,7 @@ void Guild::BroadcastToOfficers(WorldSession *session, const std::string& msg, u WorldPacket data; ChatHandler::FillMessageData(&data, session, CHAT_MSG_OFFICER, language, NULL, 0, msg.c_str(), NULL); - Player *pl = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)); + Player *pl = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first)); if (pl && pl->GetSession() && HasRankRight(pl->GetRank(),GR_RIGHT_OFFCHATLISTEN) && !pl->GetSocial()->HasIgnore(session->GetPlayer()->GetGUIDLow())) pl->GetSession()->SendPacket(&data); @@ -580,7 +580,7 @@ void Guild::BroadcastPacket(WorldPacket *packet) { for(MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr) { - Player *player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)); + Player *player = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first)); if (player) player->GetSession()->SendPacket(packet); } @@ -592,7 +592,7 @@ void Guild::BroadcastPacketToRank(WorldPacket *packet, uint32 rankId) { if (itr->second.RankId == rankId) { - Player *player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)); + Player *player = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first)); if (player) player->GetSession()->SendPacket(packet); } @@ -731,7 +731,7 @@ void Guild::Roster(WorldSession *session /*= NULL*/) } for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr) { - if (Player *pl = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER))) + if (Player *pl = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first))) { data << uint64(pl->GetGUID()); data << uint8(1); @@ -746,7 +746,7 @@ void Guild::Roster(WorldSession *session /*= NULL*/) } else { - data << uint64(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)); + data << uint64(ObjectGuid(HIGHGUID_PLAYER, itr->first).GetRawValue()); data << uint8(0); data << itr->second.Name; data << uint32(itr->second.RankId); @@ -976,7 +976,7 @@ void Guild::DisplayGuildBankContentUpdate(uint8 TabId, int32 slot1, int32 slot2) for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr) { - Player *player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)); + Player *player = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first)); if (!player) continue; @@ -1011,7 +1011,7 @@ void Guild::DisplayGuildBankContentUpdate(uint8 TabId, GuildItemPosCountVec cons for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr) { - Player *player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)); + Player *player = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first)); if (!player) continue; diff --git a/src/game/Guild.h b/src/game/Guild.h index 25dc1ac9f..f3d4184b9 100644 --- a/src/game/Guild.h +++ b/src/game/Guild.h @@ -343,7 +343,7 @@ class Guild void BroadcastWorker(Do& _do, Player* except = NULL) { for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr) - if(Player *player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER))) + if(Player *player = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first))) if(player != except) _do(player); } diff --git a/src/game/LFGHandler.cpp b/src/game/LFGHandler.cpp index 8ec053df9..ddfdd0a6a 100644 --- a/src/game/LFGHandler.cpp +++ b/src/game/LFGHandler.cpp @@ -147,38 +147,59 @@ static void AttemptAddMore(Player* _player) } } -void WorldSession::HandleLfgSetAutoJoinOpcode( WorldPacket & /*recv_data*/ ) +void WorldSession::HandleLfgJoinOpcode( WorldPacket & recv_data ) { - sLog.outDebug("CMSG_LFG_SET_AUTOJOIN"); + sLog.outDebug("CMSG_LFG_JOIN"); LookingForGroup_auto_join = true; + uint8 counter1, counter2; + std::string comment; + + recv_data >> Unused(); // lfg roles + recv_data >> Unused(); // unk1 (unused?) + recv_data >> Unused(); // unk2 (unused?) + + recv_data >> counter1; + for (uint8 i = 0; i < counter1; i++) + recv_data >> Unused(); // queue block? (type/zone?) + + recv_data >> counter2; + for (uint8 i = 0; i < counter2; i++) + recv_data >> Unused(); // unk (unused?) + + recv_data >> comment; // lfg comment + if(!_player) // needed because STATUS_AUTHED return; AttemptJoin(_player); } -void WorldSession::HandleLfgClearAutoJoinOpcode( WorldPacket & /*recv_data*/ ) +void WorldSession::HandleLfgLeaveOpcode( WorldPacket & /*recv_data*/ ) { - sLog.outDebug("CMSG_LFG_CLEAR_AUTOJOIN"); + sLog.outDebug("CMSG_LFG_LEAVE"); LookingForGroup_auto_join = false; } -void WorldSession::HandleLfmSetAutoFillOpcode( WorldPacket & /*recv_data*/ ) +void WorldSession::HandleSearchLfgJoinOpcode( WorldPacket & recv_data ) { - sLog.outDebug("CMSG_LFM_SET_AUTOFILL"); + sLog.outDebug("CMSG_SEARCH_LFG_JOIN"); LookingForGroup_auto_add = true; + recv_data >> Unused(); // join id? + if(!_player) // needed because STATUS_AUTHED return; AttemptAddMore(_player); } -void WorldSession::HandleLfmClearAutoFillOpcode( WorldPacket & /*recv_data*/ ) +void WorldSession::HandleSearchLfgLeaveOpcode( WorldPacket & recv_data ) { - sLog.outDebug("CMSG_LFM_CLEAR_AUTOFILL"); + sLog.outDebug("CMSG_SEARCH_LFG_LEAVE"); LookingForGroup_auto_add = false; + + recv_data >> Unused(); // join id? } void WorldSession::HandleLfgClearOpcode( WorldPacket & /*recv_data */ ) diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp index 97dd213b5..51d30c002 100644 --- a/src/game/Level1.cpp +++ b/src/game/Level1.cpp @@ -261,7 +261,7 @@ bool ChatHandler::HandleGPSCommand(const char* args) { uint64 guid = extractGuidFromLink((char*)args); if(guid) - obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*m_session->GetPlayer(),guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); + obj = (WorldObject*)m_session->GetPlayer()->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_OR_GAMEOBJECT); if(!obj) { diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index e8a3d18c2..91400aede 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -3407,7 +3407,7 @@ bool ChatHandler::HandleGetDistanceCommand(const char* args) { uint64 guid = extractGuidFromLink((char*)args); if(guid) - obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*m_session->GetPlayer(),guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); + obj = (WorldObject*)m_session->GetPlayer()->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_OR_GAMEOBJECT); if(!obj) { diff --git a/src/game/LootHandler.cpp b/src/game/LootHandler.cpp index df258edc3..ef0666e85 100644 --- a/src/game/LootHandler.cpp +++ b/src/game/LootHandler.cpp @@ -453,7 +453,7 @@ void WorldSession::HandleLootMasterGiveOpcode( WorldPacket & recv_data ) return; } - Player *target = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(target_playerguid, 0, HIGHGUID_PLAYER)); + Player *target = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, target_playerguid)); if(!target) return; diff --git a/src/game/Map.cpp b/src/game/Map.cpp index befc8e17c..a1e5a846a 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -205,8 +205,7 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _par i_id(id), i_InstanceId(InstanceId), m_unloadTimer(0), m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE), m_activeNonPlayersIter(m_activeNonPlayers.end()), - i_gridExpiry(expiry), m_parentMap(_parent ? _parent : this), - m_hiDynObjectGuid(1), m_hiPetGuid(1), m_hiVehicleGuid(1) + i_gridExpiry(expiry), m_parentMap(_parent ? _parent : this) { for(unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx) { @@ -3485,6 +3484,49 @@ void Map::ScriptsProcess() pSource->PlayDirectSound(step.script->datalong,pTarget); break; } + case SCRIPT_COMMAND_CREATE_ITEM: + { + if (!target && !source) + { + sLog.outError("SCRIPT_COMMAND_CREATE_ITEM call for NULL object."); + break; + } + + // only Player + if ((!target || target->GetTypeId() != TYPEID_PLAYER) && (!source || source->GetTypeId() != TYPEID_PLAYER)) + { + sLog.outError("SCRIPT_COMMAND_CREATE_ITEM call for non-player (TypeIdSource: %u)(TypeIdTarget: %u), skipping.", source ? source->GetTypeId() : 0, target ? target->GetTypeId() : 0); + break; + } + + Player* pReceiver = target && target->GetTypeId() == TYPEID_PLAYER ? (Player*)target : (Player*)source; + + if (Item* pItem = pReceiver->StoreNewItemInInventorySlot(step.script->datalong, step.script->datalong2)) + pReceiver->SendNewItem(pItem, step.script->datalong2, true, false); + + break; + } + case SCRIPT_COMMAND_DESPAWN_SELF: + { + if (!target && !source) + { + sLog.outError("SCRIPT_COMMAND_DESPAWN_SELF call for NULL object."); + break; + } + + // only creature + if ((!target || target->GetTypeId() != TYPEID_UNIT) && (!source || source->GetTypeId() != TYPEID_UNIT)) + { + sLog.outError("SCRIPT_COMMAND_DESPAWN_SELF call for non-creature (TypeIdSource: %u)(TypeIdTarget: %u), skipping.", source ? source->GetTypeId() : 0, target ? target->GetTypeId() : 0); + break; + } + + Creature* pCreature = target && target->GetTypeId() == TYPEID_UNIT ? (Creature*)target : (Creature*)source; + + pCreature->ForcedDespawn(step.script->datalong); + + break; + } default: sLog.outError("Unknown script command %u called.",step.script->command); break; @@ -3498,22 +3540,22 @@ void Map::ScriptsProcess() return; } -Creature* Map::GetCreature(uint64 guid) +Creature* Map::GetCreature(ObjectGuid guid) { - return m_objectsStore.find(guid, (Creature*)NULL); + return m_objectsStore.find(guid.GetRawValue(), (Creature*)NULL); } -Vehicle* Map::GetVehicle(uint64 guid) +Vehicle* Map::GetVehicle(ObjectGuid guid) { - return m_objectsStore.find(guid, (Vehicle*)NULL); + return m_objectsStore.find(guid.GetRawValue(), (Vehicle*)NULL); } -Pet* Map::GetPet(uint64 guid) +Pet* Map::GetPet(ObjectGuid guid) { - return m_objectsStore.find(guid, (Pet*)NULL); + return m_objectsStore.find(guid.GetRawValue(), (Pet*)NULL); } -Corpse* Map::GetCorpse(uint64 guid) +Corpse* Map::GetCorpse(ObjectGuid guid) { Corpse * ret = ObjectAccessor::GetCorpseInMap(guid,GetId()); if (!ret) @@ -3523,33 +3565,32 @@ Corpse* Map::GetCorpse(uint64 guid) return ret; } -Creature* Map::GetCreatureOrPetOrVehicle(uint64 guid) +Creature* Map::GetCreatureOrPetOrVehicle(ObjectGuid guid) { - if (IS_PLAYER_GUID(guid)) - return NULL; + switch(guid.GetHigh()) + { + case HIGHGUID_UNIT: return GetCreature(guid); + case HIGHGUID_PET: return GetPet(guid); + case HIGHGUID_VEHICLE: return GetVehicle(guid); + default: break; + } - if (IS_PET_GUID(guid)) - return GetPet(guid); - - if (IS_VEHICLE_GUID(guid)) - return GetVehicle(guid); - - return GetCreature(guid); + return NULL; } -GameObject* Map::GetGameObject(uint64 guid) +GameObject* Map::GetGameObject(ObjectGuid guid) { - return m_objectsStore.find(guid, (GameObject*)NULL); + return m_objectsStore.find(guid.GetRawValue(), (GameObject*)NULL); } -DynamicObject* Map::GetDynamicObject(uint64 guid) +DynamicObject* Map::GetDynamicObject(ObjectGuid guid) { - return m_objectsStore.find(guid, (DynamicObject*)NULL); + return m_objectsStore.find(guid.GetRawValue(), (DynamicObject*)NULL); } -WorldObject* Map::GetWorldObject(uint64 guid) +WorldObject* Map::GetWorldObject(ObjectGuid guid) { - switch(GUID_HIPART(guid)) + switch(guid.GetHigh()) { case HIGHGUID_PLAYER: return ObjectAccessor::FindPlayer(guid); case HIGHGUID_GAMEOBJECT: return GetGameObject(guid); @@ -3592,26 +3633,11 @@ uint32 Map::GenerateLocalLowGuid(HighGuid guidhigh) switch(guidhigh) { case HIGHGUID_DYNAMICOBJECT: - if (m_hiDynObjectGuid >= 0xFFFFFFFE) - { - sLog.outError("DynamicObject guid overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } - return m_hiDynObjectGuid++; + return m_DynObjectGuids.Generate(); case HIGHGUID_PET: - if(m_hiPetGuid>=0x00FFFFFE) - { - sLog.outError("Pet guid overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } - return m_hiPetGuid++; + return m_PetGuids.Generate(); case HIGHGUID_VEHICLE: - if(m_hiVehicleGuid>=0x00FFFFFF) - { - sLog.outError("Vehicle guid overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } - return m_hiVehicleGuid++; + return m_VehicleGuids.Generate(); default: ASSERT(0); } diff --git a/src/game/Map.h b/src/game/Map.h index af153a232..bd6c0c952 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -396,14 +396,14 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj void RemoveFromActive(Creature* obj); - Creature* GetCreature(uint64 guid); - Vehicle* GetVehicle(uint64 guid); - Pet* GetPet(uint64 guid); - Creature* GetCreatureOrPetOrVehicle(uint64 guid); - GameObject* GetGameObject(uint64 guid); - DynamicObject* GetDynamicObject(uint64 guid); - Corpse* GetCorpse(uint64 guid); - WorldObject* GetWorldObject(uint64 guid); + Creature* GetCreature(ObjectGuid guid); + Vehicle* GetVehicle(ObjectGuid guid); + Pet* GetPet(ObjectGuid guid); + Creature* GetCreatureOrPetOrVehicle(ObjectGuid guid); + GameObject* GetGameObject(ObjectGuid guid); + DynamicObject* GetDynamicObject(ObjectGuid guid); + Corpse* GetCorpse(ObjectGuid guid); + WorldObject* GetWorldObject(ObjectGuid guid); TypeUnorderedMapContainer& GetObjectsStore() { return m_objectsStore; } @@ -495,9 +495,9 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj std::multimap m_scriptSchedule; // Map local low guid counters - uint32 m_hiDynObjectGuid; - uint32 m_hiPetGuid; - uint32 m_hiVehicleGuid; + ObjectGuidGenerator m_DynObjectGuids; + ObjectGuidGenerator m_PetGuids; + ObjectGuidGenerator m_VehicleGuids; // Type specific code for add/remove to/from grid template diff --git a/src/game/MotionMaster.cpp b/src/game/MotionMaster.cpp index 5e473f142..b02188278 100644 --- a/src/game/MotionMaster.cpp +++ b/src/game/MotionMaster.cpp @@ -28,6 +28,7 @@ #include "PointMovementGenerator.h" #include "TargetedMovementGenerator.h" #include "WaypointMovementGenerator.h" +#include "RandomMovementGenerator.h" #include @@ -209,6 +210,19 @@ void MotionMaster::MoveIdle() push(&si_idleMovement); } +void MotionMaster::MoveRandom() +{ + if (i_owner->GetTypeId() == TYPEID_PLAYER) + { + sLog.outError("Player (GUID: %u) attempt to move random.", i_owner->GetGUIDLow()); + } + else + { + DEBUG_LOG("Creature (Entry: %u GUID: %u) move random.", i_owner->GetEntry(), i_owner->GetGUIDLow()); + Mutate(new RandomMovementGenerator(*i_owner)); + } +} + void MotionMaster::MoveTargetedHome() { diff --git a/src/game/MotionMaster.h b/src/game/MotionMaster.h index 5ed08f72c..139387a71 100644 --- a/src/game/MotionMaster.h +++ b/src/game/MotionMaster.h @@ -95,6 +95,7 @@ class MANGOS_DLL_SPEC MotionMaster : private std::stack } void MoveIdle(); + void MoveRandom(); void MoveTargetedHome(); void MoveFollow(Unit* target, float dist, float angle); void MoveChase(Unit* target, float dist = 0.0f, float angle = 0.0f); diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp index cfdf7fa81..ffb3752a5 100644 --- a/src/game/NPCHandler.cpp +++ b/src/game/NPCHandler.cpp @@ -304,8 +304,6 @@ void WorldSession::HandleGossipSelectOptionOpcode( WorldPacket & recv_data ) if (GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); - // TODO: determine if scriptCall is needed for GO and also if scriptCall can be same as current, with modified argument WorldObject* - // can vehicle have gossip? If so, need check for this also. if (IS_CREATURE_OR_PET_GUID(guid)) { @@ -338,7 +336,16 @@ void WorldSession::HandleGossipSelectOptionOpcode( WorldPacket & recv_data ) return; } - _player->OnGossipSelect(pGo, gossipListId, menuId); + if (!code.empty()) + { + if (!Script->GOGossipSelectWithCode(_player, pGo, _player->PlayerTalkClass->GossipOptionSender(gossipListId), _player->PlayerTalkClass->GossipOptionAction(gossipListId), code.c_str())) + _player->OnGossipSelect(pGo, gossipListId, menuId); + } + else + { + if (!Script->GOGossipSelect(_player, pGo, _player->PlayerTalkClass->GossipOptionSender(gossipListId), _player->PlayerTalkClass->GossipOptionAction(gossipListId))) + _player->OnGossipSelect(pGo, gossipListId, menuId); + } } } diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp index df80b8130..d2330fc78 100644 --- a/src/game/ObjectAccessor.cpp +++ b/src/game/ObjectAccessor.cpp @@ -54,12 +54,12 @@ ObjectAccessor::~ObjectAccessor() } Unit* -ObjectAccessor::GetUnit(WorldObject const &u, uint64 guid) +ObjectAccessor::GetUnit(WorldObject const &u, ObjectGuid guid) { - if(!guid) + if(guid.IsEmpty()) return NULL; - if(IS_PLAYER_GUID(guid)) + if(guid.IsPlayer()) return FindPlayer(guid); if (!u.IsInWorld()) @@ -68,7 +68,7 @@ ObjectAccessor::GetUnit(WorldObject const &u, uint64 guid) return u.GetMap()->GetCreatureOrPetOrVehicle(guid); } -Corpse* ObjectAccessor::GetCorpseInMap( uint64 guid, uint32 mapid ) +Corpse* ObjectAccessor::GetCorpseInMap(ObjectGuid guid, uint32 mapid) { Corpse * ret = HashMapHolder::Find(guid); if(!ret) @@ -79,49 +79,8 @@ Corpse* ObjectAccessor::GetCorpseInMap( uint64 guid, uint32 mapid ) return ret; } -Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const &p, uint64 guid, uint32 typemask) -{ - switch(GUID_HIPART(guid)) - { - case HIGHGUID_ITEM: - if(typemask & TYPEMASK_ITEM && p.GetTypeId() == TYPEID_PLAYER) - return ((Player const &)p).GetItemByGuid( guid ); - break; - case HIGHGUID_PLAYER: - if(typemask & TYPEMASK_PLAYER) - return FindPlayer(guid); - break; - case HIGHGUID_GAMEOBJECT: - if(typemask & TYPEMASK_GAMEOBJECT) - return p.GetMap()->GetGameObject(guid); - break; - case HIGHGUID_UNIT: - if(typemask & TYPEMASK_UNIT) - return p.GetMap()->GetCreature(guid); - break; - case HIGHGUID_PET: - if(typemask & TYPEMASK_UNIT) - return p.GetMap()->GetPet(guid); - break; - case HIGHGUID_VEHICLE: - if(typemask & TYPEMASK_UNIT) - return p.GetMap()->GetVehicle(guid); - break; - case HIGHGUID_DYNAMICOBJECT: - if(typemask & TYPEMASK_DYNAMICOBJECT) - return p.GetMap()->GetDynamicObject(guid); - break; - case HIGHGUID_TRANSPORT: - case HIGHGUID_CORPSE: - case HIGHGUID_MO_TRANSPORT: - break; - } - - return NULL; -} - Player* -ObjectAccessor::FindPlayer(uint64 guid) +ObjectAccessor::FindPlayer(ObjectGuid guid) { Player * plr = HashMapHolder::Find(guid);; if(!plr || !plr->IsInWorld()) @@ -163,11 +122,11 @@ void ObjectAccessor::KickPlayer(uint64 guid) } Corpse* -ObjectAccessor::GetCorpseForPlayerGUID(uint64 guid) +ObjectAccessor::GetCorpseForPlayerGUID(ObjectGuid guid) { Guard guard(i_corpseGuard); - Player2CorpsesMapType::iterator iter = i_player2corpse.find(guid); + Player2CorpsesMapType::iterator iter = i_player2corpse.find(guid.GetRawValue()); if( iter == i_player2corpse.end() ) return NULL; assert(iter->second->GetType() != CORPSE_BONES); @@ -234,7 +193,7 @@ ObjectAccessor::AddCorpsesToGrid(GridPair const& gridpair,GridType& grid,Map* ma } Corpse* -ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid, bool insignia) +ObjectAccessor::ConvertCorpseForPlayer(ObjectGuid player_guid, bool insignia) { Corpse *corpse = GetCorpseForPlayerGUID(player_guid); if(!corpse) diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h index d704045b3..e704f10fe 100644 --- a/src/game/ObjectAccessor.h +++ b/src/game/ObjectAccessor.h @@ -58,9 +58,9 @@ class HashMapHolder m_objectMap.erase(o->GetGUID()); } - static T* Find(uint64 guid) + static T* Find(ObjectGuid guid) { - typename MapType::iterator itr = m_objectMap.find(guid); + typename MapType::iterator itr = m_objectMap.find(guid.GetRawValue()); return (itr != m_objectMap.end()) ? itr->second : NULL; } @@ -89,18 +89,17 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton Player2CorpsesMapType; // global (obj used for map only location local guid objects (pets currently) - static Unit* GetUnitInWorld(WorldObject const& obj, uint64 guid); + static Unit* GetUnitInWorld(WorldObject const& obj, ObjectGuid guid); // FIXME: map local object with global search - static Creature* GetCreatureInWorld(uint64 guid) { return FindHelper(guid); } - static GameObject* GetGameObjectInWorld(uint64 guid) { return FindHelper(guid); } + static Creature* GetCreatureInWorld(ObjectGuid guid) { return FindHelper(guid); } + static GameObject* GetGameObjectInWorld(ObjectGuid guid) { return FindHelper(guid); } // possible local search for specific object map - static Object* GetObjectByTypeMask(WorldObject const &, uint64, uint32 typemask); - static Unit* GetUnit(WorldObject const &, uint64); + static Unit* GetUnit(WorldObject const &, ObjectGuid guid); // Player access - static Player* FindPlayer(uint64 guid); + static Player* FindPlayer(ObjectGuid guid); static Player* FindPlayerByName(const char *name); static void KickPlayer(uint64 guid); @@ -112,12 +111,12 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton::Insert(object); } @@ -132,11 +131,11 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton static OBJECT* FindHelper(uint64 guid) + template static OBJECT* FindHelper(ObjectGuid guid) { for (std::list::const_iterator i = i_mapList.begin() ; i != i_mapList.end(); ++i) { - if (OBJECT* ret = (*i)->GetObjectsStore().find(guid, (OBJECT*)NULL)) + if (OBJECT* ret = (*i)->GetObjectsStore().find(guid.GetRawValue(), (OBJECT*)NULL)) return ret; } @@ -154,15 +153,15 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::SingletonGetPet(guid) : NULL; return GetCreatureInWorld(guid); diff --git a/src/game/ObjectGuid.cpp b/src/game/ObjectGuid.cpp index ac12891f0..1c543bd0c 100644 --- a/src/game/ObjectGuid.cpp +++ b/src/game/ObjectGuid.cpp @@ -17,22 +17,25 @@ */ #include "ObjectGuid.h" + +#include "World.h" + #include -char const* ObjectGuid::GetTypeName() const +char const* ObjectGuid::GetTypeName(HighGuid high) { - switch(GetHigh()) + switch(high) { - case HIGHGUID_ITEM: return "item"; - case HIGHGUID_PLAYER: return !IsEmpty() ? "player" : "none"; - case HIGHGUID_GAMEOBJECT: return "gameobject"; - case HIGHGUID_TRANSPORT: return "transport"; - case HIGHGUID_UNIT: return "creature"; - case HIGHGUID_PET: return "pet"; - case HIGHGUID_VEHICLE: return "vehicle"; - case HIGHGUID_DYNAMICOBJECT:return "dynobject"; - case HIGHGUID_CORPSE: return "corpse"; - case HIGHGUID_MO_TRANSPORT: return "mo_transport"; + case HIGHGUID_ITEM: return "Item"; + case HIGHGUID_PLAYER: return "Player"; + case HIGHGUID_GAMEOBJECT: return "Gameobject"; + case HIGHGUID_TRANSPORT: return "Transport"; + case HIGHGUID_UNIT: return "Creature"; + case HIGHGUID_PET: return "Pet"; + case HIGHGUID_VEHICLE: return "Vehicle"; + case HIGHGUID_DYNAMICOBJECT:return "DynObject"; + case HIGHGUID_CORPSE: return "Corpse"; + case HIGHGUID_MO_TRANSPORT: return "MoTransport"; default: return ""; } @@ -48,6 +51,17 @@ std::string ObjectGuid::GetString() const return str.str(); } +template +uint32 ObjectGuidGenerator::Generate() +{ + if (m_nextGuid >= ObjectGuid::GetMaxCounter(high)-1) + { + sLog.outError("%s guid overflow!! Can't continue, shutting down server. ",ObjectGuid::GetTypeName(high)); + World::StopNow(ERROR_EXIT_CODE); + } + return m_nextGuid++; +} + ByteBuffer& operator<< (ByteBuffer& buf, ObjectGuid const& guid) { buf << uint64(guid.GetRawValue()); @@ -71,3 +85,13 @@ ByteBuffer &operator>>(ByteBuffer& buf, PackedGuidReader const& guid) guid.m_guidPtr->Set(buf.readPackGUID()); return buf; } + +template uint32 ObjectGuidGenerator::Generate(); +template uint32 ObjectGuidGenerator::Generate(); +template uint32 ObjectGuidGenerator::Generate(); +template uint32 ObjectGuidGenerator::Generate(); +template uint32 ObjectGuidGenerator::Generate(); +template uint32 ObjectGuidGenerator::Generate(); +template uint32 ObjectGuidGenerator::Generate(); +template uint32 ObjectGuidGenerator::Generate(); +template uint32 ObjectGuidGenerator::Generate(); diff --git a/src/game/ObjectGuid.h b/src/game/ObjectGuid.h index fca0a8fc4..c8ac65228 100644 --- a/src/game/ObjectGuid.h +++ b/src/game/ObjectGuid.h @@ -41,11 +41,16 @@ enum TypeMask TYPEMASK_OBJECT = 0x0001, TYPEMASK_ITEM = 0x0002, TYPEMASK_CONTAINER = 0x0006, // TYPEMASK_ITEM | 0x0004 - TYPEMASK_UNIT = 0x0008, + TYPEMASK_UNIT = 0x0008, // players also have it TYPEMASK_PLAYER = 0x0010, TYPEMASK_GAMEOBJECT = 0x0020, TYPEMASK_DYNAMICOBJECT = 0x0040, - TYPEMASK_CORPSE = 0x0080 + TYPEMASK_CORPSE = 0x0080, + + // used combinations in Player::GetObjectByTypeMask (TYPEMASK_UNIT case ignore players in call) + TYPEMASK_CREATURE_OR_GAMEOBJECT = TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT, + TYPEMASK_CREATURE_GAMEOBJECT_OR_ITEM = TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT | TYPEMASK_ITEM, + TYPEMASK_CREATURE_GAMEOBJECT_PLAYER_OR_ITEM = TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT | TYPEMASK_ITEM | TYPEMASK_PLAYER, }; enum HighGuid @@ -66,7 +71,6 @@ enum HighGuid //*** Must be replaced by ObjectGuid use *** #define IS_CREATURE_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_UNIT ) #define IS_PET_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_PET ) -#define IS_VEHICLE_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_VEHICLE ) #define IS_CREATURE_OR_PET_GUID(Guid)( IS_CREATURE_GUID(Guid) || IS_PET_GUID(Guid) ) #define IS_PLAYER_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_PLAYER && Guid!=0 ) #define IS_UNIT_GUID(Guid) ( IS_CREATURE_OR_PET_GUID(Guid) || IS_PLAYER_GUID(Guid) ) @@ -128,6 +132,7 @@ class ObjectGuid ObjectGuid() : m_guid(0) {} ObjectGuid(uint64 const& guid) : m_guid(guid) {} // NOTE: must be explicit in future for more strict control type conversions ObjectGuid(HighGuid hi, uint32 entry, uint32 counter) : m_guid(uint64(counter) | (uint64(entry) << 24) | (uint64(hi) << 48)) {} + ObjectGuid(HighGuid hi, uint32 counter) : m_guid(uint64(counter) | (uint64(hi) << 48)) {} public: // modifiers PackedGuidReader ReadAsPacked() { return PackedGuidReader(*this); } @@ -136,6 +141,8 @@ class ObjectGuid // Possible removed in future for more strict control type conversions void operator= (uint64 const& guid) { m_guid = guid; } + + PackedGuid WriteAsPacked() const; public: // accessors uint64 const& GetRawValue() const { return m_guid; } HighGuid GetHigh() const { return HighGuid((m_guid >> 48) & 0x0000FFFF); } @@ -147,11 +154,21 @@ class ObjectGuid : uint32(m_guid & UI64LIT(0x00000000FFFFFFFF)); } + static uint32 GetMaxCounter(HighGuid high) + { + return HasEntry(high) + ? uint32(0x00FFFFFF) + : uint32(0xFFFFFFFF); + } + + uint32 GetMaxCounter() const { return GetMaxCounter(GetHigh()); } + bool IsEmpty() const { return m_guid == 0; } bool IsCreature() const { return GetHigh() == HIGHGUID_UNIT; } bool IsPet() const { return GetHigh() == HIGHGUID_PET; } bool IsVehicle() const { return GetHigh() == HIGHGUID_VEHICLE; } bool IsCreatureOrPet() const { return IsCreature() || IsPet(); } + bool IsCreatureOrVehicle() const { return IsCreature() || IsVehicle(); } bool IsPlayer() const { return !IsEmpty() && GetHigh() == HIGHGUID_PLAYER; } bool IsUnit() const { return IsCreatureOrPet() || IsPlayer(); } bool IsItem() const { return GetHigh() == HIGHGUID_ITEM; } @@ -161,9 +178,9 @@ class ObjectGuid bool IsTransport() const { return GetHigh() == HIGHGUID_TRANSPORT; } bool IsMOTransport() const { return GetHigh() == HIGHGUID_MO_TRANSPORT; } - TypeID GetTypeId() + static TypeID GetTypeId(HighGuid high) { - switch(GetHigh()) + switch(high) { case HIGHGUID_ITEM: return TYPEID_ITEM; //case HIGHGUID_CONTAINER: return TYPEID_CONTAINER; HIGHGUID_CONTAINER==HIGHGUID_ITEM currently @@ -180,14 +197,19 @@ class ObjectGuid } } - PackedGuid WriteAsPacked() const; + TypeID GetTypeId() const { return GetTypeId(GetHigh()); } + + bool operator< (ObjectGuid const& guid) const { return GetRawValue() < guid.GetRawValue(); } + public: // accessors - for debug - char const* GetTypeName() const; + static char const* GetTypeName(HighGuid high); + char const* GetTypeName() const { return !IsEmpty() ? GetTypeName(GetHigh()) : "None"; } std::string GetString() const; + private: // internal functions - bool HasEntry() const + static bool HasEntry(HighGuid high) { - switch(GetHigh()) + switch(high) { case HIGHGUID_ITEM: case HIGHGUID_PLAYER: @@ -205,6 +227,8 @@ class ObjectGuid } } + bool HasEntry() const { return HasEntry(GetHigh()); } + private: // fields uint64 m_guid; }; @@ -229,6 +253,23 @@ class PackedGuid ByteBuffer m_packedGuid; }; +template +class ObjectGuidGenerator +{ + public: // constructors + explicit ObjectGuidGenerator(uint32 start = 1) : m_nextGuid(start) {} + + public: // modifiers + void Set(uint32 val) { m_nextGuid = val; } + uint32 Generate(); + + public: // accessors + uint32 GetNextAfterMaxUsed() const { return m_nextGuid; } + + private: // fields + uint32 m_nextGuid; +}; + ByteBuffer& operator<< (ByteBuffer& buf, ObjectGuid const& guid); ByteBuffer& operator>> (ByteBuffer& buf, ObjectGuid& guid); diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 75fa6412c..b6997b746 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -45,6 +45,8 @@ #include "WaypointManager.h" #include "GossipDef.h" +#include + INSTANTIATE_SINGLETON_1(ObjectMgr); ScriptMapMap sQuestEndScripts; @@ -128,22 +130,30 @@ bool SpellClickInfo::IsFitToRequirements(Player const* player) const return true; } -ObjectMgr::ObjectMgr() +template +T IdGenerator::Generate() { - m_hiCharGuid = 1; - m_hiCreatureGuid = 1; - m_hiItemGuid = 1; - m_hiGoGuid = 1; - m_hiCorpseGuid = 1; - m_hiPetNumber = 1; - m_ItemTextId = 1; - m_mailid = 1; - m_equipmentSetGuid = 1; - m_guildId = 1; - m_arenaTeamId = 1; - m_auctionid = 1; - m_groupId = 1; + if (m_nextGuid >= std::numeric_limits::max()-1) + { + sLog.outError("%s guid overflow!! Can't continue, shutting down server. ",m_name); + World::StopNow(ERROR_EXIT_CODE); + } + return m_nextGuid++; +} +template uint32 IdGenerator::Generate(); +template uint64 IdGenerator::Generate(); + +ObjectMgr::ObjectMgr() : + m_ArenaTeamIds("Arena team ids"), + m_AuctionIds("Auction ids"), + m_EquipmentSetIds("Equipment set ids"), + m_GuildIds("Guild ids"), + m_ItemTextIds("Item text ids"), + m_MailIds("Mail ids"), + m_PetNumbers("Pet numbers"), + m_GroupIds("Group ids") +{ // Only zero condition left, others will be added while loading DB tables mConditions.resize(1); } @@ -4360,6 +4370,27 @@ void ObjectMgr::LoadScripts(ScriptMapMap& scripts, char const* tablename) } break; } + case SCRIPT_COMMAND_CREATE_ITEM: + { + if (!GetItemPrototype(tmp.datalong)) + { + sLog.outErrorDb("Table `%s` has nonexistent item (entry: %u) in SCRIPT_COMMAND_CREATE_ITEM for script id %u", + tablename, tmp.datalong, tmp.id); + continue; + } + if (!tmp.datalong2) + { + sLog.outErrorDb("Table `%s` SCRIPT_COMMAND_CREATE_ITEM but amount is %u for script id %u", + tablename, tmp.datalong2, tmp.id); + continue; + } + break; + } + case SCRIPT_COMMAND_DESPAWN_SELF: + { + // for later, we might consider despawn by database guid, and define in datalong2 as option to despawn self. + break; + } } if (scripts.find(tmp.id) == scripts.end()) @@ -5658,7 +5689,7 @@ void ObjectMgr::PackGroupIds() bar.step(); } - m_groupId = groupId; + m_GroupIds.Set(groupId); sLog.outString( ">> Group Ids remapped, next group id is %u", groupId ); sLog.outString(); @@ -5669,164 +5700,94 @@ void ObjectMgr::SetHighestGuids() QueryResult *result = CharacterDatabase.Query( "SELECT MAX(guid) FROM characters" ); if( result ) { - m_hiCharGuid = (*result)[0].GetUInt32()+1; + m_CharGuids.Set((*result)[0].GetUInt32()+1); delete result; } result = WorldDatabase.Query( "SELECT MAX(guid) FROM creature" ); if( result ) { - m_hiCreatureGuid = (*result)[0].GetUInt32()+1; + m_CreatureGuids.Set((*result)[0].GetUInt32()+1); delete result; } result = CharacterDatabase.Query( "SELECT MAX(guid) FROM item_instance" ); if( result ) { - m_hiItemGuid = (*result)[0].GetUInt32()+1; + m_ItemGuids.Set((*result)[0].GetUInt32()+1); delete result; } // Cleanup other tables from not existed guids (>=m_hiItemGuid) - CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item >= '%u'", m_hiItemGuid); - CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid >= '%u'", m_hiItemGuid); - CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE itemguid >= '%u'", m_hiItemGuid); - CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE item_guid >= '%u'", m_hiItemGuid); + CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item >= '%u'", m_ItemGuids.GetNextAfterMaxUsed()); + CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid >= '%u'", m_ItemGuids.GetNextAfterMaxUsed()); + CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE itemguid >= '%u'", m_ItemGuids.GetNextAfterMaxUsed()); + CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE item_guid >= '%u'", m_ItemGuids.GetNextAfterMaxUsed()); result = WorldDatabase.Query("SELECT MAX(guid) FROM gameobject" ); if( result ) { - m_hiGoGuid = (*result)[0].GetUInt32()+1; + m_GameobjectGuids.Set((*result)[0].GetUInt32()+1); delete result; } result = CharacterDatabase.Query("SELECT MAX(id) FROM auctionhouse" ); if( result ) { - m_auctionid = (*result)[0].GetUInt32()+1; + m_AuctionIds.Set((*result)[0].GetUInt32()+1); delete result; } result = CharacterDatabase.Query( "SELECT MAX(id) FROM mail" ); if( result ) { - m_mailid = (*result)[0].GetUInt32()+1; + m_MailIds.Set((*result)[0].GetUInt32()+1); delete result; } result = CharacterDatabase.Query( "SELECT MAX(id) FROM item_text" ); if( result ) { - m_ItemTextId = (*result)[0].GetUInt32()+1; + m_ItemTextIds.Set((*result)[0].GetUInt32()+1); delete result; } result = CharacterDatabase.Query( "SELECT MAX(guid) FROM corpse" ); if( result ) { - m_hiCorpseGuid = (*result)[0].GetUInt32()+1; + m_CorpseGuids.Set((*result)[0].GetUInt32()+1); delete result; } result = CharacterDatabase.Query("SELECT MAX(arenateamid) FROM arena_team"); if (result) { - m_arenaTeamId = (*result)[0].GetUInt32()+1; + m_ArenaTeamIds.Set((*result)[0].GetUInt32()+1); delete result; } result = CharacterDatabase.Query("SELECT MAX(setguid) FROM character_equipmentsets"); if (result) { - m_equipmentSetGuid = (*result)[0].GetUInt64()+1; + m_EquipmentSetIds.Set((*result)[0].GetUInt64()+1); delete result; } result = CharacterDatabase.Query( "SELECT MAX(guildid) FROM guild" ); if (result) { - m_guildId = (*result)[0].GetUInt32()+1; + m_GuildIds.Set((*result)[0].GetUInt32()+1); delete result; } result = CharacterDatabase.Query( "SELECT MAX(groupId) FROM groups" ); if (result) { - m_groupId = (*result)[0].GetUInt32()+1; + m_GroupIds.Set((*result)[0].GetUInt32()+1); delete result; } } -uint32 ObjectMgr::GenerateArenaTeamId() -{ - if(m_arenaTeamId>=0xFFFFFFFE) - { - sLog.outError("Arena team ids overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } - return m_arenaTeamId++; -} - -uint32 ObjectMgr::GenerateAuctionID() -{ - if(m_auctionid>=0xFFFFFFFE) - { - sLog.outError("Auctions ids overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } - return m_auctionid++; -} - -uint64 ObjectMgr::GenerateEquipmentSetGuid() -{ - if(m_equipmentSetGuid>=0xFFFFFFFFFFFFFFFEll) - { - sLog.outError("EquipmentSet guid overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } - return m_equipmentSetGuid++; -} - -uint32 ObjectMgr::GenerateGuildId() -{ - if(m_guildId>=0xFFFFFFFE) - { - sLog.outError("Guild ids overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } - return m_guildId++; -} - -uint32 ObjectMgr::GenerateGroupId() -{ - if(m_groupId>=0xFFFFFFFE) - { - sLog.outError("Group ids overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } - return m_groupId++; -} - -uint32 ObjectMgr::GenerateMailID() -{ - if(m_mailid>=0xFFFFFFFE) - { - sLog.outError("Mail ids overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } - return m_mailid++; -} - -uint32 ObjectMgr::GenerateItemTextID() -{ - if(m_ItemTextId>=0xFFFFFFFE) - { - sLog.outError("Item text ids overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } - return m_ItemTextId++; -} - uint32 ObjectMgr::CreateItemText(std::string text) { uint32 newItemTextId = GenerateItemTextID(); @@ -5846,40 +5807,15 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh) switch(guidhigh) { case HIGHGUID_ITEM: - if(m_hiItemGuid>=0xFFFFFFFE) - { - sLog.outError("Item guid overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } - return m_hiItemGuid++; + return m_ItemGuids.Generate(); case HIGHGUID_UNIT: - if(m_hiCreatureGuid>=0x00FFFFFE) - { - sLog.outError("Creature guid overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } - return m_hiCreatureGuid++; + return m_CreatureGuids.Generate(); case HIGHGUID_PLAYER: - if(m_hiCharGuid>=0xFFFFFFFE) - { - sLog.outError("Players guid overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } - return m_hiCharGuid++; + return m_CharGuids.Generate(); case HIGHGUID_GAMEOBJECT: - if(m_hiGoGuid>=0x00FFFFFE) - { - sLog.outError("Gameobject guid overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } - return m_hiGoGuid++; + return m_GameobjectGuids.Generate(); case HIGHGUID_CORPSE: - if(m_hiCorpseGuid>=0xFFFFFFFE) - { - sLog.outError("Corpse guid overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } - return m_hiCorpseGuid++; + return m_CorpseGuids.Generate(); default: ASSERT(0); } @@ -6291,7 +6227,7 @@ void ObjectMgr::LoadPetNumber() if(result) { Field *fields = result->Fetch(); - m_hiPetNumber = fields[0].GetUInt32()+1; + m_PetNumbers.Set(fields[0].GetUInt32()+1); delete result; } @@ -6299,7 +6235,7 @@ void ObjectMgr::LoadPetNumber() bar.step(); sLog.outString(); - sLog.outString( ">> Loaded the max pet number: %d", m_hiPetNumber-1); + sLog.outString( ">> Loaded the max pet number: %d", m_PetNumbers.GetNextAfterMaxUsed()-1); } std::string ObjectMgr::GeneratePetName(uint32 entry) @@ -6319,11 +6255,6 @@ std::string ObjectMgr::GeneratePetName(uint32 entry) return *(list0.begin()+urand(0, list0.size()-1)) + *(list1.begin()+urand(0, list1.size()-1)); } -uint32 ObjectMgr::GeneratePetNumber() -{ - return ++m_hiPetNumber; -} - void ObjectMgr::LoadCorpses() { uint32 count = 0; diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index e565570ae..c16b3d73b 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -372,6 +372,24 @@ MANGOS_DLL_SPEC LanguageDesc const* GetLanguageDescByID(uint32 lang); class PlayerDumpReader; +template +class IdGenerator +{ + public: // constructors + explicit IdGenerator(char const* _name) : m_name(_name), m_nextGuid(1) {} + + public: // modifiers + void Set(T val) { m_nextGuid = val; } + T Generate(); + + public: // accessors + T GetNextAfterMaxUsed() const { return m_nextGuid; } + + private: // fields + char const* m_name; + T m_nextGuid; +}; + class ObjectMgr { friend class PlayerDumpReader; @@ -653,14 +671,14 @@ class ObjectMgr void SetHighestGuids(); uint32 GenerateLowGuid(HighGuid guidhigh); - uint32 GenerateArenaTeamId(); - uint32 GenerateAuctionID(); - uint64 GenerateEquipmentSetGuid(); - uint32 GenerateGuildId(); - uint32 GenerateGroupId(); - uint32 GenerateItemTextID(); - uint32 GenerateMailID(); - uint32 GeneratePetNumber(); + uint32 GenerateArenaTeamId() { return m_ArenaTeamIds.Generate(); } + uint32 GenerateAuctionID() { return m_AuctionIds.Generate(); } + uint64 GenerateEquipmentSetGuid() { return m_EquipmentSetIds.Generate(); } + uint32 GenerateGuildId() { return m_GuildIds.Generate(); } + uint32 GenerateGroupId() { return m_GroupIds.Generate(); } + uint32 GenerateItemTextID() { return m_ItemGuids.Generate(); } + uint32 GenerateMailID() { return m_MailIds.Generate(); } + uint32 GeneratePetNumber() { return m_PetNumbers.Generate(); } uint32 CreateItemText(std::string text); void AddItemText(uint32 itemTextId, std::string text) { mItemTexts[itemTextId] = text; } @@ -889,21 +907,21 @@ class ObjectMgr protected: // first free id for selected id type - uint32 m_arenaTeamId; - uint32 m_auctionid; - uint64 m_equipmentSetGuid; - uint32 m_guildId; - uint32 m_ItemTextId; - uint32 m_mailid; - uint32 m_hiPetNumber; - uint32 m_groupId; + IdGenerator m_ArenaTeamIds; + IdGenerator m_AuctionIds; + IdGenerator m_EquipmentSetIds; + IdGenerator m_GuildIds; + IdGenerator m_ItemTextIds; + IdGenerator m_MailIds; + IdGenerator m_PetNumbers; + IdGenerator m_GroupIds; // first free low guid for selected guid type - uint32 m_hiCharGuid; - uint32 m_hiCreatureGuid; - uint32 m_hiItemGuid; - uint32 m_hiGoGuid; - uint32 m_hiCorpseGuid; + ObjectGuidGenerator m_CharGuids; + ObjectGuidGenerator m_CreatureGuids; + ObjectGuidGenerator m_ItemGuids; + ObjectGuidGenerator m_GameobjectGuids; + ObjectGuidGenerator m_CorpseGuids; QuestMap mQuestTemplates; diff --git a/src/game/ObjectPosSelector.cpp b/src/game/ObjectPosSelector.cpp index 8a97b9644..af9bbb1ab 100644 --- a/src/game/ObjectPosSelector.cpp +++ b/src/game/ObjectPosSelector.cpp @@ -17,6 +17,7 @@ */ #include "ObjectPosSelector.h" +#include "Object.h" ObjectPosSelector::ObjectPosSelector(float x,float y,float size,float dist) : m_center_x(x),m_center_y(y),m_size(size),m_dist(dist) diff --git a/src/game/Opcodes.cpp b/src/game/Opcodes.cpp index 8d84bd205..13ae0795a 100644 --- a/src/game/Opcodes.cpp +++ b/src/game/Opcodes.cpp @@ -886,10 +886,10 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x359*/ { "MSG_MOVE_START_ASCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, /*0x35A*/ { "MSG_MOVE_STOP_ASCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, /*0x35B*/ { "SMSG_ARENA_TEAM_STATS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x35C*/ { "CMSG_LFG_JOIN", STATUS_LOGGEDIN, &WorldSession::HandleLfgSetAutoJoinOpcode }, - /*0x35D*/ { "CMSG_LFG_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleLfgClearAutoJoinOpcode }, - /*0x35E*/ { "CMSG_SEARCH_LFG_JOIN", STATUS_LOGGEDIN, &WorldSession::HandleLfmSetAutoFillOpcode }, - /*0x35F*/ { "CMSG_SEARCH_LFG_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleLfmClearAutoFillOpcode }, + /*0x35C*/ { "CMSG_LFG_JOIN", STATUS_LOGGEDIN, &WorldSession::HandleLfgJoinOpcode }, + /*0x35D*/ { "CMSG_LFG_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleLfgLeaveOpcode }, + /*0x35E*/ { "CMSG_SEARCH_LFG_JOIN", STATUS_LOGGEDIN, &WorldSession::HandleSearchLfgJoinOpcode }, + /*0x35F*/ { "CMSG_SEARCH_LFG_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleSearchLfgLeaveOpcode }, /*0x360*/ { "SMSG_UPDATE_LFG_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x361*/ { "SMSG_LFG_PROPOSAL_DECLINED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x362*/ { "CMSG_LFG_PROPOSAL_RESULT", STATUS_LOGGEDIN, &WorldSession::Handle_NULL }, diff --git a/src/game/Player.cpp b/src/game/Player.cpp index c827a9287..1c1291e43 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -17678,12 +17678,13 @@ void Player::HandleStealthedUnitsDetection() { if(!hasAtClient) { + ObjectGuid i_guid = (*i)->GetGUID(); (*i)->SendCreateUpdateToPlayer(this); - m_clientGUIDs.insert((*i)->GetGUID()); + m_clientGUIDs.insert(i_guid); #ifdef MANGOS_DEBUG if((sLog.getLogFilter() & LOG_FILTER_VISIBILITY_CHANGES)==0) - sLog.outDebug("Object %u (Type: %u) is detected in stealth by player %u. Distance = %f",(*i)->GetGUIDLow(),(*i)->GetTypeId(),GetGUIDLow(),GetDistance(*i)); + sLog.outDebug("%s is detected in stealth by player %u. Distance = %f",i_guid.GetString().c_str(),GetGUIDLow(),GetDistance(*i)); #endif // target aura duration for caster show only if target exist at caster client @@ -18853,12 +18854,14 @@ void Player::UpdateVisibilityOf(WorldObject const* viewPoint, WorldObject* targe if (target->GetTypeId()==TYPEID_UNIT) BeforeVisibilityDestroy((Creature*)target,this); + ObjectGuid t_guid = target->GetGUID(); + target->DestroyForPlayer(this); - m_clientGUIDs.erase(target->GetGUID()); + m_clientGUIDs.erase(t_guid); #ifdef MANGOS_DEBUG if((sLog.getLogFilter() & LOG_FILTER_VISIBILITY_CHANGES)==0) - sLog.outDebug("Object %u (Type: %u) out of range for player %u. Distance = %f",target->GetGUIDLow(),target->GetTypeId(),GetGUIDLow(),GetDistance(target)); + sLog.outDebug("%s out of range for player %u. Distance = %f",t_guid.GetString().c_str(),GetGUIDLow(),GetDistance(target)); #endif } } @@ -18887,13 +18890,13 @@ void Player::UpdateVisibilityOf(WorldObject const* viewPoint, WorldObject* targe } template -inline void UpdateVisibilityOf_helper(std::set& s64, T* target) +inline void UpdateVisibilityOf_helper(std::set& s64, T* target) { s64.insert(target->GetGUID()); } template<> -inline void UpdateVisibilityOf_helper(std::set& s64, GameObject* target) +inline void UpdateVisibilityOf_helper(std::set& s64, GameObject* target) { if(!target->IsTransport()) s64.insert(target->GetGUID()); @@ -18908,12 +18911,14 @@ void Player::UpdateVisibilityOf(WorldObject const* viewPoint, T* target, UpdateD { BeforeVisibilityDestroy(target,this); + ObjectGuid t_guid = target->GetGUID(); + target->BuildOutOfRangeUpdateBlock(&data); - m_clientGUIDs.erase(target->GetGUID()); + m_clientGUIDs.erase(t_guid); #ifdef MANGOS_DEBUG if((sLog.getLogFilter() & LOG_FILTER_VISIBILITY_CHANGES)==0) - sLog.outDebug("Object %u (Type: %u, Entry: %u) is out of range for player %u. Distance = %f",target->GetGUIDLow(),target->GetTypeId(),target->GetEntry(),GetGUIDLow(),GetDistance(target)); + sLog.outDebug("%s is out of range for player %u. Distance = %f",t_guid.GetString().c_str(),GetGUIDLow(),GetDistance(target)); #endif } } @@ -19539,13 +19544,12 @@ void Player::UpdateForQuestWorldObjects() WorldPacket packet; for(ClientGUIDs::const_iterator itr=m_clientGUIDs.begin(); itr!=m_clientGUIDs.end(); ++itr) { - if(IS_GAMEOBJECT_GUID(*itr)) + if (itr->IsGameobject()) { - GameObject *obj = GetMap()->GetGameObject(*itr); - if(obj) + if (GameObject *obj = GetMap()->GetGameObject(*itr)) obj->BuildValuesUpdateBlockForPlayer(&udata,this); } - else if(IS_CREATURE_GUID(*itr) || IS_VEHICLE_GUID(*itr)) + else if (itr->IsCreatureOrVehicle()) { Creature *obj = GetMap()->GetCreatureOrPetOrVehicle(*itr); if(!obj) @@ -21705,3 +21709,46 @@ void Player::SetHomebindToLocation(WorldLocation const& loc, uint32 area_id) CharacterDatabase.PExecute("UPDATE character_homebind SET map = '%u', zone = '%u', position_x = '%f', position_y = '%f', position_z = '%f' WHERE guid = '%u'", m_homebindMapId, m_homebindAreaId, m_homebindX, m_homebindY, m_homebindZ, GetGUIDLow()); } + +Object* Player::GetObjectByTypeMask(ObjectGuid guid, TypeMask typemask) +{ + switch(guid.GetHigh()) + { + case HIGHGUID_ITEM: + if (typemask & TYPEMASK_ITEM) + return GetItemByGuid(guid.GetRawValue()); + break; + case HIGHGUID_PLAYER: + if (GetGUID()==guid.GetRawValue()) + return this; + if ((typemask & TYPEMASK_PLAYER) && IsInWorld()) + return ObjectAccessor::FindPlayer(guid.GetRawValue()); + break; + case HIGHGUID_GAMEOBJECT: + if ((typemask & TYPEMASK_GAMEOBJECT) && IsInWorld()) + return GetMap()->GetGameObject(guid); + break; + case HIGHGUID_UNIT: + if ((typemask & TYPEMASK_UNIT) && IsInWorld()) + return GetMap()->GetCreature(guid); + break; + case HIGHGUID_PET: + if ((typemask & TYPEMASK_UNIT) && IsInWorld()) + return GetMap()->GetPet(guid); + break; + case HIGHGUID_VEHICLE: + if ((typemask & TYPEMASK_UNIT) && IsInWorld()) + return GetMap()->GetVehicle(guid); + break; + case HIGHGUID_DYNAMICOBJECT: + if ((typemask & TYPEMASK_DYNAMICOBJECT) && IsInWorld()) + return GetMap()->GetDynamicObject(guid); + break; + case HIGHGUID_TRANSPORT: + case HIGHGUID_CORPSE: + case HIGHGUID_MO_TRANSPORT: + break; + } + + return NULL; +} diff --git a/src/game/Player.h b/src/game/Player.h index 27222522a..f274762c7 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -2179,8 +2179,10 @@ class MANGOS_DLL_SPEC Player : public Unit void RelocateToHomebind() { SetLocationMapId(m_homebindMapId); Relocate(m_homebindX, m_homebindY, m_homebindZ); } bool TeleportToHomebind(uint32 options = 0) { return TeleportTo(m_homebindMapId, m_homebindX, m_homebindY, m_homebindZ, GetOrientation(), options); } + Object* GetObjectByTypeMask(ObjectGuid guid, TypeMask typemask); + // currently visible objects at player client - typedef std::set ClientGUIDs; + typedef std::set ClientGUIDs; ClientGUIDs m_clientGUIDs; bool HaveAtClient(WorldObject const* u) { return u==this || m_clientGUIDs.find(u->GetGUID())!=m_clientGUIDs.end(); } diff --git a/src/game/PlayerDump.cpp b/src/game/PlayerDump.cpp index 532ff4454..669bf654a 100644 --- a/src/game/PlayerDump.cpp +++ b/src/game/PlayerDump.cpp @@ -416,18 +416,18 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s // make sure the same guid doesn't already exist and is safe to use bool incHighest = true; - if (guid != 0 && guid < sObjectMgr.m_hiCharGuid) + if (guid != 0 && guid < sObjectMgr.m_CharGuids.GetNextAfterMaxUsed()) { result = CharacterDatabase.PQuery("SELECT * FROM characters WHERE guid = '%d'", guid); if (result) { - guid = sObjectMgr.m_hiCharGuid; // use first free if exists + guid = sObjectMgr.m_CharGuids.GetNextAfterMaxUsed(); delete result; } else incHighest = false; } else - guid = sObjectMgr.m_hiCharGuid; + guid = sObjectMgr.m_CharGuids.GetNextAfterMaxUsed(); // normalize the name if specified and check if it exists if (!normalizePlayerName(name)) @@ -536,7 +536,7 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s if(!changetoknth(vals, OBJECT_FIELD_GUID+1, newguid)) ROLLBACK(DUMP_FILE_BROKEN); for(uint16 field = PLAYER_FIELD_INV_SLOT_HEAD; field < PLAYER_FARSIGHT; field++) - if(!changetokGuid(vals, field+1, items, sObjectMgr.m_hiItemGuid, true)) + if (!changetokGuid(vals, field+1, items, sObjectMgr.m_ItemGuids.GetNextAfterMaxUsed(), true)) ROLLBACK(DUMP_FILE_BROKEN); if(!changenth(line, 3, vals.c_str())) ROLLBACK(DUMP_FILE_BROKEN); @@ -562,40 +562,40 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s } case DTT_INVENTORY: // character_inventory t. { - if(!changenth(line, 1, newguid)) + if (!changenth(line, 1, newguid)) ROLLBACK(DUMP_FILE_BROKEN); // bag, item - if(!changeGuid(line, 2, items, sObjectMgr.m_hiItemGuid, true)) + if (!changeGuid(line, 2, items, sObjectMgr.m_ItemGuids.GetNextAfterMaxUsed(), true)) ROLLBACK(DUMP_FILE_BROKEN); - if(!changeGuid(line, 4, items, sObjectMgr.m_hiItemGuid)) + if (!changeGuid(line, 4, items, sObjectMgr.m_ItemGuids.GetNextAfterMaxUsed())) ROLLBACK(DUMP_FILE_BROKEN); break; } case DTT_ITEM: // item_instance t. { // item, owner, data field:item, owner guid - if(!changeGuid(line, 1, items, sObjectMgr.m_hiItemGuid)) + if (!changeGuid(line, 1, items, sObjectMgr.m_ItemGuids.GetNextAfterMaxUsed())) ROLLBACK(DUMP_FILE_BROKEN); - if(!changenth(line, 2, newguid)) + if (!changenth(line, 2, newguid)) ROLLBACK(DUMP_FILE_BROKEN); std::string vals = getnth(line,3); - if(!changetokGuid(vals, OBJECT_FIELD_GUID+1, items, sObjectMgr.m_hiItemGuid)) + if (!changetokGuid(vals, OBJECT_FIELD_GUID+1, items, sObjectMgr.m_ItemGuids.GetNextAfterMaxUsed())) ROLLBACK(DUMP_FILE_BROKEN); - if(!changetoknth(vals, ITEM_FIELD_OWNER+1, newguid)) + if (!changetoknth(vals, ITEM_FIELD_OWNER+1, newguid)) ROLLBACK(DUMP_FILE_BROKEN); - //if(!changetokGuid(vals, ITEM_FIELD_ITEM_TEXT_ID+1, itemTexts, sObjectMgr.m_ItemTextId,true)) + //if (!changetokGuid(vals, ITEM_FIELD_ITEM_TEXT_ID+1, itemTexts, sObjectMgr.m_ItemTextIds.GetNextAfterMaxUsed(), true)) // ROLLBACK(DUMP_FILE_BROKEN); - if(!changenth(line, 3, vals.c_str())) + if (!changenth(line, 3, vals.c_str())) ROLLBACK(DUMP_FILE_BROKEN); break; } case DTT_ITEM_GIFT: // character_gift { // guid,item_guid, - if(!changenth(line, 1, newguid)) + if (!changenth(line, 1, newguid)) ROLLBACK(DUMP_FILE_BROKEN); - if(!changeGuid(line, 2, items, sObjectMgr.m_hiItemGuid)) + if (!changeGuid(line, 2, items, sObjectMgr.m_ItemGuids.GetNextAfterMaxUsed())) ROLLBACK(DUMP_FILE_BROKEN); break; } @@ -603,8 +603,10 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s { //store a map of old pet id to new inserted pet id for use by type 5 tables snprintf(currpetid, 20, "%s", getnth(line, 1).c_str()); - if(strlen(lastpetid)==0) snprintf(lastpetid, 20, "%s", currpetid); - if(strcmp(lastpetid,currpetid)!=0) + if (strlen(lastpetid)==0) + snprintf(lastpetid, 20, "%s", currpetid); + + if (strcmp(lastpetid,currpetid)!=0) { snprintf(newpetid, 20, "%d", sObjectMgr.GeneratePetNumber()); snprintf(lastpetid, 20, "%s", currpetid); @@ -612,15 +614,15 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s std::map :: const_iterator petids_iter = petids.find(atoi(currpetid)); - if(petids_iter == petids.end()) + if (petids_iter == petids.end()) { petids.insert(PetIdsPair(atoi(currpetid), atoi(newpetid))); } // item, entry, owner, ... - if(!changenth(line, 1, newpetid)) + if (!changenth(line, 1, newpetid)) ROLLBACK(DUMP_FILE_BROKEN); - if(!changenth(line, 3, newguid)) + if (!changenth(line, 3, newguid)) ROLLBACK(DUMP_FILE_BROKEN); break; @@ -631,12 +633,12 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s // lookup currpetid and match to new inserted pet id std::map :: const_iterator petids_iter = petids.find(atoi(currpetid)); - if(petids_iter == petids.end()) // couldn't find new inserted id + if (petids_iter == petids.end()) // couldn't find new inserted id ROLLBACK(DUMP_FILE_BROKEN); snprintf(newpetid, 20, "%d", petids_iter->second); - if(!changenth(line, 1, newpetid)) + if (!changenth(line, 1, newpetid)) ROLLBACK(DUMP_FILE_BROKEN); break; @@ -644,29 +646,29 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s case DTT_MAIL: // mail { // id,messageType,stationery,mailtemplate,sender,receiver,subject,itemText - if(!changeGuid(line, 1, mails, sObjectMgr.m_mailid)) + if (!changeGuid(line, 1, mails, sObjectMgr.m_MailIds.GetNextAfterMaxUsed())) ROLLBACK(DUMP_FILE_BROKEN); - if(!changenth(line, 6, newguid)) + if (!changenth(line, 6, newguid)) ROLLBACK(DUMP_FILE_BROKEN); - if(!changeGuid(line, 8, itemTexts, sObjectMgr.m_ItemTextId)) + if (!changeGuid(line, 8, itemTexts, sObjectMgr.m_ItemTextIds.GetNextAfterMaxUsed())) ROLLBACK(DUMP_FILE_BROKEN); break; } case DTT_MAIL_ITEM: // mail_items { // mail_id,item_guid,item_template,receiver - if(!changeGuid(line, 1, mails, sObjectMgr.m_mailid)) + if (!changeGuid(line, 1, mails, sObjectMgr.m_MailIds.GetNextAfterMaxUsed())) ROLLBACK(DUMP_FILE_BROKEN); - if(!changeGuid(line, 2, items, sObjectMgr.m_hiItemGuid)) + if (!changeGuid(line, 2, items, sObjectMgr.m_ItemGuids.GetNextAfterMaxUsed())) ROLLBACK(DUMP_FILE_BROKEN); - if(!changenth(line, 4, newguid)) + if (!changenth(line, 4, newguid)) ROLLBACK(DUMP_FILE_BROKEN); break; } case DTT_ITEM_TEXT: // item_text { // id - if(!changeGuid(line, 1, itemTexts, sObjectMgr.m_ItemTextId)) + if (!changeGuid(line, 1, itemTexts, sObjectMgr.m_ItemTextIds.GetNextAfterMaxUsed())) ROLLBACK(DUMP_FILE_BROKEN); // add it to cache @@ -686,12 +688,13 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s CharacterDatabase.CommitTransaction(); - sObjectMgr.m_hiItemGuid += items.size(); - sObjectMgr.m_mailid += mails.size(); - sObjectMgr.m_ItemTextId += itemTexts.size(); + //FIXME: current code with post-updating guids not safe for future per-map threads + sObjectMgr.m_ItemGuids.Set(sObjectMgr.m_ItemGuids.GetNextAfterMaxUsed() + items.size()); + sObjectMgr.m_MailIds.Set(sObjectMgr.m_MailIds.GetNextAfterMaxUsed() + mails.size()); + sObjectMgr.m_ItemTextIds.Set(sObjectMgr.m_ItemTextIds.GetNextAfterMaxUsed() + itemTexts.size()); if(incHighest) - ++sObjectMgr.m_hiCharGuid; + sObjectMgr.m_CharGuids.Set(sObjectMgr.m_CharGuids.GetNextAfterMaxUsed()+1); fclose(fin); diff --git a/src/game/PoolManager.cpp b/src/game/PoolManager.cpp index bf6068494..1efbdf2a9 100644 --- a/src/game/PoolManager.cpp +++ b/src/game/PoolManager.cpp @@ -206,7 +206,7 @@ void PoolGroup::Despawn1Object(uint32 guid) { sObjectMgr.RemoveCreatureFromGrid(guid, data); - if (Creature* pCreature = ObjectAccessor::GetCreatureInWorld(MAKE_NEW_GUID(guid, data->id, HIGHGUID_UNIT))) + if (Creature* pCreature = ObjectAccessor::GetCreatureInWorld(ObjectGuid(HIGHGUID_UNIT, data->id, guid))) pCreature->AddObjectToRemoveList(); } } @@ -219,7 +219,7 @@ void PoolGroup::Despawn1Object(uint32 guid) { sObjectMgr.RemoveGameobjectFromGrid(guid, data); - if (GameObject* pGameobject = ObjectAccessor::GetGameObjectInWorld(MAKE_NEW_GUID(guid, data->id, HIGHGUID_GAMEOBJECT))) + if (GameObject* pGameobject = ObjectAccessor::GetGameObjectInWorld(ObjectGuid(HIGHGUID_GAMEOBJECT, data->id, guid))) pGameobject->AddObjectToRemoveList(); } } @@ -403,7 +403,7 @@ template <> void PoolGroup::ReSpawn1Object(PoolObject* obj) { if (GameObjectData const* data = sObjectMgr.GetGOData(obj->guid)) - if (GameObject* pGameobject = ObjectAccessor::GetGameObjectInWorld(MAKE_NEW_GUID(obj->guid, data->id, HIGHGUID_GAMEOBJECT))) + if (GameObject* pGameobject = ObjectAccessor::GetGameObjectInWorld(ObjectGuid(HIGHGUID_GAMEOBJECT, data->id, obj->guid))) pGameobject->GetMap()->Add(pGameobject); } diff --git a/src/game/QuestHandler.cpp b/src/game/QuestHandler.cpp index fdac5cbf4..e925099af 100644 --- a/src/game/QuestHandler.cpp +++ b/src/game/QuestHandler.cpp @@ -37,7 +37,7 @@ void WorldSession::HandleQuestgiverStatusQueryOpcode( WorldPacket & recv_data ) uint8 questStatus = DIALOG_STATUS_NONE; uint8 defstatus = DIALOG_STATUS_NONE; - Object* questgiver = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); + Object* questgiver = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_OR_GAMEOBJECT); if(!questgiver) { sLog.outDetail("Error in CMSG_QUESTGIVER_STATUS_QUERY, called for not found questgiver (Typeid: %u GUID: %u)",GuidHigh2TypeId(GUID_HIPART(guid)),GUID_LOPART(guid)); @@ -118,7 +118,7 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode( WorldPacket & recv_data ) sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc = %u, quest = %u, unk1 = %u", uint32(GUID_LOPART(guid)), quest, unk1 ); - Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT|TYPEMASK_ITEM|TYPEMASK_PLAYER); + Object* pObject = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_GAMEOBJECT_PLAYER_OR_ITEM); // no or incorrect quest giver if(!pObject @@ -234,7 +234,7 @@ void WorldSession::HandleQuestgiverQueryQuestOpcode( WorldPacket & recv_data ) sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_QUERY_QUEST npc = %u, quest = %u, unk1 = %u", uint32(GUID_LOPART(guid)), quest, unk1 ); // Verify that the guid is valid and is a questgiver or involved in the requested quest - Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT|TYPEMASK_ITEM); + Object* pObject = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_GAMEOBJECT_OR_ITEM); if(!pObject||!pObject->hasQuest(quest) && !pObject->hasInvolvedQuest(quest)) { _player->PlayerTalkClass->CloseGossip(); @@ -278,7 +278,7 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode( WorldPacket & recv_data ) sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %u, quest = %u, reward = %u",uint32(GUID_LOPART(guid)),quest,reward ); - Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); + Object* pObject = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_OR_GAMEOBJECT); if(!pObject) return; @@ -328,7 +328,7 @@ void WorldSession::HandleQuestgiverRequestRewardOpcode( WorldPacket & recv_data sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_REQUEST_REWARD npc = %u, quest = %u",uint32(GUID_LOPART(guid)),quest ); - Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); + Object* pObject = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_OR_GAMEOBJECT); if(!pObject||!pObject->hasInvolvedQuest(quest)) return; @@ -644,7 +644,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket uint8 questStatus = DIALOG_STATUS_NONE; uint8 defstatus = DIALOG_STATUS_NONE; - if (IS_CREATURE_OR_PET_GUID(*itr)) + if (itr->IsCreatureOrPet()) { // need also pet quests case support Creature *questgiver = GetPlayer()->GetMap()->GetCreatureOrPetOrVehicle(*itr); @@ -660,7 +660,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket data << uint8(questStatus); ++count; } - else if(IS_GAMEOBJECT_GUID(*itr)) + else if (itr->IsGameobject()) { GameObject *questgiver = GetPlayer()->GetMap()->GetGameObject(*itr); if(!questgiver) diff --git a/src/game/ScriptCalls.cpp b/src/game/ScriptCalls.cpp index 0040a1617..c5f77ddde 100644 --- a/src/game/ScriptCalls.cpp +++ b/src/game/ScriptCalls.cpp @@ -58,10 +58,13 @@ bool LoadScriptingModule(char const* libName) ||!(testScript->ScriptsFree =(scriptCallScriptsFree )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"ScriptsFree" )) ||!(testScript->ScriptsVersion =(scriptCallScriptsVersion )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"ScriptsVersion" )) ||!(testScript->GossipHello =(scriptCallGossipHello )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GossipHello" )) + ||!(testScript->GOGossipHello =(scriptCallGOGossipHello )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GOGossipHello" )) ||!(testScript->GOChooseReward =(scriptCallGOChooseReward )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GOChooseReward" )) ||!(testScript->QuestAccept =(scriptCallQuestAccept )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"QuestAccept" )) ||!(testScript->GossipSelect =(scriptCallGossipSelect )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GossipSelect" )) + ||!(testScript->GOGossipSelect =(scriptCallGOGossipSelect )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GOGossipSelect" )) ||!(testScript->GossipSelectWithCode=(scriptCallGossipSelectWithCode)MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GossipSelectWithCode")) + ||!(testScript->GOGossipSelectWithCode=(scriptCallGOGossipSelectWithCode)MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GOGossipSelectWithCode")) ||!(testScript->QuestSelect =(scriptCallQuestSelect )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"QuestSelect" )) ||!(testScript->QuestComplete =(scriptCallQuestComplete )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"QuestComplete" )) ||!(testScript->NPCDialogStatus =(scriptCallNPCDialogStatus )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"NPCDialogStatus" )) diff --git a/src/game/ScriptCalls.h b/src/game/ScriptCalls.h index 281deb113..7747c917f 100644 --- a/src/game/ScriptCalls.h +++ b/src/game/ScriptCalls.h @@ -41,9 +41,12 @@ typedef void(MANGOS_IMPORT * scriptCallScriptsFree) (); typedef char const* (MANGOS_IMPORT * scriptCallScriptsVersion) (); typedef bool(MANGOS_IMPORT * scriptCallGossipHello) (Player *player, Creature *_Creature ); +typedef bool(MANGOS_IMPORT * scriptCallGOGossipHello) (Player *player, GameObject *_GO); typedef bool(MANGOS_IMPORT * scriptCallQuestAccept) (Player *player, Creature *_Creature, Quest const *); typedef bool(MANGOS_IMPORT * scriptCallGossipSelect)(Player *player, Creature *_Creature, uint32 sender, uint32 action); +typedef bool(MANGOS_IMPORT * scriptCallGOGossipSelect)(Player *player, GameObject *_GO, uint32 sender, uint32 action); typedef bool(MANGOS_IMPORT * scriptCallGossipSelectWithCode)( Player *player, Creature *_Creature, uint32 sender, uint32 action, const char* sCode ); +typedef bool(MANGOS_IMPORT * scriptCallGOGossipSelectWithCode)( Player *player, GameObject *_GO, uint32 sender, uint32 action, const char* sCode ); typedef bool(MANGOS_IMPORT * scriptCallQuestSelect)( Player *player, Creature *_Creature, Quest const* ); typedef bool(MANGOS_IMPORT * scriptCallQuestComplete)(Player *player, Creature *_Creature, Quest const*); typedef uint32(MANGOS_IMPORT * scriptCallNPCDialogStatus)( Player *player, Creature *_Creature); @@ -70,10 +73,13 @@ typedef struct scriptCallScriptsVersion ScriptsVersion; scriptCallGossipHello GossipHello; + scriptCallGOGossipHello GOGossipHello; scriptCallGOChooseReward GOChooseReward; scriptCallQuestAccept QuestAccept; scriptCallGossipSelect GossipSelect; + scriptCallGOGossipSelect GOGossipSelect; scriptCallGossipSelectWithCode GossipSelectWithCode; + scriptCallGOGossipSelectWithCode GOGossipSelectWithCode; scriptCallQuestSelect QuestSelect; scriptCallQuestComplete QuestComplete; scriptCallNPCDialogStatus NPCDialogStatus; diff --git a/src/game/SocialMgr.cpp b/src/game/SocialMgr.cpp index 17c1f9400..0d358df92 100644 --- a/src/game/SocialMgr.cpp +++ b/src/game/SocialMgr.cpp @@ -281,7 +281,7 @@ void SocialMgr::BroadcastToFriendListers(Player *player, WorldPacket *packet) PlayerSocialMap::const_iterator itr2 = itr->second.m_playerSocialMap.find(guid); if(itr2 != itr->second.m_playerSocialMap.end() && (itr2->second.Flags & SOCIAL_FLAG_FRIEND)) { - Player *pFriend = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)); + Player *pFriend = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first)); // PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters // MODERATOR, GAME MASTER, ADMINISTRATOR can see all diff --git a/src/game/Spell.h b/src/game/Spell.h index a09c7c0e7..86520d6c6 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -51,7 +51,9 @@ enum SpellCastTargetFlags TARGET_FLAG_UNK1 = 0x00004000, // 199 spells, opening object/lock TARGET_FLAG_CORPSE = 0x00008000, // pguid, resurrection spells TARGET_FLAG_UNK2 = 0x00010000, // pguid, not used in any spells as of 3.0.3 (can be set dynamically) - TARGET_FLAG_GLYPH = 0x00020000 // used in glyph spells + TARGET_FLAG_GLYPH = 0x00020000, // used in glyph spells + TARGET_FLAG_UNK3 = 0x00040000, // + TARGET_FLAG_UNK4 = 0x00080000 // uint32, loop { vec3, guid -> if guid == 0 break } }; enum SpellCastFlags diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 9fb6fe619..2538c2c56 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -8936,7 +8936,8 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 case 5142: // Increased Lightning Damage case 5147: // Improved Consecration / Libram of Resurgence case 5148: // Idol of the Shooting Star - case 6008: // Increased Lightning Damage / Totem of Hex + case 6008: // Increased Lightning Damage + case 8627: // Totem of Hex { DoneTotal+=(*i)->GetModifier()->m_amount; break; @@ -9035,6 +9036,18 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 } break; } + case SPELLFAMILY_PRIEST: + { + // Glyph of Smite + if (spellProto->SpellFamilyFlags & UI64LIT(0x00000080)) + { + // Holy Fire + if (pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, UI64LIT(0x00100000), NULL)) + if (Aura *aur = GetAura(55692, EFFECT_INDEX_0)) + DoneTotalMod *= (aur->GetModifier()->m_amount+100.0f) / 100.0f; + } + break; + } case SPELLFAMILY_DEATHKNIGHT: { // Icy Touch, Howling Blast and Frost Strike diff --git a/src/game/UpdateData.cpp b/src/game/UpdateData.cpp index 49105bfad..ec3ba1434 100644 --- a/src/game/UpdateData.cpp +++ b/src/game/UpdateData.cpp @@ -23,18 +23,19 @@ #include "Log.h" #include "Opcodes.h" #include "World.h" +#include "ObjectGuid.h" #include UpdateData::UpdateData() : m_blockCount(0) { } -void UpdateData::AddOutOfRangeGUID(std::set& guids) +void UpdateData::AddOutOfRangeGUID(std::set& guids) { m_outOfRangeGUIDs.insert(guids.begin(),guids.end()); } -void UpdateData::AddOutOfRangeGUID(const uint64 &guid) +void UpdateData::AddOutOfRangeGUID(ObjectGuid const &guid) { m_outOfRangeGUIDs.insert(guid); } @@ -114,10 +115,8 @@ bool UpdateData::BuildPacket(WorldPacket *packet) buf << (uint8) UPDATETYPE_OUT_OF_RANGE_OBJECTS; buf << (uint32) m_outOfRangeGUIDs.size(); - for(std::set::const_iterator i = m_outOfRangeGUIDs.begin(); i != m_outOfRangeGUIDs.end(); ++i) - { - buf.appendPackGUID(*i); - } + for(std::set::const_iterator i = m_outOfRangeGUIDs.begin(); i != m_outOfRangeGUIDs.end(); ++i) + buf << i->WriteAsPacked(); } buf.append(m_data); diff --git a/src/game/UpdateData.h b/src/game/UpdateData.h index e4e583b60..d6845b286 100644 --- a/src/game/UpdateData.h +++ b/src/game/UpdateData.h @@ -22,7 +22,7 @@ #include "ByteBuffer.h" class WorldPacket; - +class ObjectGuid; enum OBJECT_UPDATE_TYPE { @@ -54,18 +54,18 @@ class UpdateData public: UpdateData(); - void AddOutOfRangeGUID(std::set& guids); - void AddOutOfRangeGUID(const uint64 &guid); + void AddOutOfRangeGUID(std::set& guids); + void AddOutOfRangeGUID(ObjectGuid const &guid); void AddUpdateBlock(const ByteBuffer &block); bool BuildPacket(WorldPacket *packet); bool HasData() { return m_blockCount > 0 || !m_outOfRangeGUIDs.empty(); } void Clear(); - std::set const& GetOutOfRangeGUIDs() const { return m_outOfRangeGUIDs; } + std::set const& GetOutOfRangeGUIDs() const { return m_outOfRangeGUIDs; } protected: uint32 m_blockCount; - std::set m_outOfRangeGUIDs; + std::set m_outOfRangeGUIDs; ByteBuffer m_data; void Compress(void* dst, uint32 *dst_size, void* src, int src_size); diff --git a/src/game/World.cpp b/src/game/World.cpp index 0f785b3bb..7d9f3d757 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -725,6 +725,8 @@ void World::LoadConfigSettings(bool reload) setConfig(CONFIG_BOOL_OFFHAND_CHECK_AT_TALENTS_RESET, "OffhandCheckAtTalentsReset", false); + setConfig(CONFIG_BOOL_KICK_PLAYER_ON_BAD_PACKET, "Network.KickOnBadPacket", false); + if(int clientCacheId = sConfig.GetIntDefault("ClientCacheVersion", 0)) { // overwrite DB/old value diff --git a/src/game/World.h b/src/game/World.h index 72642d34d..3c201437c 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -301,6 +301,7 @@ enum eConfigBoolValues CONFIG_BOOL_ARENA_AUTO_DISTRIBUTE_POINTS, CONFIG_BOOL_ARENA_QUEUE_ANNOUNCER_JOIN, CONFIG_BOOL_ARENA_QUEUE_ANNOUNCER_EXIT, + CONFIG_BOOL_KICK_PLAYER_ON_BAD_PACKET, CONFIG_BOOL_VALUE_COUNT }; @@ -368,6 +369,8 @@ enum RealmZone #define SCRIPT_COMMAND_REMOVE_AURA 14 // source (datalong2!=0) or target (datalong==0) unit, datalong = spell_id #define SCRIPT_COMMAND_CAST_SPELL 15 // source/target cast spell at target/source (script->datalong2: 0: s->t 1: s->s 2: t->t 3: t->s #define SCRIPT_COMMAND_PLAY_SOUND 16 // source = any object, target=any/player, datalong (sound_id), datalong2 (bitmask: 0/1=anyone/target, 0/2=with distance dependent, so 1|2 = 3 is target with distance dependent) +#define SCRIPT_COMMAND_CREATE_ITEM 17 // source or target must be player, datalong = item entry, datalong2 = amount +#define SCRIPT_COMMAND_DESPAWN_SELF 18 // source or target must be creature, datalong = despawn delay /// Storage class for commands issued for delayed execution struct CliCommandHolder diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp index 846332c5a..4b3919f34 100644 --- a/src/game/WorldSession.cpp +++ b/src/game/WorldSession.cpp @@ -248,15 +248,23 @@ bool WorldSession::Update(uint32 /*diff*/) break; } } - catch(ByteBufferException &) + catch (ByteBufferException &) { - sLog.outError("WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.", + sLog.outError("WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i.", packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId()); if(sLog.IsOutDebug()) { sLog.outDebug("Dumping error causing packet:"); packet->hexlike(); } + + if (sWorld.getConfig(CONFIG_BOOL_KICK_PLAYER_ON_BAD_PACKET)) + { + sLog.outDetail("Disconnecting session [account id %u / address %s] for badly formatted packet.", + GetAccountId(), GetRemoteAddress().c_str()); + + KickPlayer(); + } } delete packet; diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h index 776b1043e..3c4cd778b 100644 --- a/src/game/WorldSession.h +++ b/src/game/WorldSession.h @@ -641,10 +641,10 @@ class MANGOS_DLL_SPEC WorldSession void HandleSetDungeonDifficultyOpcode(WorldPacket& recv_data); void HandleSetRaidDifficultyOpcode(WorldPacket& recv_data); void HandleMoveSetCanFlyAckOpcode(WorldPacket& recv_data); - void HandleLfgSetAutoJoinOpcode(WorldPacket& recv_data); - void HandleLfgClearAutoJoinOpcode(WorldPacket& recv_data); - void HandleLfmSetAutoFillOpcode(WorldPacket& recv_data); - void HandleLfmClearAutoFillOpcode(WorldPacket& recv_data); + void HandleLfgJoinOpcode(WorldPacket& recv_data); + void HandleLfgLeaveOpcode(WorldPacket& recv_data); + void HandleSearchLfgJoinOpcode(WorldPacket& recv_data); + void HandleSearchLfgLeaveOpcode(WorldPacket& recv_data); void HandleLfgClearOpcode(WorldPacket& recv_data); void HandleLfmClearOpcode(WorldPacket& recv_data); void HandleSetLfmOpcode(WorldPacket& recv_data); diff --git a/src/game/WorldSocket.cpp b/src/game/WorldSocket.cpp index acc4faf9e..c181c8d82 100644 --- a/src/game/WorldSocket.cpp +++ b/src/game/WorldSocket.cpp @@ -713,7 +713,7 @@ int WorldSocket::ProcessIncoming (WorldPacket* new_pct) } catch (ByteBufferException &) { - sLog.outError("WorldSocket::ProcessIncoming ByteBufferException occured while parsing an instant handled packet (opcode: %u) from client %s, accountid=%i. Disconnected client.", + sLog.outError("WorldSocket::ProcessIncoming ByteBufferException occured while parsing an instant handled packet (opcode: %u) from client %s, accountid=%i.", opcode, GetRemoteAddress().c_str(), m_Session?m_Session->GetAccountId():-1); if(sLog.IsOutDebug()) { @@ -721,7 +721,15 @@ int WorldSocket::ProcessIncoming (WorldPacket* new_pct) new_pct->hexlike(); } - return -1; + if (sWorld.getConfig(CONFIG_BOOL_KICK_PLAYER_ON_BAD_PACKET)) + { + sLog.outDetail("Disconnecting session [account id %i / address %s] for badly formatted packet.", + m_Session?m_Session->GetAccountId():-1, GetRemoteAddress().c_str()); + + return -1; + } + else + return 0; } ACE_NOTREACHED (return 0); diff --git a/src/mangosd/mangosd.conf.dist.in b/src/mangosd/mangosd.conf.dist.in index 43e415994..f4abaa1a7 100644 --- a/src/mangosd/mangosd.conf.dist.in +++ b/src/mangosd/mangosd.conf.dist.in @@ -1348,12 +1348,18 @@ Arena.ArenaSeason.InProgress = 1 # Default: 0 (enable Nagle algorithm, less traffic, more latency) # 1 (TCP_NO_DELAY, disable Nagle algorithm, more traffic but less latency) # +# Network.KickOnBadPacket +# Kick player on bad packet format. +# Default: 0 - do not kick +# 1 - kick +# ################################################################################################################### Network.Threads = 1 Network.OutKBuff = -1 Network.OutUBuff = 65536 Network.TcpNodelay = 1 +Network.KickOnBadPacket = 0 ################################################################################################################### # CONSOLE, REMOTE ACCESS AND SOAP diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index a6f00386e..d00a99ed8 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "9565" + #define REVISION_NR "9578" #endif // __REVISION_NR_H__