From 8bf52f7c63cf2f5671ad862743af2530fe52d411 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 19 Oct 2009 23:24:41 +0400 Subject: [PATCH 01/25] [8678] Move objects updates store and proccessing for send to client in per map way. --- src/game/Item.cpp | 12 ++++++++++++ src/game/Item.h | 2 ++ src/game/Map.cpp | 25 +++++++++++++++++++++++++ src/game/Map.h | 12 ++++++++++++ src/game/MapManager.cpp | 1 - src/game/Object.cpp | 36 ++++++++++++++++++++++-------------- src/game/Object.h | 7 ++++++- src/game/ObjectAccessor.cpp | 25 ------------------------- src/game/ObjectAccessor.h | 19 ------------------- src/shared/revision_nr.h | 2 +- 10 files changed, 80 insertions(+), 61 deletions(-) diff --git a/src/game/Item.cpp b/src/game/Item.cpp index 644c13dfa..ba6381cb7 100644 --- a/src/game/Item.cpp +++ b/src/game/Item.cpp @@ -996,6 +996,18 @@ bool Item::IsBindedNotWith( Player const* player ) const } } +void Item::AddToClientUpdateList() +{ + if (Player* pl = GetOwner()) + pl->GetMap()->AddUpdateObject(this); +} + +void Item::RemoveFromClientUpdateList() +{ + if (Player* pl = GetOwner()) + pl->GetMap()->RemoveUpdateObject(this); +} + void Item::BuildUpdateData(UpdateDataMapType& update_players) { if (Player* pl = GetOwner()) diff --git a/src/game/Item.h b/src/game/Item.h index a1b444007..59aa86f6d 100644 --- a/src/game/Item.h +++ b/src/game/Item.h @@ -313,6 +313,8 @@ class MANGOS_DLL_SPEC Item : public Object bool IsPotion() const { return GetProto()->IsPotion(); } bool IsConjuredConsumable() const { return GetProto()->IsConjuredConsumable(); } + void AddToClientUpdateList(); + void RemoveFromClientUpdateList(); void BuildUpdateData(UpdateDataMapType& update_players); private: uint8 m_slot; diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 4abed7b57..51d9cddb8 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -697,6 +697,9 @@ void Map::Update(const uint32 &t_diff) } } + // Send world objects and item update field changes + SendObjectUpdates(); + // Don't unload grids if it's battleground, since we may have manually added GOs,creatures, those doesn't load from DB at grid re-load ! // This isn't really bother us, since as soon as we have instanced BG-s, the whole map unloads as the BG gets ended if (!IsBattleGroundOrArena()) @@ -3415,3 +3418,25 @@ DynamicObject* Map::GetDynamicObject(uint64 guid) { return m_objectsStore.find(guid, (DynamicObject*)NULL); } + +void Map::SendObjectUpdates() +{ + UpdateDataMapType update_players; + + while(!i_objectsToClientUpdate.empty()) + { + Object* obj = *i_objectsToClientUpdate.begin(); + i_objectsToClientUpdate.erase(i_objectsToClientUpdate.begin()); + if (!obj) + continue; + obj->BuildUpdateData(update_players); + } + + WorldPacket packet; // here we allocate a std::vector with a size of 0x10000 + for(UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter) + { + iter->second.BuildPacket(&packet); + iter->first->GetSession()->SendPacket(&packet); + packet.clear(); // clean the string + } +} \ No newline at end of file diff --git a/src/game/Map.h b/src/game/Map.h index a50a3e1f4..af5b94cd6 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -428,6 +428,16 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj DynamicObject* GetDynamicObject(uint64 guid); TypeUnorderedMapContainer& GetObjectsStore() { return m_objectsStore; } + + void AddUpdateObject(Object *obj) + { + i_objectsToClientUpdate.insert(obj); + } + + void RemoveUpdateObject(Object *obj) + { + i_objectsToClientUpdate.erase( obj ); + } private: void LoadMapAndVMap(int gx, int gy); void LoadVMap(int gx, int gy); @@ -472,6 +482,8 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj void setNGrid(NGridType* grid, uint32 x, uint32 y); void ScriptsProcess(); + void SendObjectUpdates(); + std::set i_objectsToClientUpdate; protected: void SetUnloadReferenceLock(const GridPair &p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadReferenceLock(on); } diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp index 624e3b884..f129e6db9 100644 --- a/src/game/MapManager.cpp +++ b/src/game/MapManager.cpp @@ -268,7 +268,6 @@ MapManager::Update(uint32 diff) iter->second->Update(i_timer.GetCurrent()); } - ObjectAccessor::Instance().Update(i_timer.GetCurrent()); for (TransportSet::iterator iter = m_Transports.begin(); iter != m_Transports.end(); ++iter) (*iter)->Update(i_timer.GetCurrent()); diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 08fcee5b4..b795475aa 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -80,9 +80,6 @@ Object::Object( ) : m_PackGUID(sizeof(uint64)+1) Object::~Object( ) { - if(m_objectUpdated) - ObjectAccessor::Instance().RemoveUpdateObject(this); - if(m_uint32Values) { if(IsInWorld()) @@ -744,10 +741,11 @@ void Object::ClearUpdateMask(bool remove) if(m_uint32Values_mirror[index]!= m_uint32Values[index]) m_uint32Values_mirror[index] = m_uint32Values[index]; } + if(m_objectUpdated) { if(remove) - ObjectAccessor::Instance().RemoveUpdateObject(this); + RemoveFromClientUpdateList(); m_objectUpdated = false; } } @@ -801,7 +799,7 @@ void Object::SetInt32Value( uint16 index, int32 value ) { if(!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + AddToClientUpdateList(); m_objectUpdated = true; } } @@ -820,7 +818,7 @@ void Object::SetUInt32Value( uint16 index, uint32 value ) { if(!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + AddToClientUpdateList(); m_objectUpdated = true; } } @@ -839,7 +837,7 @@ void Object::SetUInt64Value( uint16 index, const uint64 &value ) { if(!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + AddToClientUpdateList(); m_objectUpdated = true; } } @@ -858,7 +856,7 @@ void Object::SetFloatValue( uint16 index, float value ) { if(!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + AddToClientUpdateList(); m_objectUpdated = true; } } @@ -884,7 +882,7 @@ void Object::SetByteValue( uint16 index, uint8 offset, uint8 value ) { if(!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + AddToClientUpdateList(); m_objectUpdated = true; } } @@ -910,7 +908,7 @@ void Object::SetUInt16Value( uint16 index, uint8 offset, uint16 value ) { if(!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + AddToClientUpdateList(); m_objectUpdated = true; } } @@ -979,7 +977,7 @@ void Object::SetFlag( uint16 index, uint32 newFlag ) { if(!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + AddToClientUpdateList(); m_objectUpdated = true; } } @@ -1000,7 +998,7 @@ void Object::RemoveFlag( uint16 index, uint32 oldFlag ) { if(!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + AddToClientUpdateList(); m_objectUpdated = true; } } @@ -1025,7 +1023,7 @@ void Object::SetByteFlag( uint16 index, uint8 offset, uint8 newFlag ) { if(!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + AddToClientUpdateList(); m_objectUpdated = true; } } @@ -1050,7 +1048,7 @@ void Object::RemoveByteFlag( uint16 index, uint8 offset, uint8 oldFlag ) { if(!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + AddToClientUpdateList(); m_objectUpdated = true; } } @@ -1871,6 +1869,16 @@ void WorldObject::UpdateObjectVisibility() GetMap()->UpdateObjectVisibility(this, cell, p); } +void WorldObject::AddToClientUpdateList() +{ + GetMap()->AddUpdateObject(this); +} + +void WorldObject::RemoveFromClientUpdateList() +{ + GetMap()->RemoveUpdateObject(this); +} + struct WorldObjectChangeAccumulator { UpdateDataMapType &i_updateDatas; diff --git a/src/game/Object.h b/src/game/Object.h index 20b543eab..d515af136 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -124,7 +124,7 @@ class MANGOS_DLL_SPEC Object m_inWorld = true; // synchronize values mirror with values array (changes will send in updatecreate opcode any way - ClearUpdateMask(true); + ClearUpdateMask(false); // false - we can't have update dat in update queue before adding to world } virtual void RemoveFromWorld() { @@ -148,6 +148,8 @@ class MANGOS_DLL_SPEC Object virtual void BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target ) const; void SendCreateUpdateToPlayer(Player* player); + virtual void AddToClientUpdateList() =0; + virtual void RemoveFromClientUpdateList() =0; virtual void BuildUpdateData(UpdateDataMapType& update_players) =0; void BuildValuesUpdateBlockForPlayer( UpdateData *data, Player *target ) const; void BuildOutOfRangeUpdateBlock( UpdateData *data ) const; @@ -308,6 +310,7 @@ class MANGOS_DLL_SPEC Object virtual void _SetUpdateBits(UpdateMask *updateMask, Player *target) const; virtual void _SetCreateBits(UpdateMask *updateMask, Player *target) const; + void BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2 ) const; void BuildValuesUpdate(uint8 updatetype, ByteBuffer *data, UpdateMask *updateMask, Player *target ) const; void BuildUpdateDataForPlayer(Player* pl, UpdateDataMapType& update_players); @@ -494,6 +497,8 @@ class MANGOS_DLL_SPEC WorldObject : public Object //this function should be removed in nearest time... Map const* GetBaseMap() const; + void AddToClientUpdateList(); + void RemoveFromClientUpdateList(); void BuildUpdateData(UpdateDataMapType &); Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime); diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp index dc377cd12..7cc289104 100644 --- a/src/game/ObjectAccessor.cpp +++ b/src/game/ObjectAccessor.cpp @@ -331,31 +331,6 @@ ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid, bool insignia) return bones; } -void -ObjectAccessor::Update(uint32 diff) -{ - UpdateDataMapType update_players; - { - Guard guard(i_updateGuard); - while(!i_objects.empty()) - { - Object* obj = *i_objects.begin(); - i_objects.erase(i_objects.begin()); - if (!obj) - continue; - obj->BuildUpdateData(update_players); - } - } - - WorldPacket packet; // here we allocate a std::vector with a size of 0x10000 - for(UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter) - { - iter->second.BuildPacket(&packet); - iter->first->GetSession()->SendPacket(&packet); - packet.clear(); // clean the string - } -} - /// Define the static member of HashMapHolder template UNORDERED_MAP< uint64, T* > HashMapHolder::m_objectMap; diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h index 5778732c7..c562f5e74 100644 --- a/src/game/ObjectAccessor.h +++ b/src/game/ObjectAccessor.h @@ -152,27 +152,10 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton::Remove(pl); - - Guard guard(i_updateGuard); - i_objects.erase((Object *)pl); } void SaveAllPlayers(); - void AddUpdateObject(Object *obj) - { - Guard guard(i_updateGuard); - i_objects.insert(obj); - } - - void RemoveUpdateObject(Object *obj) - { - Guard guard(i_updateGuard); - i_objects.erase( obj ); - } - - void Update(uint32 diff); - Corpse* GetCorpseForPlayerGUID(uint64 guid); void RemoveCorpse(Corpse *corpse); void AddCorpse(Corpse* corpse); @@ -206,9 +189,7 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton Guard; - std::set i_objects; LockType i_playerGuard; - LockType i_updateGuard; LockType i_corpseGuard; }; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index d993e1e04..74aa52fe4 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 "8677" + #define REVISION_NR "8678" #endif // __REVISION_NR_H__ From dcadfb7caed974d029f5e4e7616256b88e58ae30 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Tue, 20 Oct 2009 01:11:19 +0400 Subject: [PATCH 02/25] [8679] Remove 2 now unneeded includes. --- src/game/MapManager.cpp | 1 - src/game/Object.cpp | 1 - src/shared/revision_nr.h | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp index f129e6db9..65157aedd 100644 --- a/src/game/MapManager.cpp +++ b/src/game/MapManager.cpp @@ -21,7 +21,6 @@ #include "Policies/SingletonImp.h" #include "Database/DatabaseEnv.h" #include "Log.h" -#include "ObjectAccessor.h" #include "Transports.h" #include "GridDefines.h" #include "MapInstanced.h" diff --git a/src/game/Object.cpp b/src/game/Object.cpp index b795475aa..524e56bc4 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -31,7 +31,6 @@ #include "UpdateMask.h" #include "Util.h" #include "MapManager.h" -#include "ObjectAccessor.h" #include "Log.h" #include "Transports.h" #include "TargetedMovementGenerator.h" diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 74aa52fe4..d290c9a97 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 "8678" + #define REVISION_NR "8679" #endif // __REVISION_NR_H__ From f015e77a07792127fd1f9ef75020554537eb91ba Mon Sep 17 00:00:00 2001 From: seirge Date: Tue, 20 Oct 2009 11:20:28 +0400 Subject: [PATCH 03/25] [8680] Spawn objects only in loaded grids (not just created) Real object creating in grid make sense only if grid data already loaded, in other cases gameevent/pool related object will loaded at normal grid data loading. Signed-off-by: VladimirMangos --- src/game/GameEventMgr.cpp | 4 ++-- src/game/Map.h | 6 ++++++ src/game/PoolHandler.cpp | 4 ++-- src/shared/revision_nr.h | 2 +- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/game/GameEventMgr.cpp b/src/game/GameEventMgr.cpp index 2ff2f92c1..24f9652bd 100644 --- a/src/game/GameEventMgr.cpp +++ b/src/game/GameEventMgr.cpp @@ -522,7 +522,7 @@ void GameEventMgr::GameEventSpawn(int16 event_id) // Spawn if necessary (loaded grids only) Map* map = const_cast(MapManager::Instance().CreateBaseMap(data->mapid)); // We use spawn coords to spawn - if(!map->Instanceable() && !map->IsRemovalGrid(data->posX,data->posY)) + if(!map->Instanceable() && map->IsLoaded(data->posX,data->posY)) { Creature* pCreature = new Creature; //sLog.outDebug("Spawning creature %u",*itr); @@ -555,7 +555,7 @@ void GameEventMgr::GameEventSpawn(int16 event_id) // this base map checked as non-instanced and then only existed Map* map = const_cast(MapManager::Instance().CreateBaseMap(data->mapid)); // We use current coords to unspawn, not spawn coords since creature can have changed grid - if(!map->Instanceable() && !map->IsRemovalGrid(data->posX, data->posY)) + if(!map->Instanceable() && map->IsLoaded(data->posX, data->posY)) { GameObject* pGameobject = new GameObject; //sLog.outDebug("Spawning gameobject %u", *itr); diff --git a/src/game/Map.h b/src/game/Map.h index af5b94cd6..1a458bda8 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -296,6 +296,12 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj return( !getNGrid(p.x_coord, p.y_coord) || getNGrid(p.x_coord, p.y_coord)->GetGridState() == GRID_STATE_REMOVAL ); } + bool IsLoaded(float x, float y) const + { + GridPair p = MaNGOS::ComputeGridPair(x, y); + return loaded(p); + } + bool GetUnloadLock(const GridPair &p) const { return getNGrid(p.x_coord, p.y_coord)->getUnloadLock(); } void SetUnloadLock(const GridPair &p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadExplicitLock(on); } void LoadGrid(const Cell& cell, bool no_unload = false); diff --git a/src/game/PoolHandler.cpp b/src/game/PoolHandler.cpp index e038add5c..fe38d3f82 100644 --- a/src/game/PoolHandler.cpp +++ b/src/game/PoolHandler.cpp @@ -243,7 +243,7 @@ bool PoolGroup::Spawn1Object(uint32 guid) // Spawn if necessary (loaded grids only) Map* map = const_cast(MapManager::Instance().CreateBaseMap(data->mapid)); // We use spawn coords to spawn - if (!map->Instanceable() && !map->IsRemovalGrid(data->posX, data->posY)) + if (!map->Instanceable() && map->IsLoaded(data->posX, data->posY)) { Creature* pCreature = new Creature; //sLog.outDebug("Spawning creature %u",guid); @@ -273,7 +273,7 @@ bool PoolGroup::Spawn1Object(uint32 guid) // this base map checked as non-instanced and then only existed Map* map = const_cast(MapManager::Instance().CreateBaseMap(data->mapid)); // We use current coords to unspawn, not spawn coords since creature can have changed grid - if (!map->Instanceable() && !map->IsRemovalGrid(data->posX, data->posY)) + if (!map->Instanceable() && map->IsLoaded(data->posX, data->posY)) { GameObject* pGameobject = new GameObject; //sLog.outDebug("Spawning gameobject %u", guid); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index d290c9a97..0fac39084 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 "8679" + #define REVISION_NR "8680" #endif // __REVISION_NR_H__ From 20a5cbcdcae554e64e30443443e6833c64ef4b12 Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Tue, 20 Oct 2009 11:17:10 +0200 Subject: [PATCH 04/25] [8681] Update one creature type flag name and correct typos in comments. Signed-off-by: NoFantasy --- src/game/SharedDefines.h | 6 +++--- src/shared/revision_nr.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 83945c8e2..71d0b2133 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -1884,7 +1884,7 @@ enum CreatureFamily enum CreatureTypeFlags { CREATURE_TYPEFLAGS_TAMEABLE = 0x00001, //tameable by any hunter - CREATURE_TYPEFLAGS_UNK2 = 0x00002, //? Related to spirits/ghosts in any form? Allow gossip interaction if player is also ghost? Visibility? + CREATURE_TYPEFLAGS_GHOST = 0x00002, //creature are also visible for not alive player. Allow gossip interaction if npcflag allow? CREATURE_TYPEFLAGS_UNK3 = 0x00004, CREATURE_TYPEFLAGS_UNK4 = 0x00008, CREATURE_TYPEFLAGS_UNK5 = 0x00010, @@ -1900,8 +1900,8 @@ enum CreatureTypeFlags CREATURE_TYPEFLAGS_UNK15 = 0x04000, //? Possibly not in use CREATURE_TYPEFLAGS_ENGINEERLOOT = 0x08000, //can be looted by engineer CREATURE_TYPEFLAGS_EXOTIC = 0x10000, //can be tamed by hunter as exotic pet - CREATURE_TYPEFLAGS_UNK18 = 0x20000, //? Related to veichles/pvp? - CREATURE_TYPEFLAGS_UNK19 = 0x40000, //? Related to veichle/siege weapons? + CREATURE_TYPEFLAGS_UNK18 = 0x20000, //? Related to vehicles/pvp? + CREATURE_TYPEFLAGS_UNK19 = 0x40000, //? Related to vehicle/siege weapons? CREATURE_TYPEFLAGS_UNK20 = 0x80000 }; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 0fac39084..d36745571 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 "8680" + #define REVISION_NR "8681" #endif // __REVISION_NR_H__ From 2db2600d65dcf55928fce97319179993fc55b5e7 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Tue, 20 Oct 2009 14:52:07 +0400 Subject: [PATCH 05/25] [8682] Restore build at Unix/Linux Not tested, but fix repoted build problem. --- src/game/DestinationHolderImp.h | 1 + src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/game/DestinationHolderImp.h b/src/game/DestinationHolderImp.h index 1340e0d1b..3db095f1e 100644 --- a/src/game/DestinationHolderImp.h +++ b/src/game/DestinationHolderImp.h @@ -21,6 +21,7 @@ #include "MapManager.h" #include "DestinationHolder.h" +#include "Unit.h" #include diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index d36745571..770298933 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 "8681" + #define REVISION_NR "8682" #endif // __REVISION_NR_H__ From 8271e7eb99b9ce568f2d414921484560c36329c2 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Tue, 20 Oct 2009 16:44:00 +0400 Subject: [PATCH 06/25] [8683] Correctly update negetive aura duration at loading. Thanks to ApoC for problem reseach. --- src/game/Player.cpp | 4 ++-- src/shared/revision_nr.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index e7ac1ccf1..38920cf5d 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -14835,10 +14835,10 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff) // negative effects should continue counting down after logout if (remaintime != -1 && !IsPositiveEffect(spellid, effindex)) { - if(remaintime <= int32(timediff)) + if (remaintime/IN_MILISECONDS <= int32(timediff)) continue; - remaintime -= timediff; + remaintime -= timediff*IN_MILISECONDS; } // prevent wrong values of remaincharges diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 770298933..d6d39036c 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 "8682" + #define REVISION_NR "8683" #endif // __REVISION_NR_H__ From efe057112d53df3387a361e8dc01e692a3f3fd34 Mon Sep 17 00:00:00 2001 From: reeshack Date: Tue, 20 Oct 2009 18:34:53 +0400 Subject: [PATCH 07/25] [8684] Typos in code for talent 30675 and ranks affect at spell 421 ranks 7 & 8 casting. Signed-off-by: VladimirMangos --- src/game/Unit.cpp | 4 ++-- src/shared/revision_nr.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 6518b56c6..eb01b162b 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -6276,8 +6276,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu case 10605: spellId = 45300; break; // Rank 4 case 25439: spellId = 45301; break; // Rank 5 case 25442: spellId = 45302; break; // Rank 6 - case 49268: spellId = 49270; break; // Rank 7 - case 49269: spellId = 49271; break; // Rank 8 + case 49270: spellId = 49268; break; // Rank 7 + case 49271: spellId = 49269; break; // Rank 8 default: sLog.outError("Unit::HandleDummyAuraProc: non handled spell id: %u (LO)", procSpell->Id); return false; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index d6d39036c..ac77abd4b 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 "8683" + #define REVISION_NR "8684" #endif // __REVISION_NR_H__ From cd43a0a192297a6af4f4800f5a1f0fcb61a0b4ef Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Tue, 20 Oct 2009 19:27:52 +0200 Subject: [PATCH 08/25] [8685] Add a few more creature type_flag enum names (meaning still unknown) --- src/game/SharedDefines.h | 44 ++++++++++++++++++++++------------------ src/shared/revision_nr.h | 2 +- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 71d0b2133..8021243fb 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -1883,26 +1883,30 @@ enum CreatureFamily enum CreatureTypeFlags { - CREATURE_TYPEFLAGS_TAMEABLE = 0x00001, //tameable by any hunter - CREATURE_TYPEFLAGS_GHOST = 0x00002, //creature are also visible for not alive player. Allow gossip interaction if npcflag allow? - CREATURE_TYPEFLAGS_UNK3 = 0x00004, - CREATURE_TYPEFLAGS_UNK4 = 0x00008, - CREATURE_TYPEFLAGS_UNK5 = 0x00010, - CREATURE_TYPEFLAGS_UNK6 = 0x00020, - CREATURE_TYPEFLAGS_UNK7 = 0x00040, - CREATURE_TYPEFLAGS_UNK8 = 0x00080, - CREATURE_TYPEFLAGS_HERBLOOT = 0x00100, //can be looted by herbalist - CREATURE_TYPEFLAGS_MININGLOOT = 0x00200, //can be looted by miner - CREATURE_TYPEFLAGS_UNK11 = 0x00400, - CREATURE_TYPEFLAGS_UNK12 = 0x00800, //? Related to mounts in some way. If mounted, fight mounted, mount appear as independant when rider dies? - CREATURE_TYPEFLAGS_UNK13 = 0x01000, //? Can aid any player in combat if in range? - CREATURE_TYPEFLAGS_UNK14 = 0x02000, - CREATURE_TYPEFLAGS_UNK15 = 0x04000, //? Possibly not in use - CREATURE_TYPEFLAGS_ENGINEERLOOT = 0x08000, //can be looted by engineer - CREATURE_TYPEFLAGS_EXOTIC = 0x10000, //can be tamed by hunter as exotic pet - CREATURE_TYPEFLAGS_UNK18 = 0x20000, //? Related to vehicles/pvp? - CREATURE_TYPEFLAGS_UNK19 = 0x40000, //? Related to vehicle/siege weapons? - CREATURE_TYPEFLAGS_UNK20 = 0x80000 + CREATURE_TYPEFLAGS_TAMEABLE = 0x000001, // Tameable by any hunter + CREATURE_TYPEFLAGS_GHOST = 0x000002, // Creature are also visible for not alive player. Allow gossip interaction if npcflag allow? + CREATURE_TYPEFLAGS_UNK3 = 0x000004, + CREATURE_TYPEFLAGS_UNK4 = 0x000008, + CREATURE_TYPEFLAGS_UNK5 = 0x000010, + CREATURE_TYPEFLAGS_UNK6 = 0x000020, + CREATURE_TYPEFLAGS_UNK7 = 0x000040, + CREATURE_TYPEFLAGS_UNK8 = 0x000080, + CREATURE_TYPEFLAGS_HERBLOOT = 0x000100, // Can be looted by herbalist + CREATURE_TYPEFLAGS_MININGLOOT = 0x000200, // Can be looted by miner + CREATURE_TYPEFLAGS_UNK11 = 0x000400, + CREATURE_TYPEFLAGS_UNK12 = 0x000800, // ? Related to mounts in some way. If mounted, fight mounted, mount appear as independant when rider dies? + CREATURE_TYPEFLAGS_UNK13 = 0x001000, // ? Can aid any player in combat if in range? + CREATURE_TYPEFLAGS_UNK14 = 0x002000, + CREATURE_TYPEFLAGS_UNK15 = 0x004000, // ? Possibly not in use + CREATURE_TYPEFLAGS_ENGINEERLOOT = 0x008000, // Can be looted by engineer + CREATURE_TYPEFLAGS_EXOTIC = 0x010000, // Can be tamed by hunter as exotic pet + CREATURE_TYPEFLAGS_UNK18 = 0x020000, // ? Related to vehicles/pvp? + CREATURE_TYPEFLAGS_UNK19 = 0x040000, // ? Related to vehicle/siege weapons? + CREATURE_TYPEFLAGS_UNK20 = 0x080000, + CREATURE_TYPEFLAGS_UNK21 = 0x100000, + CREATURE_TYPEFLAGS_UNK22 = 0x200000, + CREATURE_TYPEFLAGS_UNK23 = 0x400000, + CREATURE_TYPEFLAGS_UNK24 = 0x800000 // ? First seen in 3.2.2. Related to banner/backpack of creature/companion? }; enum CreatureEliteType diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index ac77abd4b..4413e6f5f 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 "8684" + #define REVISION_NR "8685" #endif // __REVISION_NR_H__ From 5bae4fccf842dc386469d19418a52793fe4295f3 Mon Sep 17 00:00:00 2001 From: ApoC Date: Tue, 20 Oct 2009 19:39:23 +0200 Subject: [PATCH 09/25] [8686] Fixed logic of triggering spells from SPELL_AURA_PERIODIC_TRIGGER_SPELL and SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE. This patch should correct target selection for triggered spells with target type TARGET_SELF. Signed-off-by: ApoC --- src/game/SpellAuras.cpp | 80 ++++++++++++++++++++++------------------ src/shared/revision_nr.h | 2 +- 2 files changed, 46 insertions(+), 36 deletions(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 8015555f8..1e2d83ec8 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -572,7 +572,7 @@ Aura* CreateAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoi Unit* Aura::GetCaster() const { - if(m_caster_guid==m_target->GetGUID()) + if(m_caster_guid == m_target->GetGUID()) return m_target; //return ObjectAccessor::GetUnit(*m_target,m_caster_guid); @@ -1450,10 +1450,10 @@ void Aura::HandleAddTargetTrigger(bool apply, bool /*Real*/) void Aura::TriggerSpell() { - Unit* caster = GetCaster(); + const uint64& casterGUID = GetCasterGUID(); Unit* target = GetTriggerTarget(); - if(!caster || !target) + if(!casterGUID || !target) return; // generic casting code with custom spells and target/caster customs @@ -1479,9 +1479,9 @@ void Aura::TriggerSpell() case 17949: case 27252: { - if (caster->GetTypeId()!=TYPEID_PLAYER) + if (target->GetTypeId() != TYPEID_PLAYER) return; - Item* item = ((Player*)caster)->GetWeaponForAttack(BASE_ATTACK); + Item* item = ((Player*)target)->GetWeaponForAttack(BASE_ATTACK); if (!item) return; uint32 enchant_id = 0; @@ -1496,10 +1496,10 @@ void Aura::TriggerSpell() return; } // remove old enchanting before applying new - ((Player*)caster)->ApplyEnchantment(item,TEMP_ENCHANTMENT_SLOT,false); + ((Player*)target)->ApplyEnchantment(item,TEMP_ENCHANTMENT_SLOT,false); item->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, m_modifier.periodictime+1000, 0); // add new enchanting - ((Player*)caster)->ApplyEnchantment(item,TEMP_ENCHANTMENT_SLOT,true); + ((Player*)target)->ApplyEnchantment(item,TEMP_ENCHANTMENT_SLOT,true); return; } // // Periodic Mana Burn @@ -1542,14 +1542,13 @@ void Aura::TriggerSpell() // Restoration case 23493: { - int32 heal = caster->GetMaxHealth() / 10; - caster->DealHeal(caster, heal, auraSpellInfo); + int32 heal = target->GetMaxHealth() / 10; + target->DealHeal(target, heal, auraSpellInfo); - int32 mana = caster->GetMaxPower(POWER_MANA); - if (mana) + if (int32 mana = target->GetMaxPower(POWER_MANA)) { mana /= 10; - caster->EnergizeBySpell(caster, 23493, mana, POWER_MANA); + target->EnergizeBySpell(target, 23493, mana, POWER_MANA); } return; } @@ -1579,7 +1578,7 @@ void Aura::TriggerSpell() case 25371: { int32 bpDamage = target->GetMaxHealth()*10/100; - caster->CastCustomSpell(target, 25373, &bpDamage, NULL, NULL, true, NULL, this); + target->CastCustomSpell(target, 25373, &bpDamage, NULL, NULL, true, NULL, this, casterGUID); return; } // // Pain Spike @@ -1606,7 +1605,7 @@ void Aura::TriggerSpell() case 27808: { int32 bpDamage = target->GetMaxHealth()*26/100; - caster->CastCustomSpell(target, 29879, &bpDamage, NULL, NULL, true, NULL, this); + target->CastCustomSpell(target, 29879, &bpDamage, NULL, NULL, true, NULL, this, casterGUID); return; } // // Detonate Mana @@ -1657,10 +1656,13 @@ void Aura::TriggerSpell() // Extract Gas case 30427: { + Unit* caster = GetCaster(); + if (!caster) + return; // move loot to player inventory and despawn target if(caster->GetTypeId() ==TYPEID_PLAYER && - target->GetTypeId() == TYPEID_UNIT && - ((Creature*)target)->GetCreatureInfo()->type == CREATURE_TYPE_GAS_CLOUD) + target->GetTypeId() == TYPEID_UNIT && + ((Creature*)target)->GetCreatureInfo()->type == CREATURE_TYPE_GAS_CLOUD) { Player* player = (Player*)caster; Creature* creature = (Creature*)target; @@ -1700,7 +1702,7 @@ void Aura::TriggerSpell() case 31373: { // Summon Elemental after create item - caster->SummonCreature(17870, 0, 0, 0, caster->GetOrientation(), TEMPSUMMON_DEAD_DESPAWN, 0); + target->SummonCreature(17870, 0, 0, 0, target->GetOrientation(), TEMPSUMMON_DEAD_DESPAWN, 0); return; } // // Bloodmyst Tesla @@ -1722,9 +1724,9 @@ void Aura::TriggerSpell() { // cast 24 spells 34269-34289, 34314-34316 for(uint32 spell_id = 34269; spell_id != 34290; ++spell_id) - caster->CastSpell(m_target, spell_id, true); + target->CastSpell(target, spell_id, true, NULL, this, casterGUID); for(uint32 spell_id = 34314; spell_id != 34317; ++spell_id) - caster->CastSpell(m_target, spell_id, true); + target->CastSpell(target, spell_id, true, NULL, this, casterGUID); return; } // // Gravity Lapse @@ -1815,7 +1817,10 @@ void Aura::TriggerSpell() if(m_target->GetTypeId() != TYPEID_UNIT) return; - caster->CastSpell(caster, 38495, true); + if (Unit* caster = GetCaster()) + caster->CastSpell(caster, 38495, true, NULL, this); + else + return; Creature* creatureTarget = (Creature*)m_target; @@ -2073,7 +2078,7 @@ void Aura::TriggerSpell() bool all = true; for(int i = 0; i < MAX_TOTEM; ++i) { - if(!caster->m_TotemSlot[i]) + if(!target->m_TotemSlot[i]) { all = false; break; @@ -2081,9 +2086,9 @@ void Aura::TriggerSpell() } if(all) - caster->CastSpell(caster, 38437, true); + target->CastSpell(target, 38437, true, NULL, this); else - caster->RemoveAurasDueToSpell(38437); + target->RemoveAurasDueToSpell(38437); return; } default: @@ -2113,14 +2118,14 @@ void Aura::TriggerSpell() // 2) maybe aura must be replace by new with accumulative stat mods instead stacking // prevent cast by triggered auras - if(m_caster_guid == m_target->GetGUID()) + if(casterGUID == target->GetGUID()) return; // stop triggering after each affected stats lost > 90 int32 intelectLoss = 0; int32 spiritLoss = 0; - Unit::AuraList const& mModStat = m_target->GetAurasByType(SPELL_AURA_MOD_STAT); + Unit::AuraList const& mModStat = target->GetAurasByType(SPELL_AURA_MOD_STAT); for(Unit::AuraList::const_iterator i = mModStat.begin(); i != mModStat.end(); ++i) { if ((*i)->GetId() == 1010) @@ -2137,47 +2142,52 @@ void Aura::TriggerSpell() if(intelectLoss <= -90 && spiritLoss <= -90) return; - caster = target; break; } // Mana Tide case 16191: { - caster->CastCustomSpell(target, trigger_spell_id, &m_modifier.m_amount, NULL, NULL, true, NULL, this); + target->CastCustomSpell(target, trigger_spell_id, &m_modifier.m_amount, NULL, NULL, true, NULL, this); return; } // Ground Slam case 33525: - target->CastSpell(target, trigger_spell_id, true); + target->CastSpell(target, trigger_spell_id, true, NULL, this, casterGUID); return; // Beacon of Light case 53563: // original caster must be target (beacon) - m_target->CastSpell(m_target,trigger_spell_id,true,NULL,this,m_target->GetGUID()); + target->CastSpell(target, trigger_spell_id, true, NULL, this, target->GetGUID()); return; } } // All ok cast by default case if(triggeredSpellInfo) - caster->CastSpell(target, triggeredSpellInfo, true, 0, this); - else if(target->GetTypeId()!=TYPEID_UNIT || !Script->EffectDummyCreature(caster, GetId(), GetEffIndex(), (Creature*)target)) - sLog.outError("Aura::TriggerSpell: Spell %u have 0 in EffectTriggered[%d], not handled custom case?",GetId(),GetEffIndex()); + target->CastSpell(target, triggeredSpellInfo, true, NULL, this, casterGUID); + else + { + if (Unit* caster = GetCaster()) + { + if(target->GetTypeId() != TYPEID_UNIT || !Script->EffectDummyCreature(caster, GetId(), GetEffIndex(), (Creature*)target)) + sLog.outError("Aura::TriggerSpell: Spell %u have 0 in EffectTriggered[%d], not handled custom case?",GetId(),GetEffIndex()); + } + } } void Aura::TriggerSpellWithValue() { - Unit* caster = GetCaster(); + const uint64& casterGUID = GetCasterGUID(); Unit* target = GetTriggerTarget(); - if(!caster || !target) + if(!casterGUID || !target) return; // generic casting code with custom spells and target/caster customs uint32 trigger_spell_id = GetSpellProto()->EffectTriggerSpell[m_effIndex]; int32 basepoints0 = this->GetModifier()->m_amount; - caster->CastCustomSpell(target, trigger_spell_id, &basepoints0, NULL, NULL, true, NULL, this); + target->CastCustomSpell(target, trigger_spell_id, &basepoints0, NULL, NULL, true, NULL, this, casterGUID); } /*********************************************************/ diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 4413e6f5f..224e103f3 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 "8685" + #define REVISION_NR "8686" #endif // __REVISION_NR_H__ From 58139610eb45555c2336c77e981f5e32aff0aa34 Mon Sep 17 00:00:00 2001 From: ApoC Date: Tue, 20 Oct 2009 23:12:38 +0200 Subject: [PATCH 10/25] [8687] Fixes in TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT. * Removed my too script check on data load. * Allow looking up fo DB target also if spell has required focus set. * Makes DB targets optional not required. Signed-off-by: ApoC --- src/game/Spell.cpp | 19 ++++++++++++------- src/game/SpellMgr.cpp | 25 ------------------------- src/shared/revision_nr.h | 2 +- 3 files changed, 13 insertions(+), 33 deletions(-) diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 9e56a833b..b9d653f6d 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -4124,8 +4124,7 @@ SpellCastResult Spell::CheckCast(bool strict) (m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT && m_spellInfo->EffectImplicitTargetA[j] != TARGET_SELF) || m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES || m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT_COORDINATES || - // Check possible in DB targets only for spells with no implicit spell focus - (m_spellInfo->EffectImplicitTargetA[j] == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT && !m_spellInfo->RequiresSpellFocus)) + m_spellInfo->EffectImplicitTargetA[j] == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT) { SpellScriptTargetBounds bounds = spellmgr.GetSpellScriptTargetBounds(m_spellInfo->Id); @@ -4242,11 +4241,17 @@ SpellCastResult Spell::CheckCast(bool strict) //Missing DB Entry or targets for this spellEffect. else { - // not report target not existence for triggered spells - if(m_triggeredByAuraSpell || m_IsTriggeredSpell) - return SPELL_FAILED_DONT_REPORT; - else - return SPELL_FAILED_BAD_TARGETS; + /* For TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT makes DB targets optional not required for now + * TODO: Makes more research for this target type + */ + if (m_spellInfo->EffectImplicitTargetA[j] != TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT) + { + // not report target not existence for triggered spells + if(m_triggeredByAuraSpell || m_IsTriggeredSpell) + return SPELL_FAILED_DONT_REPORT; + else + return SPELL_FAILED_BAD_TARGETS; + } } } } diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 544a84079..f2971702a 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -2205,31 +2205,6 @@ void SpellMgr::LoadSpellScriptTarget() continue; } - // More checks on TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT - bool ok = true; - for (int i = 0; i < 3; ++i) - { - if (spellProto->EffectImplicitTargetA[i] == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT || - spellProto->EffectImplicitTargetB[i] == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT) - { - if (spellProto->RequiresSpellFocus) - { - sLog.outErrorDb("Table `spell_script_target`: spellId %u for TargetEnty %u of type TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT is wrong because spell has implicit ReqSpellFocus %u.", spellId, targetEntry, spellProto->RequiresSpellFocus); - ok = false; - break; - } - - if (type != SPELL_TARGET_TYPE_GAMEOBJECT) - { - sLog.outErrorDb("Table `spell_script_target`: spellId %u has target type TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT but target in table is creature (must be gameobject).", spellId); - ok = false; - break; - } - } - } - if (!ok) - continue; - // Checks by target type switch (type) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 224e103f3..9e02251d4 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 "8686" + #define REVISION_NR "8687" #endif // __REVISION_NR_H__ From e990d5c5095612fc0205344e1282ea5115eefa52 Mon Sep 17 00:00:00 2001 From: balrok Date: Mon, 19 Oct 2009 20:25:02 +0200 Subject: [PATCH 11/25] [8688] proper implementation of creatures ghost-flags this reverts 8676 (9c50d9e70314b0cd9eb0fe3bac8040d64a9965a5) the new flag is from wdb-files so your database should be already alright also i've dropped the function Player::CanInteractWithNPCs cause it was used only in one place and didn't seem to make anything easier NOTE for this flag: it just means that the creature can be seen by ghost-players too.. so they are still visible for alive players.. unless a special aura or ther unitflag (spiritguide/healer) disables this.. (see next commit for it) --- sql/mangos.sql | 2 +- .../8688_01_mangos_creature_template.sql | 5 +++ sql/updates/Makefile.am | 2 ++ src/game/AggressorAI.cpp | 3 +- src/game/Creature.cpp | 6 ++-- src/game/Creature.h | 1 - src/game/Player.cpp | 31 +++++-------------- src/game/Player.h | 1 - src/game/SharedDefines.h | 2 +- src/game/Unit.cpp | 3 +- src/shared/revision_nr.h | 2 +- src/shared/revision_sql.h | 2 +- 12 files changed, 24 insertions(+), 36 deletions(-) create mode 100644 sql/updates/8688_01_mangos_creature_template.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 26d1b3c5f..0a03d0cf3 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -24,7 +24,7 @@ CREATE TABLE `db_version` ( `version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL, `cache_id` int(10) default '0', - `required_8676_01_mangos_creature_template` bit(1) default NULL + `required_8688_01_mangos_creature_template` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- diff --git a/sql/updates/8688_01_mangos_creature_template.sql b/sql/updates/8688_01_mangos_creature_template.sql new file mode 100644 index 000000000..02540006d --- /dev/null +++ b/sql/updates/8688_01_mangos_creature_template.sql @@ -0,0 +1,5 @@ +ALTER TABLE db_version CHANGE COLUMN required_8676_01_mangos_creature_template required_8688_01_mangos_creature_template bit; + +-- reverts last update - we now have something better +UPDATE creature_template SET flags_extra = flags_extra & ~(0x200) WHERE npcflag +& (16384|32768); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 5137ff8d4..9198d0d4a 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -136,6 +136,7 @@ pkgdata_DATA = \ 8608_02_mangos_battleground_events.sql \ 8618_01_mangos_spell_proc_event.sql \ 8676_01_mangos_creature_template.sql \ + 8688_01_mangos_creature_template.sql \ README ## Additional files to include when running 'make dist' @@ -252,4 +253,5 @@ EXTRA_DIST = \ 8608_02_mangos_battleground_events.sql \ 8618_01_mangos_spell_proc_event.sql \ 8676_01_mangos_creature_template.sql \ + 8688_01_mangos_creature_template.sql \ README diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp index faa4e608d..f611a87b6 100644 --- a/src/game/AggressorAI.cpp +++ b/src/game/AggressorAI.cpp @@ -19,6 +19,7 @@ #include "AggressorAI.h" #include "Errors.h" #include "Creature.h" +#include "SharedDefines.h" #include "ObjectAccessor.h" #include "VMapFactory.h" #include "World.h" @@ -46,7 +47,7 @@ AggressorAI::MoveInLineOfSight(Unit *u) if( !m_creature->canFly() && m_creature->GetDistanceZ(u) > CREATURE_Z_ATTACK_RANGE ) return; - if( !(m_creature->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_GHOST) && !m_creature->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_DIED) && u->isTargetableForAttack() && + if (!m_creature->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_DIED) && u->isTargetableForAttack() && ( m_creature->IsHostileTo( u ) /*|| u->getVictim() && m_creature->IsFriendlyTo( u->getVictim() )*/ ) && u->isInAccessablePlaceFor(m_creature) ) { diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index b666a0289..c15da2c44 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -1749,7 +1749,7 @@ bool Creature::IsVisibleInGridForPlayer(Player* pl) const // Live player (or with not release body see live creatures or death creatures with corpse disappearing time > 0 if(pl->isAlive() || pl->GetDeathTimer() > 0) { - if(GetCreatureInfo()->flags_extra & (CREATURE_FLAG_EXTRA_INVISIBLE | CREATURE_FLAG_EXTRA_GHOST)) + if (GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_INVISIBLE) return false; return (isAlive() || m_deathTimer > 0 || (m_isDeadByDefault && m_deathState == CORPSE)); } @@ -1766,8 +1766,8 @@ bool Creature::IsVisibleInGridForPlayer(Player* pl) const } } - // Dead player see ghosts - if (GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_GHOST) + // Dead player can see ghosts + if (GetCreatureInfo()->type_flags & CREATURE_TYPEFLAGS_GHOST_VISIBLE) return true; // and not see any other diff --git a/src/game/Creature.h b/src/game/Creature.h index d41364ce2..f0025a9c6 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -143,7 +143,6 @@ enum CreatureFlagsExtra CREATURE_FLAG_EXTRA_NO_XP_AT_KILL = 0x00000040, // creature kill not provide XP CREATURE_FLAG_EXTRA_INVISIBLE = 0x00000080, // creature is always invisible for player (mostly trigger creatures) CREATURE_FLAG_EXTRA_NOT_TAUNTABLE = 0x00000100, // creature is immune to taunt auras and effect attack me - CREATURE_FLAG_EXTRA_GHOST = 0x00000200, // creature is only visible for dead players }; // GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 38920cf5d..20aff8838 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -2072,24 +2072,10 @@ void Player::RegenerateHealth(uint32 diff) ModifyHealth(int32(addvalue)); } -bool Player::CanInteractWithNPCs(bool alive) const -{ - if(alive && !isAlive()) - return false; - if(isInFlight()) - return false; - - return true; -} - -Creature* -Player::GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask) +Creature* Player::GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask) { // unit checks - if (!guid) - return NULL; - - if(!IsInWorld()) + if (!guid || !IsInWorld() || isInFlight()) return NULL; // exist (we need look pets also for some interaction (quest/etc) @@ -2097,23 +2083,20 @@ Player::GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask) if (!unit) return NULL; - // player check - if(!CanInteractWithNPCs(!(unit->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_GHOST))) - return NULL; - // appropriate npc type - if(npcflagmask && !unit->HasFlag( UNIT_NPC_FLAGS, npcflagmask )) + if (npcflagmask && !unit->HasFlag( UNIT_NPC_FLAGS, npcflagmask )) return NULL; - if (isAlive() && !unit->isAlive()) + // if a dead unit should be able to talk - the creature must be alive and have special flags + if (!unit->isAlive()) return NULL; // not allow interaction under control, but allow with own pets - if(unit->GetCharmerGUID()) + if (unit->GetCharmerGUID()) return NULL; // not enemy - if( unit->IsHostileTo(this)) + if (unit->IsHostileTo(this)) return NULL; // not unfriendly diff --git a/src/game/Player.h b/src/game/Player.h index ff6a185d3..5533110c1 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1046,7 +1046,6 @@ class MANGOS_DLL_SPEC Player : public Unit void SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time); Creature* GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask); - bool CanInteractWithNPCs(bool alive = true) const; GameObject* GetGameObjectIfCanInteractWith(uint64 guid, GameobjectTypes type) const; void UpdateVisibilityForPlayer(); diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 8021243fb..45762a66f 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -1884,7 +1884,7 @@ enum CreatureFamily enum CreatureTypeFlags { CREATURE_TYPEFLAGS_TAMEABLE = 0x000001, // Tameable by any hunter - CREATURE_TYPEFLAGS_GHOST = 0x000002, // Creature are also visible for not alive player. Allow gossip interaction if npcflag allow? + CREATURE_TYPEFLAGS_GHOST_VISIBLE = 0x000002, // Creatures which can _also_ be seen when player is a ghost CREATURE_TYPEFLAGS_UNK3 = 0x000004, CREATURE_TYPEFLAGS_UNK4 = 0x000008, CREATURE_TYPEFLAGS_UNK5 = 0x000010, diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index eb01b162b..4d3a51a32 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -9603,8 +9603,7 @@ bool Unit::isTargetableForAttack(bool inverseAlive /*=false*/) const if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE)) return false; - // target is dead or has ghost-flag - if ((!isAlive() || (GetTypeId() == TYPEID_UNIT && ((Creature *)this)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_GHOST)) != inverseAlive) + if (!(isAlive() != inverseAlive)) return false; return IsInWorld() && !hasUnitState(UNIT_STAT_DIED)&& !isInFlight() /*&& !isStealth()*/; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 9e02251d4..eee8b347d 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 "8687" + #define REVISION_NR "8688" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index 55c964243..faf8d488d 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_MANGOS "required_8676_01_mangos_creature_template" + #define REVISION_DB_MANGOS "required_8688_01_mangos_creature_template" #define REVISION_DB_REALMD "required_8332_01_realmd_realmcharacters" #endif // __REVISION_SQL_H__ From 46389e4e1c7302a5c63dd2b59789e38186ac66d8 Mon Sep 17 00:00:00 2001 From: balrok Date: Tue, 20 Oct 2009 17:57:57 +0200 Subject: [PATCH 12/25] [8689] implement function Unit::isInvisibleForAlive with that i've implemented all known auras which makes units invisible for alive.. but that's currently quite hacky i think best would be if we could set a unit-flag after those auras getting applied --- src/game/AggressorAI.cpp | 2 +- src/game/Creature.cpp | 5 +++-- src/game/CreatureEventAI.cpp | 2 +- src/game/GuardAI.cpp | 2 +- src/game/PetAI.cpp | 2 +- src/game/Player.cpp | 3 +++ src/game/Unit.cpp | 24 +++++++++++++++++++----- src/game/Unit.h | 1 + src/shared/revision_nr.h | 2 +- 9 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp index f611a87b6..7e01aba55 100644 --- a/src/game/AggressorAI.cpp +++ b/src/game/AggressorAI.cpp @@ -49,7 +49,7 @@ AggressorAI::MoveInLineOfSight(Unit *u) if (!m_creature->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_DIED) && u->isTargetableForAttack() && ( m_creature->IsHostileTo( u ) /*|| u->getVictim() && m_creature->IsFriendlyTo( u->getVictim() )*/ ) && - u->isInAccessablePlaceFor(m_creature) ) + u->isInAccessablePlaceFor(m_creature) && !u->isInvisibleForAlive()) { float attackRadius = m_creature->GetAttackDistance(u); if(m_creature->IsWithinDistInMap(u, attackRadius) && m_creature->IsWithinLOSInMap(u) ) diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index c15da2c44..2a195e7d0 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -1746,11 +1746,12 @@ bool Creature::IsVisibleInGridForPlayer(Player* pl) const if(pl->isGameMaster()) return true; + if (GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_INVISIBLE) + return false; + // Live player (or with not release body see live creatures or death creatures with corpse disappearing time > 0 if(pl->isAlive() || pl->GetDeathTimer() > 0) { - if (GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_INVISIBLE) - return false; return (isAlive() || m_deathTimer > 0 || (m_isDeadByDefault && m_deathState == CORPSE)); } diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp index 3e9c59e28..4743f12d4 100644 --- a/src/game/CreatureEventAI.cpp +++ b/src/game/CreatureEventAI.cpp @@ -995,7 +995,7 @@ void CreatureEventAI::MoveInLineOfSight(Unit *who) return; if (!m_creature->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_DIED) && who->isTargetableForAttack() && - m_creature->IsHostileTo(who) && who->isInAccessablePlaceFor(m_creature)) + m_creature->IsHostileTo(who) && who->isInAccessablePlaceFor(m_creature) && !who->isInvisibleForAlive()) { if (!m_creature->canFly() && m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE) return; diff --git a/src/game/GuardAI.cpp b/src/game/GuardAI.cpp index 3d5b529a7..3bae9ef61 100644 --- a/src/game/GuardAI.cpp +++ b/src/game/GuardAI.cpp @@ -43,7 +43,7 @@ void GuardAI::MoveInLineOfSight(Unit *u) if (!m_creature->getVictim() && u->isTargetableForAttack() && ( u->IsHostileToPlayers() || m_creature->IsHostileTo(u) /*|| u->getVictim() && m_creature->IsFriendlyTo(u->getVictim())*/ ) && - u->isInAccessablePlaceFor(m_creature)) + u->isInAccessablePlaceFor(m_creature) && !u->isInvisibleForAlive()) { float attackRadius = m_creature->GetAttackDistance(u); if (m_creature->IsWithinDistInMap(u,attackRadius)) diff --git a/src/game/PetAI.cpp b/src/game/PetAI.cpp index 354ef371a..b20e5cb12 100644 --- a/src/game/PetAI.cpp +++ b/src/game/PetAI.cpp @@ -47,7 +47,7 @@ void PetAI::MoveInLineOfSight(Unit *u) if( !m_creature->getVictim() && m_creature->GetCharmInfo() && m_creature->GetCharmInfo()->HasReactState(REACT_AGGRESSIVE) && u->isTargetableForAttack() && m_creature->IsHostileTo( u ) && - u->isInAccessablePlaceFor(m_creature)) + u->isInAccessablePlaceFor(m_creature) && !u->isInvisibleForAlive()) { float attackRadius = m_creature->GetAttackDistance(u); if(m_creature->IsWithinDistInMap(u, attackRadius) && m_creature->GetDistanceZ(u) <= CREATURE_Z_ATTACK_RANGE) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 20aff8838..7d7069ed1 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -2091,6 +2091,9 @@ Creature* Player::GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask) if (!unit->isAlive()) return NULL; + if (isAlive() && unit->isInvisibleForAlive()) + return NULL; + // not allow interaction under control, but allow with own pets if (unit->GetCharmerGUID()) return NULL; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 4d3a51a32..5ef95104a 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -9603,7 +9603,7 @@ bool Unit::isTargetableForAttack(bool inverseAlive /*=false*/) const if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE)) return false; - if (!(isAlive() != inverseAlive)) + if ((isAlive() && !isInvisibleForAlive()) == inverseAlive) return false; return IsInWorld() && !hasUnitState(UNIT_STAT_DIED)&& !isInFlight() /*&& !isStealth()*/; @@ -9700,7 +9700,7 @@ bool Unit::isVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, boo Map& _map = *u->GetMap(); // Grid dead/alive checks - if( u->GetTypeId()==TYPEID_PLAYER) + if (u->GetTypeId()==TYPEID_PLAYER) { // non visible at grid for any stealth state if(!IsVisibleInGridForPlayer((Player *)u)) @@ -9717,16 +9717,19 @@ bool Unit::isVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, boo return false; } + if (u->isAlive() && isInvisibleForAlive()) + return false; + // always seen by owner - if(GetCharmerOrOwnerGUID()==u->GetGUID()) + if (GetCharmerOrOwnerGUID()==u->GetGUID()) return true; // always seen by far sight caster - if( u->GetTypeId()==TYPEID_PLAYER && ((Player*)u)->GetFarSight()==GetGUID()) + if (u->GetTypeId()==TYPEID_PLAYER && ((Player*)u)->GetFarSight()==GetGUID()) return true; // different visible distance checks - if(u->isInFlight()) // what see player in flight + if (u->isInFlight()) // what see player in flight { // use object grey distance for all (only see objects any way) if (!IsWithinDistInMap(viewPoint,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), is3dDistance)) @@ -10621,6 +10624,17 @@ bool Unit::isVisibleForInState( Player const* u, WorldObject const* viewPoint, b return isVisibleForOrDetect(u, viewPoint, false, inVisibleList, false); } +/// returns true if creature can't be seen by alive units +bool Unit::isInvisibleForAlive() const +{ + // TODO: more generic check for those auras + // TODO: maybe we also don't need an isAlive() check for visibilty.. but only those auras + if (HasAura(10848) || HasAura(36978) || HasAura(40131) || HasAura(27978) || HasAura(33900)) + return true; + // TODO: maybe spiritservices also have just an aura + return isSpiritService(); +} + uint32 Unit::GetCreatureType() const { if(GetTypeId() == TYPEID_PLAYER) diff --git a/src/game/Unit.h b/src/game/Unit.h index 48d53db0b..eb13fe3ff 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1329,6 +1329,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject bool isVisibleForInState(Player const* u, WorldObject const* viewPoint, bool inVisibleList) const; // function for low level grid visibility checks in player/creature cases virtual bool IsVisibleInGridForPlayer(Player* pl) const = 0; + bool isInvisibleForAlive() const; AuraList & GetSingleCastAuras() { return m_scAuras; } AuraList const& GetSingleCastAuras() const { return m_scAuras; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index eee8b347d..e8e9dcb9d 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 "8688" + #define REVISION_NR "8689" #endif // __REVISION_NR_H__ From 20e89820756f8057c53741aa4e3c81c855a70dd8 Mon Sep 17 00:00:00 2001 From: balrok Date: Tue, 20 Oct 2009 18:53:16 +0200 Subject: [PATCH 13/25] [8690] added unit auraFlag variable this can be used for faster checking if an unit has a specific aura applied.. also implemented the alive-invisible auras now with this way --- src/game/SpellAuras.cpp | 10 ++++++++++ src/game/Unit.cpp | 5 ++--- src/game/Unit.h | 8 ++++++++ src/shared/revision_nr.h | 2 +- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 1e2d83ec8..4faf8b9e0 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -2467,6 +2467,16 @@ void Aura::HandleAuraDummy(bool apply, bool Real) m_target->PlayDirectSound(14972, (Player *)m_target); } return; + case 10848: + case 36978: + case 40131: + case 27978: + case 33900: + if (apply) + m_target->m_AuraFlags |= UNIT_AURAFLAG_ALIVE_INVISIBLE; + else + m_target->m_AuraFlags |= ~UNIT_AURAFLAG_ALIVE_INVISIBLE; + return; } break; } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 5ef95104a..35d60cb5c 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -104,6 +104,7 @@ Unit::Unit() //m_AurasCheck = 2000; //m_removeAuraTimer = 4; m_AurasUpdateIterator = m_Auras.end(); + m_AuraFlags = 0; m_Visibility = VISIBILITY_ON; @@ -10627,9 +10628,7 @@ bool Unit::isVisibleForInState( Player const* u, WorldObject const* viewPoint, b /// returns true if creature can't be seen by alive units bool Unit::isInvisibleForAlive() const { - // TODO: more generic check for those auras - // TODO: maybe we also don't need an isAlive() check for visibilty.. but only those auras - if (HasAura(10848) || HasAura(36978) || HasAura(40131) || HasAura(27978) || HasAura(33900)) + if (m_AuraFlags & UNIT_AURAFLAG_ALIVE_INVISIBLE) return true; // TODO: maybe spiritservices also have just an aura return isSpiritService(); diff --git a/src/game/Unit.h b/src/game/Unit.h index eb13fe3ff..95a062647 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -469,6 +469,12 @@ enum DamageEffectType SELF_DAMAGE = 5 }; +/// internal used flags for marking special auras - for example some dummy-auras +enum UnitAuraFlags +{ + UNIT_AURAFLAG_ALIVE_INVISIBLE = 0x1, // aura which makes unit invisible for alive +}; + enum UnitVisibility { VISIBILITY_OFF = 0, // absolute, not detectable, GM-like, can see all other @@ -1390,6 +1396,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject Aura* GetDummyAura(uint32 spell_id) const; + uint32 m_AuraFlags; + uint32 GetDisplayId() { return GetUInt32Value(UNIT_FIELD_DISPLAYID); } void SetDisplayId(uint32 modelId); uint32 GetNativeDisplayId() { return GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID); } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index e8e9dcb9d..7c2aa67bf 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 "8689" + #define REVISION_NR "8690" #endif // __REVISION_NR_H__ From ac6e13d0e34cfc273e2d3cb16b00ffe50886d472 Mon Sep 17 00:00:00 2001 From: balrok Date: Tue, 20 Oct 2009 22:35:07 +0200 Subject: [PATCH 14/25] [8691] fix battleground spiritguides they are now alive and so some spellchecks got invalid --- src/game/Spell.cpp | 2 +- src/game/SpellAuras.cpp | 3 --- src/shared/revision_nr.h | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index b9d653f6d..979fb6f4e 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -3930,7 +3930,7 @@ SpellCastResult Spell::CheckCast(bool strict) if(m_spellInfo->TargetAuraStateNot && target->HasAuraState(AuraState(m_spellInfo->TargetAuraStateNot))) return SPELL_FAILED_TARGET_AURASTATE; - if (IsDeathOnlySpell(m_spellInfo) && target->isAlive()) + if (!m_IsTriggeredSpell && IsDeathOnlySpell(m_spellInfo) && target->isAlive()) return SPELL_FAILED_TARGET_NOT_DEAD; // Target aura req check if need diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 4faf8b9e0..c301b9f81 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -6265,9 +6265,6 @@ void Aura::HandleSchoolAbsorb(bool apply, bool Real) void Aura::PeriodicTick() { - if (!m_target->isAlive() != IsDeathOnlySpell(GetSpellProto())) - return; - switch(m_modifier.m_auraname) { case SPELL_AURA_PERIODIC_DAMAGE: diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 7c2aa67bf..76aecc253 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 "8690" + #define REVISION_NR "8691" #endif // __REVISION_NR_H__ From 6a2e23cac09a88d7ec1221393ba96482d71187f6 Mon Sep 17 00:00:00 2001 From: DonTomika Date: Tue, 20 Oct 2009 23:30:34 +0200 Subject: [PATCH 15/25] [8692] Fixed trigger part of spell 31944. Signed-off-by: ApoC --- src/game/SpellAuras.cpp | 9 +++++++-- src/shared/revision_nr.h | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index c301b9f81..afed0ac18 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -1707,8 +1707,13 @@ void Aura::TriggerSpell() } // // Bloodmyst Tesla // case 31611: break; -// // Doomfire -// case 31944: break; + // Doomfire + case 31944: + { + int32 damage = m_modifier.m_amount * ((float)(GetAuraDuration() + m_modifier.periodictime) / GetAuraMaxDuration()); + target->CastCustomSpell(target, 31969, &damage, NULL, NULL, true, NULL, this, casterGUID); + return; + } // // Teleport Test // case 32236: break; // // Earthquake diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 76aecc253..f0a9ab120 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 "8691" + #define REVISION_NR "8692" #endif // __REVISION_NR_H__ From 86b60901bfec3a073d2fc8f9d57992d4490758da Mon Sep 17 00:00:00 2001 From: Corfen Date: Tue, 20 Oct 2009 23:53:13 +0200 Subject: [PATCH 16/25] [8693] Fixed glyph 45785 Signed-off-by: ApoC --- sql/mangos.sql | 3 ++- sql/updates/8693_01_mangos_spell_proc_event.sql | 4 ++++ sql/updates/Makefile.am | 2 ++ src/game/Unit.cpp | 6 ++++++ src/shared/revision_nr.h | 2 +- src/shared/revision_sql.h | 2 +- 6 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 sql/updates/8693_01_mangos_spell_proc_event.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 0a03d0cf3..5e68dd49f 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -24,7 +24,7 @@ CREATE TABLE `db_version` ( `version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL, `cache_id` int(10) default '0', - `required_8688_01_mangos_creature_template` bit(1) default NULL + `required_8693_01_mangos_spell_proc_event` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -18324,6 +18324,7 @@ INSERT INTO `spell_proc_event` VALUES (63108, 0x00000000, 5, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (63156, 0x00000000, 0, 0x00000001, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (63245, 0x00000000, 5, 0x00000100, 0x00800000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(63320, 0x00000000, 5, 0x00040000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (63730, 0x00000000, 6, 0x00000800, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (64928, 0x00000000, 11, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0); /*!40000 ALTER TABLE `spell_proc_event` ENABLE KEYS */; diff --git a/sql/updates/8693_01_mangos_spell_proc_event.sql b/sql/updates/8693_01_mangos_spell_proc_event.sql new file mode 100644 index 000000000..ab9325e6d --- /dev/null +++ b/sql/updates/8693_01_mangos_spell_proc_event.sql @@ -0,0 +1,4 @@ +ALTER TABLE db_version CHANGE COLUMN required_8688_01_mangos_creature_template required_8693_01_mangos_spell_proc_event bit; + +DELETE FROM spell_proc_event WHERE entry = 63320; +INSERT INTO spell_proc_event VALUES (63320, 0x00000000, 5, 0x00040000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0); \ No newline at end of file diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 9198d0d4a..b5a77a857 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -137,6 +137,7 @@ pkgdata_DATA = \ 8618_01_mangos_spell_proc_event.sql \ 8676_01_mangos_creature_template.sql \ 8688_01_mangos_creature_template.sql \ + 8693_01_mangos_spell_proc_event.sql \ README ## Additional files to include when running 'make dist' @@ -254,4 +255,5 @@ EXTRA_DIST = \ 8618_01_mangos_spell_proc_event.sql \ 8676_01_mangos_creature_template.sql \ 8688_01_mangos_creature_template.sql \ + 8693_01_mangos_spell_proc_event.sql \ README diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 35d60cb5c..9df0ff87d 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -5387,6 +5387,12 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu triggered_spell_id = 63106; break; } + // Glyph of Life Tap + case 63320: + { + triggered_spell_id = 63321; + break; + } } break; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index f0a9ab120..8f0b9ea1d 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 "8692" + #define REVISION_NR "8693" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index faf8d488d..cfd08a92e 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_MANGOS "required_8688_01_mangos_creature_template" + #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 fcf854c0bbdb8e5077e0152b05b1fce880787363 Mon Sep 17 00:00:00 2001 From: balrok Date: Wed, 21 Oct 2009 00:07:03 +0200 Subject: [PATCH 17/25] [8694] GMs should see units with "invisibleForAlive()" --- src/game/Unit.cpp | 6 +++--- src/shared/revision_nr.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 9df0ff87d..876eaf76a 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -9724,9 +9724,6 @@ bool Unit::isVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, boo return false; } - if (u->isAlive() && isInvisibleForAlive()) - return false; - // always seen by owner if (GetCharmerOrOwnerGUID()==u->GetGUID()) return true; @@ -9788,6 +9785,9 @@ bool Unit::isVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, boo return true; } + if (u->isAlive() && isInvisibleForAlive()) + return false; + // non faction visibility non-breakable for non-GMs if (m_Visibility == VISIBILITY_OFF) return false; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 8f0b9ea1d..5eeaa5833 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 "8693" + #define REVISION_NR "8694" #endif // __REVISION_NR_H__ From 012b54a63d8deb46990e9295f9fc45f57d0d0440 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Wed, 21 Oct 2009 04:48:44 +0400 Subject: [PATCH 18/25] [8695] Fix negative auras remain time calculation at loading for pets. In similar ways as recently fixed for players. --- src/game/Pet.cpp | 4 ++-- src/shared/revision_nr.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index d1765c092..97bb876c3 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -1179,10 +1179,10 @@ void Pet::_LoadAuras(uint32 timediff) // negative effects should continue counting down after logout if (remaintime != -1 && !IsPositiveEffect(spellid, effindex)) { - if(remaintime <= int32(timediff)) + if (remaintime/IN_MILISECONDS <= int32(timediff)) continue; - remaintime -= timediff; + remaintime -= timediff*IN_MILISECONDS; } // prevent wrong values of remaincharges diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 5eeaa5833..f9ad0acad 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 "8694" + #define REVISION_NR "8695" #endif // __REVISION_NR_H__ From 1571997f31f9835b579b956c94e0c2650afb5964 Mon Sep 17 00:00:00 2001 From: hunuza Date: Wed, 21 Oct 2009 15:27:36 +0200 Subject: [PATCH 19/25] Add describtion for a new quest flag added in 3.1.2. Signed-off-by: hunuza --- src/game/QuestDef.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/game/QuestDef.h b/src/game/QuestDef.h index 02729db1d..d8dc4fabf 100644 --- a/src/game/QuestDef.h +++ b/src/game/QuestDef.h @@ -132,6 +132,9 @@ enum __QuestFlags QUEST_FLAGS_AUTO_REWARDED = 0x00000400, // These quests are automatically rewarded on quest complete and they will never appear in quest log client side. QUEST_FLAGS_TBC_RACES = 0x00000800, // Not used currently: Blood elf/Draenei starting zone quests QUEST_FLAGS_DAILY = 0x00001000, // Used to know quest is Daily one + QUEST_FLAGS_UNK3 = 0x00002000, + QUEST_FLAGS_UNK4 = 0x00004000, // ? Membership Card Renewal + QUEST_FLAGS_WEEKLY = 0x00008000, // Not used currently: Weekly quests // Mangos flags for set SpecialFlags in DB if required but used only at server QUEST_MANGOS_FLAGS_REPEATABLE = 0x010000, // Set by 1 in SpecialFlags from DB From 7ffb8e20ff70f80a674fd942656ff0fcb0396baa Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Wed, 21 Oct 2009 17:54:47 +0400 Subject: [PATCH 20/25] [8696] Replace pure virtual functions for better error output. --- src/game/Object.cpp | 18 ++++++++++++++++++ src/game/Object.h | 8 +++++--- src/shared/revision_nr.h | 2 +- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 524e56bc4..2b08089a4 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1076,6 +1076,24 @@ void Object::BuildUpdateDataForPlayer(Player* pl, UpdateDataMapType& update_play BuildValuesUpdateBlockForPlayer(&iter->second, iter->first); } +void Object::AddToClientUpdateList() +{ + sLog.outError("Unexpected call of Object::AddToClientUpdateList for object (TypeId: %u Update fields: %u)",GetTypeId(), m_valuesCount); + ASSERT(false); +} + +void Object::RemoveFromClientUpdateList() +{ + sLog.outError("Unexpected call of Object::RemoveFromClientUpdateList for object (TypeId: %u Update fields: %u)",GetTypeId(), m_valuesCount); + ASSERT(false); +} + +void Object::BuildUpdateData( UpdateDataMapType& update_players ) +{ + sLog.outError("Unexpected call of Object::BuildUpdateData for object (TypeId: %u Update fields: %u)",GetTypeId(), m_valuesCount); + ASSERT(false); +} + WorldObject::WorldObject() : m_mapId(0), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL), m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f), m_currMap(NULL) diff --git a/src/game/Object.h b/src/game/Object.h index d515af136..67a183ad9 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -148,9 +148,11 @@ class MANGOS_DLL_SPEC Object virtual void BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target ) const; void SendCreateUpdateToPlayer(Player* player); - virtual void AddToClientUpdateList() =0; - virtual void RemoveFromClientUpdateList() =0; - virtual void BuildUpdateData(UpdateDataMapType& update_players) =0; + // must be overwrite in appropriate subclasses (WorldObject, Item currently), or will crash + virtual void AddToClientUpdateList(); + virtual void RemoveFromClientUpdateList(); + virtual void BuildUpdateData(UpdateDataMapType& update_players); + void BuildValuesUpdateBlockForPlayer( UpdateData *data, Player *target ) const; void BuildOutOfRangeUpdateBlock( UpdateData *data ) const; void BuildMovementUpdateBlock( UpdateData * data, uint32 flags = 0 ) const; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index f9ad0acad..9792c806a 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 "8695" + #define REVISION_NR "8696" #endif // __REVISION_NR_H__ From 314687092f30b819bff19ce329b9df85aa6d0a58 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Wed, 21 Oct 2009 19:21:07 +0400 Subject: [PATCH 21/25] [8697] Check creature/GO spawnmask at server loading. Note: this check only out of range value in masks. And not detect another possible DB problem: After last client switch spawnmask for raid dengeons need update for correct work. In expection same spawn for both normal or both heroic modes: raid normal spawn mask from 1 to 3 (1|2) raid heroic spawn mask from 2 to 12 (4|8) In other case heroic spawn will used for 25-normal mode with empty heroic mode instances. --- src/game/DBCEnums.h | 19 ++++++++++++++++ src/game/ObjectMgr.cpp | 49 ++++++++++++++++++++++++++++++++++++++-- src/shared/revision_nr.h | 2 +- 3 files changed, 67 insertions(+), 3 deletions(-) diff --git a/src/game/DBCEnums.h b/src/game/DBCEnums.h index 8d28b555a..d56cb7e14 100644 --- a/src/game/DBCEnums.h +++ b/src/game/DBCEnums.h @@ -247,6 +247,25 @@ enum Difficulty #define MAX_RAID_DIFFICULTY 4 #define MAX_DIFFICULTY 4 +enum SpawnMask +{ + SPAWNMASK_CONTINENT = 1, // any any maps without spawn modes + + SPAWNMASK_DUNGEON_NORMAL = (1 << DUNGEON_DIFFICULTY_NORMAL), + SPAWNMASK_DUNGEON_HEROIC = (1 << DUNGEON_DIFFICULTY_HEROIC), + SPAWNMASK_DUNGEON_ALL = (SPAWNMASK_DUNGEON_NORMAL | SPAWNMASK_DUNGEON_HEROIC), + + SPAWNMASK_RAID_10MAN_NORMAL = (1 << RAID_DIFFICULTY_10MAN_NORMAL), + SPAWNMASK_RAID_25MAN_NORMAL = (1 << RAID_DIFFICULTY_25MAN_NORMAL), + SPAWNMASK_RAID_NORMAL_ALL = (SPAWNMASK_RAID_10MAN_NORMAL | SPAWNMASK_RAID_25MAN_NORMAL), + + SPAWNMASK_RAID_10MAN_HEROIC = (1 << RAID_DIFFICULTY_10MAN_HEROIC), + SPAWNMASK_RAID_25MAN_HEROIC = (1 << RAID_DIFFICULTY_25MAN_HEROIC), + SPAWNMASK_RAID_HEROIC_ALL = (SPAWNMASK_RAID_10MAN_HEROIC | SPAWNMASK_RAID_25MAN_HEROIC), + + SPAWNMASK_RAID_ALL = (SPAWNMASK_RAID_NORMAL_ALL | SPAWNMASK_RAID_HEROIC_ALL), +}; + enum FactionTemplateFlags { FACTION_TEMPLATE_FLAG_CONTESTED_GUARD = 0x00001000, // faction will attack players that were involved in PvP combats diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 22a46ae1f..dca6aa441 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -1080,6 +1080,29 @@ void ObjectMgr::LoadCreatures() int16 gameEvent = fields[18].GetInt16(); int16 PoolId = fields[19].GetInt16(); + MapEntry const* mapEntry = sMapStore.LookupEntry(data.mapid); + if(!mapEntry) + { + sLog.outErrorDb("Table `creature` have creature (GUID: %u) that spawned at not existed map (Id: %u), skipped.",guid, data.mapid ); + continue; + } + + if(mapEntry->IsNonRaidDungeon()) + { + if(data.spawnMask & ~SPAWNMASK_DUNGEON_ALL) + sLog.outErrorDb("Table `creature` have creature (GUID: %u) that have wrong spawn mask %u for non-raid dungeon map (Id: %u).",guid, data.spawnMask, data.mapid ); + } + else if(mapEntry->IsRaid()) + { + if(data.spawnMask & ~SPAWNMASK_RAID_ALL) + sLog.outErrorDb("Table `creature` have creature (GUID: %u) that have wrong spawn mask %u for raid dungeon map (Id: %u).",guid, data.spawnMask, data.mapid ); + } + else + { + if(data.spawnMask & ~SPAWNMASK_CONTINENT) + sLog.outErrorDb("Table `creature` have creature (GUID: %u) that have wrong spawn mask %u for non-dungeon map (Id: %u).",guid, data.spawnMask, data.mapid ); + } + if(heroicCreatures.find(data.id)!=heroicCreatures.end()) { sLog.outErrorDb("Table `creature` have creature (GUID: %u) that listed as heroic template (entry: %u) in `creature_template`, skipped.",guid, data.id ); @@ -1103,8 +1126,7 @@ void ObjectMgr::LoadCreatures() if(cInfo->flags_extra & CREATURE_FLAG_EXTRA_INSTANCE_BIND) { - MapEntry const* map = sMapStore.LookupEntry(data.mapid); - if(!map || !map->IsDungeon()) + if(!mapEntry || !mapEntry->IsDungeon()) sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with `creature_template`.`flags_extra` including CREATURE_FLAG_EXTRA_INSTANCE_BIND but creature are not in instance.",guid,data.id); } @@ -1259,6 +1281,29 @@ void ObjectMgr::LoadGameobjects() data.rotation3 = fields[10].GetFloat(); data.spawntimesecs = fields[11].GetInt32(); + MapEntry const* mapEntry = sMapStore.LookupEntry(data.mapid); + if(!mapEntry) + { + sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) that spawned at not existed map (Id: %u), skip", guid, data.id, data.mapid); + continue; + } + + if(mapEntry->IsNonRaidDungeon()) + { + if(data.spawnMask & ~SPAWNMASK_DUNGEON_ALL) + sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) that have wrong spawn mask %u for non-raid dungeon map (Id: %u), skip", guid, data.id, data.spawnMask, data.mapid); + } + else if(mapEntry->IsRaid()) + { + if(data.spawnMask & ~SPAWNMASK_RAID_ALL) + sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) that have wrong spawn mask %u for raid dungeon map (Id: %u), skip", guid, data.id, data.spawnMask, data.mapid); + } + else + { + if(data.spawnMask & ~SPAWNMASK_CONTINENT) + sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) that have wrong spawn mask %u for non-dungeon map (Id: %u), skip", guid, data.id, data.spawnMask, data.mapid); + } + if (data.spawntimesecs == 0 && gInfo->IsDespawnAtAction()) { sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) with `spawntimesecs` (0) value, but gameobejct marked as despawnable at action.", guid, data.id); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 9792c806a..7a1fd1a9a 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 "8696" + #define REVISION_NR "8697" #endif // __REVISION_NR_H__ From ffc2f97d3b7c530f03754928145e35c45737eb72 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Wed, 21 Oct 2009 21:07:13 +0400 Subject: [PATCH 22/25] [8698] Better way check spawn masks (for specific map) Also note: i has been totaly wrong in my last notes in prev. commit :(( Old "heroic raid" fine map to new normal 25. Sorry. --- src/game/ObjectMgr.cpp | 50 ++++++++++++++++------------------------ src/shared/revision_nr.h | 2 +- 2 files changed, 21 insertions(+), 31 deletions(-) diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index dca6aa441..d4a002855 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -1041,6 +1041,14 @@ void ObjectMgr::LoadCreatures() if(cInfo->HeroicEntry) heroicCreatures.insert(cInfo->HeroicEntry); + // build single time for check spawnmask + std::map spawnMasks; + for(uint32 i = 0; i < sMapStore.GetNumRows(); ++i) + if(sMapStore.LookupEntry(i)) + for(int k = 0; k < MAX_DIFFICULTY; ++k) + if (GetMapDifficultyData(i,Difficulty(k))) + spawnMasks[i] |= (1 << k); + barGoLink bar(result->GetRowCount()); do @@ -1087,21 +1095,8 @@ void ObjectMgr::LoadCreatures() continue; } - if(mapEntry->IsNonRaidDungeon()) - { - if(data.spawnMask & ~SPAWNMASK_DUNGEON_ALL) - sLog.outErrorDb("Table `creature` have creature (GUID: %u) that have wrong spawn mask %u for non-raid dungeon map (Id: %u).",guid, data.spawnMask, data.mapid ); - } - else if(mapEntry->IsRaid()) - { - if(data.spawnMask & ~SPAWNMASK_RAID_ALL) - sLog.outErrorDb("Table `creature` have creature (GUID: %u) that have wrong spawn mask %u for raid dungeon map (Id: %u).",guid, data.spawnMask, data.mapid ); - } - else - { - if(data.spawnMask & ~SPAWNMASK_CONTINENT) - sLog.outErrorDb("Table `creature` have creature (GUID: %u) that have wrong spawn mask %u for non-dungeon map (Id: %u).",guid, data.spawnMask, data.mapid ); - } + if (data.spawnMask & ~spawnMasks[data.mapid]) + sLog.outErrorDb("Table `creature` have creature (GUID: %u) that have wrong spawn mask %u including not supported difficulty modes for map (Id: %u).",guid, data.spawnMask, data.mapid ); if(heroicCreatures.find(data.id)!=heroicCreatures.end()) { @@ -1231,6 +1226,14 @@ void ObjectMgr::LoadGameobjects() return; } + // build single time for check spawnmask + std::map spawnMasks; + for(uint32 i = 0; i < sMapStore.GetNumRows(); ++i) + if(sMapStore.LookupEntry(i)) + for(int k = 0; k < MAX_DIFFICULTY; ++k) + if (GetMapDifficultyData(i,Difficulty(k))) + spawnMasks[i] |= (1 << k); + barGoLink bar(result->GetRowCount()); do @@ -1288,21 +1291,8 @@ void ObjectMgr::LoadGameobjects() continue; } - if(mapEntry->IsNonRaidDungeon()) - { - if(data.spawnMask & ~SPAWNMASK_DUNGEON_ALL) - sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) that have wrong spawn mask %u for non-raid dungeon map (Id: %u), skip", guid, data.id, data.spawnMask, data.mapid); - } - else if(mapEntry->IsRaid()) - { - if(data.spawnMask & ~SPAWNMASK_RAID_ALL) - sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) that have wrong spawn mask %u for raid dungeon map (Id: %u), skip", guid, data.id, data.spawnMask, data.mapid); - } - else - { - if(data.spawnMask & ~SPAWNMASK_CONTINENT) - sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) that have wrong spawn mask %u for non-dungeon map (Id: %u), skip", guid, data.id, data.spawnMask, data.mapid); - } + if (data.spawnMask & ~spawnMasks[data.mapid]) + sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) that have wrong spawn mask %u including not supported difficulty modes for map (Id: %u), skip", guid, data.id, data.spawnMask, data.mapid); if (data.spawntimesecs == 0 && gInfo->IsDespawnAtAction()) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 7a1fd1a9a..102e0af34 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 "8697" + #define REVISION_NR "8698" #endif // __REVISION_NR_H__ From 97c94cff565104078be6b5df4cf7a15c488cae8c Mon Sep 17 00:00:00 2001 From: balrok Date: Wed, 21 Oct 2009 17:23:25 +0200 Subject: [PATCH 23/25] fixed problems with isInvisbleForAlive removed redundant check at MoveInLos this check is already done in istargetableForAttack thx to NoFantasy fixed in isVisibleForOrDetect that isInvisbleForAlive wasn't checked.. and therefore all spiritserviceprovider got visible thx to NetSky --- src/game/AggressorAI.cpp | 2 +- src/game/CreatureEventAI.cpp | 2 +- src/game/GuardAI.cpp | 2 +- src/game/PetAI.cpp | 2 +- src/game/Unit.cpp | 9 +++++---- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp index 7e01aba55..fdde05f7d 100644 --- a/src/game/AggressorAI.cpp +++ b/src/game/AggressorAI.cpp @@ -49,7 +49,7 @@ AggressorAI::MoveInLineOfSight(Unit *u) if (!m_creature->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_DIED) && u->isTargetableForAttack() && ( m_creature->IsHostileTo( u ) /*|| u->getVictim() && m_creature->IsFriendlyTo( u->getVictim() )*/ ) && - u->isInAccessablePlaceFor(m_creature) && !u->isInvisibleForAlive()) + u->isInAccessablePlaceFor(m_creature)) { float attackRadius = m_creature->GetAttackDistance(u); if(m_creature->IsWithinDistInMap(u, attackRadius) && m_creature->IsWithinLOSInMap(u) ) diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp index 4743f12d4..3e9c59e28 100644 --- a/src/game/CreatureEventAI.cpp +++ b/src/game/CreatureEventAI.cpp @@ -995,7 +995,7 @@ void CreatureEventAI::MoveInLineOfSight(Unit *who) return; if (!m_creature->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_DIED) && who->isTargetableForAttack() && - m_creature->IsHostileTo(who) && who->isInAccessablePlaceFor(m_creature) && !who->isInvisibleForAlive()) + m_creature->IsHostileTo(who) && who->isInAccessablePlaceFor(m_creature)) { if (!m_creature->canFly() && m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE) return; diff --git a/src/game/GuardAI.cpp b/src/game/GuardAI.cpp index 3bae9ef61..3d5b529a7 100644 --- a/src/game/GuardAI.cpp +++ b/src/game/GuardAI.cpp @@ -43,7 +43,7 @@ void GuardAI::MoveInLineOfSight(Unit *u) if (!m_creature->getVictim() && u->isTargetableForAttack() && ( u->IsHostileToPlayers() || m_creature->IsHostileTo(u) /*|| u->getVictim() && m_creature->IsFriendlyTo(u->getVictim())*/ ) && - u->isInAccessablePlaceFor(m_creature) && !u->isInvisibleForAlive()) + u->isInAccessablePlaceFor(m_creature)) { float attackRadius = m_creature->GetAttackDistance(u); if (m_creature->IsWithinDistInMap(u,attackRadius)) diff --git a/src/game/PetAI.cpp b/src/game/PetAI.cpp index b20e5cb12..354ef371a 100644 --- a/src/game/PetAI.cpp +++ b/src/game/PetAI.cpp @@ -47,7 +47,7 @@ void PetAI::MoveInLineOfSight(Unit *u) if( !m_creature->getVictim() && m_creature->GetCharmInfo() && m_creature->GetCharmInfo()->HasReactState(REACT_AGGRESSIVE) && u->isTargetableForAttack() && m_creature->IsHostileTo( u ) && - u->isInAccessablePlaceFor(m_creature) && !u->isInvisibleForAlive()) + u->isInAccessablePlaceFor(m_creature)) { float attackRadius = m_creature->GetAttackDistance(u); if(m_creature->IsWithinDistInMap(u, attackRadius) && m_creature->GetDistanceZ(u) <= CREATURE_Z_ATTACK_RANGE) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 876eaf76a..c145d17ad 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -9613,7 +9613,7 @@ bool Unit::isTargetableForAttack(bool inverseAlive /*=false*/) const if ((isAlive() && !isInvisibleForAlive()) == inverseAlive) return false; - return IsInWorld() && !hasUnitState(UNIT_STAT_DIED)&& !isInFlight() /*&& !isStealth()*/; + return IsInWorld() && !hasUnitState(UNIT_STAT_DIED) && !isInFlight(); } int32 Unit::ModifyHealth(int32 dVal) @@ -9772,6 +9772,10 @@ bool Unit::isVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, boo return false; } + if (u->isAlive() && isInvisibleForAlive()) + if (u->GetTypeId() == TYPEID_PLAYER && !((Player *)u)->isGameMaster()) + return false; + // Visible units, always are visible for all units, except for units under invisibility and phases if (m_Visibility == VISIBILITY_ON && u->m_invisibilityMask==0 && InSamePhase(u)) return true; @@ -9785,9 +9789,6 @@ bool Unit::isVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, boo return true; } - if (u->isAlive() && isInvisibleForAlive()) - return false; - // non faction visibility non-breakable for non-GMs if (m_Visibility == VISIBILITY_OFF) return false; From 211b50ce63d2466ab4b5716aa3703d3053148f51 Mon Sep 17 00:00:00 2001 From: laise Date: Wed, 21 Oct 2009 22:46:40 +0400 Subject: [PATCH 24/25] [8699] Fix instance bound difficulty selection. This must fix crashes at enter to heroic mode instances and raids showup after client switch. Signed-off-by: VladimirMangos I can't repeat crashes with existed raids after changes apply but possible in some cases need drop content of related DB table for resolve some crashes. --- src/game/Group.cpp | 2 +- src/game/MapInstanced.cpp | 4 +++- src/shared/revision_nr.h | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/game/Group.cpp b/src/game/Group.cpp index b3f77f529..48aa5ec3d 100644 --- a/src/game/Group.cpp +++ b/src/game/Group.cpp @@ -1596,7 +1596,7 @@ InstanceGroupBind* Group::GetBoundInstance(Player* player) InstanceGroupBind* Group::GetBoundInstance(Map* aMap) { // Currently spawn numbering not different from map difficulty - Difficulty difficulty = Difficulty(aMap->GetSpawnMode()); + Difficulty difficulty = GetDifficulty(aMap->IsRaid()); // some instances only have one difficulty MapDifficulty const* mapDiff = GetMapDifficultyData(aMap->GetId(),difficulty); diff --git a/src/game/MapInstanced.cpp b/src/game/MapInstanced.cpp index 0aa985ffe..1455adf7e 100644 --- a/src/game/MapInstanced.cpp +++ b/src/game/MapInstanced.cpp @@ -167,7 +167,9 @@ Map* MapInstanced::CreateInstance(const uint32 mapId, Player * player) // if no instanceId via group members or instance saves is found // the instance will be created for the first time NewInstanceId = MapManager::Instance().GenerateInstanceId(); - map = CreateInstance(NewInstanceId, NULL, player->GetDifficulty(IsRaid())); + + Difficulty diff = player->GetGroup() ? player->GetGroup()->GetDifficulty(IsRaid()) : player->GetDifficulty(IsRaid()); + map = CreateInstance(NewInstanceId, NULL, diff); } } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 102e0af34..520f42ada 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 "8698" + #define REVISION_NR "8699" #endif // __REVISION_NR_H__ From f59f7d2a2ef3d0df7657263e81808d87266aeba0 Mon Sep 17 00:00:00 2001 From: balrok Date: Wed, 21 Oct 2009 21:37:20 +0200 Subject: [PATCH 25/25] [8700] fixed very high reputation in alterac valley bug happened when one team owned a mine at the end of the match and is caused through an uninitalized variable through that players could gain or lose _very_ much reputation sorry :x --- src/game/BattleGroundAV.cpp | 3 ++- src/shared/revision_nr.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/game/BattleGroundAV.cpp b/src/game/BattleGroundAV.cpp index d66da6736..e0e7f7198 100644 --- a/src/game/BattleGroundAV.cpp +++ b/src/game/BattleGroundAV.cpp @@ -336,7 +336,7 @@ void BattleGroundAV::EndBattleGround(uint32 winner) // now we have the values give the honor/reputation to the teams: uint32 team[BG_TEAMS_COUNT] = { ALLIANCE, HORDE }; uint32 faction[BG_TEAMS_COUNT] = { BG_AV_FACTION_A, BG_AV_FACTION_H }; - for(uint32 i = 0; i < BG_TEAMS_COUNT; i++) + for (uint32 i = 0; i < BG_TEAMS_COUNT; i++) { if (tower_survived[i]) { @@ -800,6 +800,7 @@ void BattleGroundAV::Reset() m_RepOwnedGrave = (isBGWeekend) ? BG_AV_REP_OWNED_GRAVE_HOLIDAY : BG_AV_REP_OWNED_GRAVE; m_RepSurviveCaptain = (isBGWeekend) ? BG_AV_REP_SURVIVING_CAPTAIN_HOLIDAY : BG_AV_REP_SURVIVING_CAPTAIN; m_RepSurviveTower = (isBGWeekend) ? BG_AV_REP_SURVIVING_TOWER_HOLIDAY : BG_AV_REP_SURVIVING_TOWER; + m_RepOwnedMine = (isBGWeekend) ? BG_AV_REP_OWNED_MINE_HOLIDAY : BG_AV_REP_OWNED_MINE; for(uint8 i = 0; i < BG_TEAMS_COUNT; i++) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 520f42ada..40114edfa 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 "8699" + #define REVISION_NR "8700" #endif // __REVISION_NR_H__