diff options
author | megamage <none@none.none> | 2011-12-20 17:05:08 -0500 |
---|---|---|
committer | megamage <none@none.none> | 2011-12-20 17:07:09 -0500 |
commit | 8cf2062c1f253f71696deeda6d7e1e393d115009 (patch) | |
tree | 17aa3ba004215a0b94db3b2da2658c4bb70b8032 | |
parent | e1afd79b1ee2bceef56c8c768fdd984d5f03967c (diff) |
Update grid system. Try to fix some crashes and transport passengers (now they are despawned after a while).
24 files changed, 117 insertions, 87 deletions
diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp index 31cc21659c9..cd05cba7475 100755 --- a/src/server/game/Entities/Corpse/Corpse.cpp +++ b/src/server/game/Entities/Corpse/Corpse.cpp @@ -26,7 +26,7 @@ #include "GossipDef.h" #include "World.h" -Corpse::Corpse(CorpseType type) : WorldObject() +Corpse::Corpse(CorpseType type) : WorldObject(type != CORPSE_BONES) , m_type(type) { m_objectType |= TYPEMASK_CORPSE; @@ -39,9 +39,6 @@ Corpse::Corpse(CorpseType type) : WorldObject() m_time = time(NULL); lootForBody = false; - - if (type != CORPSE_BONES) - m_isWorldObject = true; } Corpse::~Corpse() @@ -162,20 +159,11 @@ void Corpse::DeleteFromDB(SQLTransaction& trans) trans->Append(stmt); } -bool Corpse::LoadFromDB(uint32 guid, Field* fields) +bool Corpse::LoadCorpseFromDB(uint32 guid, Field* fields) { uint32 ownerGuid = fields[17].GetUInt32(); // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 // SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, guildId, flags, dynFlags, time, corpseType, instanceId, phaseMask, corpseGuid, guid FROM corpse WHERE corpseType <> 0 - m_type = CorpseType(fields[13].GetUInt8()); - if (m_type >= MAX_CORPSE_TYPE) - { - sLog->outError("Corpse (guid: %u, owner: %u) have wrong corpse type (%u), not loading.", guid, ownerGuid, m_type); - return false; - } - if (m_type != CORPSE_BONES) - m_isWorldObject = true; - float posX = fields[0].GetFloat(); float posY = fields[1].GetFloat(); float posZ = fields[2].GetFloat(); diff --git a/src/server/game/Entities/Corpse/Corpse.h b/src/server/game/Entities/Corpse/Corpse.h index 2e45606b88f..a704e2243eb 100755 --- a/src/server/game/Entities/Corpse/Corpse.h +++ b/src/server/game/Entities/Corpse/Corpse.h @@ -59,7 +59,7 @@ class Corpse : public WorldObject, public GridObject<Corpse> bool Create(uint32 guidlow, Player* owner); void SaveToDB(); - bool LoadFromDB(uint32 guid, Field* fields); + bool LoadCorpseFromDB(uint32 guid, Field* fields); void DeleteBonesFromWorld(); void DeleteFromDB(SQLTransaction& trans); diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 3238d9873a9..f97d01a42a4 100755 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -137,7 +137,7 @@ bool ForcedDespawnDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) return true; } -Creature::Creature(): Unit(), MapCreature(), +Creature::Creature(bool isWorldObject): Unit(isWorldObject), MapCreature(), lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLowGUID(0), m_PlayerDamageReq(0), m_lootMoney(0), m_lootRecipient(0), m_lootRecipientGroup(0), m_corpseRemoveTime(0), m_respawnTime(0), m_respawnDelay(300), m_corpseDelay(60), m_respawnradius(0.0f), m_reactState(REACT_AGGRESSIVE), @@ -160,6 +160,7 @@ m_creatureInfo(NULL), m_creatureData(NULL), m_formation(NULL) ResetLootMode(); // restore default loot mode TriggerJustRespawned = false; + m_isTempWorldObject = false; } Creature::~Creature() diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 6ae9fa97462..d84221f0e63 100755 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -440,7 +440,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature { public: - explicit Creature(); + explicit Creature(bool isWorldObject = false); virtual ~Creature(); void AddToWorld(); @@ -707,6 +707,9 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature uint32 GetGUIDTransport() { return guid_transport; } void FarTeleportTo(Map* map, float X, float Y, float Z, float O); + + bool m_isTempWorldObject; //true when possessed + protected: bool CreateFromProto(uint32 guidlow, uint32 Entry, uint32 vehId, uint32 team, const CreatureData* data = NULL); bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL); diff --git a/src/server/game/Entities/Creature/TemporarySummon.cpp b/src/server/game/Entities/Creature/TemporarySummon.cpp index b17606b83cc..1b06f0f0b6a 100755 --- a/src/server/game/Entities/Creature/TemporarySummon.cpp +++ b/src/server/game/Entities/Creature/TemporarySummon.cpp @@ -22,8 +22,8 @@ #include "ObjectMgr.h" #include "TemporarySummon.h" -TempSummon::TempSummon(SummonPropertiesEntry const* properties, Unit* owner) : -Creature(), m_Properties(properties), m_type(TEMPSUMMON_MANUAL_DESPAWN), +TempSummon::TempSummon(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject) : +Creature(isWorldObject), m_Properties(properties), m_type(TEMPSUMMON_MANUAL_DESPAWN), m_timer(0), m_lifetime(0) { m_summonerGUID = owner ? owner->GetGUID() : 0; @@ -272,7 +272,7 @@ void TempSummon::RemoveFromWorld() Creature::RemoveFromWorld(); } -Minion::Minion(SummonPropertiesEntry const* properties, Unit* owner) : TempSummon(properties, owner) +Minion::Minion(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject) : TempSummon(properties, owner, isWorldObject) , m_owner(owner) { ASSERT(m_owner); @@ -306,7 +306,7 @@ bool Minion::IsGuardianPet() const return isPet() || (m_Properties && m_Properties->Category == SUMMON_CATEGORY_PET); } -Guardian::Guardian(SummonPropertiesEntry const* properties, Unit* owner) : Minion(properties, owner) +Guardian::Guardian(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject) : Minion(properties, owner, isWorldObject) , m_bonusSpellDamage(0) { memset(m_statFromOwner, 0, sizeof(float)*MAX_STATS); @@ -340,7 +340,7 @@ void Guardian::InitSummon() m_owner->ToPlayer()->CharmSpellInitialize(); } -Puppet::Puppet(SummonPropertiesEntry const* properties, Unit* owner) : Minion(properties, owner) +Puppet::Puppet(SummonPropertiesEntry const* properties, Unit* owner) : Minion(properties, owner, false) //maybe true? { ASSERT(owner->GetTypeId() == TYPEID_PLAYER); m_owner = (Player*)owner; diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h index 1982dec4bb8..69ae8349155 100755 --- a/src/server/game/Entities/Creature/TemporarySummon.h +++ b/src/server/game/Entities/Creature/TemporarySummon.h @@ -24,7 +24,7 @@ class TempSummon : public Creature { public: - explicit TempSummon(SummonPropertiesEntry const* properties, Unit* owner); + explicit TempSummon(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject); virtual ~TempSummon() {} void Update(uint32 time); virtual void InitStats(uint32 lifetime); @@ -48,7 +48,7 @@ class TempSummon : public Creature class Minion : public TempSummon { public: - Minion(SummonPropertiesEntry const* properties, Unit* owner); + Minion(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject); void InitStats(uint32 duration); void RemoveFromWorld(); Unit* GetOwner() { return m_owner; } @@ -64,7 +64,7 @@ class Minion : public TempSummon class Guardian : public Minion { public: - Guardian(SummonPropertiesEntry const* properties, Unit* owner); + Guardian(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject); void InitStats(uint32 duration); bool InitStatsForLevel(uint8 level); void InitSummon(); diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.cpp b/src/server/game/Entities/DynamicObject/DynamicObject.cpp index 30afd43cf14..4e0d2d7d0b9 100755 --- a/src/server/game/Entities/DynamicObject/DynamicObject.cpp +++ b/src/server/game/Entities/DynamicObject/DynamicObject.cpp @@ -27,7 +27,7 @@ #include "GridNotifiersImpl.h" #include "ScriptMgr.h" -DynamicObject::DynamicObject() : WorldObject(), +DynamicObject::DynamicObject(bool isWorldObject) : WorldObject(isWorldObject), _aura(NULL), _removedAura(NULL), _caster(NULL), _duration(0), _isViewpoint(false) { m_objectType |= TYPEMASK_DYNAMICOBJECT; @@ -79,7 +79,7 @@ void DynamicObject::RemoveFromWorld() } } -bool DynamicObject::CreateDynamicObject(uint32 guidlow, Unit* caster, uint32 spellId, Position const& pos, float radius, bool active, DynamicObjectType type) +bool DynamicObject::CreateDynamicObject(uint32 guidlow, Unit* caster, uint32 spellId, Position const& pos, float radius, DynamicObjectType type) { SetMap(caster->GetMap()); Relocate(pos); @@ -105,8 +105,7 @@ bool DynamicObject::CreateDynamicObject(uint32 guidlow, Unit* caster, uint32 spe SetFloatValue(DYNAMICOBJECT_RADIUS, radius); SetUInt32Value(DYNAMICOBJECT_CASTTIME, getMSTime()); - m_isWorldObject = active; - if (active) + if (IsWorldObject()) setActive(true); //must before add to map to be put in world container if (!GetMap()->AddToMap(this)) diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.h b/src/server/game/Entities/DynamicObject/DynamicObject.h index c178fe98d14..bd8c15cdba4 100755 --- a/src/server/game/Entities/DynamicObject/DynamicObject.h +++ b/src/server/game/Entities/DynamicObject/DynamicObject.h @@ -35,13 +35,13 @@ enum DynamicObjectType class DynamicObject : public WorldObject, public GridObject<DynamicObject> { public: - DynamicObject(); + DynamicObject(bool isWorldObject); ~DynamicObject(); void AddToWorld(); void RemoveFromWorld(); - bool CreateDynamicObject(uint32 guidlow, Unit* caster, uint32 spellId, Position const& pos, float radius, bool active, DynamicObjectType type); + bool CreateDynamicObject(uint32 guidlow, Unit* caster, uint32 spellId, Position const& pos, float radius, DynamicObjectType type); void Update(uint32 p_time); void Remove(); void SetDuration(int32 newDuration); diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index de1b0f84871..036664a2760 100755 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -30,7 +30,7 @@ #include "CreatureAISelector.h" #include "Group.h" -GameObject::GameObject() : WorldObject(), m_goValue(new GameObjectValue), m_AI(NULL) +GameObject::GameObject() : WorldObject(false), m_goValue(new GameObjectValue), m_AI(NULL) { m_objectType |= TYPEMASK_GAMEOBJECT; m_objectTypeId = TYPEID_GAMEOBJECT; diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index d4723cbec42..d4679928d82 100755 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -82,7 +82,7 @@ Object::Object() : m_PackGUID(sizeof(uint64)+1) WorldObject::~WorldObject() { // this may happen because there are many !create/delete - if (m_isWorldObject && m_currMap) + if (IsWorldObject() && m_currMap) { if (GetTypeId() == TYPEID_CORPSE) { @@ -1221,8 +1221,8 @@ void MovementInfo::OutDebug() sLog->outString("splineElevation: %f", splineElevation); } -WorldObject::WorldObject(): WorldLocation(), -m_isWorldObject(false), m_name(""), m_isActive(false), m_zoneScript(NULL), +WorldObject::WorldObject(bool isWorldObject): WorldLocation(), +m_isWorldObject(isWorldObject), m_name(""), m_isActive(false), m_zoneScript(NULL), m_transport(NULL), m_currMap(NULL), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL), m_notifyflags(0), m_executed_notifies(0) { @@ -1238,6 +1238,17 @@ void WorldObject::SetWorldObject(bool on) GetMap()->AddObjectToSwitchList(this, on); } +bool WorldObject::IsWorldObject() const +{ + if (m_isWorldObject) + return true; + + if (ToCreature() && ToCreature()->m_isTempWorldObject) + return true; + + return false; +} + void WorldObject::setActive(bool on) { if (m_isActive == on) @@ -2051,7 +2062,7 @@ void WorldObject::SetMap(Map* map) m_currMap = map; m_mapId = map->GetId(); m_InstanceId = map->GetInstanceId(); - if (m_isWorldObject) + if (IsWorldObject()) m_currMap->AddWorldObject(this); } @@ -2059,7 +2070,7 @@ void WorldObject::ResetMap() { ASSERT(m_currMap); ASSERT(!IsInWorld()); - if (m_isWorldObject) + if (IsWorldObject()) m_currMap->RemoveWorldObject(this); m_currMap = NULL; //maybe not for corpse @@ -2149,10 +2160,10 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert switch (mask) { case UNIT_MASK_SUMMON: - summon = new TempSummon(properties, summoner); + summon = new TempSummon(properties, summoner, false); break; case UNIT_MASK_GUARDIAN: - summon = new Guardian(properties, summoner); + summon = new Guardian(properties, summoner, false); break; case UNIT_MASK_PUPPET: summon = new Puppet(properties, summoner); @@ -2161,7 +2172,7 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert summon = new Totem(properties, summoner); break; case UNIT_MASK_MINION: - summon = new Minion(properties, summoner); + summon = new Minion(properties, summoner, false); break; default: return NULL; diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index eab4dbeba99..786b23f6340 100755 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -561,7 +561,7 @@ class FlaggedValuesArray32 class WorldObject : public Object, public WorldLocation { protected: - explicit WorldObject(); + explicit WorldObject(bool isWorldObject); //note: here it means if it is in grid object list or world object list public: virtual ~WorldObject(); @@ -800,6 +800,9 @@ class WorldObject : public Object, public WorldLocation bool isActiveObject() const { return m_isActive; } void setActive(bool isActiveObject); void SetWorldObject(bool apply); + bool IsPermanentWorldObject() const { return m_isWorldObject; } + bool IsWorldObject() const; + template<class NOTIFIER> void VisitNearbyObject(float const& radius, NOTIFIER& notifier) const { if (IsInWorld()) GetMap()->VisitAll(GetPositionX(), GetPositionY(), radius, notifier); } template<class NOTIFIER> void VisitNearbyGridObject(float const& radius, NOTIFIER& notifier) const { if (IsInWorld()) GetMap()->VisitGrid(GetPositionX(), GetPositionY(), radius, notifier); } template<class NOTIFIER> void VisitNearbyWorldObject(float const& radius, NOTIFIER& notifier) const { if (IsInWorld()) GetMap()->VisitWorld(GetPositionX(), GetPositionY(), radius, notifier); } @@ -812,7 +815,6 @@ class WorldObject : public Object, public WorldLocation double rand_chance() const { return GetMap()->mtRand.randExc(100.0);} #endif - bool m_isWorldObject; uint32 LastUsedScriptID; // Transports @@ -830,6 +832,7 @@ class WorldObject : public Object, public WorldLocation protected: std::string m_name; bool m_isActive; + const bool m_isWorldObject; ZoneScript* m_zoneScript; // transports diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index f730363d0c6..4e33142f5ce 100755 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -33,7 +33,7 @@ #define PET_XP_FACTOR 0.05f -Pet::Pet(Player* owner, PetType type) : Guardian(NULL, owner), +Pet::Pet(Player* owner, PetType type) : Guardian(NULL, owner, true), m_usedTalentCount(0), m_removed(false), m_owner(owner), m_happinessTimer(7500), m_petType(type), m_duration(0), m_auraRaidUpdateMask(0), m_loading(false), m_declinedname(NULL) @@ -50,8 +50,6 @@ m_auraRaidUpdateMask(0), m_loading(false), m_declinedname(NULL) m_name = "Pet"; m_regenTimer = PET_FOCUS_REGEN_INTERVAL; - - m_isWorldObject = true; } Pet::~Pet() diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 3216abb13a0..510813a4e56 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -629,7 +629,7 @@ UpdateMask Player::updateVisualBits; #ifdef _MSC_VER #pragma warning(disable:4355) #endif -Player::Player (WorldSession* session): Unit(), m_achievementMgr(this), m_reputationMgr(this) +Player::Player(WorldSession* session): Unit(true), m_achievementMgr(this), m_reputationMgr(this) { #ifdef _MSC_VER #pragma warning(default:4355) @@ -839,7 +839,6 @@ Player::Player (WorldSession* session): Unit(), m_achievementMgr(this), m_reputa m_grantableLevels = 0; m_ControlledByPlayer = true; - m_isWorldObject = true; sWorld->IncreasePlayerCount(); diff --git a/src/server/game/Entities/Totem/Totem.cpp b/src/server/game/Entities/Totem/Totem.cpp index 97629e802d4..fc368b1f109 100755 --- a/src/server/game/Entities/Totem/Totem.cpp +++ b/src/server/game/Entities/Totem/Totem.cpp @@ -25,7 +25,7 @@ #include "SpellMgr.h" #include "SpellInfo.h" -Totem::Totem(SummonPropertiesEntry const* properties, Unit* owner) : Minion(properties, owner) +Totem::Totem(SummonPropertiesEntry const* properties, Unit* owner) : Minion(properties, owner, false) { m_unitTypeMask |= UNIT_MASK_TOTEM; m_duration = 0; diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index 008f752306d..d533f6fe5b9 100755 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -633,7 +633,8 @@ void Transport::BuildStopMovePacket(Map const* targetMap) uint32 Transport::AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y, float z, float o, uint32 anim) { Map* map = GetMap(); - Creature* creature = new Creature; + //make it world object so it will not be unloaded with grid + Creature* creature = new Creature(true); if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, GetPhaseMask(), entry, 0, GetGOInfo()->faction, 0, 0, 0, 0)) { @@ -666,7 +667,6 @@ uint32 Transport::AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y, map->AddToMap(creature); m_NPCPassengerSet.insert(creature); - creature->SetWorldObject(true); //so it will not be unloaded with grid if (tguid == 0) { diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 193dd1786b0..d08d345eb55 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -144,7 +144,7 @@ _hitMask(hitMask), _spell(spell), _damageInfo(damageInfo), _healInfo(healInfo) #ifdef _MSC_VER #pragma warning(disable:4355) #endif -Unit::Unit(): WorldObject(), +Unit::Unit(bool isWorldObject): WorldObject(isWorldObject), m_movedPlayer(NULL), m_lastSanctuaryTime(0), IsAIEnabled(false), NeedChangeAI(false), m_ControlledByPlayer(false), i_AI(NULL), i_disabledAI(NULL), m_procDeep(0), m_removedAurasCount(0), i_motionMaster(this), m_ThreatManager(this), m_vehicle(NULL), diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 5f1bfd18627..b18223ae3ce 100755 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -2233,7 +2233,7 @@ class Unit : public WorldObject } protected: - explicit Unit (); + explicit Unit (bool isWorldObject); UnitAI* i_AI, *i_disabledAI; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 020f7bd56a9..5353e048066 100755 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -6721,9 +6721,15 @@ void ObjectMgr::LoadCorpses() { Field* fields = result->Fetch(); uint32 guid = fields[16].GetUInt32(); + CorpseType type = CorpseType(fields[13].GetUInt8()); + if (type >= MAX_CORPSE_TYPE) + { + sLog->outError("Corpse (guid: %u) have wrong corpse type (%u), not loading.", guid, type); + continue; + } - Corpse* corpse = new Corpse(); - if (!corpse->LoadFromDB(guid, fields)) + Corpse* corpse = new Corpse(type); + if (!corpse->LoadCorpseFromDB(guid, fields)) { delete corpse; continue; diff --git a/src/server/game/Grids/Grid.h b/src/server/game/Grids/Grid.h index 448c4cb35fd..7e66cf1080a 100755 --- a/src/server/game/Grids/Grid.h +++ b/src/server/game/Grids/Grid.h @@ -100,7 +100,12 @@ class Grid /** Returns the number of object within the grid. */ - unsigned int ActiveObjectsInGrid(void) const { return /*m_activeGridObjects.size()+*/i_objects.template Count<ACTIVE_OBJECT>(); } + //unsigned int ActiveObjectsInGrid(void) const { return i_objects.template Count<ACTIVE_OBJECT>(); } + template<class T> + uint32 GetWorldObjectCountInGrid() const + { + return i_objects.template Count<T>(); + } /** Inserts a container type object into the grid. */ diff --git a/src/server/game/Grids/GridStates.cpp b/src/server/game/Grids/GridStates.cpp index 5f88516c9ac..4e63388c356 100755 --- a/src/server/game/Grids/GridStates.cpp +++ b/src/server/game/Grids/GridStates.cpp @@ -31,7 +31,7 @@ void ActiveState::Update(Map &m, NGridType &grid, GridInfo & info, const uint32 info.UpdateTimeTracker(t_diff); if (info.getTimeTracker().Passed()) { - if (grid.ActiveObjectsInGrid() == 0 && !m.ActiveObjectsNearGrid(grid)) + if (!grid.GetWorldObjectCountInNGrid<Player>() && !m.ActiveObjectsNearGrid(grid)) { ObjectGridStoper worker; TypeContainerVisitor<ObjectGridStoper, GridTypeMapContainer> visitor(worker); diff --git a/src/server/game/Grids/NGrid.h b/src/server/game/Grids/NGrid.h index 97a47f7d272..5a4a6015a00 100755 --- a/src/server/game/Grids/NGrid.h +++ b/src/server/game/Grids/NGrid.h @@ -158,14 +158,28 @@ class NGrid GetGridType(x, y).Visit(visitor); } - unsigned int ActiveObjectsInGrid(void) const + //This gets the player count in grid + //I disable this to avoid confusion (active object usually means something else) + /* + uint32 GetActiveObjectCountInGrid() const { - unsigned int count=0; - for (unsigned int x=0; x < N; ++x) - for (unsigned int y=0; y < N; ++y) + uint32 count = 0; + for (uint32 x = 0; x < N; ++x) + for (uint32 y = 0; y < N; ++y) count += i_cells[x][y].ActiveObjectsInGrid(); return count; } + */ + + template<class T> + uint32 GetWorldObjectCountInNGrid() const + { + uint32 count = 0; + for (uint32 x = 0; x < N; ++x) + for (uint32 y = 0; y < N; ++y) + count += i_cells[x][y].GetWorldObjectCountInGrid<T>(); + return count; + } private: uint32 i_gridId; diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 306af9c962a..34a7b60bcbd 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -59,7 +59,7 @@ Map::~Map() while (!i_worldObjects.empty()) { WorldObject* obj = *i_worldObjects.begin(); - ASSERT(obj->m_isWorldObject); + ASSERT(obj->IsWorldObject()); //ASSERT(obj->GetTypeId() == TYPEID_CORPSE); obj->RemoveFromWorld(); obj->ResetMap(); @@ -238,7 +238,7 @@ template<class T> void Map::AddToGrid(T* obj, Cell const& cell) { NGridType* grid = getNGrid(cell.GridX(), cell.GridY()); - if (obj->m_isWorldObject) + if (obj->IsWorldObject()) grid->GetGridType(cell.CellX(), cell.CellY()).template AddWorldObject<T>(obj); else grid->GetGridType(cell.CellX(), cell.CellY()).template AddGridObject<T>(obj); @@ -248,7 +248,7 @@ template<> void Map::AddToGrid(Creature* obj, Cell const& cell) { NGridType* grid = getNGrid(cell.GridX(), cell.GridY()); - if (obj->m_isWorldObject) + if (obj->IsWorldObject()) grid->GetGridType(cell.CellX(), cell.CellY()).AddWorldObject(obj); else grid->GetGridType(cell.CellX(), cell.CellY()).AddGridObject(obj); @@ -256,9 +256,9 @@ void Map::AddToGrid(Creature* obj, Cell const& cell) obj->SetCurrentCell(cell); } -template<class T> -void Map::SwitchGridContainers(T* obj, bool on) +void Map::SwitchGridContainers(Creature* obj, bool on) { + ASSERT(!obj->IsPermanentWorldObject()); CellCoord p = Trinity::ComputeCellCoord(obj->GetPositionX(), obj->GetPositionY()); if (!p.IsCoordValid()) { @@ -278,15 +278,18 @@ void Map::SwitchGridContainers(T* obj, bool on) obj->RemoveFromGrid(); //This step is not really necessary but we want to do ASSERT in remove/add if (on) - grid.AddWorldObject<T>(obj); + { + grid.AddWorldObject(obj); + AddWorldObject(obj); + } else - grid.AddGridObject<T>(obj); - obj->m_isWorldObject = on; + { + grid.AddGridObject(obj); + RemoveWorldObject(obj); + } + obj->m_isTempWorldObject = on; } -template void Map::SwitchGridContainers(Creature*, bool); -//template void Map::SwitchGridContainers(DynamicObject*, bool); - template<class T> void Map::DeleteFromWorld(T* obj) { @@ -909,8 +912,15 @@ bool Map::UnloadGrid(NGridType& ngrid, bool unloadAll) const uint32 y = ngrid.getY(); { - if (!unloadAll && ActiveObjectsNearGrid(ngrid)) - return false; + if (!unloadAll) + { + //pets, possessed creatures (must be active), transport passengers + if (ngrid.GetWorldObjectCountInNGrid<Creature>()) + return false; + + if (ActiveObjectsNearGrid(ngrid)) + return false; + } sLog->outDebug(LOG_FILTER_MAPS, "Unloading grid[%u, %u] for map %u", x, y, GetId()); @@ -1975,15 +1985,8 @@ void Map::RemoveAllObjectsInRemoveList() bool on = itr->second; i_objectsToSwitch.erase(itr); - switch (obj->GetTypeId()) - { - case TYPEID_UNIT: - if (!obj->ToCreature()->isPet()) - SwitchGridContainers(obj->ToCreature(), on); - break; - default: - break; - } + if (obj->GetTypeId() == TYPEID_UNIT && !obj->IsPermanentWorldObject()) + SwitchGridContainers(obj->ToCreature(), on); } //sLog->outDebug(LOG_FILTER_MAPS, "Object remover 1 check."); diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 8c4703a9f3a..542d9119830 100755 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -405,7 +405,7 @@ class Map : public GridRefManager<NGridType> void RemoveFromActive(Creature* obj); - template<class T> void SwitchGridContainers(T* obj, bool active); + void SwitchGridContainers(Creature* creature, bool toWorldContainer); template<class NOTIFIER> void VisitAll(const float &x, const float &y, float radius, NOTIFIER ¬ifier); template<class NOTIFIER> void VisitFirstFound(const float &x, const float &y, float radius, NOTIFIER ¬ifier); template<class NOTIFIER> void VisitWorld(const float &x, const float &y, float radius, NOTIFIER ¬ifier); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 97332436f09..d4581b1c47e 100755 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -2606,8 +2606,8 @@ void Spell::EffectPersistentAA(SpellEffIndex effIndex) // Caster not in world, might be spell triggered from aura removal if (!caster->IsInWorld()) return; - DynamicObject* dynObj = new DynamicObject(); - if (!dynObj->CreateDynamicObject(sObjectMgr->GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), caster, m_spellInfo->Id, *m_targets.GetDst(), radius, false, DYNAMIC_OBJECT_AREA_SPELL)) + DynamicObject* dynObj = new DynamicObject(false); + if (!dynObj->CreateDynamicObject(sObjectMgr->GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), caster, m_spellInfo->Id, *m_targets.GetDst(), radius, DYNAMIC_OBJECT_AREA_SPELL)) { delete dynObj; return; @@ -3455,8 +3455,8 @@ void Spell::EffectAddFarsight(SpellEffIndex effIndex) if (!m_caster->IsInWorld()) return; - DynamicObject* dynObj = new DynamicObject(); - if (!dynObj->CreateDynamicObject(sObjectMgr->GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, *m_targets.GetDst(), radius, true, DYNAMIC_OBJECT_FARSIGHT_FOCUS)) + DynamicObject* dynObj = new DynamicObject(true); + if (!dynObj->CreateDynamicObject(sObjectMgr->GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, *m_targets.GetDst(), radius, DYNAMIC_OBJECT_FARSIGHT_FOCUS)) { delete dynObj; return; |