From b4ea5a6d19264d3b09478f089930c0dd5199b03c Mon Sep 17 00:00:00 2001 From: ApoC Date: Wed, 21 Oct 2009 22:54:26 +0200 Subject: [PATCH 01/10] [8701] Fixes and inprovements in pool system. * Fixed object is removed from guid->object map but still spawned in world under some conditions * Fixed possibility to spawn already spawned object * Fixed objects despawning (missing part for explicitly chanced objects added) Signed-off-by: ApoC --- src/game/Creature.cpp | 2 +- src/game/GameEventMgr.cpp | 4 +- src/game/PoolHandler.cpp | 217 ++++++++++++++++++++------------------ src/game/PoolHandler.h | 11 +- src/shared/revision_nr.h | 2 +- 5 files changed, 123 insertions(+), 113 deletions(-) diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 2a195e7d0..f82474f83 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -369,7 +369,7 @@ void Creature::Update(uint32 diff) uint16 poolid = poolhandler.IsPartOfAPool(GetGUIDLow(), GetTypeId()); if (poolid) - poolhandler.UpdatePool(poolid, GetGUIDLow(), GetTypeId()); + poolhandler.UpdatePool(poolid, GetGUIDLow(), TYPEID_UNIT); else GetMap()->Add(this); } diff --git a/src/game/GameEventMgr.cpp b/src/game/GameEventMgr.cpp index 24f9652bd..99b77722f 100644 --- a/src/game/GameEventMgr.cpp +++ b/src/game/GameEventMgr.cpp @@ -580,7 +580,9 @@ void GameEventMgr::GameEventSpawn(int16 event_id) for (IdList::iterator itr = mGameEventPoolIds[internal_event_id].begin();itr != mGameEventPoolIds[internal_event_id].end();++itr) { - poolhandler.SpawnPool(*itr); + poolhandler.SpawnPool(*itr, 0, 0); + poolhandler.SpawnPool(*itr, 0, TYPEID_GAMEOBJECT); + poolhandler.SpawnPool(*itr, 0, TYPEID_UNIT); } } diff --git a/src/game/PoolHandler.cpp b/src/game/PoolHandler.cpp index fe38d3f82..7824654cb 100644 --- a/src/game/PoolHandler.cpp +++ b/src/game/PoolHandler.cpp @@ -28,13 +28,6 @@ INSTANTIATE_SINGLETON_1(PoolHandler); //////////////////////////////////////////////////////////// // Methods of template class PoolGroup -template -PoolGroup::PoolGroup() -{ - m_SpawnedPoolAmount = 0; - m_LastDespawnedNode = 0; -} - // Method to add a gameobject/creature guid to the proper list depending on pool type and chance value template void PoolGroup::AddEntry(PoolObject& poolitem, uint32 maxentries) @@ -64,35 +57,49 @@ bool PoolGroup::CheckPool(void) template bool PoolGroup::IsSpawnedObject(uint32 guid) { - for (uint32 i=0; i -uint32 PoolGroup::RollOne(void) +void PoolGroup::RollOne(int32& index, PoolObjectList** store, uint32 triggerFrom) { - if (!ExplicitlyChanced.empty()) // First explicitly chanced entries are checked + if (!ExplicitlyChanced.empty()) { - float roll = rand_chance(); + float roll = (float)rand_chance(); - for (uint32 i=0; i::RollOne(void) template void PoolGroup::DespawnObject(uint32 guid) { - for (size_t i=0; i < EqualChanced.size(); ++i) + for (size_t i = 0; i < EqualChanced.size(); ++i) { if (EqualChanced[i].spawned) { if (!guid || EqualChanced[i].guid == guid) { - if (guid) - m_LastDespawnedNode = EqualChanced[i].guid; - else - Despawn1Object(EqualChanced[i].guid); - + Despawn1Object(EqualChanced[i].guid); EqualChanced[i].spawned = false; if (m_SpawnedPoolAmount > 0) @@ -119,6 +122,21 @@ void PoolGroup::DespawnObject(uint32 guid) } } } + + for (size_t i = 0; i < ExplicitlyChanced.size(); ++i) + { + if (ExplicitlyChanced[i].spawned) + { + if (!guid || ExplicitlyChanced[i].guid == guid) + { + Despawn1Object(ExplicitlyChanced[i].guid); + ExplicitlyChanced[i].spawned = false; + + if (m_SpawnedPoolAmount > 0) + --m_SpawnedPoolAmount; + } + } + } } // Method that is actualy doing the removal job on one creature @@ -176,58 +194,48 @@ void PoolGroup::RemoveOneRelation(uint16 child_pool_id) } } -// Method that Spawn 1+ creatures or gameobject -// if cache is false (initialization or event start), X creatures are spawned with X <= limit (< if limit higher that the number of creatures in pool) -// if cache is true, this means only one has to be spawned (or respawned if the rolled one is same as cached one) template -void PoolGroup::SpawnObject(uint32 limit, bool cache) +void PoolGroup::SpawnObject(uint32 limit, uint32 triggerFrom) { - if (limit == 1) // This is the only case where explicit chance is used + uint32 lastDespawned = 0; + int count = limit - m_SpawnedPoolAmount; + + // If triggered from some object respawn this object is still marked as spawned + // and also counted into m_SpawnedPoolAmount so we need increase count to be + // spawned by 1 + if (triggerFrom) + ++count; + + // This will try to spawn the rest of pool, not guaranteed + for (int i = 0; i < count; ++i) { - uint32 roll = RollOne(); - if (!cache || (cache && m_LastDespawnedNode != roll)) + int index; + PoolObjectList* store; + + RollOne(index, &store, triggerFrom); + if (index == -1) + continue; + if ((*store)[index].guid == lastDespawned) + continue; + + if ((*store)[index].guid == triggerFrom) { - if (cache) - Despawn1Object(m_LastDespawnedNode); - Spawn1Object(roll); + (*store)[index].spawned = ReSpawn1Object(triggerFrom); + triggerFrom = 0; + continue; } else - ReSpawn1Object(roll); - m_LastDespawnedNode = 0; - } - else if (limit < EqualChanced.size() && m_SpawnedPoolAmount < limit) - { - std::vector IndexList; - for (size_t i = 0; i < EqualChanced.size(); ++i) - if (!EqualChanced[i].spawned) - IndexList.push_back(i); + (*store)[index].spawned = Spawn1Object((*store)[index].guid); - while (m_SpawnedPoolAmount < limit && IndexList.size() > 0) + if (triggerFrom) { - uint32 roll = urand(1, IndexList.size()) - 1; - uint32 index = IndexList[roll]; - if (!cache || (cache && EqualChanced[index].guid != m_LastDespawnedNode)) - { - if (cache) - Despawn1Object(m_LastDespawnedNode); - - EqualChanced[index].spawned = Spawn1Object(EqualChanced[index].guid); - } - else - EqualChanced[index].spawned = ReSpawn1Object(EqualChanced[index].guid); - - if (EqualChanced[index].spawned) - ++m_SpawnedPoolAmount; // limited group use the Spawned variable to store the number of actualy spawned creatures - - std::vector::iterator itr = IndexList.begin()+roll; - IndexList.erase(itr); + // One spawn one despawn no count increase + DespawnObject(triggerFrom); + lastDespawned = triggerFrom; + triggerFrom = 0; } - m_LastDespawnedNode = 0; - } - else // Not enough objects in pool, so spawn all - { - for (size_t i = 0; i < EqualChanced.size(); ++i) - EqualChanced[i].spawned = Spawn1Object(EqualChanced[i].guid); + else + ++m_SpawnedPoolAmount; } } @@ -235,8 +243,7 @@ void PoolGroup::SpawnObject(uint32 limit, bool cache) template <> bool PoolGroup::Spawn1Object(uint32 guid) { - CreatureData const* data = objmgr.GetCreatureData(guid); - if (data) + if (CreatureData const* data = objmgr.GetCreatureData(guid)) { objmgr.AddCreatureToGrid(guid, data); @@ -250,11 +257,10 @@ bool PoolGroup::Spawn1Object(uint32 guid) if (!pCreature->LoadFromDB(guid, map)) { delete pCreature; + return false; } else - { map->Add(pCreature); - } } return true; } @@ -265,8 +271,7 @@ bool PoolGroup::Spawn1Object(uint32 guid) template <> bool PoolGroup::Spawn1Object(uint32 guid) { - GameObjectData const* data = objmgr.GetGOData(guid); - if (data) + if (GameObjectData const* data = objmgr.GetGOData(guid)) { objmgr.AddGameobjectToGrid(guid, data); // Spawn if necessary (loaded grids only) @@ -280,6 +285,7 @@ bool PoolGroup::Spawn1Object(uint32 guid) if (!pGameobject->LoadFromDB(guid, map)) { delete pGameobject; + return false; } else { @@ -296,7 +302,9 @@ bool PoolGroup::Spawn1Object(uint32 guid) template <> bool PoolGroup::Spawn1Object(uint32 child_pool_id) { - poolhandler.SpawnPool(child_pool_id); + poolhandler.SpawnPool(child_pool_id, 0, 0); + poolhandler.SpawnPool(child_pool_id, 0, TYPEID_GAMEOBJECT); + poolhandler.SpawnPool(child_pool_id, 0, TYPEID_UNIT); return true; } @@ -304,8 +312,7 @@ bool PoolGroup::Spawn1Object(uint32 child_pool_id) template <> bool PoolGroup::ReSpawn1Object(uint32 guid) { - CreatureData const* data = objmgr.GetCreatureData(guid); - if (data) + if (CreatureData const* data = objmgr.GetCreatureData(guid)) { if (Creature* pCreature = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(guid, data->id, HIGHGUID_UNIT), (Creature*)NULL)) pCreature->GetMap()->Add(pCreature); @@ -318,8 +325,7 @@ bool PoolGroup::ReSpawn1Object(uint32 guid) template <> bool PoolGroup::ReSpawn1Object(uint32 guid) { - GameObjectData const* data = objmgr.GetGOData(guid); - if (data) + if (GameObjectData const* data = objmgr.GetGOData(guid)) { if (GameObject* pGameobject = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(guid, data->id, HIGHGUID_GAMEOBJECT), (GameObject*)NULL)) pGameobject->GetMap()->Add(pGameobject); @@ -628,7 +634,9 @@ void PoolHandler::Initialize() sLog.outErrorDb("Pool Id (%u) has all creatures or gameobjects with explicit chance sum <>100 and no equal chance defined. The pool system cannot pick one to spawn.", pool_entry); continue; } - SpawnPool(pool_entry); + SpawnPool(pool_entry, 0, 0); + SpawnPool(pool_entry, 0, TYPEID_GAMEOBJECT); + SpawnPool(pool_entry, 0, TYPEID_UNIT); count++; } while (result->NextRow()); delete result; @@ -640,25 +648,35 @@ void PoolHandler::Initialize() // Call to spawn a pool, if cache if true the method will spawn only if cached entry is different // If it's same, the gameobject/creature is respawned only (added back to map) -void PoolHandler::SpawnPool(uint16 pool_id, bool cache) +void PoolHandler::SpawnPool(uint16 pool_id, uint32 guid, uint32 type) { - if (!mPoolPoolGroups[pool_id].isEmpty()) - mPoolPoolGroups[pool_id].SpawnObject(mPoolTemplate[pool_id].MaxLimit, cache); - if (!mPoolGameobjectGroups[pool_id].isEmpty()) - mPoolGameobjectGroups[pool_id].SpawnObject(mPoolTemplate[pool_id].MaxLimit, cache); - if (!mPoolCreatureGroups[pool_id].isEmpty()) - mPoolCreatureGroups[pool_id].SpawnObject(mPoolTemplate[pool_id].MaxLimit, cache); + switch (type) + { + case TYPEID_UNIT: + if (!mPoolCreatureGroups[pool_id].isEmpty()) + mPoolCreatureGroups[pool_id].SpawnObject(mPoolTemplate[pool_id].MaxLimit, guid); + break; + case TYPEID_GAMEOBJECT: + if (!mPoolGameobjectGroups[pool_id].isEmpty()) + mPoolGameobjectGroups[pool_id].SpawnObject(mPoolTemplate[pool_id].MaxLimit, guid); + break; + default: + if (!mPoolPoolGroups[pool_id].isEmpty()) + mPoolPoolGroups[pool_id].SpawnObject(mPoolTemplate[pool_id].MaxLimit, guid); + } } // Call to despawn a pool, all gameobjects/creatures in this pool are removed void PoolHandler::DespawnPool(uint16 pool_id) { - if (!mPoolPoolGroups[pool_id].isEmpty()) - mPoolPoolGroups[pool_id].DespawnObject(); - if (!mPoolGameobjectGroups[pool_id].isEmpty()) - mPoolGameobjectGroups[pool_id].DespawnObject(); if (!mPoolCreatureGroups[pool_id].isEmpty()) mPoolCreatureGroups[pool_id].DespawnObject(); + + if (!mPoolGameobjectGroups[pool_id].isEmpty()) + mPoolGameobjectGroups[pool_id].DespawnObject(); + + if (!mPoolPoolGroups[pool_id].isEmpty()) + mPoolPoolGroups[pool_id].DespawnObject(); } // Call to update the pool when a gameobject/creature part of pool [pool_id] is ready to respawn @@ -666,19 +684,10 @@ void PoolHandler::DespawnPool(uint16 pool_id) // Then the spawn pool call will use this cache to decide void PoolHandler::UpdatePool(uint16 pool_id, uint32 guid, uint32 type) { - uint16 motherpoolid = IsPartOfAPool(pool_id, 0); - - if (motherpoolid) - mPoolPoolGroups[motherpoolid].DespawnObject(pool_id); - else if (type == TYPEID_GAMEOBJECT && !mPoolGameobjectGroups[pool_id].isEmpty()) - mPoolGameobjectGroups[pool_id].DespawnObject(guid); - else if (type != TYPEID_GAMEOBJECT && !mPoolCreatureGroups[pool_id].isEmpty()) - mPoolCreatureGroups[pool_id].DespawnObject(guid); - - if (motherpoolid) - SpawnPool(motherpoolid, true); + if (uint16 motherpoolid = IsPartOfAPool(pool_id, 0)) + SpawnPool(motherpoolid, 0, 0); else - SpawnPool(pool_id, true); + SpawnPool(pool_id, guid, type); } // Method that tell if the gameobject/creature is part of a pool and return the pool id if yes diff --git a/src/game/PoolHandler.h b/src/game/PoolHandler.h index 652d8e2cf..9ea0cd376 100644 --- a/src/game/PoolHandler.h +++ b/src/game/PoolHandler.h @@ -40,25 +40,24 @@ struct PoolObject template class PoolGroup { + typedef std::vector PoolObjectList; public: - PoolGroup(); + PoolGroup() : m_SpawnedPoolAmount(0) { } ~PoolGroup() {}; bool isEmpty() { return ExplicitlyChanced.empty() && EqualChanced.empty(); } void AddEntry(PoolObject& poolitem, uint32 maxentries); bool CheckPool(void); - uint32 RollOne(void); + void RollOne(int32& index, PoolObjectList** store, uint32 triggerFrom); bool IsSpawnedObject(uint32 guid); void DespawnObject(uint32 guid=0); void Despawn1Object(uint32 guid); - void SpawnObject(uint32 limit, bool cache=false); + void SpawnObject(uint32 limit, uint32 triggerFrom); bool Spawn1Object(uint32 guid); bool ReSpawn1Object(uint32 guid); void RemoveOneRelation(uint16 child_pool_id); private: - typedef std::vector PoolObjectList; PoolObjectList ExplicitlyChanced; PoolObjectList EqualChanced; - uint32 m_LastDespawnedNode; // Store the guid of the removed creature/gameobject during a pool update uint32 m_SpawnedPoolAmount; // Used to know the number of spawned objects }; @@ -75,7 +74,7 @@ class PoolHandler uint16 IsPartOfAPool(uint32 guid, uint32 type); bool IsSpawnedObject(uint16 pool_id, uint32 guid, uint32 type); bool CheckPool(uint16 pool_id); - void SpawnPool(uint16 pool_id, bool cache=false); + void SpawnPool(uint16 pool_id, uint32 guid, uint32 type); void DespawnPool(uint16 pool_id); void UpdatePool(uint16 pool_id, uint32 guid, uint32 type); void Initialize(); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 40114edfa..abddd151e 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 "8700" + #define REVISION_NR "8701" #endif // __REVISION_NR_H__ From 69abc9ece43c33d2f322c2266261247293645e16 Mon Sep 17 00:00:00 2001 From: balrok Date: Wed, 21 Oct 2009 22:06:40 +0200 Subject: [PATCH 02/10] [8702] removed startup-error for creature_loot_template id=0 for alterac valley we've defined Player-loot inside creature_loot_template with id=0 this hack is used, so that we won't need to create an extra table player_loot_template for just one case if later more player-loot will be needed, we should implement new table and remove this also added sql-fix for reputation of last commit it will just fix those which are hated by faction 729/730 --- sql/characters.sql | 2 +- sql/updates/8702_01_characters_character_reputation.sql | 3 +++ sql/updates/Makefile.am | 2 ++ src/game/LootMgr.cpp | 4 ++++ src/shared/revision_nr.h | 2 +- src/shared/revision_sql.h | 2 +- 6 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 sql/updates/8702_01_characters_character_reputation.sql diff --git a/sql/characters.sql b/sql/characters.sql index 88664efca..f7252a19b 100644 --- a/sql/characters.sql +++ b/sql/characters.sql @@ -21,7 +21,7 @@ DROP TABLE IF EXISTS `character_db_version`; CREATE TABLE `character_db_version` ( - `required_8596_01_characters_bugreport` bit(1) default NULL + `required_8702_01_characters_character_reputation` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB'; -- diff --git a/sql/updates/8702_01_characters_character_reputation.sql b/sql/updates/8702_01_characters_character_reputation.sql new file mode 100644 index 000000000..cb18d7576 --- /dev/null +++ b/sql/updates/8702_01_characters_character_reputation.sql @@ -0,0 +1,3 @@ +ALTER TABLE character_db_version CHANGE COLUMN required_8596_01_characters_bugreport required_8702_01_characters_character_reputation bit; + +UPDATE character_reputation SET standing = 0 WHERE faction IN (729, 730) AND standing < 0; diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index b5a77a857..800b9a85e 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -138,6 +138,7 @@ pkgdata_DATA = \ 8676_01_mangos_creature_template.sql \ 8688_01_mangos_creature_template.sql \ 8693_01_mangos_spell_proc_event.sql \ + 8702_01_characters_character_reputation.sql \ README ## Additional files to include when running 'make dist' @@ -256,4 +257,5 @@ EXTRA_DIST = \ 8676_01_mangos_creature_template.sql \ 8688_01_mangos_creature_template.sql \ 8693_01_mangos_spell_proc_event.sql \ + 8702_01_characters_character_reputation.sql \ README diff --git a/src/game/LootMgr.cpp b/src/game/LootMgr.cpp index 70c386605..343a93074 100644 --- a/src/game/LootMgr.cpp +++ b/src/game/LootMgr.cpp @@ -1093,6 +1093,10 @@ void LoadLootTemplates_Creature() for(LootIdSet::const_iterator itr = ids_setUsed.begin(); itr != ids_setUsed.end(); ++itr) ids_set.erase(*itr); + // for alterac valley we've defined Player-loot inside creature_loot_template id=0 + // this hack is used, so that we won't need to create an extra table player_loot_template for just one case + ids_set.erase(0); + // output error for any still listed (not referenced from appropriate table) ids LootTemplates_Creature.ReportUnusedIds(ids_set); } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index abddd151e..575cb392c 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 "8701" + #define REVISION_NR "8702" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index cfd08a92e..73a6bbfed 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ - #define REVISION_DB_CHARACTERS "required_8596_01_characters_bugreport" + #define REVISION_DB_CHARACTERS "required_8702_01_characters_character_reputation" #define REVISION_DB_MANGOS "required_8693_01_mangos_spell_proc_event" #define REVISION_DB_REALMD "required_8332_01_realmd_realmcharacters" #endif // __REVISION_SQL_H__ From f762b57fea589cbda45598170a445d62f53d5cde Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 22 Oct 2009 02:32:02 +0400 Subject: [PATCH 03/10] [8703] Remove templates and some used functions from ObjectAccessor. --- src/game/Map.cpp | 25 +++++++++- src/game/ObjectAccessor.cpp | 20 -------- src/game/ObjectAccessor.h | 94 ++++++++----------------------------- src/shared/revision_nr.h | 2 +- 4 files changed, 44 insertions(+), 97 deletions(-) diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 51d9cddb8..1959fb697 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -775,7 +775,30 @@ bool Map::RemoveBones(uint64 guid, float x, float y) { if (IsRemovalGrid(x, y)) { - Corpse * corpse = ObjectAccessor::Instance().GetObjectInWorld(GetId(), x, y, guid, (Corpse*)NULL); + Corpse* corpse = ObjectAccessor::GetObjectInWorld(guid, (Corpse*)NULL); + if(!corpse || corpse->GetMapId() != GetId()) + return false; + + CellPair p = MaNGOS::ComputeCellPair(x,y); + if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP ) + { + sLog.outError("Map::RemoveBones: invalid coordinates supplied X:%f Y:%f grid cell [%u:%u]", x, y, p.x_coord, p.y_coord); + return false; + } + + CellPair q = MaNGOS::ComputeCellPair(corpse->GetPositionX(),corpse->GetPositionY()); + if(q.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || q.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP ) + { + sLog.outError("Map::RemoveBones: object (GUID: %u TypeId: %u) has invalid coordinates X:%f Y:%f grid cell [%u:%u]", corpse->GetGUIDLow(), corpse->GetTypeId(), corpse->GetPositionX(), corpse->GetPositionY(), q.x_coord, q.y_coord); + return false; + } + + int32 dx = int32(p.x_coord) - int32(q.x_coord); + int32 dy = int32(p.y_coord) - int32(q.y_coord); + + if (dx <= -2 || dx >= 2 || dy <= -2 || dy >= 2) + return false; + if(corpse && corpse->GetTypeId() == TYPEID_CORPSE && corpse->GetType() == CORPSE_BONES) corpse->DeleteBonesFromWorld(); else diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp index 7cc289104..1001ae9d2 100644 --- a/src/game/ObjectAccessor.cpp +++ b/src/game/ObjectAccessor.cpp @@ -182,18 +182,6 @@ ObjectAccessor::SaveAllPlayers() itr->second->SaveToDB(); } -Pet* -ObjectAccessor::GetPet(uint64 guid) -{ - return GetObjectInWorld(guid, (Pet*)NULL); -} - -Vehicle* -ObjectAccessor::GetVehicle(uint64 guid) -{ - return GetObjectInWorld(guid, (Vehicle*)NULL); -} - Corpse* ObjectAccessor::GetCorpseForPlayerGUID(uint64 guid) { @@ -343,11 +331,3 @@ template class HashMapHolder; /// Define the static member of ObjectAccessor std::list ObjectAccessor::i_mapList; - -template Player* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, Player* /*fake*/); -template Pet* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, Pet* /*fake*/); -template Vehicle* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, Vehicle* /*fake*/); -template Creature* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, Creature* /*fake*/); -template Corpse* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, Corpse* /*fake*/); -template GameObject* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, GameObject* /*fake*/); -template DynamicObject* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, DynamicObject* /*fake*/); diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h index c562f5e74..a51fdb773 100644 --- a/src/game/ObjectAccessor.h +++ b/src/game/ObjectAccessor.h @@ -90,46 +90,25 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton Player2CorpsesMapType; - template static T* GetObjectInWorld(uint64 guid, T* /*fake*/) - { - return HashMapHolder::Find(guid); - } + // global + static Player* GetObjectInWorld(uint64 guid, Player* /*fake*/) { return HashMapHolder::Find(guid); } + static Corpse* GetObjectInWorld(uint64 guid, Corpse* /*fake*/) { return HashMapHolder::Find(guid); } + static Unit* GetObjectInWorld(uint64 guid, Unit* /*fake*/); - template static T* GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, T* /*fake*/) - { - T* obj = GetObjectInWorld(guid, (T*)NULL); - if(!obj || obj->GetMapId() != mapid) return NULL; - - CellPair p = MaNGOS::ComputeCellPair(x,y); - if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP ) - { - sLog.outError("ObjectAccessor::GetObjectInWorld: invalid coordinates supplied X:%f Y:%f grid cell [%u:%u]", x, y, p.x_coord, p.y_coord); - return NULL; - } - - CellPair q = MaNGOS::ComputeCellPair(obj->GetPositionX(),obj->GetPositionY()); - if(q.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || q.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP ) - { - sLog.outError("ObjectAccessor::GetObjecInWorld: object (GUID: %u TypeId: %u) has invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUIDLow(), obj->GetTypeId(), obj->GetPositionX(), obj->GetPositionY(), q.x_coord, q.y_coord); - return NULL; - } - - int32 dx = int32(p.x_coord) - int32(q.x_coord); - int32 dy = int32(p.y_coord) - int32(q.y_coord); - - if (dx > -2 && dx < 2 && dy > -2 && dy < 2) return obj; - else return NULL; - } + // map local object with global search + static Creature* GetObjectInWorld(uint64 guid, Creature* /*fake*/) { return FindHelper(guid); } + static GameObject* GetObjectInWorld(uint64 guid, GameObject* /*fake*/) { return FindHelper(guid); } + static Pet* GetObjectInWorld(uint64 guid, Pet* /*fake*/) { return FindHelper(guid); } + static Vehicle* GetObjectInWorld(uint64 guid, Vehicle* /*fake*/) { return FindHelper(guid); } static WorldObject* GetWorldObject(WorldObject const &, uint64); static Object* GetObjectByTypeMask(WorldObject const &, uint64, uint32 typemask); static Creature* GetCreatureOrPetOrVehicle(WorldObject const &, uint64); static Unit* GetUnit(WorldObject const &, uint64); - static Pet* GetPet(Unit const &, uint64 guid) { return GetPet(guid); } static Player* GetPlayer(Unit const &, uint64 guid) { return FindPlayer(guid); } static Corpse* GetCorpse(WorldObject const &u, uint64 guid); - static Pet* GetPet(uint64 guid); - static Vehicle* GetVehicle(uint64 guid); + static Pet* GetPet(uint64 guid) { return GetObjectInWorld(guid, (Pet*)NULL); } + static Vehicle* GetVehicle(uint64 guid) { return GetObjectInWorld(guid, (Vehicle*)NULL); } static Player* FindPlayer(uint64); Player* FindPlayerByName(const char *name) ; @@ -139,20 +118,11 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton::GetContainer(); } - template void AddObject(T *object) - { - HashMapHolder::Insert(object); - } - - template void RemoveObject(T *object) - { - HashMapHolder::Remove(object); - } - - void RemoveObject(Player *pl) - { - HashMapHolder::Remove(pl); - } + // For call from Player/Corpse AddToWorld/RemoveFromWorld only + void AddObject(Corpse *object) { HashMapHolder::Insert(object); } + void AddObject(Player *object) { HashMapHolder::Insert(object); } + void RemoveObject(Corpse *object) { HashMapHolder::Remove(object); } + void RemoveObject(Player *object) { HashMapHolder::Remove(object); } void SaveAllPlayers(); @@ -193,33 +163,7 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton inline Creature* ObjectAccessor::GetObjectInWorld(uint64 guid, Creature* /*fake*/) -{ - return FindHelper(guid); -} - -template <> inline GameObject* ObjectAccessor::GetObjectInWorld(uint64 guid, GameObject* /*fake*/) -{ - return FindHelper(guid); -} - -template <> inline DynamicObject* ObjectAccessor::GetObjectInWorld(uint64 guid, DynamicObject* /*fake*/) -{ - return FindHelper(guid); -} - -template <> inline Pet* ObjectAccessor::GetObjectInWorld(uint64 guid, Pet* /*fake*/) -{ - return FindHelper(guid); -} - -template <> inline Vehicle* ObjectAccessor::GetObjectInWorld(uint64 guid, Vehicle* /*fake*/) -{ - return FindHelper(guid); -} - -template <> inline Unit* ObjectAccessor::GetObjectInWorld(uint64 guid, Unit* /*fake*/) +inline Unit* ObjectAccessor::GetObjectInWorld(uint64 guid, Unit* /*fake*/) { if(!guid) return NULL; @@ -234,9 +178,9 @@ template <> inline Unit* ObjectAccessor::GetObjectInWorld(uint64 guid, Unit* /*f } if (IS_PET_GUID(guid)) - return (Unit*)GetObjectInWorld(guid, (Pet*)NULL); + return GetObjectInWorld(guid, (Pet*)NULL); - return (Unit*)GetObjectInWorld(guid, (Creature*)NULL); + return GetObjectInWorld(guid, (Creature*)NULL); } #endif diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 575cb392c..b36d78094 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 "8702" + #define REVISION_NR "8703" #endif // __REVISION_NR_H__ From ae9ae781fce5339c67e8a37b66073e9ad48c47b6 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 22 Oct 2009 06:32:37 +0400 Subject: [PATCH 04/10] [8704] Fixed crash "Object with certain key already in but objects are different!" * It possible in result events 1) creature move from respawn grid 2) respawn grid unloaded by timeout, but not current grid for creature 3) respawn grid loaded before current grid with creture unload 4) duplicate attempt created in old grid Until recent guid storage move to map we create duplicate creature with same (continent) or diff guid. With diff strange possible result in it work in world. --- src/game/ObjectGridLoader.cpp | 20 +++++++++++++++++++- src/shared/revision_nr.h | 2 +- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/game/ObjectGridLoader.cpp b/src/game/ObjectGridLoader.cpp index 9c60cd2b1..dff9cd426 100644 --- a/src/game/ObjectGridLoader.cpp +++ b/src/game/ObjectGridLoader.cpp @@ -104,6 +104,16 @@ template<> void addUnitState(Creature *obj, CellPair const& cell_pair) obj->SetCurrentCell(cell); } +template bool alreadyLoaded(Map* /*map*/, uint32 /*guid*/, T* /*fake*/) +{ + // Non creature objects not walk by grids +} + +template<> bool alreadyLoaded(Map* map, uint32 guid, Creature* fake) +{ + return map->GetObjectsStore().find(guid,fake); +} + template void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager &m, uint32 &count, Map* map) { @@ -111,8 +121,16 @@ void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager & for(CellGuidSet::const_iterator i_guid = guid_set.begin(); i_guid != guid_set.end(); ++i_guid) { - T* obj = new T; uint32 guid = *i_guid; + + // Note: this will fully correct work only at non-instanced maps, + // at instanced maps will use dynamic selected guid + // and then duplicate just will not detected and will be 2 creature with identical DB guid + // with some chance + if (alreadyLoaded(map,guid,(T*)NULL)) + continue; // still loaded in another grid (move from respawn [this] grid early), we not need second copy + + T* obj = new T; //sLog.outString("DEBUG: LoadHelper from table: %s for (guid: %u) Loading",table,guid); if(!obj->LoadFromDB(guid, map)) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index b36d78094..9ffec8043 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 "8703" + #define REVISION_NR "8704" #endif // __REVISION_NR_H__ From d482193ceadb9bd189211e84ff289086244be26d Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 22 Oct 2009 06:44:05 +0400 Subject: [PATCH 05/10] [8705] Move DynamicObject guid counting from global levle to map. This is first step in guid counting for map local object types at map level. Map local countin let 1) have more wide guid space and then more seldom have problems with guid counter overflow 2) possible implement (later) restart map at guid overflow without server shutdown. 3) let use static guids (not for DynamicOPbject that not stored in DB anyway) in instances instead dynamic allocated. --- src/game/Map.cpp | 26 ++++++++++++++++++++++++-- src/game/Map.h | 5 +++++ src/game/ObjectMgr.cpp | 8 -------- src/game/ObjectMgr.h | 2 -- src/game/SpellEffects.cpp | 4 ++-- src/shared/revision_nr.h | 2 +- 6 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 1959fb697..594f151ef 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -202,7 +202,8 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _par i_id(id), i_InstanceId(InstanceId), m_unloadTimer(0), m_activeNonPlayersIter(m_activeNonPlayers.end()), i_gridExpiry(expiry), m_parentMap(_parent ? _parent : this), - m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE) + m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE), + m_hiDynObjectGuid(1) { for(unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx) { @@ -3462,4 +3463,25 @@ void Map::SendObjectUpdates() iter->first->GetSession()->SendPacket(&packet); packet.clear(); // clean the string } -} \ No newline at end of file +} + +uint32 Map::GenerateLocalLowGuid(HighGuid guidhigh) +{ + // TODO: for map local guid counters possible force reload map instead shutdown server at guid counter overflow + 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++; + default: + ASSERT(0); + } + + ASSERT(0); + return 0; +} + diff --git a/src/game/Map.h b/src/game/Map.h index 1a458bda8..88122ba31 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -444,6 +444,9 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj { i_objectsToClientUpdate.erase( obj ); } + + // DynObjects currently + uint32 GenerateLocalLowGuid(HighGuid guidhigh); private: void LoadMapAndVMap(int gx, int gy); void LoadVMap(int gx, int gy); @@ -526,6 +529,8 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj std::set i_objectsToRemove; std::multimap m_scriptSchedule; + uint32 m_hiDynObjectGuid; // Map local dynobject low guid counter + // Type specific code for add/remove to/from grid template void AddToGrid(T*, NGridType *, Cell const&); diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index d4a002855..d13b2146c 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -133,7 +133,6 @@ ObjectMgr::ObjectMgr() m_hiVehicleGuid = 1; m_hiItemGuid = 1; m_hiGoGuid = 1; - m_hiDoGuid = 1; m_hiCorpseGuid = 1; m_hiPetNumber = 1; m_ItemTextId = 1; @@ -5714,13 +5713,6 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh) World::StopNow(ERROR_EXIT_CODE); } return m_hiCorpseGuid++; - case HIGHGUID_DYNAMICOBJECT: - if(m_hiDoGuid>=0xFFFFFFFE) - { - sLog.outError("DynamicObject guid overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } - return m_hiDoGuid++; default: ASSERT(0); } diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index b36394cb1..f34479ca6 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -24,7 +24,6 @@ #include "Bag.h" #include "Creature.h" #include "Player.h" -#include "DynamicObject.h" #include "GameObject.h" #include "Corpse.h" #include "QuestDef.h" @@ -792,7 +791,6 @@ class ObjectMgr uint32 m_hiVehicleGuid; uint32 m_hiItemGuid; uint32 m_hiGoGuid; - uint32 m_hiDoGuid; uint32 m_hiCorpseGuid; QuestMap mQuestTemplates; diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 902153aa8..91922cafe 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -2872,7 +2872,7 @@ void Spell::EffectPersistentAA(uint32 i) int32 duration = GetSpellDuration(m_spellInfo); DynamicObject* dynObj = new DynamicObject; - if (!dynObj->Create(objmgr.GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, i, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, duration, radius)) + if (!dynObj->Create(m_caster->GetMap()->GenerateLocalLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, i, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, duration, radius)) { delete dynObj; return; @@ -3679,7 +3679,7 @@ void Spell::EffectAddFarsight(uint32 i) DynamicObject* dynObj = new DynamicObject; // set radius to 0: spell not expected to work as persistent aura - if(!dynObj->Create(objmgr.GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, i, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, duration, 0)) + if(!dynObj->Create(m_caster->GetMap()->GenerateLocalLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, i, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, duration, 0)) { delete dynObj; return; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 9ffec8043..134c4e000 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 "8704" + #define REVISION_NR "8705" #endif // __REVISION_NR_H__ From 3860ec2427e3be4b0ac1d2571352953a74590fb5 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 22 Oct 2009 06:51:13 +0400 Subject: [PATCH 06/10] [8706] Fixed typo in [8704] --- src/game/ObjectGridLoader.cpp | 1 + src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/game/ObjectGridLoader.cpp b/src/game/ObjectGridLoader.cpp index dff9cd426..483b63e30 100644 --- a/src/game/ObjectGridLoader.cpp +++ b/src/game/ObjectGridLoader.cpp @@ -107,6 +107,7 @@ template<> void addUnitState(Creature *obj, CellPair const& cell_pair) template bool alreadyLoaded(Map* /*map*/, uint32 /*guid*/, T* /*fake*/) { // Non creature objects not walk by grids + return false; } template<> bool alreadyLoaded(Map* map, uint32 guid, Creature* fake) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 134c4e000..55ea2b0a4 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 "8705" + #define REVISION_NR "8706" #endif // __REVISION_NR_H__ From f1800cf05ae7998cd2788bcc4d39dba10a20480f Mon Sep 17 00:00:00 2001 From: balrok Date: Thu, 22 Oct 2009 13:13:43 +0200 Subject: [PATCH 07/10] [8707] fixed linuxbuild --- src/game/ObjectAccessor.h | 3 +-- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h index a51fdb773..eb81fed68 100644 --- a/src/game/ObjectAccessor.h +++ b/src/game/ObjectAccessor.h @@ -30,15 +30,14 @@ #include "GridDefines.h" #include "Object.h" #include "Player.h" +#include "Corpse.h" #include #include class Creature; -class Corpse; class Unit; class GameObject; -class DynamicObject; class Vehicle; class WorldObject; class Map; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 55ea2b0a4..57918381f 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 "8706" + #define REVISION_NR "8707" #endif // __REVISION_NR_H__ From eb26f27a21a74bd6db8251a62bc7483a4027b5f6 Mon Sep 17 00:00:00 2001 From: KiriX Date: Thu, 22 Oct 2009 14:10:27 +0200 Subject: [PATCH 08/10] [8708] Fixed damage from spell 1120 and ranks when target below or equal 25% of health. Signed-off-by: ApoC --- sql/mangos_spell_check.sql | 1 + src/game/SpellAuras.cpp | 11 +++++++++++ src/shared/revision_nr.h | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/sql/mangos_spell_check.sql b/sql/mangos_spell_check.sql index aa401c50f..3bcb54084 100644 --- a/sql/mangos_spell_check.sql +++ b/sql/mangos_spell_check.sql @@ -345,6 +345,7 @@ INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMas /*id fm familyMaskA fmMaskB icon vis cat eff aur ef name code */ ( 0, 3,0x0000000020000000,0x00000000, -1, -1, -1, 2, -1,-1,'Arcane Blast', 'Spell::EffectSchoolDMG'), ( 0, 9,0x0000000000000800,0x00000000, -1, -1, -1, 2, -1,-1,'Arcane Shot', 'Spell::EffectSchoolDMG'), +( 0, 5,0x0000000000004000,0x00000000, -1, -1, -1, -1, -1,-1,'Drain Soul', 'Aura::HandlePeriodicDamage'), ( 0,10,0x0000000000004000,0x00000000, -1, -1, -1, 2, -1,-1,'Avenger\'s Shield', 'Spell::EffectSchoolDMG'), ( 0, 4,0x0000040000000000,0x00000000, -1, -1, -1, 2, -1,-1,'Bloodthirst', 'Spell::EffectSchoolDMG'), (0, 4,0x0000000000000001,0x00000000, -1, 867, -1, 3, -1,-1,'Charge', 'Spell::EffectDummy'), diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index afed0ac18..75a166efb 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -4509,6 +4509,17 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real) } break; } + case SPELLFAMILY_WARLOCK: + { + // Drain Soul + if (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000004000)) + { + if (m_target->GetHealth() * 100 / m_target->GetMaxHealth() <= 25) + m_modifier.m_amount *= 4; + return; + } + break; + } case SPELLFAMILY_DRUID: { // Rake diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 57918381f..ccc294964 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 "8707" + #define REVISION_NR "8708" #endif // __REVISION_NR_H__ From 53b6d28a24547c815be750f8174f7843b6544f69 Mon Sep 17 00:00:00 2001 From: Tassader2 Date: Fri, 13 Mar 2009 17:10:09 +0100 Subject: [PATCH 09/10] [8709] Show spell miss as miss, not resist Signed-off-by: ApoC --- src/game/Unit.cpp | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index c145d17ad..a1e47da82 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -2665,7 +2665,7 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit *pVictim, SpellEntry const *spell) uint32 rand = urand(0,10000); if (rand < tmp) - return SPELL_MISS_RESIST; + return SPELL_MISS_MISS; // cast by caster in front of victim if (pVictim->HasInArc(M_PI,this)) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index ccc294964..b20b38f25 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 "8708" + #define REVISION_NR "8709" #endif // __REVISION_NR_H__ From b942616deda1691919fdff953b1610469f9494bc Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 22 Oct 2009 17:23:13 +0400 Subject: [PATCH 10/10] [8710] Make vehicle guid counter per-map local. Also update/drop/move to Map some dependent functions. --- src/game/Chat.cpp | 2 +- src/game/GameObject.cpp | 2 +- src/game/Map.cpp | 23 ++++++++++++++++++----- src/game/Map.h | 7 +++++-- src/game/MovementHandler.cpp | 2 +- src/game/ObjectAccessor.cpp | 20 ++++---------------- src/game/ObjectAccessor.h | 5 +---- src/game/ObjectMgr.cpp | 8 -------- src/game/ObjectMgr.h | 1 - src/game/PetHandler.cpp | 22 +++++----------------- src/game/Player.cpp | 13 +++++-------- src/game/QuestHandler.cpp | 2 +- src/game/SpellHandler.cpp | 4 ++-- src/game/debugcmds.cpp | 2 +- src/shared/revision_nr.h | 2 +- 15 files changed, 46 insertions(+), 69 deletions(-) diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index a66c65ca4..5c8afa6c5 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -1778,7 +1778,7 @@ Creature* ChatHandler::getSelectedCreature() if(!m_session) return NULL; - return ObjectAccessor::GetCreatureOrPetOrVehicle(*m_session->GetPlayer(),m_session->GetPlayer()->GetSelection()); + return m_session->GetPlayer()->GetMap()->GetCreatureOrPetOrVehicle(m_session->GetPlayer()->GetSelection()); } char* ChatHandler::extractKeyFromLink(char* text, char const* linkType, char** something1) diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index e5253fae5..78d9f3dbe 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -79,7 +79,7 @@ void GameObject::RemoveFromWorld() // Remove GO from owner if(uint64 owner_guid = GetOwnerGUID()) { - if (Unit* owner = IS_PLAYER_GUID(owner_guid) ? ObjectAccessor::FindPlayer(owner_guid) : GetMap()->GetCreatureOrPet(owner_guid)) + if (Unit* owner = ObjectAccessor::GetUnit(*this,owner_guid)) owner->RemoveGameObject(this,false); else { diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 594f151ef..83c3143e2 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -203,7 +203,7 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _par m_activeNonPlayersIter(m_activeNonPlayers.end()), i_gridExpiry(expiry), m_parentMap(_parent ? _parent : this), m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE), - m_hiDynObjectGuid(1) + m_hiDynObjectGuid(1), m_hiVehicleGuid(1) { for(unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx) { @@ -3425,12 +3425,18 @@ Pet* Map::GetPet(uint64 guid) return m_objectsStore.find(guid, (Pet*)NULL); } -Unit* Map::GetCreatureOrPet(uint64 guid) +Creature* Map::GetCreatureOrPetOrVehicle(uint64 guid) { - if (Unit* ret = GetCreature(guid)) - return ret; + if (IS_PLAYER_GUID(guid)) + return NULL; - return GetPet(guid); + if (IS_PET_GUID(guid)) + return GetPet(guid); + + if (IS_VEHICLE_GUID(guid)) + return GetVehicle(guid); + + return GetCreature(guid); } GameObject* Map::GetGameObject(uint64 guid) @@ -3477,6 +3483,13 @@ uint32 Map::GenerateLocalLowGuid(HighGuid guidhigh) World::StopNow(ERROR_EXIT_CODE); } return m_hiDynObjectGuid++; + 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++; default: ASSERT(0); } diff --git a/src/game/Map.h b/src/game/Map.h index 88122ba31..d6fb2d5a8 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -37,6 +37,7 @@ #include #include +class Creature; class Unit; class WorldPacket; class InstanceData; @@ -429,7 +430,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj Creature* GetCreature(uint64 guid); Vehicle* GetVehicle(uint64 guid); Pet* GetPet(uint64 guid); - Unit* GetCreatureOrPet(uint64 guid); + Creature* GetCreatureOrPetOrVehicle(uint64 guid); GameObject* GetGameObject(uint64 guid); DynamicObject* GetDynamicObject(uint64 guid); @@ -529,7 +530,9 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj std::set i_objectsToRemove; std::multimap m_scriptSchedule; - uint32 m_hiDynObjectGuid; // Map local dynobject low guid counter + // Map local low guid counters + uint32 m_hiDynObjectGuid; + uint32 m_hiVehicleGuid; // Type specific code for add/remove to/from grid template diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index b1e578893..664c11d66 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -505,7 +505,7 @@ void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data) _player->m_movementInfo = mi; // using charm guid, because we don't have vehicle guid... - if(Vehicle *vehicle = ObjectAccessor::GetVehicle(vehicleGUID)) + if(Vehicle *vehicle = _player->GetMap()->GetVehicle(vehicleGUID)) { // Aura::HandleAuraControlVehicle will call Player::ExitVehicle vehicle->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE); diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp index 1001ae9d2..3959d4afb 100644 --- a/src/game/ObjectAccessor.cpp +++ b/src/game/ObjectAccessor.cpp @@ -50,21 +50,6 @@ ObjectAccessor::~ObjectAccessor() delete itr->second; } -Creature* -ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const &u, uint64 guid) -{ - if(IS_PLAYER_GUID(guid) || !u.IsInWorld()) - return NULL; - - if(IS_PET_GUID(guid)) - return u.GetMap()->GetPet(guid); - - if(IS_VEHICLE_GUID(guid)) - return u.GetMap()->GetVehicle(guid); - - return u.GetMap()->GetCreature(guid); -} - Unit* ObjectAccessor::GetUnit(WorldObject const &u, uint64 guid) { @@ -74,7 +59,10 @@ ObjectAccessor::GetUnit(WorldObject const &u, uint64 guid) if(IS_PLAYER_GUID(guid)) return FindPlayer(guid); - return GetCreatureOrPetOrVehicle(u, guid); + if (!u.IsInWorld()) + return NULL; + + return u.GetMap()->GetCreatureOrPetOrVehicle(guid); } Corpse* diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h index eb81fed68..931610226 100644 --- a/src/game/ObjectAccessor.h +++ b/src/game/ObjectAccessor.h @@ -38,7 +38,6 @@ class Creature; class Unit; class GameObject; -class Vehicle; class WorldObject; class Map; @@ -98,16 +97,14 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton(guid); } static GameObject* GetObjectInWorld(uint64 guid, GameObject* /*fake*/) { return FindHelper(guid); } static Pet* GetObjectInWorld(uint64 guid, Pet* /*fake*/) { return FindHelper(guid); } - static Vehicle* GetObjectInWorld(uint64 guid, Vehicle* /*fake*/) { return FindHelper(guid); } + static Vehicle* GetObjectInWorld(uint64 guid, Vehicle* /*fake*/); // no implementation, link error trap until creature move to Map static WorldObject* GetWorldObject(WorldObject const &, uint64); static Object* GetObjectByTypeMask(WorldObject const &, uint64, uint32 typemask); - static Creature* GetCreatureOrPetOrVehicle(WorldObject const &, uint64); static Unit* GetUnit(WorldObject const &, uint64); static Player* GetPlayer(Unit const &, uint64 guid) { return FindPlayer(guid); } static Corpse* GetCorpse(WorldObject const &u, uint64 guid); static Pet* GetPet(uint64 guid) { return GetObjectInWorld(guid, (Pet*)NULL); } - static Vehicle* GetVehicle(uint64 guid) { return GetObjectInWorld(guid, (Vehicle*)NULL); } static Player* FindPlayer(uint64); Player* FindPlayerByName(const char *name) ; diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index d13b2146c..f21cfdbd1 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -130,7 +130,6 @@ ObjectMgr::ObjectMgr() m_hiCharGuid = 1; m_hiCreatureGuid = 1; m_hiPetGuid = 1; - m_hiVehicleGuid = 1; m_hiItemGuid = 1; m_hiGoGuid = 1; m_hiCorpseGuid = 1; @@ -5685,13 +5684,6 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh) World::StopNow(ERROR_EXIT_CODE); } return m_hiPetGuid++; - 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++; case HIGHGUID_PLAYER: if(m_hiCharGuid>=0xFFFFFFFE) { diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index f34479ca6..f1c69b261 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -788,7 +788,6 @@ class ObjectMgr uint32 m_hiCharGuid; uint32 m_hiCreatureGuid; uint32 m_hiPetGuid; - uint32 m_hiVehicleGuid; uint32 m_hiItemGuid; uint32 m_hiGoGuid; uint32 m_hiCorpseGuid; diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index 9e95dfc78..83741cfec 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -276,7 +276,7 @@ void WorldSession::HandlePetNameQuery( WorldPacket & recv_data ) void WorldSession::SendPetNameQuery( uint64 petguid, uint32 petnumber) { - Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, petguid); + Creature* pet = _player->GetMap()->GetCreatureOrPetOrVehicle(petguid); if(!pet || !pet->GetCharmInfo() || pet->GetCharmInfo()->GetPetNumber() != petnumber) return; @@ -308,12 +308,7 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data ) recv_data >> petguid; - // FIXME: charmed case - //Pet* pet = ObjectAccessor::Instance().GetPet(petguid); - if(ObjectAccessor::FindPlayer(petguid)) - return; - - Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, petguid); + Creature* pet = _player->GetMap()->GetCreatureOrPetOrVehicle(petguid); if(!pet || (pet != _player->GetPet() && pet != _player->GetCharm())) { @@ -456,8 +451,7 @@ void WorldSession::HandlePetAbandon( WorldPacket & recv_data ) return; // pet/charmed - Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid); - if(pet) + if (Creature* pet = _player->GetMap()->GetCreatureOrPetOrVehicle(guid)) { if(pet->isPet()) { @@ -514,10 +508,7 @@ void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket ) if(!_player->GetPet() && !_player->GetCharm()) return; - if(ObjectAccessor::FindPlayer(guid)) - return; - - Creature* pet=ObjectAccessor::GetCreatureOrPetOrVehicle(*_player,guid); + Creature* pet = _player->GetMap()->GetCreatureOrPetOrVehicle(guid); if(!pet || (pet != _player->GetPet() && pet != _player->GetCharm())) { @@ -561,10 +552,7 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket ) if (!_player->GetPet() && !_player->GetCharm()) return; - if (GUID_HIPART(guid) == HIGHGUID_PLAYER) - return; - - Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player,guid); + Creature* pet = _player->GetMap()->GetCreatureOrPetOrVehicle(guid); if (!pet || (pet != _player->GetPet() && pet!= _player->GetCharm())) { diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 7d7069ed1..0d6bd4b76 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -2079,7 +2079,7 @@ Creature* Player::GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask) return NULL; // exist (we need look pets also for some interaction (quest/etc) - Creature *unit = ObjectAccessor::GetCreatureOrPetOrVehicle(*this,guid); + Creature *unit = GetMap()->GetCreatureOrPetOrVehicle(guid); if (!unit) return NULL; @@ -12159,8 +12159,7 @@ void Player::PrepareQuestMenu( uint64 guid ) QuestRelations* pObjectQIR; // pets also can have quests - Creature *pCreature = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, guid); - if( pCreature ) + if (Creature *pCreature = GetMap()->GetCreatureOrPetOrVehicle(guid)) { pObject = (Object*)pCreature; pObjectQR = &objmgr.mCreatureQuestRelations; @@ -12254,8 +12253,7 @@ void Player::SendPreparedQuest(uint64 guid) std::string title = ""; // need pet case for some quests - Creature *pCreature = ObjectAccessor::GetCreatureOrPetOrVehicle(*this,guid); - if (pCreature) + if (Creature *pCreature = GetMap()->GetCreatureOrPetOrVehicle(guid)) { uint32 textid = pCreature->GetNpcTextId(); GossipText const* gossiptext = objmgr.GetGossipText(textid); @@ -12318,8 +12316,7 @@ Quest const * Player::GetNextQuest( uint64 guid, Quest const *pQuest ) QuestRelations* pObjectQR; QuestRelations* pObjectQIR; - Creature *pCreature = ObjectAccessor::GetCreatureOrPetOrVehicle(*this,guid); - if( pCreature ) + if (Creature *pCreature = GetMap()->GetCreatureOrPetOrVehicle(guid)) { pObject = (Object*)pCreature; pObjectQR = &objmgr.mCreatureQuestRelations; @@ -18830,7 +18827,7 @@ void Player::UpdateForQuestWorldObjects() } else if(IS_CREATURE_GUID(*itr) || IS_VEHICLE_GUID(*itr)) { - Creature *obj = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, *itr); + Creature *obj = GetMap()->GetCreatureOrPetOrVehicle(*itr); if(!obj) continue; diff --git a/src/game/QuestHandler.cpp b/src/game/QuestHandler.cpp index 5f105b411..ad42c75b7 100644 --- a/src/game/QuestHandler.cpp +++ b/src/game/QuestHandler.cpp @@ -645,7 +645,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket if (IS_CREATURE_OR_PET_GUID(*itr)) { // need also pet quests case support - Creature *questgiver = ObjectAccessor::GetCreatureOrPetOrVehicle(*GetPlayer(),*itr); + Creature *questgiver = GetPlayer()->GetMap()->GetCreatureOrPetOrVehicle(*itr); if(!questgiver || questgiver->IsHostileTo(_player)) continue; if(!questgiver->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER)) diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp index 85d600e7b..f6b9e5efc 100644 --- a/src/game/SpellHandler.cpp +++ b/src/game/SpellHandler.cpp @@ -458,7 +458,7 @@ void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket) return; } - Creature* pet=ObjectAccessor::GetCreatureOrPetOrVehicle(*_player,guid); + Creature* pet = GetPlayer()->GetMap()->GetCreatureOrPetOrVehicle(guid); if(!pet) { @@ -550,7 +550,7 @@ void WorldSession::HandleSpellClick( WorldPacket & recv_data ) if (_player->isInCombat()) // client prevent click and set different icon at combat state return; - Creature *unit = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid); + Creature *unit = _player->GetMap()->GetCreatureOrPetOrVehicle(guid); if (!unit || unit->isInCombat()) // client prevent click and set different icon at combat state return; diff --git a/src/game/debugcmds.cpp b/src/game/debugcmds.cpp index d0f186f89..75aa9c37f 100644 --- a/src/game/debugcmds.cpp +++ b/src/game/debugcmds.cpp @@ -626,7 +626,7 @@ bool ChatHandler::HandleDebugSpawnVehicle(const char* args) Vehicle *v = new Vehicle; Map *map = m_session->GetPlayer()->GetMap(); - if (!v->Create(objmgr.GenerateLowGuid(HIGHGUID_VEHICLE), map, entry, id, m_session->GetPlayer()->GetTeam())) + if (!v->Create(map->GenerateLocalLowGuid(HIGHGUID_VEHICLE), map, entry, id, m_session->GetPlayer()->GetTeam())) { delete v; return false; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index b20b38f25..51b1be8ca 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 "8709" + #define REVISION_NR "8710" #endif // __REVISION_NR_H__