diff --git a/src/bindings/scripts/scripts/zone/ashenvale_forest/ashenvale.cpp b/src/bindings/scripts/scripts/zone/ashenvale_forest/ashenvale.cpp
index 959387b99..f7d4fe69d 100755
--- a/src/bindings/scripts/scripts/zone/ashenvale_forest/ashenvale.cpp
+++ b/src/bindings/scripts/scripts/zone/ashenvale_forest/ashenvale.cpp
@@ -541,6 +541,89 @@ bool ItemUse_item_Totemic_Beacon(Player *player, Item* _Item, SpellCastTargets c
return false;
}
+#define NPC_ICECALLERBRIATHA 25949
+
+struct TRINITY_DLL_DECL npc_Heretic_EmisaryAI : public ScriptedAI
+{
+ npc_Heretic_EmisaryAI(Creature* c) : ScriptedAI(c) {}
+
+ uint32 TalkTimer;
+ uint32 Phase;
+ uint32 Check;
+ Unit * player;
+ Creature * Briatha;
+ bool EventStarted;
+
+ void Reset()
+ {
+ Phase = 0;
+
+ TalkTimer = 5000;
+ EventStarted = false;
+ }
+
+ void MoveInLineOfSight(Unit * unit)
+ {
+ if(unit->GetTypeId() == TYPEID_PLAYER && unit->HasAura(46337, 0) && ((Player*)unit)->GetQuestStatus(11891) == QUEST_STATUS_INCOMPLETE)
+ {
+ EventStarted = true;
+ player = unit;
+ Briatha = me->GetMap()->GetCreature(me->GetMap()->GetCreatureGUID(NPC_ICECALLERBRIATHA));
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!me->getVictim())
+ {
+ if (EventStarted && Briatha)
+ {
+ if (TalkTimer < diff)
+ {
+ switch(Phase)
+ {
+ case 0:
+ Briatha->Say("These stones should be the last of them. Our coordination with Neptulon's forces will be impeccable.", LANG_NEUTRAL, 0);
+ Phase++;
+ break;
+ case 1:
+ me->Say("Yess. The Tidehunter will be pleased at this development. The Firelord's hold will weaken.", LANG_NEUTRAL, 0);
+ Phase++;
+ break;
+ case 2:
+ Briatha->Say("And your own preparations? Will the Frost Lord have a path to the portal?", LANG_NEUTRAL, 0);
+ Phase++;
+ break;
+ case 3:
+ me->Say("Skar'this has informed us well. We have worked our way into the slave pens and await your cryomancerss.", LANG_NEUTRAL, 0);
+ Phase++;
+ break;
+ case 4:
+ Briatha->Say("The ritual in Coilfang will bring Ahune through once he is fully prepared, and the resulting clash between Firelord and Frostlord will rend the foundations of this world. Our ultimate goals are in reach at last...", LANG_NEUTRAL, 0);
+ Phase = 0;
+ if(player->HasAura(46337, 0))
+ ((Player*)player)->AreaExploredOrEventHappens(11891);
+ EventStarted = false;
+ break;
+ }
+ TalkTimer = 5000;
+ }
+ else
+ TalkTimer -= diff;
+ }
+ return;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_npc_Heretic_Emisary(Creature *_Creature)
+{
+ return new npc_Heretic_EmisaryAI(_Creature);
+}
+
+
void AddSC_ashenvale()
{
Script *newscript;
@@ -573,4 +656,9 @@ void AddSC_ashenvale()
newscript->pItemUse = &ItemUse_item_Totemic_Beacon;
newscript->RegisterSelf();
+ newscript = new Script;
+ newscript->Name="npc_Heretic_Emisary";
+ newscript->GetAI = &GetAI_npc_Heretic_Emisary;
+ newscript->RegisterSelf();
+
}
\ No newline at end of file
diff --git a/src/bindings/scripts/scripts/zone/hellfire_peninsula/hellfire_peninsula.cpp b/src/bindings/scripts/scripts/zone/hellfire_peninsula/hellfire_peninsula.cpp
index bbc824a42..b52f47d4b 100755
--- a/src/bindings/scripts/scripts/zone/hellfire_peninsula/hellfire_peninsula.cpp
+++ b/src/bindings/scripts/scripts/zone/hellfire_peninsula/hellfire_peninsula.cpp
@@ -751,6 +751,52 @@ struct TRINITY_DLL_DECL npc_shattered_hand_berserkerAI : public ScriptedAI
}
};
+
+///////
+/// Ice Stone
+///////
+
+#define GOSSIP_ICE_STONE "Place your hands on stone"
+
+#define NPC_GLACIAL_TEMPLAR 26216
+
+bool GossipHello_go_ice_stone(Player *player, GameObject* _GO)
+{
+ if( player->GetQuestStatus(11954) == QUEST_STATUS_INCOMPLETE )
+ {
+ player->ADD_GOSSIP_ITEM(0, GOSSIP_ICE_STONE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
+ }
+ player->SEND_GOSSIP_MENU(_GO->GetGOInfo()->questgiver.gossipID, _GO->GetGUID());
+ return true;
+}
+
+void SendActionMenu_go_ice_stone(Player *player, GameObject* _GO, uint32 action)
+{
+ _GO->SetGoState(GO_STATE_ACTIVE);
+ _GO->SetRespawnTime(300);
+ player->CLOSE_GOSSIP_MENU();
+
+ float x,y,z;
+ player->GetClosePoint(x,y,z, 0.0f, 2.0f, frand(0, M_PI));
+
+ switch(action)
+ {
+ case GOSSIP_ACTION_INFO_DEF:
+ player->SummonCreature(NPC_GLACIAL_TEMPLAR, x,y,z, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 600000);
+ break;
+ }
+}
+
+bool GossipSelect_go_ice_stone(Player *player, GameObject* _GO, uint32 sender, uint32 action )
+{
+ switch(sender)
+ {
+ case GOSSIP_SENDER_MAIN: SendActionMenu_go_ice_stone(player, _GO, action); break;
+ }
+ return true;
+}
+
+
CreatureAI* GetAI_npc_shattered_hand_berserker(Creature *_Creature)
{
return new npc_shattered_hand_berserkerAI(_Creature);
@@ -823,4 +869,10 @@ void AddSC_hellfire_peninsula()
newscript->Name="npc_shattered_hand_berserker";
newscript->GetAI = &GetAI_npc_shattered_hand_berserker;
newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="go_ice_stone";
+ newscript->pGOHello = &GossipHello_go_ice_stone;
+ newscript->pGOSelect = &GossipSelect_go_ice_stone;
+ newscript->RegisterSelf();
}
diff --git a/src/game/AntiCheat.h b/src/game/AntiCheat.h
index 232efb24d..520ff0347 100644
--- a/src/game/AntiCheat.h
+++ b/src/game/AntiCheat.h
@@ -46,7 +46,7 @@ class ACRequest : public ACE_Method_Request
}
// is on taxi
- if (pPlayer->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_TAXI_FLIGHT) || !pPlayer->m_taxi.empty())
+ if (pPlayer->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_TAXI_FLIGHT) || pPlayer->m_taxi.GetTaxiSource())
return -1;
// speed rate differs from prev packet
@@ -147,11 +147,13 @@ class ACRequest : public ACE_Method_Request
return 0;
}
- pPlayer->m_AC_count++;
- pPlayer->m_AC_timer = IN_MILISECONDS; // 1 sek
+ pPlayer->AC.IncrementAlertCount();
+
+ // we really need it ? :p
+ //pPlayer->AC.SetTimer(IN_MILISECONDS);
//if (!(pPlayer->m_AC_count %5))
- sWorld.SendGMText(LANG_ANTICHEAT, pPlayer->GetName(), pPlayer->m_AC_count, m_speed, m_speed*fClientRate);
+ sWorld.SendGMText(LANG_ANTICHEAT, pPlayer->GetName(), pPlayer->AC.GetAlertCount(), m_speed, m_speed*fClientRate);
sLog.outCheat("Player %s (GUID: %u / ACCOUNT_ID: %u) moved for distance %f with server speed : %f (client speed: %f). MapID: %u, player's coord before X:%f Y:%f Z:%f. Player's coord now X:%f Y:%f Z:%f. MOVEMENTFLAGS: %u LATENCY: %u. BG/Arena: %s",
pPlayer->GetName(), pPlayer->GetGUIDLow(), pPlayer->GetSession()->GetAccountId(), fDistance2d, m_speed, m_speed*fClientRate, pPlayer->GetMapId(), m_pos.x, m_pos.y, m_pos.z, m_newPacket.pos.x, m_newPacket.pos.y, m_newPacket.pos.z, m_newPacket.GetMovementFlags(), m_latency, pPlayer->GetMap() ? (pPlayer->GetMap()->IsBattleGroundOrArena() ? "Yes" : "No") : "No");
diff --git a/src/game/CMakeLists.txt b/src/game/CMakeLists.txt
index 0d661933e..12bf4c20f 100755
--- a/src/game/CMakeLists.txt
+++ b/src/game/CMakeLists.txt
@@ -39,6 +39,8 @@ SET(game_STAT_SRCS
BattleGroundHandler.cpp
BattleGroundMgr.cpp
BattleGroundMgr.h
+ Camera.h
+ Camera.cpp
Cell.h
CellImpl.h
Channel.cpp
diff --git a/src/game/Camera.cpp b/src/game/Camera.cpp
new file mode 100644
index 000000000..abb4de4a1
--- /dev/null
+++ b/src/game/Camera.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2005-2011 MaNGOS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "Camera.h"
+#include "GridNotifiersImpl.h"
+#include "CellImpl.h"
+#include "Player.h"
+
+Camera::Camera(Player* pl) : m_owner(*pl), m_source(pl)
+{
+ m_source->GetViewPoint().Attach(this);
+}
+
+Camera::~Camera()
+{
+ // view of camera should be already reseted to owner (RemoveFromWorld -> Event_RemovedFromWorld -> ResetView)
+ ASSERT(m_source == &m_owner);
+
+ // for symmetry with constructor and way to make viewpoint's list empty
+ m_source->GetViewPoint().Detach(this);
+}
+
+void Camera::ReceivePacket(WorldPacket *data)
+{
+ m_owner.SendDirectMessage(data);
+}
+
+void Camera::UpdateForCurrentViewPoint()
+{
+ m_gridRef.unlink();
+
+ if (GridType* grid = m_source->GetViewPoint().m_grid)
+ grid->AddWorldObject(this);
+
+ UpdateVisibilityForOwner();
+}
+
+void Camera::SetView(WorldObject *obj, bool update_far_sight_field /*= true*/)
+{
+ ASSERT(obj);
+
+ if (m_source == obj)
+ return;
+
+ if (!m_owner.IsInMap(obj))
+ {
+ sLog.outError("Camera::SetView, viewpoint is not in map with camera's owner");
+ return;
+ }
+
+ if (!obj->isType(TypeMask(TYPEMASK_DYNAMICOBJECT | TYPEMASK_UNIT)))
+ {
+ sLog.outError("Camera::SetView, viewpoint type is not available for client");
+ return;
+ }
+
+ // detach and deregister from active objects if there are no more reasons to be active
+ m_source->GetViewPoint().Detach(this);
+ if (!m_source->isActiveObject())
+ m_source->GetMap()->RemoveFromActive(m_source);
+
+ m_source = obj;
+
+ if (!m_source->isActiveObject())
+ m_source->GetMap()->AddToActive(m_source);
+
+ m_source->GetViewPoint().Attach(this);
+
+ if (update_far_sight_field)
+ m_owner.SetUInt64Value(PLAYER_FARSIGHT, (m_source == &m_owner ? 0 : m_source->GetGUID()));
+
+ UpdateForCurrentViewPoint();
+}
+
+void Camera::Event_ViewPointVisibilityChanged()
+{
+ if (!m_owner.HaveAtClient(m_source))
+ ResetView();
+}
+
+void Camera::ResetView(bool update_far_sight_field /*= true*/)
+{
+ SetView(&m_owner, update_far_sight_field);
+}
+
+void Camera::Event_AddedToWorld()
+{
+ GridType* grid = m_source->GetViewPoint().m_grid;
+ ASSERT(grid);
+ grid->AddWorldObject(this);
+
+ UpdateVisibilityForOwner();
+}
+
+void Camera::Event_RemovedFromWorld()
+{
+ if (m_source == &m_owner)
+ {
+ m_gridRef.unlink();
+ return;
+ }
+
+ ResetView();
+}
+
+void Camera::Event_Moved()
+{
+ m_gridRef.unlink();
+ m_source->GetViewPoint().m_grid->AddWorldObject(this);
+}
+
+void Camera::UpdateVisibilityOf(WorldObject* target)
+{
+ m_owner.UpdateVisibilityOf(m_source, target);
+}
+
+template
+void Camera::UpdateVisibilityOf(T * target, UpdateData &data, std::set& vis)
+{
+ m_owner.template UpdateVisibilityOf(m_source, target,data,vis);
+}
+
+template void Camera::UpdateVisibilityOf(Player* , UpdateData& , std::set& );
+template void Camera::UpdateVisibilityOf(Creature* , UpdateData& , std::set& );
+template void Camera::UpdateVisibilityOf(Corpse* , UpdateData& , std::set& );
+template void Camera::UpdateVisibilityOf(GameObject* , UpdateData& , std::set& );
+template void Camera::UpdateVisibilityOf(DynamicObject* , UpdateData& , std::set& );
+
+void Camera::UpdateVisibilityForOwner()
+{
+ Trinity::VisibleNotifier notifier(*this);
+ Cell::VisitAllObjects(m_source, notifier, m_source->GetMap()->GetVisibilityDistance(), false);
+ notifier.Notify();
+}
+
+//////////////////
+
+ViewPoint::~ViewPoint()
+{
+ if (!m_cameras.empty())
+ {
+ sLog.outError("ViewPoint destructor called, but some cameras referenced to it");
+ }
+}
\ No newline at end of file
diff --git a/src/game/Camera.h b/src/game/Camera.h
new file mode 100644
index 000000000..06c4a6502
--- /dev/null
+++ b/src/game/Camera.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2005-2011 MaNGOS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef MANGOSSERVER_CAMERA_H
+#define MANGOSSERVER_CAMERA_H
+
+#include "Common.h"
+#include "GridDefines.h"
+
+class ViewPoint;
+class WorldObject;
+class UpdateData;
+class WorldPacket;
+class Player;
+
+/// Camera - object-receiver. Receives broadcast packets from nearby worldobjects, object visibility changes and sends them to client
+class TRINITY_DLL_SPEC Camera
+{
+ friend class ViewPoint;
+ public:
+
+ explicit Camera(Player* pl);
+ ~Camera();
+
+ WorldObject* GetBody() { return m_source;}
+ Player* GetOwner() { return &m_owner;}
+
+ // set camera's view to any worldobject
+ // Note: this worldobject must be in same map, in same phase with camera's owner(player)
+ // client supports only unit and dynamic objects as farsight objects
+ void SetView(WorldObject *obj, bool update_far_sight_field = true);
+
+ // set view to camera's owner
+ void ResetView(bool update_far_sight_field = true);
+
+ template
+ void UpdateVisibilityOf(T * obj, UpdateData &d, std::set& vis);
+ void UpdateVisibilityOf(WorldObject* obj);
+
+ void ReceivePacket(WorldPacket *data);
+
+ // updates visibility of worldobjects around viewpoint for camera's owner
+ void UpdateVisibilityForOwner();
+
+ private:
+ // called when viewpoint changes visibility state
+ void Event_AddedToWorld();
+ void Event_RemovedFromWorld();
+ void Event_Moved();
+ void Event_ViewPointVisibilityChanged();
+
+ Player& m_owner;
+ WorldObject* m_source;
+
+ void UpdateForCurrentViewPoint();
+
+ public:
+ GridReference& GetGridRef() { return m_gridRef; }
+ bool isActiveObject() const { return false; }
+ private:
+ GridReference m_gridRef;
+};
+
+/// Object-observer, notifies farsight object state to cameras that attached to it
+class TRINITY_DLL_SPEC ViewPoint
+{
+ friend class Camera;
+
+ typedef std::list CameraList;
+
+ CameraList m_cameras;
+ GridType * m_grid;
+
+ void Attach(Camera* c) { m_cameras.push_back(c); }
+ void Detach(Camera* c) { m_cameras.remove(c); }
+
+ void CameraCall(void (Camera::*handler)())
+ {
+ if (!m_cameras.empty())
+ {
+ for(CameraList::iterator itr = m_cameras.begin(); itr != m_cameras.end();)
+ {
+ Camera *c = *(itr++);
+ (c->*handler)();
+ }
+ }
+ }
+
+public:
+
+ ViewPoint() : m_grid(0) {}
+ ~ViewPoint();
+
+ bool hasViewers() const { return !m_cameras.empty(); }
+
+ // these events are called when viewpoint changes visibility state
+ void Event_AddedToWorld(GridType *grid)
+ {
+ m_grid = grid;
+ CameraCall(&Camera::Event_AddedToWorld);
+ }
+
+ void Event_RemovedFromWorld()
+ {
+ m_grid = NULL;
+ CameraCall(&Camera::Event_RemovedFromWorld);
+ }
+
+ void Event_GridChanged(GridType *grid)
+ {
+ m_grid = grid;
+ CameraCall(&Camera::Event_Moved);
+ }
+
+ void Event_ViewPointVisibilityChanged()
+ {
+ CameraCall(&Camera::Event_ViewPointVisibilityChanged);
+ }
+
+ void Call_UpdateVisibilityForOwner()
+ {
+ CameraCall(&Camera::UpdateVisibilityForOwner);
+ }
+};
+
+#endif
diff --git a/src/game/Corpse.cpp b/src/game/Corpse.cpp
index 7e6eb54ba..3a1570962 100755
--- a/src/game/Corpse.cpp
+++ b/src/game/Corpse.cpp
@@ -220,11 +220,8 @@ bool Corpse::LoadFromDB(uint32 guid, Field *fields)
return true;
}
-bool Corpse::isVisibleForInState(Player const* u, bool inVisibleList) const
+bool Corpse::isVisibleForInState(Player const* u, WorldObject const* viewPoint, bool inVisibleList) const
{
- const WorldObject* viewPoint = u->GetFarsightTarget();
- if (!viewPoint || !u->HasFarsightVision()) viewPoint = u;
-
return IsInWorld() && u->IsInWorld() && IsWithinDistInMap(viewPoint, World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false);
}
diff --git a/src/game/Corpse.h b/src/game/Corpse.h
index 435e2e630..f216c1cce 100755
--- a/src/game/Corpse.h
+++ b/src/game/Corpse.h
@@ -76,7 +76,7 @@ class Corpse : public WorldObject
GridPair const& GetGrid() const { return m_grid; }
void SetGrid(GridPair const& grid) { m_grid = grid; }
- bool isVisibleForInState(Player const* u, bool inVisibleList) const;
+ bool isVisibleForInState(Player const* u, WorldObject const* viewPoint, bool inVisibleList) const;
Loot loot; // remove insignia ONLY at BG
Player* lootRecipient;
diff --git a/src/game/DynamicObject.cpp b/src/game/DynamicObject.cpp
index 9791de569..1d1b0d722 100755
--- a/src/game/DynamicObject.cpp
+++ b/src/game/DynamicObject.cpp
@@ -60,6 +60,7 @@ void DynamicObject::RemoveFromWorld()
{
WorldObject::RemoveFromWorld();
GetMap()->RemoveFromObjMap(GetGUID());
+ GetViewPoint().Event_RemovedFromWorld();
}
}
@@ -152,11 +153,8 @@ void DynamicObject::Delay(int32 delaytime)
(*iunit)->DelayAura(m_spellId, m_effIndex, delaytime);
}
-bool DynamicObject::isVisibleForInState(Player const* u, bool inVisibleList) const
+bool DynamicObject::isVisibleForInState(Player const* u, WorldObject const* viewPoint, bool inVisibleList) const
{
- const WorldObject* viewPoint = u->GetFarsightTarget();
- if (!viewPoint || !u->HasFarsightVision()) viewPoint = u;
-
return IsInWorld() && u->IsInWorld() && (IsWithinDistInMap(viewPoint, World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false)
|| GetCasterGUID() == u->GetGUID());
}
diff --git a/src/game/DynamicObject.h b/src/game/DynamicObject.h
index d619c0925..65d75729d 100755
--- a/src/game/DynamicObject.h
+++ b/src/game/DynamicObject.h
@@ -48,7 +48,7 @@ class DynamicObject : public WorldObject
void AddAffected(Unit *unit) { m_affected.insert(unit); }
void RemoveAffected(Unit *unit) { m_affected.erase(unit); }
void Delay(int32 delaytime);
- bool isVisibleForInState(Player const* u, bool inVisibleList) const;
+ bool isVisibleForInState(Player const* u, WorldObject const* viewPoint, bool inVisibleList) const;
float GetObjectBoundingRadius() const // overwrite WorldObject version
{
diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp
index d7658d7d2..a33443d40 100755
--- a/src/game/GameObject.cpp
+++ b/src/game/GameObject.cpp
@@ -778,7 +778,7 @@ void GameObject::SaveRespawnTime()
objmgr.SaveGORespawnTime(m_DBTableGuid,GetInstanceId(),m_respawnTime);
}
-bool GameObject::isVisibleForInState(Player const* u, bool inVisibleList) const
+bool GameObject::isVisibleForInState(Player const* u, WorldObject const* viewPoint, bool inVisibleList) const
{
// Not in world
if (!IsInWorld() || !u->IsInWorld())
@@ -808,10 +808,6 @@ bool GameObject::isVisibleForInState(Player const* u, bool inVisibleList) const
return false;
}
- // check distance
- const WorldObject* viewPoint = u->GetFarsightTarget();
- if (!viewPoint || !u->HasFarsightVision()) viewPoint = u;
-
return IsWithinDistInMap(viewPoint, World::GetMaxVisibleDistanceForObject() + (inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false);
}
diff --git a/src/game/GameObject.h b/src/game/GameObject.h
index 15da2b453..be38f464f 100755
--- a/src/game/GameObject.h
+++ b/src/game/GameObject.h
@@ -609,7 +609,7 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject
void TriggeringLinkedGameObject(uint32 trapEntry, Unit* target);
- bool isVisibleForInState(Player const* u, bool inVisibleList) const;
+ bool isVisibleForInState(Player const* u, WorldObject const* viewPoint, bool inVisibleList) const;
bool canDetectTrap(Player const* u, float distance) const;
GameObject* LookupFishingHoleAround(float range);
diff --git a/src/game/GridDefines.h b/src/game/GridDefines.h
index 1a0313939..3c5fa461f 100755
--- a/src/game/GridDefines.h
+++ b/src/game/GridDefines.h
@@ -32,6 +32,7 @@ class DynamicObject;
class GameObject;
class Pet;
class Player;
+class Camera;
#ifdef LARGE_CELL
#define MAX_NUMBER_OF_CELLS 8
@@ -79,9 +80,10 @@ struct GridMapLiquidData
};
// Creature used instead pet to simplify *::Visit templates (not required duplicate code for Creature->Pet case)
-typedef TYPELIST_4(Player, Creature/*pets*/, Corpse/*resurrectable*/, DynamicObject/*farsight target*/) AllWorldObjectTypes;
+typedef TYPELIST_4(Player, Creature/*pets*/, Corpse/*resurrectable*/, Camera) AllWorldObjectTypes;
typedef TYPELIST_4(GameObject, Creature/*except pets*/, DynamicObject, Corpse/*Bones*/) AllGridObjectTypes;
+typedef GridRefManager CameraMapType;
typedef GridRefManager CorpseMapType;
typedef GridRefManager CreatureMapType;
typedef GridRefManager DynamicObjectMapType;
diff --git a/src/game/GridNotifiers.cpp b/src/game/GridNotifiers.cpp
index e3c0d4b0d..29ac6ef3c 100755
--- a/src/game/GridNotifiers.cpp
+++ b/src/game/GridNotifiers.cpp
@@ -19,230 +19,83 @@
*/
#include "GridNotifiers.h"
-#include "GridNotifiersImpl.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "UpdateData.h"
#include "Item.h"
#include "Map.h"
-#include "MapManager.h"
#include "Transports.h"
#include "ObjectAccessor.h"
-#include "CellImpl.h"
#include "SpellAuras.h"
using namespace Trinity;
-void VisibleNotifier::SendToSelf()
+void VisibleChangesNotifier::Visit(CameraMapType &m)
{
+ for (CameraMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
+ iter->getSource()->UpdateVisibilityOf(&i_object);
+}
+
+void VisibleNotifier::Notify()
+{
+ Player& player = *i_camera.GetOwner();
// at this moment i_clientGUIDs have guids that not iterate at grid level checks
// but exist one case when this possible and object not out of range: transports
- if (Transport* transport = i_player.GetTransport())
- for (Transport::PlayerSet::const_iterator itr = transport->GetPassengers().begin();itr!=transport->GetPassengers().end();++itr)
+ if(Transport* transport = player.GetTransport())
+ {
+ for(Transport::PlayerSet::const_iterator itr = transport->GetPassengers().begin();itr!=transport->GetPassengers().end();++itr)
{
- if (vis_guids.find((*itr)->GetGUID()) != vis_guids.end())
+ if(i_clientGUIDs.find((*itr)->GetGUID())!=i_clientGUIDs.end())
{
- vis_guids.erase((*itr)->GetGUID());
-
- i_player.UpdateVisibilityOf((*itr), i_data, i_visibleNow);
-
- if (!(*itr)->isNeedNotify(NOTIFY_VISIBILITY_CHANGED))
- (*itr)->UpdateVisibilityOf(&i_player);
+ // ignore far sight case
+ (*itr)->UpdateVisibilityOf(*itr, &player);
+ player.UpdateVisibilityOf(&player, *itr, i_data, i_visibleNow);
+ i_clientGUIDs.erase((*itr)->GetGUID());
}
}
-
- for (Player::ClientGUIDs::const_iterator it = vis_guids.begin();it != vis_guids.end(); ++it)
- {
- i_player.m_clientGUIDs.erase(*it);
- i_data.AddOutOfRangeGUID(*it);
- if (IS_PLAYER_GUID(*it))
- {
- Player* plr = ObjectAccessor::FindPlayer(*it);
- if (plr && plr->IsInWorld() && !plr->isNeedNotify(NOTIFY_VISIBILITY_CHANGED))
- plr->UpdateVisibilityOf(&i_player);
- }
- }
-
- if (!i_data.HasData())
- return;
-
- WorldPacket packet;
- i_data.BuildPacket(&packet);
- i_player.GetSession()->SendPacket(&packet);
-
- for (std::set::const_iterator it = i_visibleNow.begin(); it != i_visibleNow.end(); ++it)
- i_player.SendInitialVisiblePackets(*it);
-}
-
-void VisibleChangesNotifier::Visit(PlayerMapType &m)
-{
- for (PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
- {
- if (iter->getSource() == &i_object)
- continue;
-
- iter->getSource()->UpdateVisibilityOf(&i_object);
-
- if (!iter->getSource()->GetSharedVisionList().empty())
- for (SharedVisionList::const_iterator i = iter->getSource()->GetSharedVisionList().begin(); i != iter->getSource()->GetSharedVisionList().end(); ++i)
- if ((*i)->HasFarsightVision() && (*i)->GetFarsightTarget() == iter->getSource())
- (*i)->UpdateVisibilityOf(&i_object);
}
-}
-
-void VisibleChangesNotifier::Visit(CreatureMapType &m)
-{
- for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
- if(!iter->getSource()->GetSharedVisionList().empty())
- for(SharedVisionList::const_iterator i = iter->getSource()->GetSharedVisionList().begin(); i != iter->getSource()->GetSharedVisionList().end(); ++i)
- if ((*i)->HasFarsightVision() && (*i)->GetFarsightTarget() == iter->getSource())
- (*i)->UpdateVisibilityOf(&i_object);
-}
-
-void VisibleChangesNotifier::Visit(DynamicObjectMapType &m)
-{
- for (DynamicObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
- if(IS_PLAYER_GUID(iter->getSource()->GetCasterGUID()))
- if(Player* caster = (Player*)iter->getSource()->GetCaster())
- caster->UpdateVisibilityOf(&i_object);
-}
-
-inline void CreatureUnitRelocationWorker(Creature* c, Unit* u)
-{
- if (!u->isAlive() || !c->isAlive() || c == u)
- return;
-
- // hacky exception for Sunblade Lookout, Shattered Sun Bombardier and Brutallus
- if (u->isInFlight() && c->GetEntry() != 25132 && c->GetEntry() != 25144 && c->GetEntry() != 25158)
- return;
-
- if (c->HasReactState(REACT_AGGRESSIVE) && !c->hasUnitState(UNIT_STAT_SIGHTLESS))
- if (c->_IsWithinDist(u, DEFAULT_VISIBILITY_DISTANCE, true) && c->IsAIEnabled)
- c->AI()->MoveInLineOfSight_Safe(u);
-}
-void PlayerRelocationNotifier::Visit(PlayerMapType &m)
-{
- for (PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
+ // generate outOfRange for not iterate objects
+ for (Player::ClientGUIDs::iterator itr = i_clientGUIDs.begin(); itr != i_clientGUIDs.end(); ++itr)
{
- Player* plr = iter->getSource();
-
- vis_guids.erase(plr->GetGUID());
-
- i_player.UpdateVisibilityOf(plr,i_data,i_visibleNow);
-
- WorldObject const* viewPoint = plr->GetFarsightTarget();
- if (!viewPoint || !plr->HasFarsightVision()) viewPoint = plr;
+ player.m_clientGUIDs.erase(*itr);
+ i_data.AddOutOfRangeGUID(*itr);
- if (viewPoint->isNeedNotify(NOTIFY_VISIBILITY_CHANGED))
+ if (!IS_PLAYER_GUID(*itr))
continue;
- plr->UpdateVisibilityOf(&i_player);
- }
-}
-
-void PlayerRelocationNotifier::Visit(CreatureMapType &m)
-{
- bool relocated_for_ai = (i_player.GetFarsightTarget() == NULL);
- for (CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
- {
- Creature * c = iter->getSource();
-
- vis_guids.erase(c->GetGUID());
-
- i_player.UpdateVisibilityOf(c,i_data,i_visibleNow);
-
- if (relocated_for_ai && !c->isNeedNotify(NOTIFY_VISIBILITY_CHANGED))
- CreatureUnitRelocationWorker(c, &i_player);
+ if (Player *plr = ObjectAccessor::FindPlayer(*itr))
+ {
+ if (plr->IsInWorld())
+ plr->UpdateVisibilityOf(plr->GetCamera().GetBody(), &player);
+ }
}
-}
-void CreatureRelocationNotifier::Visit(PlayerMapType &m)
-{
- for (PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
+ if (i_data.HasData())
{
- Player * pl = iter->getSource();
-
- WorldObject const* viewPoint = pl->GetFarsightTarget();
- if (!viewPoint || !pl->HasFarsightVision()) viewPoint = pl;
-
- if (!viewPoint->isNeedNotify(NOTIFY_VISIBILITY_CHANGED))
- pl->UpdateVisibilityOf(&i_creature);
-
- CreatureUnitRelocationWorker(&i_creature, pl);
+ // send create/outofrange packet to player (except player create updates that already sent using SendUpdateToPlayer)
+ WorldPacket packet;
+ i_data.BuildPacket(&packet);
+ player.GetSession()->SendPacket(&packet);
}
-}
-void CreatureRelocationNotifier::Visit(CreatureMapType &m)
-{
- if (!i_creature.isAlive())
- return;
+ // Now do operations that required done at object visibility change to visible
- for (CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
+ // send data at target visibility change (adding to client)
+ for (std::set::const_iterator vItr = i_visibleNow.begin(); vItr != i_visibleNow.end(); ++vItr)
{
- Creature* c = iter->getSource();
- CreatureUnitRelocationWorker(&i_creature, c);
+ // target aura duration for caster show only if target exist at caster client
+ if ((*vItr) != &player && (*vItr)->isType(TYPEMASK_UNIT))
+ player.SendAuraDurationsForTarget((Unit*)(*vItr));
- if (!c->isNeedNotify(NOTIFY_VISIBILITY_CHANGED))
- CreatureUnitRelocationWorker(c, &i_creature);
- }
-}
-
-void DelayedUnitRelocation::Visit(CreatureMapType &m)
-{
- for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
- {
- Creature * unit = iter->getSource();
- if (!unit->isNeedNotify(NOTIFY_VISIBILITY_CHANGED))
- continue;
-
- CreatureRelocationNotifier relocate(*unit);
-
- TypeContainerVisitor c2world_relocation(relocate);
- TypeContainerVisitor c2grid_relocation(relocate);
-
- cell.Visit(p, c2world_relocation, i_map, *unit, i_radius);
- cell.Visit(p, c2grid_relocation, i_map, *unit, i_radius);
- }
-}
-
-void DelayedUnitRelocation::Visit(PlayerMapType &m)
-{
- for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
- {
- Player * player = iter->getSource();
-
- WorldObject const* viewPoint = player->GetFarsightTarget();
- if (!viewPoint || !player->HasFarsightVision()) viewPoint = player;
-
- if (!viewPoint->isNeedNotify(NOTIFY_VISIBILITY_CHANGED))
- continue;
-
- if (player != viewPoint && !viewPoint->IsPositionValid())
- continue;
-
- CellPair pair2(Trinity::ComputeCellPair(viewPoint->GetPositionX(), viewPoint->GetPositionY()));
- Cell cell2(pair2);
-
- PlayerRelocationNotifier relocate(*player);
- TypeContainerVisitor c2world_relocation(relocate);
- TypeContainerVisitor c2grid_relocation(relocate);
-
- cell2.Visit(pair2, c2world_relocation, i_map, *viewPoint, i_radius);
- cell2.Visit(pair2, c2grid_relocation, i_map, *viewPoint, i_radius);
-
- relocate.SendToSelf();
- }
-}
+ // non finished movements show to player
+ if ((*vItr)->GetTypeId()==TYPEID_UNIT && ((Creature*)(*vItr))->isAlive())
+ {
+ ((Creature*)(*vItr))->SendMonsterMoveWithSpeedToCurrentDestination(&player);
-void AIRelocationNotifier::Visit(CreatureMapType &m)
-{
- for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
- {
- Creature *c = iter->getSource();
- CreatureUnitRelocationWorker(c, &i_unit);
- if (isCreature)
- CreatureUnitRelocationWorker((Creature*)&i_unit, c);
+ if (((Creature*)(*vItr))->getVictim())
+ ((Creature*)(*vItr))->SendMeleeAttackStart(((Creature*)(*vItr))->getVictim());
+ }
}
}
@@ -321,88 +174,68 @@ void DynamicObjectUpdater::Visit(PlayerMapType &m)
VisitHelper(itr->getSource());
}
-void Deliverer::Visit(PlayerMapType &m)
+void MessageDeliverer::Visit(CameraMapType &m)
{
- for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
+ for(CameraMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
{
- if (!i_dist || iter->getSource()->GetDistance(&i_source) <= i_dist)
- {
- // Send packet to all who are sharing the player's vision
- if (!iter->getSource()->GetSharedVisionList().empty())
- {
- SharedVisionList::const_iterator it = iter->getSource()->GetSharedVisionList().begin();
- for (; it != iter->getSource()->GetSharedVisionList().end(); ++it)
- SendPacket(*it);
- }
-
- VisitObject(iter->getSource());
- }
- }
-}
+ Player* owner = iter->getSource()->GetOwner();
-void Deliverer::Visit(CreatureMapType &m)
-{
- for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
- {
- if (!i_dist || iter->getSource()->GetDistance(&i_source) <= i_dist)
+ if (i_toSelf || owner != &i_player)
{
- // Send packet to all who are sharing the creature's vision
- if (!iter->getSource()->GetSharedVisionList().empty())
- {
- SharedVisionList::const_iterator it = iter->getSource()->GetSharedVisionList().begin();
- for (; it != iter->getSource()->GetSharedVisionList().end(); ++it)
- SendPacket(*it);
- }
+ if (WorldSession* session = owner->GetSession())
+ session->SendPacket(i_message);
}
}
}
-void Deliverer::Visit(DynamicObjectMapType &m)
+void MessageDelivererExcept::Visit(CameraMapType &m)
{
- for (DynamicObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
+ for(CameraMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
{
- if (IS_PLAYER_GUID(iter->getSource()->GetCasterGUID()))
- {
- // Send packet back to the caster if the caster has vision of dynamic object
- Player* caster = (Player*)iter->getSource()->GetCaster();
- if (caster && caster->GetUInt64Value(PLAYER_FARSIGHT) == iter->getSource()->GetGUID() &&
- (!i_dist || iter->getSource()->GetDistance(&i_source) <= i_dist))
- SendPacket(caster);
- }
+ Player* owner = iter->getSource()->GetOwner();
+
+ if (owner == i_skipped_receiver)
+ continue;
+
+ if (WorldSession* session = owner->GetSession())
+ session->SendPacket(i_message);
}
}
-void Deliverer::SendPacket(Player* plr)
+void ObjectMessageDeliverer::Visit(CameraMapType &m)
{
- if (!plr)
- return;
-
- // Don't send the packet to self if not supposed to
- if (!i_toSelf && plr == &i_source)
- return;
-
- // Don't send the packet to possesor if not supposed to
- if (!i_toPossessor && plr->isPossessing() && plr->GetCharmGUID() == i_source.GetGUID())
- return;
-
- if (plr_list.find(plr->GetGUID()) == plr_list.end())
+ for(CameraMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
{
- if (WorldSession* session = plr->GetSession())
+ if(WorldSession* session = iter->getSource()->GetOwner()->GetSession())
session->SendPacket(i_message);
- plr_list.insert(plr->GetGUID());
}
}
-void MessageDeliverer::VisitObject(Player* plr)
+void MessageDistDeliverer::Visit(CameraMapType &m)
{
- SendPacket(plr);
+ for(CameraMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
+ {
+ Player * owner = iter->getSource()->GetOwner();
+
+ if ((i_toSelf || owner != &i_player) &&
+ (!i_ownTeamOnly || owner->GetTeam() == i_player.GetTeam()) &&
+ (!i_dist || iter->getSource()->GetBody()->IsWithinDist(&i_player,i_dist)))
+ {
+ if (WorldSession* session = owner->GetSession())
+ session->SendPacket(i_message);
+ }
+ }
}
-void MessageDistDeliverer::VisitObject(Player* plr)
+void ObjectMessageDistDeliverer::Visit(CameraMapType &m)
{
- if (!i_ownTeamOnly || (i_source.GetTypeId() == TYPEID_PLAYER && plr->GetTeam() == ((Player&)i_source).GetTeam()))
+ for(CameraMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
{
- SendPacket(plr);
+ if (!i_dist || iter->getSource()->GetBody()->IsWithinDist(&i_object,i_dist))
+ {
+ if (WorldSession* session = iter->getSource()->GetOwner()->GetSession())
+ session->SendPacket(i_message);
+ }
}
}
diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h
index 20331bc95..b103c4c34 100755
--- a/src/game/GridNotifiers.h
+++ b/src/game/GridNotifiers.h
@@ -39,17 +39,17 @@ class Player;
namespace Trinity
{
- struct VisibleNotifier
+ struct TRINITY_DLL_DECL VisibleNotifier
{
- Player &i_player;
+ Camera& i_camera;
UpdateData i_data;
- std::set i_visibleNow;
- Player::ClientGUIDs vis_guids;
-
- VisibleNotifier(Player &player) : i_player(player), vis_guids(player.m_clientGUIDs) {}
+ Player::ClientGUIDs i_clientGUIDs;
+ std::set i_visibleNow;
+ explicit VisibleNotifier(Camera &c) : i_camera(c), i_clientGUIDs(c.GetOwner()->m_clientGUIDs) {}
template void Visit(GridRefManager &m);
- void SendToSelf(void);
+ void Visit(CameraMapType &m) {}
+ void Notify(void);
};
struct TRINITY_DLL_DECL VisibleChangesNotifier
@@ -58,50 +58,32 @@ namespace Trinity
explicit VisibleChangesNotifier(WorldObject &object) : i_object(object) {}
template void Visit(GridRefManager &) {}
- void Visit(PlayerMapType &);
- void Visit(CreatureMapType &);
- void Visit(DynamicObjectMapType &);
+ void Visit(CameraMapType &);
};
- struct PlayerRelocationNotifier : public VisibleNotifier
+ struct TRINITY_DLL_DECL PlayerRelocationNotifier
{
- PlayerRelocationNotifier(Player &pl) : VisibleNotifier(pl) {}
-
- template void Visit(GridRefManager &m) { VisibleNotifier::Visit(m); }
- void Visit(CreatureMapType &);
+ Player &i_player;
+ PlayerRelocationNotifier(Player &pl) : i_player(pl) {}
+ template void Visit(GridRefManager &) {}
void Visit(PlayerMapType &);
+ void Visit(CreatureMapType &);
};
- struct CreatureRelocationNotifier
+ struct TRINITY_DLL_DECL CreatureRelocationNotifier
{
Creature &i_creature;
CreatureRelocationNotifier(Creature &c) : i_creature(c) {}
template void Visit(GridRefManager &) {}
- void Visit(CreatureMapType &);
- void Visit(PlayerMapType &);
+ #ifdef WIN32
+ template<> void Visit(PlayerMapType &);
+ #endif
};
- struct DelayedUnitRelocation
- {
- Map &i_map;
- Cell &cell;
- CellPair &p;
- const float i_radius;
- DelayedUnitRelocation(Cell &c, CellPair &pair, Map &map, float radius) :
- cell(c), p(pair), i_map(map), i_radius(radius) {}
- template void Visit(GridRefManager &) {}
- void Visit(CreatureMapType &);
- void Visit(PlayerMapType &);
- };
-
- struct AIRelocationNotifier
- {
- Unit &i_unit;
- bool isCreature;
- explicit AIRelocationNotifier(Unit &unit) : i_unit(unit), isCreature(unit.GetTypeId() == TYPEID_UNIT) {}
- template void Visit(GridRefManager &) {}
- void Visit(CreatureMapType &);
- };
+ #ifndef WIN32
+ template<> inline void Trinity::CreatureRelocationNotifier::Visit(CreatureMapType &m);
+ template<> inline void Trinity::CreatureRelocationNotifier::Visit(PlayerMapType &m);
+ #endif
struct TRINITY_DLL_DECL GridUpdater
{
@@ -114,7 +96,7 @@ namespace Trinity
for (typename GridRefManager::iterator iter = m.begin(); iter != m.end(); ++iter)
{
WorldObject::UpdateHelper helper(iter->getSource());
- helper.Update(i_timeDiff);
+ helper.Update(i_timeDiff);
}
}
@@ -125,46 +107,58 @@ namespace Trinity
void Visit(CorpseMapType &m) { updateObjects(m); }
};
- struct TRINITY_DLL_DECL Deliverer
+ struct TRINITY_DLL_DECL MessageDeliverer
{
- WorldObject &i_source;
+ Player &i_player;
WorldPacket *i_message;
- std::set plr_list;
- bool i_toPossessor;
bool i_toSelf;
- float i_dist;
- Deliverer(WorldObject &src, WorldPacket *msg, bool to_possessor, bool to_self, float dist = 0.0f) : i_source(src), i_message(msg), i_toPossessor(to_possessor), i_toSelf(to_self), i_dist(dist) {}
- void Visit(PlayerMapType &m);
- void Visit(CreatureMapType &m);
- void Visit(DynamicObjectMapType &m);
- virtual void VisitObject(Player* plr) = 0;
- void SendPacket(Player* plr);
+ MessageDeliverer(Player &pl, WorldPacket *msg, bool to_self) : i_player(pl), i_message(msg), i_toSelf(to_self) {}
+ void Visit(CameraMapType &m);
template void Visit(GridRefManager &) {}
};
- struct TRINITY_DLL_DECL MessageDeliverer : public Deliverer
+ struct MessageDelivererExcept
{
- MessageDeliverer(Player &pl, WorldPacket *msg, bool to_possessor, bool to_self) : Deliverer(pl, msg, to_possessor, to_self) {}
- void VisitObject(Player* plr);
+ WorldPacket* i_message;
+ Player const* i_skipped_receiver;
+
+ MessageDelivererExcept(WorldPacket *msg, Player const* skipped)
+ : i_message(msg), i_skipped_receiver(skipped) {}
+
+ void Visit(CameraMapType &m);
+ template void Visit(GridRefManager &) {}
};
- struct TRINITY_DLL_DECL ObjectMessageDeliverer : public Deliverer
+ struct TRINITY_DLL_DECL ObjectMessageDeliverer
{
- explicit ObjectMessageDeliverer(WorldObject &src, WorldPacket *msg, bool to_possessor) : Deliverer(src, msg, to_possessor, false) {}
- void VisitObject(Player* plr) { SendPacket(plr); }
+ WorldPacket *i_message;
+ explicit ObjectMessageDeliverer(WorldPacket *msg) : i_message(msg) {}
+ void Visit(CameraMapType &m);
+ template void Visit(GridRefManager &) {}
};
- struct TRINITY_DLL_DECL MessageDistDeliverer : public Deliverer
+ struct TRINITY_DLL_DECL MessageDistDeliverer
{
+ Player &i_player;
+ WorldPacket *i_message;
+ bool i_toSelf;
bool i_ownTeamOnly;
- MessageDistDeliverer(Player &pl, WorldPacket *msg, bool to_possessor, float dist, bool to_self, bool ownTeamOnly) : Deliverer(pl, msg, to_possessor, to_self, dist), i_ownTeamOnly(ownTeamOnly) {}
- void VisitObject(Player* plr);
+ float i_dist;
+
+ MessageDistDeliverer(Player &pl, WorldPacket *msg, float dist, bool to_self, bool ownTeamOnly)
+ : i_player(pl), i_message(msg), i_toSelf(to_self), i_ownTeamOnly(ownTeamOnly), i_dist(dist) {}
+ void Visit(CameraMapType &m);
+ template void Visit(GridRefManager &) {}
};
- struct TRINITY_DLL_DECL ObjectMessageDistDeliverer : public Deliverer
+ struct TRINITY_DLL_DECL ObjectMessageDistDeliverer
{
- ObjectMessageDistDeliverer(WorldObject &obj, WorldPacket *msg, bool to_possessor, float dist) : Deliverer(obj, msg, to_possessor, false, dist) {}
- void VisitObject(Player* plr) { SendPacket(plr); }
+ WorldObject &i_object;
+ WorldPacket *i_message;
+ float i_dist;
+ ObjectMessageDistDeliverer(WorldObject &obj, WorldPacket *msg, float dist) : i_object(obj), i_message(msg), i_dist(dist) {}
+ void Visit(CameraMapType &m);
+ template void Visit(GridRefManager &) {}
};
struct TRINITY_DLL_DECL ObjectUpdater
@@ -174,6 +168,7 @@ namespace Trinity
template void Visit(GridRefManager &m);
void Visit(PlayerMapType &) {}
void Visit(CorpseMapType &) {}
+ void Visit(CameraMapType &) {}
void Visit(CreatureMapType &);
};
@@ -467,6 +462,25 @@ namespace Trinity
template void Visit(GridRefManager &) {}
};
+ template
+ struct TRINITY_DLL_DECL CameraDistWorker
+ {
+ WorldObject const* i_searcher;
+ float i_dist;
+ Do& i_do;
+
+ CameraDistWorker(WorldObject const* searcher, float _dist, Do& _do)
+ : i_searcher(searcher), i_dist(_dist), i_do(_do) {}
+
+ void Visit(CameraMapType &m)
+ {
+ for(CameraMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
+ if (itr->getSource()->GetBody()->IsWithinDist(i_searcher,i_dist))
+ i_do(itr->getSource()->GetOwner());
+ }
+ template void Visit(GridRefManager &) {}
+ };
+
// CHECKS && DO classes
// WorldObject check classes
@@ -705,7 +719,7 @@ namespace Trinity
bool operator()(Unit* u)
{
if (u->isTargetableForAttack() && i_obj->IsWithinDistInMap(u, i_range) &&
- !i_funit->IsFriendlyTo(u) && u->isVisibleForOrDetect(i_funit,false) )
+ !i_funit->IsFriendlyTo(u) && u->isVisibleForOrDetect(i_funit,i_funit,false) )
{
i_range = i_obj->GetDistance(u); // use found unit range as new range limit for next check
return true;
diff --git a/src/game/GridNotifiersImpl.h b/src/game/GridNotifiersImpl.h
index 3bd334db6..e9cd79f57 100755
--- a/src/game/GridNotifiersImpl.h
+++ b/src/game/GridNotifiersImpl.h
@@ -30,25 +30,113 @@
#include "SpellAuras.h"
template
-inline void
-Trinity::VisibleNotifier::Visit(GridRefManager &m)
+inline void Trinity::VisibleNotifier::Visit(GridRefManager &m)
{
for(typename GridRefManager::iterator iter = m.begin(); iter != m.end(); ++iter)
{
- vis_guids.erase(iter->getSource()->GetGUID());
- i_player.UpdateVisibilityOf(iter->getSource(),i_data,i_visibleNow);
+ i_camera.UpdateVisibilityOf(iter->getSource(), i_data, i_visibleNow);
+ i_clientGUIDs.erase(iter->getSource()->GetGUID());
}
}
-inline void
-Trinity::ObjectUpdater::Visit(CreatureMapType &m)
+inline void Trinity::ObjectUpdater::Visit(CreatureMapType &m)
{
for (CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
+ {
if (iter->getSource()->IsInWorld() && !iter->getSource()->isSpiritService())
{
WorldObject::UpdateHelper helper(iter->getSource());
helper.Update(i_timeDiff);
}
+ }
+}
+
+inline void Trinity::PlayerRelocationNotifier::Visit(PlayerMapType &m)
+{
+ for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
+ {
+ if (&i_player==iter->getSource())
+ continue;
+
+ // visibility for players updated by ObjectAccessor::UpdateVisibilityFor calls in appropriate places
+
+ // Cancel Trade
+ if (i_player.GetTrader()==iter->getSource())
+ // iteraction distance
+ if (!i_player.IsWithinDistInMap(iter->getSource(), INTERACTION_DISTANCE))
+ i_player.GetSession()->SendCancelTrade(); // will clode both side trade windows
+ }
+}
+
+inline void PlayerCreatureRelocationWorker(Player* pl, Creature* c)
+{
+ // Creature AI reaction
+
+ // hacky exception for Sunblade Lookout, Shattered Sun Bombardier and Brutallus
+ if (pl->isInFlight() && c->GetEntry() != 25132 && c->GetEntry() != 25144 && c->GetEntry() != 25158)
+ return;
+
+ if (!c->hasUnitState(UNIT_STAT_FLEEING) && c->HasReactState(REACT_AGGRESSIVE) && !c->hasUnitState(UNIT_STAT_SIGHTLESS))
+ {
+ if (c->AI() /*&& c->AI()->IsVisible(pl)*/ && !c->IsInEvadeMode())
+ c->AI()->MoveInLineOfSight_Safe(pl);
+ }
+}
+
+inline void CreatureCreatureRelocationWorker(Creature* c1, Creature* c2)
+{
+ if (!c1->hasUnitState(UNIT_STAT_FLEEING) && c1->HasReactState(REACT_AGGRESSIVE) && !c1->hasUnitState(UNIT_STAT_SIGHTLESS))
+ {
+ if (c1->AI() /*&& c->AI()->IsVisible(pl)*/ && !c1->IsInEvadeMode())
+ c1->AI()->MoveInLineOfSight_Safe(c2);
+ }
+
+ if (!c2->hasUnitState(UNIT_STAT_FLEEING) && c2->HasReactState(REACT_AGGRESSIVE) && !c2->hasUnitState(UNIT_STAT_SIGHTLESS))
+ {
+ if (c2->AI() /*&& c->AI()->IsVisible(pl)*/ && !c2->IsInEvadeMode())
+ c2->AI()->MoveInLineOfSight_Safe(c1);
+ }
+}
+
+inline void Trinity::PlayerRelocationNotifier::Visit(CreatureMapType &m)
+{
+ if (!i_player.isAlive() || i_player.isInFlight())
+ return;
+
+ for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
+ {
+ Creature* c = iter->getSource();
+ if (c->isAlive())
+ PlayerCreatureRelocationWorker(&i_player, c);
+ }
+}
+
+template<>
+inline void Trinity::CreatureRelocationNotifier::Visit(PlayerMapType &m)
+{
+ if (!i_creature.isAlive())
+ return;
+
+ for (PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
+ {
+ Player* player = iter->getSource();
+ if (player->isAlive() && !player->isInFlight())
+ PlayerCreatureRelocationWorker(player, &i_creature);
+ }
+}
+
+template<>
+inline void Trinity::CreatureRelocationNotifier::Visit(CreatureMapType &m)
+{
+ if (!i_creature.isAlive())
+ return;
+
+ for(CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
+ {
+ Creature* c = iter->getSource();
+ if (c != &i_creature && c->isAlive())
+ CreatureCreatureRelocationWorker(c, &i_creature);
+ }
}
// SEARCHERS & LIST SEARCHERS & WORKERS
diff --git a/src/game/GuardAI.cpp b/src/game/GuardAI.cpp
index a4099d4e8..9f7d8da5b 100755
--- a/src/game/GuardAI.cpp
+++ b/src/game/GuardAI.cpp
@@ -127,7 +127,7 @@ void GuardAI::UpdateAI(const uint32 /*diff*/)
bool GuardAI::IsVisible(Unit *pl) const
{
return m_creature->IsWithinDistInMap(pl,sWorld.getConfig(CONFIG_SIGHT_GUARDER)) &&
- pl->isVisibleForOrDetect(m_creature,true);
+ pl->isVisibleForOrDetect(m_creature,m_creature,true);
}
void GuardAI::JustDied(Unit *killer)
diff --git a/src/game/Map.cpp b/src/game/Map.cpp
index a38633221..48fea14fe 100755
--- a/src/game/Map.cpp
+++ b/src/game/Map.cpp
@@ -158,8 +158,7 @@ void Map::DeleteStateMachine()
Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode)
: i_mapEntry (sMapStore.LookupEntry(id)), i_spawnMode(SpawnMode),
i_id(id), i_InstanceId(InstanceId), m_unloadTimer(0), i_gridExpiry(expiry),
- m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE), m_activeNonPlayersIter(m_activeNonPlayers.end()), i_scriptLock(true),
- m_VisibilityNotifyPeriod(DEFAULT_VISIBILITY_NOTIFY_PERIOD)
+ m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE), m_activeNonPlayersIter(m_activeNonPlayers.end()), i_scriptLock(true)
{
for (unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx)
{
@@ -171,8 +170,6 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode)
}
}
- m_VisibilityNotifyPeriod = World::GetVisibilityNotifyPeriodOnContinents();
-
//lets initialize visibility distance for map
Map::InitVisibilityDistance();
}
@@ -334,8 +331,8 @@ void Map::EnsureGridCreated(const GridPair &p)
{
if (!getNGrid(p.x_coord, p.y_coord))
{
- Guard guard(*this);
- if (!getNGrid(p.x_coord, p.y_coord))
+ //Guard guard(*this);
+ //if (!getNGrid(p.x_coord, p.y_coord))
{
sLog.outDebug("Loading grid[%u,%u] for map %u", p.x_coord, p.y_coord, i_id);
@@ -426,7 +423,9 @@ bool Map::Add(Player *player)
SendInitTransports(player);
player->m_clientGUIDs.clear();
- player->UpdateObjectVisibility(true);
+
+ player->GetViewPoint().Event_AddedToWorld(&(*grid)(cell.CellX(), cell.CellY()));
+ UpdateObjectVisibility(player,cell,p);
return true;
}
@@ -444,11 +443,6 @@ Map::Add(T *obj)
}
Cell cell(p);
- if (obj->IsInWorld()) // need some clean up later
- {
- obj->UpdateObjectVisibility(true);
- return;
- }
if (obj->isActiveObject())
EnsureGridLoadedAtEnter(cell);
@@ -466,31 +460,31 @@ Map::Add(T *obj)
DEBUG_LOG("Object %u enters grid[%u,%u]", GUID_LOPART(obj->GetGUID()), cell.GridX(), cell.GridY());
- //trigger needs to cast spell, if not update, cannot see visual
- obj->UpdateObjectVisibility(true);
+ obj->GetViewPoint().Event_AddedToWorld(&(*grid)(cell.CellX(), cell.CellY()));
+ UpdateObjectVisibility(obj,cell,p);
}
void Map::MessageBroadcast(Player *player, WorldPacket *msg, bool to_self, bool to_possessor)
{
- Trinity::MessageDeliverer post_man(*player, msg, to_possessor, to_self);
+ Trinity::MessageDeliverer post_man(*player, msg, to_self);
Cell::VisitWorldObjects(player, post_man, GetVisibilityDistance());
}
void Map::MessageBroadcast(WorldObject *obj, WorldPacket *msg, bool to_possessor)
{
- Trinity::ObjectMessageDeliverer post_man(*obj, msg, to_possessor);
+ Trinity::ObjectMessageDeliverer post_man(msg);
Cell::VisitWorldObjects(obj, post_man, GetVisibilityDistance());
}
void Map::MessageDistBroadcast(Player *player, WorldPacket *msg, float dist, bool to_self, bool to_possessor, bool own_team_only)
{
- Trinity::MessageDistDeliverer post_man(*player, msg, to_possessor, dist, to_self, own_team_only);
+ Trinity::MessageDistDeliverer post_man(*player, msg, dist, to_self, own_team_only);
Cell::VisitWorldObjects(player, post_man, GetVisibilityDistance());
}
void Map::MessageDistBroadcast(WorldObject *obj, WorldPacket *msg, float dist, bool to_possessor)
{
- Trinity::ObjectMessageDistDeliverer post_man(*obj, msg, to_possessor, dist);
+ Trinity::ObjectMessageDistDeliverer post_man(*obj, msg, dist);
Cell::VisitWorldObjects(obj, post_man, GetVisibilityDistance());
}
@@ -611,101 +605,6 @@ void Map::Update(const uint32 &t_diff)
ScriptsProcess();
i_scriptLock = false;
}
-
- MoveAllCreaturesInMoveList();
-
- if(!m_mapRefManager.isEmpty() || !m_activeNonPlayers.empty())
- ProcessRelocationNotifies(t_diff);
-}
-
-struct ResetNotifier
-{
- templateinline void resetNotify(GridRefManager &m)
- {
- for(typename GridRefManager::iterator iter=m.begin(); iter != m.end(); ++iter)
- iter->getSource()->ResetAllNotifies();
- }
-
- template void Visit(GridRefManager &) {}
- void Visit(CreatureMapType &m) { resetNotify(m);}
- void Visit(PlayerMapType &m) { resetNotify(m);}
-};
-
-void Map::ProcessRelocationNotifies(const uint32 & diff)
-{
- for(GridRefManager::iterator i = GridRefManager::begin(); i != GridRefManager::end(); ++i)
- {
- NGridType *grid = i->getSource();
-
- if (grid->GetGridState() != GRID_STATE_ACTIVE)
- continue;
-
- grid->getGridInfoRef()->getRelocationTimer().TUpdate(diff);
- if (!grid->getGridInfoRef()->getRelocationTimer().TPassed())
- continue;
-
- uint32 gx = grid->getX(), gy = grid->getY();
-
- CellPair cell_min(gx*MAX_NUMBER_OF_CELLS, gy*MAX_NUMBER_OF_CELLS);
- CellPair cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord+MAX_NUMBER_OF_CELLS);
-
- for (uint32 x = cell_min.x_coord; x < cell_max.x_coord; ++x)
- {
- for (uint32 y = cell_min.y_coord; y < cell_max.y_coord; ++y)
- {
- uint32 cell_id = (y * TOTAL_NUMBER_OF_CELLS_PER_MAP) + x;
- if (!isCellMarked(cell_id))
- continue;
-
- CellPair pair(x,y);
- Cell cell(pair);
- cell.SetNoCreate();
-
- Trinity::DelayedUnitRelocation cell_relocation(cell, pair, *this, GetVisibilityDistance());
- TypeContainerVisitor grid_object_relocation(cell_relocation);
- TypeContainerVisitor world_object_relocation(cell_relocation);
- Visit(cell, grid_object_relocation);
- Visit(cell, world_object_relocation);
- }
- }
- }
-
- ResetNotifier reset;
- TypeContainerVisitor grid_notifier(reset);
- TypeContainerVisitor world_notifier(reset);
-
- for (GridRefManager::iterator i = GridRefManager::begin(); i != GridRefManager::end(); ++i)
- {
- NGridType *grid = i->getSource();
-
- if (grid->GetGridState() != GRID_STATE_ACTIVE)
- continue;
-
- if (!grid->getGridInfoRef()->getRelocationTimer().TPassed())
- continue;
-
- grid->getGridInfoRef()->getRelocationTimer().TReset(diff, m_VisibilityNotifyPeriod);
- uint32 gx = grid->getX(), gy = grid->getY();
-
- CellPair cell_min(gx*MAX_NUMBER_OF_CELLS, gy*MAX_NUMBER_OF_CELLS);
- CellPair cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord+MAX_NUMBER_OF_CELLS);
-
- for (uint32 x = cell_min.x_coord; x < cell_max.x_coord; ++x)
- {
- for (uint32 y = cell_min.y_coord; y < cell_max.y_coord; ++y)
- {
- uint32 cell_id = (y * TOTAL_NUMBER_OF_CELLS_PER_MAP) + x;
- if (!isCellMarked(cell_id))
- continue;
-
- CellPair pair(x,y);
- Cell cell(pair);
- cell.SetNoCreate();
- Visit(cell, grid_notifier);
- Visit(cell, world_notifier);
- }
- }
- }
}
void Map::SendObjectUpdates()
@@ -763,11 +662,11 @@ void Map::Remove(Player *player, bool remove)
NGridType *grid = getNGrid(cell.GridX(), cell.GridY());
assert(grid != NULL);
- player->UpdateObjectVisibility(true);
player->RemoveFromWorld();
RemoveFromGrid(player,grid,cell);
SendRemoveTransports(player);
+ UpdateObjectVisibility(player,cell,p);
if (remove)
DeleteFromWorld(player);
@@ -807,7 +706,8 @@ void Map::Remove(T *obj, bool remove)
obj->RemoveFromWorld();
if (obj->isActiveObject())
RemoveFromActive(obj);
- obj->UpdateObjectVisibility(true);
+
+ UpdateObjectVisibility(obj,cell,p); // i think will be better to call this function while object still in grid, this changes nothing but logically is better(as for me)
RemoveFromGrid(obj,grid,cell);
if (remove)
@@ -821,13 +721,14 @@ void Map::Remove(T *obj, bool remove)
void Map::PlayerRelocation(Player *player, float x, float y, float z, float orientation)
{
- assert(player);
+ ASSERT(player);
CellPair old_val = Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
CellPair new_val = Trinity::ComputeCellPair(x, y);
Cell old_cell(old_val);
Cell new_cell(new_val);
+ bool same_cell = (new_cell == old_cell);
player->Relocate(x, y, z, orientation);
@@ -841,19 +742,28 @@ void Map::PlayerRelocation(Player *player, float x, float y, float z, float orie
NGridType* oldGrid = getNGrid(old_cell.GridX(), old_cell.GridY());
RemoveFromGrid(player, oldGrid,old_cell);
- if (old_cell.DiffGrid(new_cell))
+ if (!old_cell.DiffGrid(new_cell))
+ AddToGrid(player, oldGrid,new_cell);
+ else
EnsureGridLoadedAtEnter(new_cell, player);
NGridType* newGrid = getNGrid(new_cell.GridX(), new_cell.GridY());
- AddToGrid(player, newGrid,new_cell);
+ player->GetViewPoint().Event_GridChanged(&(*newGrid)(new_cell.CellX(),new_cell.CellY()));
}
- player->UpdateObjectVisibility(player->GetMotionMaster()->GetCurrentMovementGeneratorType() != IDLE_MOTION_TYPE);
+ player->OnRelocated();
+
+ NGridType* newGrid = getNGrid(new_cell.GridX(), new_cell.GridY());
+ if (!same_cell && newGrid->GetGridState() != GRID_STATE_ACTIVE)
+ {
+ ResetGridExpiry(*newGrid, 0.1f);
+ newGrid->SetGridState(GRID_STATE_ACTIVE);
+ }
}
void Map::CreatureRelocation(Creature *creature, float x, float y, float z, float ang)
{
- assert(CheckGridIntegrity(creature,false));
+ ASSERT(CheckGridIntegrity(creature,false));
Cell old_cell = creature->GetCurrentCell();
@@ -863,91 +773,50 @@ void Map::CreatureRelocation(Creature *creature, float x, float y, float z, floa
// delay creature move for grid/cell to grid/cell moves
if (old_cell.DiffCell(new_cell) || old_cell.DiffGrid(new_cell))
{
- #ifdef TRINITY_DEBUG
- if ((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0)
- sLog.outDebug("Creature (GUID: %u Entry: %u) added to moving list from grid[%u,%u]cell[%u,%u] to grid[%u,%u]cell[%u,%u].", creature->GetGUIDLow(), creature->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
- #endif
- AddCreatureToMoveList(creature,x,y,z,ang);
- // in diffcell/diffgrid case notifiers called at finishing move creature in Map::MoveAllCreaturesInMoveList
- }
- else
- {
- creature->Relocate(x, y, z, ang);
- creature->UpdateObjectVisibility(false);
- }
- assert(CheckGridIntegrity(creature,true));
-}
-
-void Map::AddCreatureToMoveList(Creature *c, float x, float y, float z, float ang)
-{
- if (!c)
- return;
-
- i_creaturesToMove[c] = CreatureMover(x,y,z,ang);
-}
-
-void Map::MoveAllCreaturesInMoveList()
-{
- while (!i_creaturesToMove.empty())
- {
- // get data and remove element;
- CreatureMoveList::iterator iter = i_creaturesToMove.begin();
- Creature* c = iter->first;
- CreatureMover cm = iter->second;
- i_creaturesToMove.erase(iter);
-
- // calculate cells
- CellPair new_val = Trinity::ComputeCellPair(cm.x, cm.y);
- Cell new_cell(new_val);
+ DEBUG_LOG("Creature (GUID: %u Entry: %u) added to moving list from grid[%u,%u]cell[%u,%u] to grid[%u,%u]cell[%u,%u].", creature->GetGUIDLow(), creature->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
// do move or do move to respawn or remove creature if previous all fail
- if (CreatureCellRelocation(c,new_cell))
+ if (CreatureCellRelocation(creature,new_cell))
{
// update pos
- c->Relocate(cm.x, cm.y, cm.z, cm.ang);
- //CreatureRelocationNotify(c,new_cell,new_cell.cellPair());
- c->UpdateObjectVisibility(false);
+ creature->Relocate(x, y, z, ang);
+ creature->OnRelocated();
}
- else
+ else if (!CreatureRespawnRelocation(creature))
{
- // if creature can't be move in new cell/grid (not loaded) move it to repawn cell/grid
- // creature coordinates will be updated and notifiers send
- if (!CreatureRespawnRelocation(c))
- {
- // ... or unload (if respawn grid also not loaded)
- #ifdef TRINITY_DEBUG
- if ((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0)
- sLog.outDebug("Creature (GUID: %u Entry: %u) can't be move to unloaded respawn grid.",c->GetGUIDLow(),c->GetEntry());
- #endif
- c->CleanupsBeforeDelete();
- AddObjectToRemoveList(c);
- }
+ // ... or unload (if respawn grid also not loaded)
+ DEBUG_LOG("Creature (GUID: %u Entry: %u ) can't be move to unloaded respawn grid.",creature->GetGUIDLow(),creature->GetEntry());
}
}
+ else
+ {
+ creature->Relocate(x, y, z, ang);
+ creature->OnRelocated();
+ }
+
+ ASSERT(CheckGridIntegrity(creature,true));
}
bool Map::CreatureCellRelocation(Creature *c, Cell new_cell)
{
Cell const& old_cell = c->GetCurrentCell();
- if (!old_cell.DiffGrid(new_cell)) // in same grid
+ if (!old_cell.DiffGrid(new_cell) ) // in same grid
{
// if in same cell then none do
- if (old_cell.DiffCell(new_cell))
+ if(old_cell.DiffCell(new_cell))
{
- #ifdef TRINITY_DEBUG
- if ((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0)
- sLog.outDebug("Creature (GUID: %u Entry: %u) moved in grid[%u,%u] from cell[%u,%u] to cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.CellX(), new_cell.CellY());
- #endif
+ DEBUG_LOG("Creature (GUID: %u Entry: %u) moved in grid[%u,%u] from cell[%u,%u] to cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.CellX(), new_cell.CellY());
+
+ RemoveFromGrid(c,getNGrid(old_cell.GridX(), old_cell.GridY()),old_cell);
- RemoveFromGrid(c,getNGrid(old_cell.GridX(), old_cell.GridY()),old_cell);
- AddToGrid(c,getNGrid(new_cell.GridX(), new_cell.GridY()),new_cell);
+ NGridType* new_grid = getNGrid(new_cell.GridX(), new_cell.GridY());
+ AddToGrid(c,new_grid,new_cell);
+
+ c->GetViewPoint().Event_GridChanged( &(*new_grid)(new_cell.CellX(),new_cell.CellY()) );
}
else
{
- #ifdef TRINITY_DEBUG
- if ((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0)
- sLog.outDebug("Creature (GUID: %u Entry: %u) move in same grid[%u,%u]cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY());
- #endif
+ DEBUG_LOG("Creature (GUID: %u Entry: %u) move in same grid[%u,%u]cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY());
}
return true;
@@ -958,37 +827,37 @@ bool Map::CreatureCellRelocation(Creature *c, Cell new_cell)
{
EnsureGridLoadedAtEnter(new_cell);
- #ifdef TRINITY_DEBUG
- if ((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0)
- sLog.outDebug("Active creature (GUID: %u Entry: %u) moved from grid[%u,%u]cell[%u,%u] to grid[%u,%u]cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
- #endif
+ DEBUG_LOG("Active creature (GUID: %u Entry: %u) moved from grid[%u,%u]cell[%u,%u] to grid[%u,%u]cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
RemoveFromGrid(c,getNGrid(old_cell.GridX(), old_cell.GridY()),old_cell);
- AddToGrid(c,getNGrid(new_cell.GridX(), new_cell.GridY()),new_cell);
+ NGridType* new_grid = getNGrid(new_cell.GridX(), new_cell.GridY());
+ AddToGrid(c,new_grid,new_cell);
+
+ c->GetViewPoint().Event_GridChanged( &(*new_grid)(new_cell.CellX(),new_cell.CellY()));
return true;
}
// in diff. loaded grid normal creature
if (loaded(GridPair(new_cell.GridX(), new_cell.GridY())))
{
- #ifdef TRINITY_DEBUG
- if ((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0)
- sLog.outDebug("Creature (GUID: %u Entry: %u) moved from grid[%u,%u]cell[%u,%u] to grid[%u,%u]cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
- #endif
+ DEBUG_LOG(LOG_FILTER_CREATURE_MOVES, "Creature (GUID: %u Entry: %u) moved from grid[%u,%u]cell[%u,%u] to grid[%u,%u]cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
RemoveFromGrid(c,getNGrid(old_cell.GridX(), old_cell.GridY()),old_cell);
- EnsureGridCreated(GridPair(new_cell.GridX(), new_cell.GridY()));
- AddToGrid(c,getNGrid(new_cell.GridX(), new_cell.GridY()),new_cell);
+ {
+ EnsureGridCreated(GridPair(new_cell.GridX(), new_cell.GridY()));
+
+ NGridType* new_grid = getNGrid(new_cell.GridX(), new_cell.GridY());
+ AddToGrid(c,new_grid,new_cell);
+
+ c->GetViewPoint().Event_GridChanged( &(*new_grid)(new_cell.CellX(),new_cell.CellY()));
+ }
return true;
}
// fail to move: normal creature attempt move to unloaded grid
- #ifdef TRINITY_DEBUG
- if ((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0)
- sLog.outDebug("Creature (GUID: %u Entry: %u) attempt move from grid[%u,%u]cell[%u,%u] to unloaded grid[%u,%u]cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
- #endif
+ DEBUG_LOG("Creature (GUID: %u Entry: %u) attempt move from grid[%u,%u]cell[%u,%u] to unloaded grid[%u,%u]cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
return false;
}
@@ -1003,18 +872,14 @@ bool Map::CreatureRespawnRelocation(Creature *c)
c->CombatStop();
c->GetMotionMaster()->Clear();
- #ifdef TRINITY_DEBUG
- if ((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0)
- sLog.outDebug("Creature (GUID: %u Entry: %u) will moved from grid[%u,%u]cell[%u,%u] to respawn grid[%u,%u]cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), c->GetCurrentCell().GridX(), c->GetCurrentCell().GridY(), c->GetCurrentCell().CellX(), c->GetCurrentCell().CellY(), resp_cell.GridX(), resp_cell.GridY(), resp_cell.CellX(), resp_cell.CellY());
- #endif
+ DEBUG_LOG("Creature (GUID: %u Entry: %u) will moved from grid[%u,%u]cell[%u,%u] to respawn grid[%u,%u]cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), c->GetCurrentCell().GridX(), c->GetCurrentCell().GridY(), c->GetCurrentCell().CellX(), c->GetCurrentCell().CellY(), resp_cell.GridX(), resp_cell.GridY(), resp_cell.CellX(), resp_cell.CellY());
// teleport it to respawn point (like normal respawn if player see)
- if (CreatureCellRelocation(c,resp_cell))
+ if(CreatureCellRelocation(c,resp_cell))
{
c->Relocate(resp_x, resp_y, resp_z, resp_o);
c->GetMotionMaster()->Initialize(); // prevent possible problems with default move generators
- //CreatureRelocationNotify(c,resp_cell,resp_cell.cellPair());
- c->UpdateObjectVisibility(false);
+ c->OnRelocated();
return true;
}
else
@@ -1036,15 +901,15 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool unloadAll)
if (!unloadAll)
{
- // Finish creature moves, remove and delete all creatures with delayed remove before moving to respawn grids
+ // Finish remove and delete all creatures with delayed remove before moving to respawn grids
// Must know real mob position before move
- MoveAllCreaturesInMoveList();
+ RemoveAllObjectsInRemoveList();
// move creatures to respawn grids if this is diff.grid or to remove list
unloader.MoveToRespawnN();
- // Finish creature moves, remove and delete all creatures with delayed remove before unload
- MoveAllCreaturesInMoveList();
+ // Finish remove and delete all creatures with delayed remove before unload
+ RemoveAllObjectsInRemoveList();
}
ObjectGridCleaner cleaner(*grid);
@@ -1085,9 +950,6 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool unloadAll)
void Map::UnloadAll()
{
- // clear all delayed moves, useless anyway do this moves before map unload.
- i_creaturesToMove.clear();
-
for (GridRefManager::iterator i = GridRefManager::begin(); i != GridRefManager::end();)
{
NGridType &grid(*i->getSource());
@@ -1454,20 +1316,6 @@ void Map::UpdateObjectVisibility(WorldObject* obj, Cell cell, CellPair cellpair)
cell.Visit(cellpair, player_notifier, *this, *obj, GetVisibilityDistance());
}
-void Map::UpdateObjectsVisibilityFor(Player* player, Cell cell, CellPair cellpair)
-{
- Trinity::VisibleNotifier notifier(*player);
-
- cell.SetNoCreate();
- TypeContainerVisitor world_notifier(notifier);
- TypeContainerVisitor grid_notifier(notifier);
- cell.Visit(cellpair, world_notifier, *this, *player, GetVisibilityDistance());
- cell.Visit(cellpair, grid_notifier, *this, *player, GetVisibilityDistance());
-
- // send data
- notifier.SendToSelf();
-}
-
void Map::SendInitSelf(Player * player)
{
sLog.outDetail("Creating player data for himself %u", player->GetGUIDLow());
@@ -1716,47 +1564,67 @@ bool Map::ActiveObjectsNearGrid(uint32 x, uint32 y) const
return false;
}
-void Map::AddToActive(Creature* c)
+void Map::AddToActive( WorldObject* obj )
{
- AddToActiveHelper(c);
+ m_activeNonPlayers.insert(obj);
// also not allow unloading spawn grid to prevent creating creature clone at load
- if (!c->isPet() && c->GetDBTableGUIDLow())
+ if (obj->GetTypeId()==TYPEID_UNIT)
{
- float x,y,z;
- c->GetRespawnCoord(x,y,z);
- GridPair p = Trinity::ComputeGridPair(x, y);
- if (getNGrid(p.x_coord, p.y_coord))
- getNGrid(p.x_coord, p.y_coord)->incUnloadActiveLock();
- else
+ Creature* c= (Creature*)obj;
+ if (!c->isPet() && c->GetDBTableGUIDLow())
{
- GridPair p2 = Trinity::ComputeGridPair(c->GetPositionX(), c->GetPositionY());
- sLog.outError("Active creature (GUID: %u Entry: %u) added to grid[%u,%u] but spawn grid[%u,%u] not loaded.",
- c->GetGUIDLow(), c->GetEntry(), p.x_coord, p.y_coord, p2.x_coord, p2.y_coord);
+
+ float x,y,z;
+ c->GetRespawnCoord(x,y,z);
+ GridPair p = Trinity::ComputeGridPair(x, y);
+ if(getNGrid(p.x_coord, p.y_coord))
+ getNGrid(p.x_coord, p.y_coord)->incUnloadActiveLock();
+ else
+ {
+ GridPair p2 = Trinity::ComputeGridPair(c->GetPositionX(), c->GetPositionY());
+ sLog.outError("Active creature (GUID: %u Entry: %u) added to grid[%u,%u] but spawn grid[%u,%u] not loaded.",
+ c->GetGUIDLow(), c->GetEntry(), p.x_coord, p.y_coord, p2.x_coord, p2.y_coord);
+ }
}
}
}
-void Map::RemoveFromActive(Creature* c)
+void Map::RemoveFromActive( WorldObject* obj )
{
- RemoveFromActiveHelper(c);
+ // Map::Update for active object in proccess
+ if(m_activeNonPlayersIter != m_activeNonPlayers.end())
+ {
+ ActiveNonPlayers::iterator itr = m_activeNonPlayers.find(obj);
+ if(itr==m_activeNonPlayersIter)
+ ++m_activeNonPlayersIter;
+
+ m_activeNonPlayers.erase(itr);
+ }
+ else
+ m_activeNonPlayers.erase(obj);
// also allow unloading spawn grid
- if (!c->isPet() && c->GetDBTableGUIDLow())
+ if (obj->GetTypeId()==TYPEID_UNIT)
{
- float x,y,z;
- c->GetRespawnCoord(x,y,z);
- GridPair p = Trinity::ComputeGridPair(x, y);
- if (getNGrid(p.x_coord, p.y_coord))
- getNGrid(p.x_coord, p.y_coord)->decUnloadActiveLock();
- else
+ Creature* c= (Creature*)obj;
+ if(!c->isPet() && c->GetDBTableGUIDLow())
{
- GridPair p2 = Trinity::ComputeGridPair(c->GetPositionX(), c->GetPositionY());
- sLog.outError("Active creature (GUID: %u Entry: %u) removed from grid[%u,%u] but spawn grid[%u,%u] not loaded.",
- c->GetGUIDLow(), c->GetEntry(), p.x_coord, p.y_coord, p2.x_coord, p2.y_coord);
+ float x,y,z;
+ c->GetRespawnCoord(x,y,z);
+ GridPair p = Trinity::ComputeGridPair(x, y);
+ if (getNGrid(p.x_coord, p.y_coord))
+ getNGrid(p.x_coord, p.y_coord)->decUnloadActiveLock();
+ else
+ {
+ GridPair p2 = Trinity::ComputeGridPair(c->GetPositionX(), c->GetPositionY());
+ sLog.outError("Active creature (GUID: %u Entry: %u) removed from grid[%u,%u] but spawn grid[%u,%u] not loaded.",
+ c->GetGUIDLow(), c->GetEntry(), p.x_coord, p.y_coord, p2.x_coord, p2.y_coord);
+ }
}
}
}
+
void Map::ScriptsStart(ScriptMapMap const& scripts, uint32 id, Object* source, Object* target)
{
///- Find the script map
@@ -2560,8 +2428,6 @@ InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, uint8 Spaw
// the timer is started by default, and stopped when the first player joins
// this make sure it gets unloaded if for some reason no player joins
m_unloadTimer = std::max(sWorld.getConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY);
-
- m_VisibilityNotifyPeriod = World::GetVisibilityNotifyPeriodInInstances();
}
InstanceMap::~InstanceMap()
@@ -2637,7 +2503,7 @@ bool InstanceMap::Add(Player *player)
// Is it needed?
{
- Guard guard(*this);
+ //Guard guard(*this);
if (!CanEnter(player))
return false;
@@ -2911,8 +2777,6 @@ BattleGroundMap::BattleGroundMap(uint32 id, time_t expiry, uint32 InstanceId, Ba
{
m_bg = bg;
BattleGroundMap::InitVisibilityDistance();
-
- m_VisibilityNotifyPeriod = World::GetVisibilityNotifyPeriodInBGArenas();
}
BattleGroundMap::~BattleGroundMap()
@@ -2956,7 +2820,7 @@ void BattleGroundMap::Update(const uint32& t_diff)
bool BattleGroundMap::Add(Player * player)
{
{
- Guard guard(*this);
+ //Guard guard(*this);
if (!CanEnter(player))
return false;
// reset instance validity, battleground maps do not homebind
diff --git a/src/game/Map.h b/src/game/Map.h
index bbc47d034..9eca616b5 100755
--- a/src/game/Map.h
+++ b/src/game/Map.h
@@ -123,6 +123,8 @@ enum GetCreatureGuidType
class TRINITY_DLL_SPEC Map : public GridRefManager, public Trinity::ObjectLevelLockable