From e427ce80cc4cc2c1ba956dfa0342d8af49e113ff Mon Sep 17 00:00:00 2001 From: SilverIce Date: Sat, 12 Jun 2010 05:00:09 +0400 Subject: [PATCH 01/42] [10052] Camera System (based on SilverIce's repo commit 4f2f4ab + next 3 more) Signed-off-by: VladimirMangos --- src/game/AchievementMgr.cpp | 2 +- src/game/Camera.cpp | 134 +++++++++++++++++++++++++++++++++ src/game/Camera.h | 122 ++++++++++++++++++++++++++++++ src/game/ChatHandler.cpp | 2 +- src/game/DynamicObject.cpp | 3 + src/game/GridDefines.h | 5 +- src/game/GridNotifiers.cpp | 97 ++++++++++++------------ src/game/GridNotifiers.h | 31 ++++---- src/game/GridNotifiersImpl.h | 10 +-- src/game/Makefile.am | 2 + src/game/Map.cpp | 50 ++++++------ src/game/Map.h | 3 +- src/game/NPCHandler.cpp | 10 ++- src/game/Object.cpp | 29 +++++-- src/game/Object.h | 6 +- src/game/ObjectGridLoader.cpp | 21 ++++-- src/game/Player.cpp | 93 ++++++----------------- src/game/Player.h | 7 +- src/game/Spell.h | 2 + src/game/SpellAuras.cpp | 30 ++++++-- src/game/SpellEffects.cpp | 3 +- src/game/Unit.cpp | 34 ++++++++- src/shared/revision_nr.h | 2 +- win/VC100/game.vcxproj | 2 + win/VC100/game.vcxproj.filters | 6 ++ win/VC80/game.vcproj | 8 ++ win/VC90/game.vcproj | 8 ++ 27 files changed, 515 insertions(+), 207 deletions(-) create mode 100644 src/game/Camera.cpp create mode 100644 src/game/Camera.h diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index 6517f8157..d32d951a1 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -639,7 +639,7 @@ void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement) { MaNGOS::AchievementChatBuilder say_builder(*GetPlayer(), CHAT_MSG_ACHIEVEMENT, LANG_ACHIEVEMENT_EARNED,achievement->ID); MaNGOS::LocalizedPacketDo say_do(say_builder); - MaNGOS::PlayerDistWorker > say_worker(GetPlayer(),sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_SAY),say_do); + MaNGOS::CameraDistWorker > say_worker(GetPlayer(),sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_SAY),say_do); Cell::VisitWorldObjects(GetPlayer(), say_worker, sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_SAY)); } diff --git a/src/game/Camera.cpp b/src/game/Camera.cpp new file mode 100644 index 000000000..b151ec556 --- /dev/null +++ b/src/game/Camera.cpp @@ -0,0 +1,134 @@ +#include "Camera.h" +#include "GridNotifiersImpl.h" +#include "CellImpl.h" +#include "Log.h" +#include "Errors.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); + + m_owner.SetUInt64Value(PLAYER_FARSIGHT, (m_source == &m_owner ? 0 : m_source->GetGUID())); + UpdateVisibilityForOwner(); +} + +void Camera::SetView(WorldObject *obj) +{ + ASSERT(obj); + + if (!m_owner.IsInMap(obj)) + { + sLog.outError("Camera::SetView, viewpoint is not in map with camera's owner"); + return; + } + + if (!obj->isType(TYPEMASK_DYNAMICOBJECT | TYPEMASK_UNIT)) + { + sLog.outError("Camera::SetView, viewpoint type is not available for client"); + return; + } + + m_source->GetViewPoint().Detach(this); + m_source = obj; + m_source->GetViewPoint().Attach(this); + + UpdateForCurrentViewPoint(); +} + +void Camera::Event_ViewPointVisibilityChanged() +{ + if (!m_owner.HaveAtClient(m_source)) + ResetView(); +} + +void Camera::ResetView() +{ + m_source->GetViewPoint().Detach(this); + m_source = &m_owner; + m_source->GetViewPoint().Attach(this); + + UpdateForCurrentViewPoint(); +} + +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() +{ + MaNGOS::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"); + } +} diff --git a/src/game/Camera.h b/src/game/Camera.h new file mode 100644 index 000000000..65bd6b88c --- /dev/null +++ b/src/game/Camera.h @@ -0,0 +1,122 @@ + +#ifndef MANGOSSERVER_CAMERA_H +#define MANGOSSERVER_CAMERA_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 MANGOS_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); + + // set view to camera's owner + void ResetView(); + + 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 MANGOS_DLL_SPEC ViewPoint +{ + friend class Camera; + + std::list m_cameras; + std::list::iterator m_camera_iter; + GridType * m_grid; + + void Attach(Camera* c) { m_cameras.push_back(c); } + + void Detach(Camera* c) + { + if (m_camera_iter != m_cameras.end() && *m_camera_iter == c) // detach called during the loop + m_camera_iter = m_cameras.erase(m_camera_iter); + else + m_cameras.remove(c); + } + + void CameraCall(void (Camera::*handler)()) + { + if (!m_cameras.empty()) + for(m_camera_iter = m_cameras.begin(); m_camera_iter!=m_cameras.end(); ++m_camera_iter) + ((*m_camera_iter)->*handler)(); + } + +public: + + ViewPoint() : m_grid(0), m_camera_iter(m_cameras.end()) {} + ~ViewPoint(); + + // 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/ChatHandler.cpp b/src/game/ChatHandler.cpp index 3e575bb49..405118641 100644 --- a/src/game/ChatHandler.cpp +++ b/src/game/ChatHandler.cpp @@ -574,7 +574,7 @@ void WorldSession::HandleTextEmoteOpcode( WorldPacket & recv_data ) MaNGOS::EmoteChatBuilder emote_builder(*GetPlayer(), text_emote, emoteNum, unit); MaNGOS::LocalizedPacketDo emote_do(emote_builder); - MaNGOS::PlayerDistWorker > emote_worker(GetPlayer(), sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_TEXTEMOTE), emote_do); + MaNGOS::CameraDistWorker > emote_worker(GetPlayer(), sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_TEXTEMOTE), emote_do); Cell::VisitWorldObjects(GetPlayer(), emote_worker, sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_TEXTEMOTE)); GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit); diff --git a/src/game/DynamicObject.cpp b/src/game/DynamicObject.cpp index 6a36f6dda..cde2529af 100644 --- a/src/game/DynamicObject.cpp +++ b/src/game/DynamicObject.cpp @@ -50,7 +50,10 @@ void DynamicObject::RemoveFromWorld() { ///- Remove the dynamicObject from the accessor if(IsInWorld()) + { GetMap()->GetObjectsStore().erase(GetGUID(), (DynamicObject*)NULL); + GetViewPoint().Event_RemovedFromWorld(); + } Object::RemoveFromWorld(); } diff --git a/src/game/GridDefines.h b/src/game/GridDefines.h index 0f737decc..da5abba03 100644 --- a/src/game/GridDefines.h +++ b/src/game/GridDefines.h @@ -31,6 +31,7 @@ class DynamicObject; class GameObject; class Pet; class Player; +class Camera; #define MAX_NUMBER_OF_GRIDS 64 @@ -56,10 +57,12 @@ class Player; #define MAP_HALFSIZE (MAP_SIZE/2) // Creature used instead pet to simplify *::Visit templates (not required duplicate code for Creature->Pet case) -typedef TYPELIST_3(Player, Creature/*pets*/, Corpse/*resurrectable*/) AllWorldObjectTypes; +// Cameras in world list just because linked with Player objects +typedef TYPELIST_4(Player, Creature/*pets*/, Corpse/*resurrectable*/, Camera) AllWorldObjectTypes; typedef TYPELIST_4(GameObject, Creature/*except pets*/, DynamicObject, Corpse/*Bones*/) AllGridObjectTypes; typedef TYPELIST_5(Creature, Pet, Vehicle, GameObject, DynamicObject) AllMapStoredObjectTypes; +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 30d977c40..da6aa90ea 100644 --- a/src/game/GridNotifiers.cpp +++ b/src/game/GridNotifiers.cpp @@ -28,32 +28,29 @@ using namespace MaNGOS; void -VisibleChangesNotifier::Visit(PlayerMapType &m) +VisibleChangesNotifier::Visit(CameraMapType &m) { - for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) + for(CameraMapType::iterator iter=m.begin(); iter != m.end(); ++iter) { - Player* player = iter->getSource(); - if(player == &i_object) - continue; - - player->UpdateVisibilityOf(player->GetViewPoint(),&i_object); + 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()) + if(Transport* transport = player.GetTransport()) { for(Transport::PlayerSet::const_iterator itr = transport->GetPassengers().begin();itr!=transport->GetPassengers().end();++itr) { - if(i_clientGUIDs.find((*itr)->GetGUID())!=i_clientGUIDs.end()) + if (i_clientGUIDs.find((*itr)->GetGUID()) != i_clientGUIDs.end()) { // ignore far sight case - (*itr)->UpdateVisibilityOf((*itr),&i_player); - i_player.UpdateVisibilityOf(&i_player,(*itr),i_data,i_visibleNow); + (*itr)->UpdateVisibilityOf(*itr, &player); + player.UpdateVisibilityOf(&player, *itr, i_data, i_visibleNow); i_clientGUIDs.erase((*itr)->GetGUID()); } } @@ -63,27 +60,28 @@ VisibleNotifier::Notify() i_data.AddOutOfRangeGUID(i_clientGUIDs); for(ObjectGuidSet::iterator itr = i_clientGUIDs.begin();itr!=i_clientGUIDs.end();++itr) { - i_player.m_clientGUIDs.erase(*itr); + player.m_clientGUIDs.erase(*itr); - DEBUG_FILTER_LOG(LOG_FILTER_VISIBILITY_CHANGES, "%s is out of range (no in active cells set) now for player %u",itr->GetString().c_str(),i_player.GetGUIDLow()); + DEBUG_FILTER_LOG(LOG_FILTER_VISIBILITY_CHANGES, "%s is out of range (no in active cells set) now for %s", + itr->GetString().c_str(), player.GetObjectGuid().GetString().c_str()); } - if( i_data.HasData() ) + if (i_data.HasData()) { // send create/outofrange packet to player (except player create updates that already sent using SendUpdateToPlayer) WorldPacket packet; i_data.BuildPacket(&packet); - i_player.GetSession()->SendPacket(&packet); + player.GetSession()->SendPacket(&packet); // send out of range to other players if need ObjectGuidSet const& oor = i_data.GetOutOfRangeGUIDs(); for(ObjectGuidSet::const_iterator iter = oor.begin(); iter != oor.end(); ++iter) { - if(!iter->IsPlayer()) + if (!iter->IsPlayer()) continue; if (Player* plr = ObjectAccessor::FindPlayer(*iter)) - plr->UpdateVisibilityOf(plr->GetViewPoint(),&i_player); + plr->UpdateVisibilityOf(plr->GetCamera().GetBody(), &player); } } @@ -93,87 +91,92 @@ VisibleNotifier::Notify() for(std::set::const_iterator vItr = i_visibleNow.begin(); vItr != i_visibleNow.end(); ++vItr) { // target aura duration for caster show only if target exist at caster client - if((*vItr)!=&i_player && (*vItr)->isType(TYPEMASK_UNIT)) - i_player.SendAurasForTarget((Unit*)(*vItr)); + if ((*vItr) != &player && (*vItr)->isType(TYPEMASK_UNIT)) + player.SendAurasForTarget((Unit*)(*vItr)); // non finished movements show to player - if((*vItr)->GetTypeId()==TYPEID_UNIT && ((Creature*)(*vItr))->isAlive()) - ((Creature*)(*vItr))->SendMonsterMoveWithSpeedToCurrentDestination(&i_player); + if ((*vItr)->GetTypeId()==TYPEID_UNIT && ((Creature*)(*vItr))->isAlive()) + ((Creature*)(*vItr))->SendMonsterMoveWithSpeedToCurrentDestination(&player); } } void -MessageDeliverer::Visit(PlayerMapType &m) +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_toSelf || iter->getSource() != &i_player) + Player* owner = iter->getSource()->GetOwner(); + + if (i_toSelf || owner != &i_player) { - if (!i_player.InSamePhase(iter->getSource())) + if (!i_player.InSamePhase(iter->getSource()->GetBody())) continue; - if(WorldSession* session = iter->getSource()->GetSession()) + if (WorldSession* session = owner->GetSession()) session->SendPacket(i_message); } } } -void MessageDelivererExcept::Visit(PlayerMapType &m) +void MessageDelivererExcept::Visit(CameraMapType &m) { - for(PlayerMapType::iterator it = m.begin(); it!= m.end(); ++it) + for(CameraMapType::iterator iter = m.begin(); iter != m.end(); ++iter) { - Player* player = it->getSource(); - if(!player->InSamePhase(i_phaseMask) || player == i_skipped_receiver) + Player* owner = iter->getSource()->GetOwner(); + + if (!owner->InSamePhase(i_phaseMask) || owner == i_skipped_receiver) continue; - if (WorldSession* session = player->GetSession()) + if (WorldSession* session = owner->GetSession()) session->SendPacket(i_message); } } void -ObjectMessageDeliverer::Visit(PlayerMapType &m) +ObjectMessageDeliverer::Visit(CameraMapType &m) { - for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) + for(CameraMapType::iterator iter = m.begin(); iter != m.end(); ++iter) { - if(!iter->getSource()->InSamePhase(i_phaseMask)) + if(!iter->getSource()->GetBody()->InSamePhase(i_phaseMask)) continue; - if(WorldSession* session = iter->getSource()->GetSession()) + if(WorldSession* session = iter->getSource()->GetOwner()->GetSession()) session->SendPacket(i_message); } } void -MessageDistDeliverer::Visit(PlayerMapType &m) +MessageDistDeliverer::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_toSelf || iter->getSource() != &i_player ) && - (!i_ownTeamOnly || iter->getSource()->GetTeam() == i_player.GetTeam() ) && - (!i_dist || iter->getSource()->IsWithinDist(&i_player,i_dist))) + 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 (!i_player.InSamePhase(iter->getSource())) + if (!i_player.InSamePhase(iter->getSource()->GetBody())) continue; - if (WorldSession* session = iter->getSource()->GetSession()) + if (WorldSession* session = owner->GetSession()) session->SendPacket(i_message); } } } void -ObjectMessageDistDeliverer::Visit(PlayerMapType &m) +ObjectMessageDistDeliverer::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()->IsWithinDist(&i_object,i_dist)) + if (!i_dist || iter->getSource()->GetBody()->IsWithinDist(&i_object,i_dist)) { - if (!i_object.InSamePhase(iter->getSource())) + if (!i_object.InSamePhase(iter->getSource()->GetBody())) continue; - if (WorldSession* session = iter->getSource()->GetSession()) + if (WorldSession* session = iter->getSource()->GetOwner()->GetSession()) session->SendPacket(i_message); } } diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h index cd7614352..d2449085f 100644 --- a/src/game/GridNotifiers.h +++ b/src/game/GridNotifiers.h @@ -38,13 +38,14 @@ namespace MaNGOS { struct MANGOS_DLL_DECL VisibleNotifier { - Player &i_player; + Camera& i_camera; UpdateData i_data; ObjectGuidSet i_clientGUIDs; std::set i_visibleNow; - explicit VisibleNotifier(Player &player) : i_player(player),i_clientGUIDs(player.m_clientGUIDs) {} + explicit VisibleNotifier(Camera &c) : i_camera(c), i_clientGUIDs(c.GetOwner()->m_clientGUIDs) {} template void Visit(GridRefManager &m); + void Visit(CameraMapType &m) {} void Notify(void); }; @@ -54,7 +55,7 @@ namespace MaNGOS explicit VisibleChangesNotifier(WorldObject &object) : i_object(object) {} template void Visit(GridRefManager &) {} - void Visit(PlayerMapType &); + void Visit(CameraMapType &); }; struct MANGOS_DLL_DECL GridUpdater @@ -82,7 +83,7 @@ namespace MaNGOS WorldPacket *i_message; bool i_toSelf; MessageDeliverer(Player &pl, WorldPacket *msg, bool to_self) : i_player(pl), i_message(msg), i_toSelf(to_self) {} - void Visit(PlayerMapType &m); + void Visit(CameraMapType &m); template void Visit(GridRefManager &) {} }; @@ -95,7 +96,7 @@ namespace MaNGOS MessageDelivererExcept(WorldObject const* obj, WorldPacket *msg, Player const* skipped) : i_phaseMask(obj->GetPhaseMask()), i_message(msg), i_skipped_receiver(skipped) {} - void Visit(PlayerMapType &m); + void Visit(CameraMapType &m); template void Visit(GridRefManager &) {} }; @@ -105,7 +106,7 @@ namespace MaNGOS WorldPacket *i_message; explicit ObjectMessageDeliverer(WorldObject& obj, WorldPacket *msg) : i_phaseMask(obj.GetPhaseMask()), i_message(msg) {} - void Visit(PlayerMapType &m); + void Visit(CameraMapType &m); template void Visit(GridRefManager &) {} }; @@ -119,7 +120,7 @@ namespace MaNGOS 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(PlayerMapType &m); + void Visit(CameraMapType &m); template void Visit(GridRefManager &) {} }; @@ -129,7 +130,7 @@ namespace MaNGOS WorldPacket *i_message; float i_dist; ObjectMessageDistDeliverer(WorldObject &obj, WorldPacket *msg, float dist) : i_object(obj), i_message(msg), i_dist(dist) {} - void Visit(PlayerMapType &m); + void Visit(CameraMapType &m); template void Visit(GridRefManager &) {} }; @@ -140,6 +141,7 @@ namespace MaNGOS template void Visit(GridRefManager &m); void Visit(PlayerMapType &) {} void Visit(CorpseMapType &) {} + void Visit(CameraMapType &) {} void Visit(CreatureMapType &); }; @@ -476,22 +478,21 @@ namespace MaNGOS }; template - struct MANGOS_DLL_DECL PlayerDistWorker + struct MANGOS_DLL_DECL CameraDistWorker { WorldObject const* i_searcher; float i_dist; Do& i_do; - PlayerDistWorker(WorldObject const* searcher, float _dist, Do& _do) + CameraDistWorker(WorldObject const* searcher, float _dist, Do& _do) : i_searcher(searcher), i_dist(_dist), i_do(_do) {} - void Visit(PlayerMapType &m) + void Visit(CameraMapType &m) { - for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if (itr->getSource()->InSamePhase(i_searcher) && itr->getSource()->IsWithinDist(i_searcher,i_dist)) - i_do(itr->getSource()); + for(CameraMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + if (itr->getSource()->GetBody()->InSamePhase(i_searcher) && itr->getSource()->GetBody()->IsWithinDist(i_searcher,i_dist)) + i_do(itr->getSource()->GetOwner()); } - template void Visit(GridRefManager &) {} }; diff --git a/src/game/GridNotifiersImpl.h b/src/game/GridNotifiersImpl.h index 192d52f5d..c32073011 100644 --- a/src/game/GridNotifiersImpl.h +++ b/src/game/GridNotifiersImpl.h @@ -31,11 +31,9 @@ template inline void MaNGOS::VisibleNotifier::Visit(GridRefManager &m) { - WorldObject const* viewPoint = i_player.GetViewPoint(); - for(typename GridRefManager::iterator iter = m.begin(); iter != m.end(); ++iter) { - i_player.UpdateVisibilityOf(viewPoint,iter->getSource(), i_data, i_visibleNow); + i_camera.UpdateVisibilityOf(iter->getSource(), i_data, i_visibleNow); i_clientGUIDs.erase(iter->getSource()->GetGUID()); } } @@ -96,7 +94,7 @@ inline void MaNGOS::PlayerRelocationNotifier::Visit(CreatureMapType &m) if (!i_player.isAlive() || i_player.isInFlight()) return; - WorldObject const* viewPoint = i_player.GetViewPoint(); + WorldObject const* viewPoint = i_player.GetCamera().GetBody(); for(CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter) if (iter->getSource()->isAlive()) @@ -106,13 +104,13 @@ inline void MaNGOS::PlayerRelocationNotifier::Visit(CreatureMapType &m) template<> inline void MaNGOS::CreatureRelocationNotifier::Visit(PlayerMapType &m) { - if(!i_creature.isAlive()) + if (!i_creature.isAlive()) return; for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) if (Player* player = iter->getSource()) if (player->isAlive() && !player->isInFlight()) - PlayerCreatureRelocationWorker(player, player->GetViewPoint(), &i_creature); + PlayerCreatureRelocationWorker(player, player->GetCamera().GetBody(), &i_creature); } template<> diff --git a/src/game/Makefile.am b/src/game/Makefile.am index f4ef7892f..575b4c04b 100644 --- a/src/game/Makefile.am +++ b/src/game/Makefile.am @@ -76,6 +76,8 @@ libmangosgame_a_SOURCES = \ Calendar.cpp \ Calendar.h \ CalendarHandler.cpp \ + Camera.cpp \ + Camera.h \ Cell.h \ CellImpl.h \ Channel.cpp \ diff --git a/src/game/Map.cpp b/src/game/Map.cpp index bca4cca36..83718c71b 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -367,8 +367,9 @@ bool Map::Add(Player *player) SendInitSelf(player); SendInitTransports(player); + NGridType* grid = getNGrid(cell.GridX(), cell.GridY()); + player->GetViewPoint().Event_AddedToWorld(&(*grid)(cell.CellX(), cell.CellY())); UpdateObjectVisibility(player,cell,p); - UpdateObjectsVisibilityFor(player,cell,p); AddNotifier(player,cell,p); return true; @@ -406,6 +407,7 @@ Map::Add(T *obj) DEBUG_LOG("Object %u enters grid[%u,%u]", GUID_LOPART(obj->GetGUID()), cell.GridX(), cell.GridY()); + obj->GetViewPoint().Event_AddedToWorld(&(*grid)(cell.CellX(), cell.CellY())); UpdateObjectVisibility(obj,cell,p); AddNotifier(obj,cell,p); @@ -682,7 +684,6 @@ void Map::Remove(Player *player, bool remove) SendRemoveTransports(player); UpdateObjectVisibility(player,cell,p); - UpdateObjectsVisibilityFor(player,cell,p); player->ResetMap(); if( remove ) @@ -716,10 +717,9 @@ Map::Remove(T *obj, bool remove) else obj->RemoveFromWorld(); + 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); - UpdateObjectVisibility(obj,cell,p); - obj->ResetMap(); if( remove ) { @@ -759,10 +759,13 @@ Map::PlayerRelocation(Player *player, float x, float y, float z, float orientati AddToGrid(player, oldGrid,new_cell); else EnsureGridLoadedAtEnter(new_cell, player); + + NGridType* newGrid = getNGrid(new_cell.GridX(), new_cell.GridY()); + player->GetViewPoint().Event_GridChanged(&(*newGrid)(new_cell.CellX(),new_cell.CellY())); } + player->GetViewPoint().Call_UpdateVisibilityForOwner(); // if move then update what player see and who seen - UpdateObjectsVisibilityFor(player,new_cell,new_val); UpdateObjectVisibility(player, new_cell, new_val); PlayerRelocationNotify(player,new_cell,new_val); @@ -816,6 +819,7 @@ Map::CreatureRelocation(Creature *creature, float x, float y, float z, float ang creature->SetNeedNotify(); } + creature->GetViewPoint().Call_UpdateVisibilityForOwner(); ASSERT(CheckGridIntegrity(creature,true)); } @@ -829,12 +833,12 @@ bool Map::CreatureCellRelocation(Creature *c, Cell new_cell) { DEBUG_FILTER_LOG(LOG_FILTER_CREATURE_MOVES, "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()); - if( !old_cell.DiffGrid(new_cell) ) - { - RemoveFromGrid(c,getNGrid(old_cell.GridX(), old_cell.GridY()),old_cell); - AddToGrid(c,getNGrid(new_cell.GridX(), new_cell.GridY()),new_cell); - c->SetCurrentCell(new_cell); - } + RemoveFromGrid(c,getNGrid(old_cell.GridX(), old_cell.GridY()),old_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 { @@ -852,7 +856,10 @@ bool Map::CreatureCellRelocation(Creature *c, Cell new_cell) DEBUG_FILTER_LOG(LOG_FILTER_CREATURE_MOVES, "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; } @@ -865,7 +872,9 @@ bool Map::CreatureCellRelocation(Creature *c, Cell new_cell) 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); + 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; @@ -1420,21 +1429,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 ) -{ - MaNGOS::VisibleNotifier notifier(*player); - - cell.data.Part.reserved = ALL_DISTRICT; - //cell.SetNoCreate(); need trigger cell loading around the player - 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.Notify(); -} - void Map::PlayerRelocationNotify( Player* player, Cell cell, CellPair cellpair ) { MaNGOS::PlayerRelocationNotifier relocationNotifier(*player); diff --git a/src/game/Map.h b/src/game/Map.h index 5193d2c7b..8ba96e803 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -84,6 +84,8 @@ enum LevelRequirementVsMode class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::ObjectLevelLockable { friend class MapReference; + friend class ObjectGridLoader; + friend class ObjectWorldLoader; public: Map(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode, Map* _parent = NULL); virtual ~Map(); @@ -211,7 +213,6 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj void AddObjectToRemoveList(WorldObject *obj); void UpdateObjectVisibility(WorldObject* obj, Cell cell, CellPair cellpair); - void UpdateObjectsVisibilityFor(Player* player, Cell cell, CellPair cellpair); void resetMarkedCells() { marked_cells.reset(); } bool isCellMarked(uint32 pCellId) { return marked_cells.test(pCellId); } diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp index 95a869d88..749b5161b 100644 --- a/src/game/NPCHandler.cpp +++ b/src/game/NPCHandler.cpp @@ -397,11 +397,17 @@ void WorldSession::SendSpiritResurrect() _player->TeleportTo(corpseGrave->map_id, corpseGrave->x, corpseGrave->y, corpseGrave->z, _player->GetOrientation()); // or update at original position else - _player->UpdateVisibilityForPlayer(); + { + _player->GetCamera().UpdateVisibilityForOwner(); + _player->UpdateObjectVisibility(); + } } // or update at original position else - _player->UpdateVisibilityForPlayer(); + { + _player->GetCamera().UpdateVisibilityForOwner(); + _player->UpdateObjectVisibility(); + } } void WorldSession::HandleBinderActivateOpcode( WorldPacket & recv_data ) diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 55fc2d08a..c78a2e397 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1496,7 +1496,7 @@ void WorldObject::MonsterSay(int32 textId, uint32 language, uint64 TargetGuid) { MaNGOS::MonsterChatBuilder say_build(*this, CHAT_MSG_MONSTER_SAY, textId,language,TargetGuid); MaNGOS::LocalizedPacketDo say_do(say_build); - MaNGOS::PlayerDistWorker > say_worker(this,sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_SAY),say_do); + MaNGOS::CameraDistWorker > say_worker(this,sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_SAY),say_do); Cell::VisitWorldObjects(this, say_worker, sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_SAY)); } @@ -1507,7 +1507,7 @@ void WorldObject::MonsterYell(int32 textId, uint32 language, uint64 TargetGuid) MaNGOS::MonsterChatBuilder say_build(*this, CHAT_MSG_MONSTER_YELL, textId,language,TargetGuid); MaNGOS::LocalizedPacketDo say_do(say_build); - MaNGOS::PlayerDistWorker > say_worker(this,range,say_do); + MaNGOS::CameraDistWorker > say_worker(this,range,say_do); Cell::VisitWorldObjects(this, say_worker, sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_YELL)); } @@ -1530,7 +1530,7 @@ void WorldObject::MonsterTextEmote(int32 textId, uint64 TargetGuid, bool IsBossE MaNGOS::MonsterChatBuilder say_build(*this, IsBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, textId,LANG_UNIVERSAL,TargetGuid); MaNGOS::LocalizedPacketDo say_do(say_build); - MaNGOS::PlayerDistWorker > say_worker(this,range,say_do); + MaNGOS::CameraDistWorker > say_worker(this,range,say_do); Cell::VisitWorldObjects(this, say_worker, range); } @@ -1864,7 +1864,10 @@ void WorldObject::SetPhaseMask(uint32 newPhaseMask, bool update) m_phaseMask = newPhaseMask; if(update && IsInWorld()) + { UpdateObjectVisibility(); + GetViewPoint().Event_ViewPointVisibilityChanged(); + } } void WorldObject::PlayDistanceSound( uint32 sound_id, Player* target /*= NULL*/ ) @@ -1910,12 +1913,22 @@ struct WorldObjectChangeAccumulator { UpdateDataMapType &i_updateDatas; WorldObject &i_object; - WorldObjectChangeAccumulator(WorldObject &obj, UpdateDataMapType &d) : i_updateDatas(d), i_object(obj) {} - void Visit(PlayerMapType &m) + WorldObjectChangeAccumulator(WorldObject &obj, UpdateDataMapType &d) : i_updateDatas(d), i_object(obj) { - for(PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter) - if(iter->getSource()->HaveAtClient(&i_object)) - i_object.BuildUpdateDataForPlayer(iter->getSource(), i_updateDatas); + // send self fields changes in another way, otherwise + // with new camera system when player's camera too far from player, camera wouldn't receive packets and changes from player + if(i_object.isType(TYPEMASK_PLAYER)) + i_object.BuildUpdateDataForPlayer((Player*)&i_object, i_updateDatas); + } + + void Visit(CameraMapType &m) + { + for(CameraMapType::iterator iter = m.begin(); iter != m.end(); ++iter) + { + Player* owner = iter->getSource()->GetOwner(); + if(owner != &i_object && owner->HaveAtClient(&i_object)) + i_object.BuildUpdateDataForPlayer(owner, i_updateDatas); + } } template void Visit(GridRefManager &) {} diff --git a/src/game/Object.h b/src/game/Object.h index 04c31f0f5..c214a9dd4 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -23,8 +23,8 @@ #include "ByteBuffer.h" #include "UpdateFields.h" #include "UpdateData.h" -#include "GameSystem/GridReference.h" #include "ObjectGuid.h" +#include "Camera.h" #include #include @@ -476,6 +476,8 @@ class MANGOS_DLL_SPEC WorldObject : public Object void BuildUpdateData(UpdateDataMapType &); Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime); + + ViewPoint& GetViewPoint() { return m_viewPoint; } protected: explicit WorldObject(); @@ -498,6 +500,8 @@ class MANGOS_DLL_SPEC WorldObject : public Object float m_positionY; float m_positionZ; float m_orientation; + + ViewPoint m_viewPoint; }; #endif diff --git a/src/game/ObjectGridLoader.cpp b/src/game/ObjectGridLoader.cpp index 415c7ac6f..8df5d4632 100644 --- a/src/game/ObjectGridLoader.cpp +++ b/src/game/ObjectGridLoader.cpp @@ -25,6 +25,7 @@ #include "Corpse.h" #include "World.h" #include "CellImpl.h" +#include "GridDefines.h" class MANGOS_DLL_DECL ObjectGridRespawnMover { @@ -105,7 +106,7 @@ template<> void addUnitState(Creature *obj, CellPair const& cell_pair) } template -void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager &m, uint32 &count, Map* map) +void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager &m, uint32 &count, Map* map, GridType& grid) { BattleGround* bg = map->IsBattleGroundOrArena() ? ((BattleGroundMap*)map)->GetBG() : NULL; @@ -121,13 +122,16 @@ void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager & continue; } - obj->GetGridRef().link(&m, obj); + grid.AddGridObject(obj); addUnitState(obj,cell); obj->SetMap(map); obj->AddToWorld(); if(obj->isActiveObject()) map->AddToActive(obj); + + obj->GetViewPoint().Event_AddedToWorld(&grid); + if (bg) bg->OnObjectDBLoad(obj); @@ -135,7 +139,7 @@ void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager & } } -void LoadHelper(CellCorpseSet const& cell_corpses, CellPair &cell, CorpseMapType &m, uint32 &count, Map* map) +void LoadHelper(CellCorpseSet const& cell_corpses, CellPair &cell, CorpseMapType &m, uint32 &count, Map* map, GridType& grid) { if(cell_corpses.empty()) return; @@ -151,7 +155,7 @@ void LoadHelper(CellCorpseSet const& cell_corpses, CellPair &cell, CorpseMapType if(!obj) continue; - obj->GetGridRef().link(&m, obj); + grid.AddWorldObject(obj); addUnitState(obj,cell); obj->SetMap(map); @@ -173,7 +177,8 @@ ObjectGridLoader::Visit(GameObjectMapType &m) CellObjectGuids const& cell_guids = sObjectMgr.GetCellObjectGuids(i_map->GetId(), i_map->GetSpawnMode(), cell_id); - LoadHelper(cell_guids.gameobjects, cell_pair, m, i_gameObjects, i_map); + GridType& grid = (*i_map->getNGrid(i_cell.GridX(),i_cell.GridY())) (i_cell.CellX(),i_cell.CellY()); + LoadHelper(cell_guids.gameobjects, cell_pair, m, i_gameObjects, i_map, grid); } void @@ -186,7 +191,8 @@ ObjectGridLoader::Visit(CreatureMapType &m) CellObjectGuids const& cell_guids = sObjectMgr.GetCellObjectGuids(i_map->GetId(), i_map->GetSpawnMode(), cell_id); - LoadHelper(cell_guids.creatures, cell_pair, m, i_creatures, i_map); + GridType& grid = (*i_map->getNGrid(i_cell.GridX(),i_cell.GridY())) (i_cell.CellX(),i_cell.CellY()); + LoadHelper(cell_guids.creatures, cell_pair, m, i_creatures, i_map, grid); } void @@ -199,7 +205,8 @@ ObjectWorldLoader::Visit(CorpseMapType &m) // corpses are always added to spawn mode 0 and they are spawned by their instance id CellObjectGuids const& cell_guids = sObjectMgr.GetCellObjectGuids(i_map->GetId(), 0, cell_id); - LoadHelper(cell_guids.corpses, cell_pair, m, i_corpses, i_map); + GridType& grid = (*i_map->getNGrid(i_cell.GridX(),i_cell.GridY())) (i_cell.CellX(),i_cell.CellY()); + LoadHelper(cell_guids.corpses, cell_pair, m, i_corpses, i_map, grid); } void diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 53706be37..39827a33a 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -405,7 +405,7 @@ void TradeData::SetAccepted(bool state, bool crosssend /*= false*/) UpdateMask Player::updateVisualBits; -Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputationMgr(this) +Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputationMgr(this), m_camera(this) { m_transport = 0; @@ -2409,7 +2409,8 @@ void Player::SetGameMaster(bool on) getHostileRefManager().setOnlineOfflineState(true); } - UpdateVisibilityForPlayer(); + m_camera.UpdateVisibilityForOwner(); + UpdateObjectVisibility(); } void Player::SetGMVisible(bool on) @@ -4490,8 +4491,10 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness) GetZoneAndAreaId(newzone,newarea); UpdateZone(newzone,newarea); - // update visibility - UpdateVisibilityForPlayer(); + // update visibility of world around viewpoint + m_camera.UpdateVisibilityForOwner(); + // update visibility of player for nearby cameras + UpdateObjectVisibility(); if(!applySickness) return; @@ -6073,42 +6076,30 @@ void Player::SaveRecallPosition() void Player::SendMessageToSet(WorldPacket *data, bool self) { - Map * _map = IsInWorld() ? GetMap() : sMapMgr.FindMap(GetMapId(), GetInstanceId()); - if(_map) - { - _map->MessageBroadcast(this, data, self); - return; - } + if (Map * _map = IsInWorld() ? GetMap() : sMapMgr.FindMap(GetMapId(), GetInstanceId())) + _map->MessageBroadcast(this, data, false); //if player is not in world and map in not created/already destroyed //no need to create one, just send packet for itself! - if(self) + if (self) GetSession()->SendPacket(data); } void Player::SendMessageToSetInRange(WorldPacket *data, float dist, bool self) { - Map * _map = IsInWorld() ? GetMap() : sMapMgr.FindMap(GetMapId(), GetInstanceId()); - if(_map) - { - _map->MessageDistBroadcast(this, data, dist, self); - return; - } + if (Map * _map = IsInWorld() ? GetMap() : sMapMgr.FindMap(GetMapId(), GetInstanceId())) + _map->MessageDistBroadcast(this, data, dist, false); - if(self) + if (self) GetSession()->SendPacket(data); } void Player::SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool own_team_only) { - Map * _map = IsInWorld() ? GetMap() : sMapMgr.FindMap(GetMapId(), GetInstanceId()); - if(_map) - { - _map->MessageDistBroadcast(this, data, dist, self, own_team_only); - return; - } + if (Map * _map = IsInWorld() ? GetMap() : sMapMgr.FindMap(GetMapId(), GetInstanceId())) + _map->MessageDistBroadcast(this, data, dist, false, own_team_only); - if(self) + if (self) GetSession()->SendPacket(data); } @@ -15322,7 +15313,8 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) SetCreatorGUID(0); // reset some aura modifiers before aura apply - SetFarSightGUID(0); + + SetUInt64Value(PLAYER_FARSIGHT, 0); SetUInt32Value(PLAYER_TRACK_CREATURES, 0 ); SetUInt32Value(PLAYER_TRACK_RESOURCES, 0 ); @@ -18058,7 +18050,7 @@ void Player::HandleStealthedUnitsDetection() MaNGOS::UnitListSearcher searcher(this,stealthedUnits, u_check); Cell::VisitAllObjects(this, searcher, MAX_PLAYER_STEALTH_DETECT_RANGE); - WorldObject const* viewPoint = GetViewPoint(); + WorldObject const* viewPoint = GetCamera().GetBody(); for (std::list::const_iterator i = stealthedUnits.begin(); i != stealthedUnits.end(); ++i) { @@ -19154,17 +19146,6 @@ void Player::ReportedAfkBy(Player* reporter) } } -WorldObject const* Player::GetViewPoint() const -{ - if(uint64 far_sight = GetFarSight()) - { - WorldObject const* viewPoint = GetMap()->GetWorldObject(far_sight); - return viewPoint ? viewPoint : this; // always expected not NULL - } - else - return this; -} - bool Player::IsVisibleInGridForPlayer( Player* pl ) const { // gamemaster in GM mode see all, including ghosts @@ -20736,7 +20717,7 @@ void Player::EnterVehicle(Vehicle *vehicle) vehicle->setFaction(getFaction()); SetCharm(vehicle); // charm - SetFarSightGUID(vehicle->GetGUID()); // set view + m_camera.SetView(vehicle); // set view SetClientControl(vehicle, 1); // redirect controls to vehicle SetMover(vehicle); @@ -20788,7 +20769,7 @@ void Player::ExitVehicle(Vehicle *vehicle) vehicle->setFaction((GetTeam() == ALLIANCE) ? vehicle->GetCreatureInfo()->faction_A : vehicle->GetCreatureInfo()->faction_H); SetCharm(NULL); - SetFarSightGUID(0); + m_camera.ResetView(); SetClientControl(vehicle, 0); SetMover(NULL); @@ -22022,38 +22003,6 @@ bool Player::HasMovementFlag( MovementFlags f ) const return m_movementInfo.HasMovementFlag(f); } -void Player::SetFarSightGUID( uint64 guid ) -{ - if(GetFarSight() == guid) - return; - - SetUInt64Value(PLAYER_FARSIGHT, guid); - - // need triggering load grids around new view point - UpdateVisibilityForPlayer(); -} - -void Player::UpdateVisibilityForPlayer() -{ - WorldObject const* viewPoint = GetViewPoint(); - Map* m = GetMap(); - - CellPair p(MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY())); - Cell cell(p); - - m->UpdateObjectVisibility(this, cell, p); - - if (this != viewPoint) - { - CellPair pView(MaNGOS::ComputeCellPair(viewPoint->GetPositionX(), viewPoint->GetPositionY())); - Cell cellView(pView); - - m->UpdateObjectsVisibilityFor(this, cellView, pView); - } - else - m->UpdateObjectsVisibilityFor(this, cell, p); -} - void Player::ResetTimeSync() { m_timeSyncCounter = 0; diff --git a/src/game/Player.h b/src/game/Player.h index bdaa39991..544e7e18a 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1128,8 +1128,6 @@ class MANGOS_DLL_SPEC Player : public Unit Creature* GetNPCIfCanInteractWith(ObjectGuid guid, uint32 npcflagmask); GameObject* GetGameObjectIfCanInteractWith(ObjectGuid guid, uint32 gameobject_type = MAX_GAMEOBJECT_TYPE) const; - void UpdateVisibilityForPlayer(); - bool ToggleAFK(); bool ToggleDND(); bool isAFK() const { return HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK); } @@ -2250,7 +2248,6 @@ class MANGOS_DLL_SPEC Player : public Unit bool HaveAtClient(WorldObject const* u) { return u==this || m_clientGUIDs.find(u->GetGUID())!=m_clientGUIDs.end(); } - WorldObject const* GetViewPoint() const; bool IsVisibleInGridForPlayer(Player* pl) const; bool IsVisibleGloballyFor(Player* pl) const; @@ -2262,6 +2259,8 @@ class MANGOS_DLL_SPEC Player : public Unit // Stealth detection system void HandleStealthedUnitsDetection(); + Camera& GetCamera() { return m_camera; } + uint8 m_forced_speed_changes[MAX_MOVE_TYPE]; bool HasAtLoginFlag(AtLoginFlags f) const { return m_atLoginFlags & f; } @@ -2603,6 +2602,8 @@ class MANGOS_DLL_SPEC Player : public Unit m_DelayedOperations |= operation; } + Camera m_camera; + GridReference m_gridRef; MapReference m_mapRef; diff --git a/src/game/Spell.h b/src/game/Spell.h index cea75be8b..1ec5d7c14 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -808,6 +808,7 @@ namespace MaNGOS template<> inline void Visit(CorpseMapType & ) {} template<> inline void Visit(GameObjectMapType & ) {} template<> inline void Visit(DynamicObjectMapType & ) {} + template<> inline void Visit(CameraMapType & ) {} #endif }; @@ -815,6 +816,7 @@ namespace MaNGOS template<> inline void SpellNotifierCreatureAndPlayer::Visit(CorpseMapType& ) {} template<> inline void SpellNotifierCreatureAndPlayer::Visit(GameObjectMapType& ) {} template<> inline void SpellNotifierCreatureAndPlayer::Visit(DynamicObjectMapType& ) {} + template<> inline void SpellNotifierCreatureAndPlayer::Visit(CameraMapType& ) {} #endif } diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index f6badb486..c199196b9 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -2380,7 +2380,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real) (GetSpellProto()->EffectApplyAuraName[EFFECT_INDEX_0] == 1 || GetSpellProto()->EffectApplyAuraName[EFFECT_INDEX_0] == 128))) { // spells with SpellEffect=72 and aura=4: 6196, 6197, 21171, 21425 - ((Player*)target)->SetFarSightGUID(0); + ((Player*)target)->GetCamera().ResetView(); WorldPacket data(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, 0); ((Player*)target)->GetSession()->SendPacket(&data); return; @@ -3543,7 +3543,11 @@ void Aura::HandleBindSight(bool apply, bool /*Real*/) if(!caster || caster->GetTypeId() != TYPEID_PLAYER) return; - ((Player*)caster)->SetFarSightGUID(apply ? GetTarget()->GetGUID() : 0); + Camera& camera = ((Player*)caster)->GetCamera(); + if (apply) + camera.SetView(m_target); + else + camera.ResetView(); } void Aura::HandleFarSight(bool apply, bool /*Real*/) @@ -3552,7 +3556,11 @@ void Aura::HandleFarSight(bool apply, bool /*Real*/) if(!caster || caster->GetTypeId() != TYPEID_PLAYER) return; - ((Player*)caster)->SetFarSightGUID(apply ? GetTarget()->GetGUID() : 0); + Camera& camera = ((Player*)caster)->GetCamera(); + if (apply) + camera.SetView(GetTarget()); + else + camera.ResetView(); } void Aura::HandleAuraTrackCreatures(bool apply, bool /*Real*/) @@ -3607,7 +3615,7 @@ void Aura::HandleModPossess(bool apply, bool Real) return; Player* p_caster = (Player*)caster; - + Camera& camera = p_caster->GetCamera(); if( apply ) { @@ -3618,7 +3626,7 @@ void Aura::HandleModPossess(bool apply, bool Real) p_caster->SetCharm(target); - p_caster->SetFarSightGUID(target->GetGUID()); + camera.SetView(target); p_caster->SetClientControl(target, 1); p_caster->SetMover(target); @@ -3646,7 +3654,7 @@ void Aura::HandleModPossess(bool apply, bool Real) p_caster->InterruptSpell(CURRENT_CHANNELED_SPELL); // the spell is not automatically canceled when interrupted, do it now p_caster->SetCharm(NULL); - p_caster->SetFarSightGUID(0); + camera.ResetView(); p_caster->SetClientControl(target, 0); p_caster->SetMover(NULL); @@ -3695,13 +3703,19 @@ void Aura::HandleModPossessPet(bool apply, bool Real) return; Player* p_caster = (Player*)caster; + Camera& camera = p_caster->GetCamera(); if(apply) + { pet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); + camera.SetView(pet); + } else + { pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); + camera.ResetView(); + } - p_caster->SetFarSightGUID(apply ? pet->GetGUID() : 0); p_caster->SetCharm(apply ? pet : NULL); p_caster->SetClientControl(pet, apply ? 1 : 0); ((Player*)caster)->SetMover(apply ? pet : NULL); @@ -4182,7 +4196,7 @@ void Aura::HandleInvisibilityDetect(bool apply, bool Real) target->m_detectInvisibilityMask |= (1 << m_modifier.m_miscvalue); } if(Real && target->GetTypeId()==TYPEID_PLAYER) - ((Player*)target)->UpdateVisibilityForPlayer(); + ((Player*)target)->GetCamera().UpdateVisibilityForOwner(); } void Aura::HandleAuraModRoot(bool apply, bool Real) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index f0c6fcf44..d8f6aac3a 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -4244,7 +4244,8 @@ void Spell::EffectAddFarsight(SpellEffectIndex eff_idx) dynObj->SetUInt32Value(DYNAMICOBJECT_BYTES, 0x80000002); m_caster->AddDynObject(dynObj); m_caster->GetMap()->Add(dynObj); - ((Player*)m_caster)->SetFarSightGUID(dynObj->GetGUID()); + + ((Player*)m_caster)->GetCamera().SetView(dynObj); } void Spell::DoSummonWild(SpellEffectIndex eff_idx, uint32 forceFaction) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index ae03a34e5..f6a2c5a03 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -10579,10 +10579,6 @@ bool Unit::isVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, boo return false; } - // always seen by far sight caster - if (u->GetTypeId()==TYPEID_PLAYER && ((Player*)u)->GetFarSight()==GetGUID()) - return true; - // different visible distance checks if (u->isInFlight()) // what see player in flight { @@ -10781,12 +10777,41 @@ void Unit::SetVisibility(UnitVisibility x) if(IsInWorld()) { + // some auras requires visible target + if(m_Visibility == VISIBILITY_GROUP_NO_DETECT || m_Visibility == VISIBILITY_OFF) + { + static const AuraType auratypes[] = {SPELL_AURA_BIND_SIGHT, SPELL_AURA_FAR_SIGHT, SPELL_AURA_NONE}; + for (AuraType const* type = &auratypes[0]; *type != SPELL_AURA_NONE; ++type) + { + AuraList& alist = m_modAuras[*type]; + if(alist.empty()) + continue; + + for (AuraList::iterator it = alist.begin(); it != alist.end();) + { + Aura* aura = (*it); + Unit* owner = aura->GetCaster(); + + if (!owner || !isVisibleForOrDetect(owner,this,false)) + { + alist.erase(it); + RemoveAura(aura); + it = alist.begin(); + } + else + ++it; + } + } + } + Map *m = GetMap(); if(GetTypeId()==TYPEID_PLAYER) m->PlayerRelocation((Player*)this,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation()); else m->CreatureRelocation((Creature*)this,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation()); + + GetViewPoint().Event_ViewPointVisibilityChanged(); } } @@ -12039,6 +12064,7 @@ void Unit::RemoveFromWorld() RemoveAllGameObjects(); RemoveAllDynObjects(); CleanupDeletedAuras(); + GetViewPoint().Event_RemovedFromWorld(); } Object::RemoveFromWorld(); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 5c22b2fa3..926d2dd1d 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10051" + #define REVISION_NR "10052" #endif // __REVISION_NR_H__ diff --git a/win/VC100/game.vcxproj b/win/VC100/game.vcxproj index 575fef41e..44858d500 100644 --- a/win/VC100/game.vcxproj +++ b/win/VC100/game.vcxproj @@ -370,6 +370,7 @@ + @@ -517,6 +518,7 @@ + diff --git a/win/VC100/game.vcxproj.filters b/win/VC100/game.vcxproj.filters index 44940f527..804e66778 100644 --- a/win/VC100/game.vcxproj.filters +++ b/win/VC100/game.vcxproj.filters @@ -442,6 +442,9 @@ Tool + + Object + @@ -832,5 +835,8 @@ Tool + + Object + \ No newline at end of file diff --git a/win/VC80/game.vcproj b/win/VC80/game.vcproj index 409c26ffa..8f1c431a6 100644 --- a/win/VC80/game.vcproj +++ b/win/VC80/game.vcproj @@ -669,6 +669,14 @@ RelativePath="..\..\src\game\CalendarHandler.cpp" > + + + + diff --git a/win/VC90/game.vcproj b/win/VC90/game.vcproj index b8d61586e..1eb6872bc 100644 --- a/win/VC90/game.vcproj +++ b/win/VC90/game.vcproj @@ -1162,6 +1162,14 @@ RelativePath="..\..\src\game\Calendar.h" > + + + + From b4b45333d8fcd8d7f6d01259a59d606c7b68214a Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 14 Jun 2010 08:26:21 +0400 Subject: [PATCH 02/42] [10053] Use UNIT_STAT_CONTROLED for mark unit state under direct player control. * This allow prevent move home/to caster at apply * Also replace AI and reset movegens at control time * Also stop combat and clear threat/hostile list at lost control for prevent combat with freindly units. --- src/game/CreatureAI.cpp | 2 +- src/game/CreatureEventAI.cpp | 2 +- src/game/GridNotifiersImpl.h | 6 +++--- src/game/MotionMaster.cpp | 8 ++++++-- src/game/Player.cpp | 4 ++-- src/game/SpellAuras.cpp | 35 ++++++++++++++++++++++++++--------- src/game/Unit.cpp | 2 +- src/game/Unit.h | 31 +++++++++++++++++++------------ src/shared/revision_nr.h | 2 +- 9 files changed, 60 insertions(+), 32 deletions(-) diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp index b650b65fb..33cb56877 100644 --- a/src/game/CreatureAI.cpp +++ b/src/game/CreatureAI.cpp @@ -36,7 +36,7 @@ CanCastResult CreatureAI::CanCastSpell(Unit* pTarget, const SpellEntry *pSpell, if (!isTriggered) { // State does not allow - if (m_creature->hasUnitState(UNIT_STAT_CAN_NOT_REACT)) + if (m_creature->hasUnitState(UNIT_STAT_CAN_NOT_REACT_OR_LOST_CONTROL)) return CAST_FAIL_STATE; if (pSpell->PreventionType == SPELL_PREVENTION_TYPE_SILENCE && m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED)) diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp index bbb12c602..c79611c31 100644 --- a/src/game/CreatureEventAI.cpp +++ b/src/game/CreatureEventAI.cpp @@ -1319,7 +1319,7 @@ bool CreatureEventAI::CanCast(Unit* Target, SpellEntry const *Spell, bool Trigge return false; //Silenced so we can't cast - if (!Triggered && (m_creature->hasUnitState(UNIT_STAT_CAN_NOT_REACT) || + if (!Triggered && (m_creature->hasUnitState(UNIT_STAT_CAN_NOT_REACT_OR_LOST_CONTROL) || m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED))) return false; diff --git a/src/game/GridNotifiersImpl.h b/src/game/GridNotifiersImpl.h index c32073011..b1cda7ecf 100644 --- a/src/game/GridNotifiersImpl.h +++ b/src/game/GridNotifiersImpl.h @@ -67,7 +67,7 @@ inline void PlayerCreatureRelocationWorker(Player* pl, WorldObject const* viewPo pl->UpdateVisibilityOf(viewPoint,c); // Creature AI reaction - if (!c->hasUnitState(UNIT_STAT_FLEEING)) + if (!c->hasUnitState(UNIT_STAT_LOST_CONTROL)) { if (c->AI() && c->AI()->IsVisible(pl) && !c->IsInEvadeMode()) c->AI()->MoveInLineOfSight(pl); @@ -76,13 +76,13 @@ inline void PlayerCreatureRelocationWorker(Player* pl, WorldObject const* viewPo inline void CreatureCreatureRelocationWorker(Creature* c1, Creature* c2) { - if (!c1->hasUnitState(UNIT_STAT_FLEEING)) + if (!c1->hasUnitState(UNIT_STAT_LOST_CONTROL)) { if (c1->AI() && c1->AI()->IsVisible(c2) && !c1->IsInEvadeMode()) c1->AI()->MoveInLineOfSight(c2); } - if (!c2->hasUnitState(UNIT_STAT_FLEEING)) + if (!c2->hasUnitState(UNIT_STAT_LOST_CONTROL)) { if (c2->AI() && c2->AI()->IsVisible(c1) && !c2->IsInEvadeMode()) c2->AI()->MoveInLineOfSight(c1); diff --git a/src/game/MotionMaster.cpp b/src/game/MotionMaster.cpp index c43ce0f4f..e09fc962a 100644 --- a/src/game/MotionMaster.cpp +++ b/src/game/MotionMaster.cpp @@ -41,10 +41,11 @@ void MotionMaster::Initialize() { // clear ALL movement generators (including default) + i_owner->StopMoving(); Clear(false,true); // set new default movement generator - if (i_owner->GetTypeId() == TYPEID_UNIT) + if (i_owner->GetTypeId() == TYPEID_UNIT && !i_owner->hasUnitState(UNIT_STAT_CONTROLED)) { MovementGenerator* movement = FactorySelector::selectMovementGenerator((Creature*)i_owner); push(movement == NULL ? &si_idleMovement : movement); @@ -226,7 +227,7 @@ void MotionMaster::MoveRandom() void MotionMaster::MoveTargetedHome() { - if(i_owner->hasUnitState(UNIT_STAT_FLEEING)) + if(i_owner->hasUnitState(UNIT_STAT_LOST_CONTROL)) return; Clear(false); @@ -281,6 +282,9 @@ MotionMaster::MoveChase(Unit* target, float dist, float angle) void MotionMaster::MoveFollow(Unit* target, float dist, float angle) { + if(i_owner->hasUnitState(UNIT_STAT_LOST_CONTROL)) + return; + Clear(); // ignore movement request if target not exist diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 39827a33a..0596f1891 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -2236,7 +2236,7 @@ Creature* Player::GetNPCIfCanInteractWith(ObjectGuid guid, uint32 npcflagmask) return NULL; // not in interactive state - if (hasUnitState(UNIT_STAT_CAN_NOT_REACT)) + if (hasUnitState(UNIT_STAT_CAN_NOT_REACT_OR_LOST_CONTROL)) return NULL; // exist (we need look pets also for some interaction (quest/etc) @@ -2290,7 +2290,7 @@ GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid guid, uint32 gameo return NULL; // not in interactive state - if (hasUnitState(UNIT_STAT_CAN_NOT_REACT)) + if (hasUnitState(UNIT_STAT_CAN_NOT_REACT_OR_LOST_CONTROL)) return NULL; if (GameObject *go = GetMap()->GetGameObject(guid)) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index c199196b9..027037a4e 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -3619,6 +3619,8 @@ void Aura::HandleModPossess(bool apply, bool Real) if( apply ) { + target->addUnitState(UNIT_STAT_CONTROLED); + target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); target->SetCharmerGUID(p_caster->GetGUID()); @@ -3630,24 +3632,28 @@ void Aura::HandleModPossess(bool apply, bool Real) p_caster->SetClientControl(target, 1); p_caster->SetMover(target); - target->CombatStop(); + target->CombatStop(true); target->DeleteThreatList(); + target->getHostileRefManager().deleteReferences(); + + if(CharmInfo *charmInfo = target->InitCharmInfo(target)) + { + charmInfo->InitPossessCreateSpells(); + charmInfo->SetReactState(REACT_PASSIVE); + charmInfo->SetCommandState(COMMAND_STAY); + } + + p_caster->PossessSpellInitialize(); if(target->GetTypeId() == TYPEID_UNIT) { - target->StopMoving(); - target->GetMotionMaster()->Clear(); - target->GetMotionMaster()->MoveIdle(); + ((Creature*)target)->AIM_Initialize(); } else if(target->GetTypeId() == TYPEID_PLAYER) { ((Player*)target)->SetClientControl(target, 0); } - if(CharmInfo *charmInfo = target->InitCharmInfo(target)) - charmInfo->InitPossessCreateSpells(); - - p_caster->PossessSpellInitialize(); } else { @@ -3664,6 +3670,12 @@ void Aura::HandleModPossess(bool apply, bool Real) if(m_removeMode == AURA_REMOVE_BY_DELETE) return; + target->clearUnitState(UNIT_STAT_CONTROLED); + + target->CombatStop(true); + target->DeleteThreatList(); + target->getHostileRefManager().deleteReferences(); + target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); target->SetCharmerGUID(0); @@ -3772,8 +3784,9 @@ void Aura::HandleModCharm(bool apply, bool Real) target->CastStop(target == caster ? GetId() : 0); caster->SetCharm(target); - target->CombatStop(); + target->CombatStop(true); target->DeleteThreatList(); + target->getHostileRefManager().deleteReferences(); if(target->GetTypeId() == TYPEID_UNIT) { @@ -3848,6 +3861,10 @@ void Aura::HandleModCharm(bool apply, bool Real) if(caster->GetTypeId() == TYPEID_PLAYER) ((Player*)caster)->RemovePetActionBar(); + target->CombatStop(true); + target->DeleteThreatList(); + target->getHostileRefManager().deleteReferences(); + if(target->GetTypeId() == TYPEID_UNIT) { ((Creature*)target)->AIM_Initialize(); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index f6a2c5a03..d0c82d8f7 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -13736,4 +13736,4 @@ bool Unit::CheckAndIncreaseCastCounter() ++m_castCounter; return true; -} +} \ No newline at end of file diff --git a/src/game/Unit.h b/src/game/Unit.h index b4b407727..11090bf49 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -420,24 +420,25 @@ enum UnitState UNIT_STAT_STUNNED = 0x00000008, // Aura::HandleAuraModStun UNIT_STAT_ROOT = 0x00000010, // Aura::HandleAuraModRoot UNIT_STAT_ISOLATED = 0x00000020, // area auras do not affect other players, Aura::HandleAuraModSchoolImmunity + UNIT_STAT_CONTROLED = 0x00000040, // Aura::HandleAuraModPossess // persistent movement generator state (all time while movement generator applied to unit (independent from top state of movegen) - UNIT_STAT_IN_FLIGHT = 0x00000040, // player is in flight mode (in fact interrupted at far teleport until next map telport landing) - UNIT_STAT_DISTRACTED = 0x00000080, // DistractedMovementGenerator active + UNIT_STAT_IN_FLIGHT = 0x00000080, // player is in flight mode (in fact interrupted at far teleport until next map telport landing) + UNIT_STAT_DISTRACTED = 0x00000100, // DistractedMovementGenerator active // persistent movement generator state with non-persistent mirror states for stop support // (can be removed temporary by stop command or another movement generator apply) // not use _MOVE versions for generic movegen state, it can be removed temporary for unit stop and etc - UNIT_STAT_CONFUSED = 0x00000100, // ConfusedMovementGenerator active/onstack - UNIT_STAT_CONFUSED_MOVE = 0x00000200, - UNIT_STAT_ROAMING = 0x00000400, // RandomMovementGenerator/PointMovementGenerator/WaypointMovementGenerator active (now always set) - UNIT_STAT_ROAMING_MOVE = 0x00000800, - UNIT_STAT_CHASE = 0x00001000, // ChaseMovementGenerator active - UNIT_STAT_CHASE_MOVE = 0x00002000, - UNIT_STAT_FOLLOW = 0x00004000, // FollowMovementGenerator active - UNIT_STAT_FOLLOW_MOVE = 0x00008000, - UNIT_STAT_FLEEING = 0x00010000, // FleeMovementGenerator/TimedFleeingMovementGenerator active/onstack - UNIT_STAT_FLEEING_MOVE = 0x00020000, + UNIT_STAT_CONFUSED = 0x00000200, // ConfusedMovementGenerator active/onstack + UNIT_STAT_CONFUSED_MOVE = 0x00000400, + UNIT_STAT_ROAMING = 0x00000800, // RandomMovementGenerator/PointMovementGenerator/WaypointMovementGenerator active (now always set) + UNIT_STAT_ROAMING_MOVE = 0x00001000, + UNIT_STAT_CHASE = 0x00002000, // ChaseMovementGenerator active + UNIT_STAT_CHASE_MOVE = 0x00004000, + UNIT_STAT_FOLLOW = 0x00008000, // FollowMovementGenerator active + UNIT_STAT_FOLLOW_MOVE = 0x00010000, + UNIT_STAT_FLEEING = 0x00020000, // FleeMovementGenerator/TimedFleeingMovementGenerator active/onstack + UNIT_STAT_FLEEING_MOVE = 0x00040000, // masks (only for check) @@ -457,6 +458,12 @@ enum UnitState UNIT_STAT_CAN_NOT_REACT = UNIT_STAT_STUNNED | UNIT_STAT_DIED | UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING, + // AI disabled by some reason + UNIT_STAT_LOST_CONTROL = UNIT_STAT_FLEEING | UNIT_STAT_CONTROLED, + + // above 2 state cases + UNIT_STAT_CAN_NOT_REACT_OR_LOST_CONTROL = UNIT_STAT_CAN_NOT_REACT | UNIT_STAT_LOST_CONTROL, + // masks (for check or reset) // for real move using movegen check and stop (except unstoppable flight) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 926d2dd1d..247bcbbc9 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10052" + #define REVISION_NR "10053" #endif // __REVISION_NR_H__ From 10634ac5be50203658d7fb04927b841be25453a1 Mon Sep 17 00:00:00 2001 From: Laise Date: Mon, 14 Jun 2010 12:24:42 +0300 Subject: [PATCH 03/42] [10054] Fix crash when not saved action buttons are removed during spec switch --- src/game/Player.cpp | 11 ++++++++++- src/shared/revision_nr.h | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 0596f1891..106fdb4e6 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -21906,11 +21906,20 @@ void Player::ActivateSpec(uint8 specNum) // recheck action buttons (not checked at loading/spec copy) ActionButtonList const& currentActionButtonList = m_actionButtons[m_activeSpec]; - for(ActionButtonList::const_iterator itr = currentActionButtonList.begin(); itr != currentActionButtonList.end(); ++itr) + for(ActionButtonList::const_iterator itr = currentActionButtonList.begin(); itr != currentActionButtonList.end(); ) + { if (itr->second.uState != ACTIONBUTTON_DELETED) + { // remove broken without any output (it can be not correct because talents not copied at spec creating) if (!IsActionButtonDataValid(itr->first,itr->second.GetAction(),itr->second.GetType(), this, false)) + { removeActionButton(m_activeSpec,itr->first); + itr = currentActionButtonList.begin(); + continue; + } + } + ++itr; + } ResummonPetTemporaryUnSummonedIfAny(); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 247bcbbc9..fd3242f46 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10053" + #define REVISION_NR "10054" #endif // __REVISION_NR_H__ From 809d9d2063b202aaec28cccb9dc6d54245239666 Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Mon, 14 Jun 2010 17:56:44 +0200 Subject: [PATCH 04/42] [10055] Use creature equipment from normal _template when id is not set for difficulty creature_template of difficulty_entry_N then only need equipment_id when equipment should be different from the normal creature entry. Signed-off-by: NoFantasy --- src/game/Creature.cpp | 11 +++++++---- src/shared/revision_nr.h | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 6e984a990..d27c0d826 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -248,11 +248,14 @@ bool Creature::InitEntry(uint32 Entry, uint32 team, const CreatureData *data ) SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender); // Load creature equipment - if(!data || data->equipmentId == 0) - { // use default from the template - LoadEquipment(cinfo->equipmentId); + if (!data || data->equipmentId == 0) + { + if (cinfo->equipmentId == 0) + LoadEquipment(normalInfo->equipmentId); // use default from normal template if diff does not have any + else + LoadEquipment(cinfo->equipmentId); // else use from diff template } - else if(data && data->equipmentId != -1) + else if (data && data->equipmentId != -1) { // override, -1 means no equipment LoadEquipment(data->equipmentId); } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index fd3242f46..f227d15e4 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10054" + #define REVISION_NR "10055" #endif // __REVISION_NR_H__ From aa5dfc2895069cbdf949761e1fa147b8a7a4f704 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 14 Jun 2010 19:40:56 +0400 Subject: [PATCH 05/42] [10056] Re-add spell proc sql data from [7879]. * It not has been added in commit time to mangos.sql * It alsow required data updating in family masks. Thank you to NoFantasy for reseatch problem :) --- sql/mangos.sql | 3 ++- sql/updates/10056_01_mangos_spell_proc_event.sql | 5 +++++ sql/updates/Makefile.am | 2 ++ src/shared/revision_nr.h | 2 +- src/shared/revision_sql.h | 2 +- 5 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 sql/updates/10056_01_mangos_spell_proc_event.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 84b3c8c96..a84394863 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -24,7 +24,7 @@ CREATE TABLE `db_version` ( `version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL, `cache_id` int(10) default '0', - `required_10045_01_mangos_spell_proc_event` bit(1) default NULL + `required_10056_01_mangos_spell_proc_event` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -17930,6 +17930,7 @@ INSERT INTO `spell_proc_event` VALUES (31244, 0x00, 8, 0x003E0000, 0x00000009, 0x00000000, 0x00000000, 0x00002034, 0.000000, 0.000000, 0), (31394, 0x20, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (31569, 0x00, 3, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(31571, 0x00, 3, 0x00000000, 0x00000000, 0x00000008, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), (31785, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00008800, 0x00000000, 0.000000, 0.000000, 0), (31794, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), (31801, 0x01, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), diff --git a/sql/updates/10056_01_mangos_spell_proc_event.sql b/sql/updates/10056_01_mangos_spell_proc_event.sql new file mode 100644 index 000000000..d36333abe --- /dev/null +++ b/sql/updates/10056_01_mangos_spell_proc_event.sql @@ -0,0 +1,5 @@ +ALTER TABLE db_version CHANGE COLUMN required_10045_01_mangos_spell_proc_event required_10056_01_mangos_spell_proc_event bit; + +DELETE FROM spell_proc_event WHERE entry IN (31571, 31572); +INSERT INTO spell_proc_event VALUES +(31571, 0x00, 3, 0x00000000, 0x00000000, 0x00000008, 0x00004000, 0x00000000, 0.000000, 0.000000, 0); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 955657d31..af7404e6c 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -88,6 +88,7 @@ pkgdata_DATA = \ 10044_02_mangos_spell_proc_event.sql \ 10045_01_mangos_spell_proc_event.sql \ 10051_01_characters_character_aura.sql \ + 10056_01_mangos_spell_proc_event.sql \ README ## Additional files to include when running 'make dist' @@ -156,4 +157,5 @@ EXTRA_DIST = \ 10044_02_mangos_spell_proc_event.sql \ 10045_01_mangos_spell_proc_event.sql \ 10051_01_characters_character_aura.sql \ + 10056_01_mangos_spell_proc_event.sql \ README diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index f227d15e4..982dcef41 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10055" + #define REVISION_NR "10056" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index 7e2003649..3e7586ffb 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_10051_01_characters_character_aura" - #define REVISION_DB_MANGOS "required_10045_01_mangos_spell_proc_event" + #define REVISION_DB_MANGOS "required_10056_01_mangos_spell_proc_event" #define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version" #endif // __REVISION_SQL_H__ From e34315f23fa22831cd06a4174ebe6759eac1c2a0 Mon Sep 17 00:00:00 2001 From: zergtmn Date: Mon, 14 Jun 2010 22:07:10 +0400 Subject: [PATCH 06/42] [10057] Type in UNIT_STAT_CONTROLLED Signed-off-by: VladimirMangos --- src/game/MotionMaster.cpp | 2 +- src/game/SpellAuras.cpp | 4 ++-- src/game/Unit.h | 4 ++-- src/shared/revision_nr.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/game/MotionMaster.cpp b/src/game/MotionMaster.cpp index e09fc962a..1728d1009 100644 --- a/src/game/MotionMaster.cpp +++ b/src/game/MotionMaster.cpp @@ -45,7 +45,7 @@ MotionMaster::Initialize() Clear(false,true); // set new default movement generator - if (i_owner->GetTypeId() == TYPEID_UNIT && !i_owner->hasUnitState(UNIT_STAT_CONTROLED)) + if (i_owner->GetTypeId() == TYPEID_UNIT && !i_owner->hasUnitState(UNIT_STAT_CONTROLLED)) { MovementGenerator* movement = FactorySelector::selectMovementGenerator((Creature*)i_owner); push(movement == NULL ? &si_idleMovement : movement); diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 027037a4e..c99639ee2 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -3619,7 +3619,7 @@ void Aura::HandleModPossess(bool apply, bool Real) if( apply ) { - target->addUnitState(UNIT_STAT_CONTROLED); + target->addUnitState(UNIT_STAT_CONTROLLED); target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); @@ -3670,7 +3670,7 @@ void Aura::HandleModPossess(bool apply, bool Real) if(m_removeMode == AURA_REMOVE_BY_DELETE) return; - target->clearUnitState(UNIT_STAT_CONTROLED); + target->clearUnitState(UNIT_STAT_CONTROLLED); target->CombatStop(true); target->DeleteThreatList(); diff --git a/src/game/Unit.h b/src/game/Unit.h index 11090bf49..d02235dd6 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -420,7 +420,7 @@ enum UnitState UNIT_STAT_STUNNED = 0x00000008, // Aura::HandleAuraModStun UNIT_STAT_ROOT = 0x00000010, // Aura::HandleAuraModRoot UNIT_STAT_ISOLATED = 0x00000020, // area auras do not affect other players, Aura::HandleAuraModSchoolImmunity - UNIT_STAT_CONTROLED = 0x00000040, // Aura::HandleAuraModPossess + UNIT_STAT_CONTROLLED = 0x00000040, // Aura::HandleAuraModPossess // persistent movement generator state (all time while movement generator applied to unit (independent from top state of movegen) UNIT_STAT_IN_FLIGHT = 0x00000080, // player is in flight mode (in fact interrupted at far teleport until next map telport landing) @@ -459,7 +459,7 @@ enum UnitState UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING, // AI disabled by some reason - UNIT_STAT_LOST_CONTROL = UNIT_STAT_FLEEING | UNIT_STAT_CONTROLED, + UNIT_STAT_LOST_CONTROL = UNIT_STAT_FLEEING | UNIT_STAT_CONTROLLED, // above 2 state cases UNIT_STAT_CAN_NOT_REACT_OR_LOST_CONTROL = UNIT_STAT_CAN_NOT_REACT | UNIT_STAT_LOST_CONTROL, diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 982dcef41..3d4a5ca55 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10056" + #define REVISION_NR "10057" #endif // __REVISION_NR_H__ From e82f4fbd29fb7ec6cffa728b519e02a0b0cba899 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Tue, 15 Jun 2010 02:13:26 +0400 Subject: [PATCH 07/42] [10058] Add to mangos.sql data from 09720_01_mangos_spell_proc_event.sql Thank you to NoFantasy for pointing to inconsistance. --- sql/mangos.sql | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/mangos.sql b/sql/mangos.sql index a84394863..9bdd88f1a 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -18291,7 +18291,7 @@ INSERT INTO `spell_proc_event` VALUES (61618, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), (61846, 0x00, 9, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (62600, 0x00, 7, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(63108, 0x00, 5, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(63108, 0x00, 5, 0x00000002, 0x00000000, 0x00000000, 0x00040000, 0x00000000, 0.000000, 0.000000, 0), (63156, 0x00, 0, 0x00000001, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (63280, 0x00, 11, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (63320, 0x00, 5, 0x00040000, 0x00000000, 0x00008000, 0x00004000, 0x00000001, 0.000000, 0.000000, 0), diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 3d4a5ca55..a4df4b082 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10057" + #define REVISION_NR "10058" #endif // __REVISION_NR_H__ From 232629298143f6458518b3b93069216d97e1da91 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Tue, 15 Jun 2010 03:46:51 +0400 Subject: [PATCH 08/42] [10059] Cleanup in Player::m_mover uses * Also fix triggered by related checks unread packet tail spam cases. * Fix one case when expected death at fall controlled player under ground has been possible avoided --- src/game/MovementHandler.cpp | 20 +++++---- src/game/Player.cpp | 6 +-- src/game/Player.h | 4 +- src/game/SpellHandler.cpp | 86 ++++++++++++++++++++---------------- src/shared/revision_nr.h | 2 +- 5 files changed, 67 insertions(+), 51 deletions(-) diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index b4601e9b5..9c9377673 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -181,7 +181,7 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data) DEBUG_LOG("Guid: %s", guid.GetString().c_str()); DEBUG_LOG("Flags %u, time %u", flags, time/IN_MILLISECONDS); - Unit *mover = _player->m_mover; + Unit *mover = _player->GetMover(); Player *plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL; if(!plMover || !plMover->IsBeingTeleportedNear()) @@ -223,7 +223,7 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) DEBUG_LOG("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode); recv_data.hexlike(); - Unit *mover = _player->m_mover; + Unit *mover = _player->GetMover(); Player *plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL; // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck @@ -335,7 +335,7 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) // TODO: discard movement packets after the player is rooted if(plMover->isAlive()) { - plMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth()); + plMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, plMover->GetMaxHealth()); // pl can be alive if GM/etc if(!plMover->isAlive()) { @@ -434,12 +434,13 @@ void WorldSession::HandleSetActiveMoverOpcode(WorldPacket &recv_data) DEBUG_LOG("WORLD: Recvd CMSG_SET_ACTIVE_MOVER"); recv_data.hexlike(); - uint64 guid; + ObjectGuid guid; recv_data >> guid; - if(_player->m_mover->GetGUID() != guid) + if(_player->GetMover()->GetObjectGuid() != guid) { - sLog.outError("HandleSetActiveMoverOpcode: incorrect mover guid: mover is " I64FMT " and should be " I64FMT, _player->m_mover->GetGUID(), guid); + sLog.outError("HandleSetActiveMoverOpcode: incorrect mover guid: mover is %s and should be %s", + _player->GetMover()->GetObjectGuid().GetString().c_str(), guid.GetString().c_str()); return; } } @@ -455,9 +456,12 @@ void WorldSession::HandleMoveNotActiveMover(WorldPacket &recv_data) recv_data >> old_mover_guid.ReadAsPacked(); recv_data >> mi; - if(_player->m_mover->GetObjectGuid() == old_mover_guid) + if(_player->GetMover()->GetObjectGuid() == old_mover_guid) { - sLog.outError("HandleMoveNotActiveMover: incorrect mover guid: mover is " I64FMT " and should be " I64FMT " instead of " UI64FMTD, _player->m_mover->GetGUID(), _player->GetGUID(), old_mover_guid.GetRawValue()); + sLog.outError("HandleMoveNotActiveMover: incorrect mover guid: mover is %s and should be %s instead of %s", + _player->GetMover()->GetObjectGuid().GetString().c_str(), + _player->GetObjectGuid().GetString().c_str(), + old_mover_guid.GetString().c_str()); recv_data.rpos(recv_data.wpos()); // prevent warnings spam return; } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 106fdb4e6..6abae6f6a 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -405,7 +405,7 @@ void TradeData::SetAccepted(bool state, bool crosssend /*= false*/) UpdateMask Player::updateVisualBits; -Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputationMgr(this), m_camera(this) +Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputationMgr(this), m_mover(this), m_camera(this) { m_transport = 0; @@ -584,8 +584,6 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa m_summon_y = 0.0f; m_summon_z = 0.0f; - m_mover = this; - m_miniPet = 0; m_contestedPvPTimer = 0; @@ -19442,7 +19440,7 @@ void Player::SendInitialPacketsBeforeAddToMap() if(HasAuraType(SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED) || HasAuraType(SPELL_AURA_FLY) || isInFlight()) m_movementInfo.AddMovementFlag(MOVEFLAG_FLYING); - m_mover = this; + SetMover(this); } void Player::SendInitialPacketsAfterAddToMap() diff --git a/src/game/Player.h b/src/game/Player.h index 544e7e18a..8d6d64a36 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -2189,7 +2189,6 @@ class MANGOS_DLL_SPEC Player : public Unit /*********************************************************/ bool HasMovementFlag(MovementFlags f) const; // for script access to m_movementInfo.HasMovementFlag void UpdateFallInformationIfNeed(MovementInfo const& minfo,uint16 opcode); - Unit *m_mover; void SetFallInformation(uint32 time, float z) { m_lastFallTime = time; @@ -2208,6 +2207,8 @@ class MANGOS_DLL_SPEC Player : public Unit void SetClientControl(Unit* target, uint8 allowMove); void SetMover(Unit* target) { m_mover = target ? target : this; } + Unit* GetMover() const { return m_mover; } + bool IsSelfMover() const { return m_mover == this; }// normal case for player not controlling other unit void EnterVehicle(Vehicle *vehicle); void ExitVehicle(Vehicle *vehicle); @@ -2602,6 +2603,7 @@ class MANGOS_DLL_SPEC Player : public Unit m_DelayedOperations |= operation; } + Unit *m_mover; Camera m_camera; GridReference m_gridRef; diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp index 86ca9c7ba..f42a18c11 100644 --- a/src/game/SpellHandler.cpp +++ b/src/game/SpellHandler.cpp @@ -31,13 +31,6 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) { - // TODO: add targets.read() check - Player* pUser = _player; - - // ignore for remote control state - if(pUser->m_mover != pUser) - return; - uint8 bagIndex, slot; uint8 unk_flags; // flags (if 0x02 - some additional data are received) uint8 cast_count; // next cast if exists (single or not) @@ -47,9 +40,20 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) recvPacket >> bagIndex >> slot >> cast_count >> spellid >> item_guid >> glyphIndex >> unk_flags; + // TODO: add targets.read() check + Player* pUser = _player; + + // ignore for remote control state + if (!pUser->IsSelfMover()) + { + recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail + return; + } + // reject fake data if (glyphIndex >= MAX_GLYPH_SLOT_INDEX) { + recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); return; } @@ -57,12 +61,14 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) Item *pItem = pUser->GetItemByPos(bagIndex, slot); if (!pItem) { + recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); return; } if (pItem->GetGUID() != item_guid) { + recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); return; } @@ -72,6 +78,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) ItemPrototype const *proto = pItem->GetProto(); if (!proto) { + recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL ); return; } @@ -79,6 +86,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) // some item classes can be used only in equipped state if (proto->InventoryType != INVTYPE_NON_EQUIP && !pItem->IsEquipped()) { + recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL ); return; } @@ -86,6 +94,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) uint8 msg = pUser->CanUseItem(pItem); if (msg != EQUIP_ERR_OK) { + recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail pUser->SendEquipError( msg, pItem, NULL ); return; } @@ -95,6 +104,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) !(proto->Flags & ITEM_FLAGS_USEABLE_IN_ARENA) && pUser->InArena()) { + recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH,pItem,NULL); return; } @@ -107,6 +117,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) { if (IsNonCombatSpell(spellInfo)) { + recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail pUser->SendEquipError(EQUIP_ERR_NOT_IN_COMBAT,pItem,NULL); return; } @@ -116,6 +127,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) // Prevent potion drink if another potion in processing (client have potions disabled in like case) if (pItem->IsPotion() && pUser->GetLastPotionId()) { + recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail pUser->SendEquipError(EQUIP_ERR_OBJECT_IS_BUSY,pItem,NULL); return; } @@ -174,18 +186,18 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) { DETAIL_LOG("WORLD: CMSG_OPEN_ITEM packet, data length = %i",(uint32)recvPacket.size()); - Player* pUser = _player; - - // ignore for remote control state - if(pUser->m_mover != pUser) - return; - uint8 bagIndex, slot; recvPacket >> bagIndex >> slot; DETAIL_LOG("bagIndex: %u, slot: %u",bagIndex,slot); + Player* pUser = _player; + + // ignore for remote control state + if (!pUser->IsSelfMover()) + return; + Item *pItem = pUser->GetItemByPos(bagIndex, slot); if(!pItem) { @@ -257,7 +269,7 @@ void WorldSession::HandleGameObjectUseOpcode( WorldPacket & recv_data ) DEBUG_LOG( "WORLD: Recvd CMSG_GAMEOBJ_USE Message [guid=%u]", GUID_LOPART(guid)); // ignore for remote control state - if(_player->m_mover != _player) + if (!_player->IsSelfMover()) return; GameObject *obj = GetPlayer()->GetMap()->GetGameObject(guid); @@ -276,7 +288,7 @@ void WorldSession::HandleGameobjectReportUse(WorldPacket& recvPacket) DEBUG_LOG( "WORLD: Recvd CMSG_GAMEOBJ_REPORT_USE Message [in game guid: %u]", GUID_LOPART(guid)); // ignore for remote control state - if(_player->m_mover != _player) + if (!_player->IsSelfMover()) return; GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid); @@ -298,8 +310,8 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) recvPacket >> unk_flags; // flags (if 0x02 - some additional data are received) // ignore for remote control state (for player case) - Unit* mover = _player->m_mover; - if(mover != _player && mover->GetTypeId()==TYPEID_PLAYER) + Unit* mover = _player->GetMover(); + if (mover != _player && mover->GetTypeId()==TYPEID_PLAYER) { recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet return; @@ -317,7 +329,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) return; } - if(mover->GetTypeId()==TYPEID_PLAYER) + if (mover->GetTypeId()==TYPEID_PLAYER) { // not have spell in spellbook or spell passive and not casted by client if (!((Player*)mover)->HasActiveSpell (spellId) || IsPassiveSpell(spellId) ) @@ -364,7 +376,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) } // auto-selection buff level base at target level (in spellInfo) - if(targets.getUnitTarget()) + if (targets.getUnitTarget()) { SpellEntry const *actualSpellInfo = sSpellMgr.SelectAuraRankForPlayerLevel(spellInfo,targets.getUnitTarget()->getLevel()); @@ -380,16 +392,16 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) void WorldSession::HandleCancelCastOpcode(WorldPacket& recvPacket) { - // ignore for remote control state (for player case) - Unit* mover = _player->m_mover; - if(mover != _player && mover->GetTypeId()==TYPEID_PLAYER) - return; - uint32 spellId; recvPacket.read_skip(); // counter, increments with every CANCEL packet, don't use for now recvPacket >> spellId; + // ignore for remote control state (for player case) + Unit* mover = _player->GetMover(); + if (mover != _player && mover->GetTypeId()==TYPEID_PLAYER) + return; + //FIXME: hack, ignore unexpected client cancel Deadly Throw cast if(spellId==26679) return; @@ -410,10 +422,10 @@ void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket) if (spellInfo->Attributes & SPELL_ATTR_CANT_CANCEL) return; - if(!IsPositiveSpell(spellId)) + if (!IsPositiveSpell(spellId)) { // ignore for remote control state - if (_player->m_mover != _player) + if (!_player->IsSelfMover()) { // except own aura spells bool allow = false; @@ -450,16 +462,16 @@ void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket) void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket) { - // ignore for remote control state - if(_player->m_mover != _player) - return; - uint64 guid; uint32 spellId; recvPacket >> guid; recvPacket >> spellId; + // ignore for remote control state + if (!_player->IsSelfMover()) + return; + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId ); if(!spellInfo) { @@ -501,7 +513,7 @@ void WorldSession::HandleCancelAutoRepeatSpellOpcode( WorldPacket& /*recvPacket* { // cancel and prepare for deleting // do not send SMSG_CANCEL_AUTO_REPEAT! client will send this Opcode again (loop) - _player->m_mover->InterruptSpell(CURRENT_AUTOREPEAT_SPELL, true, false); + _player->GetMover()->InterruptSpell(CURRENT_AUTOREPEAT_SPELL, true, false); } void WorldSession::HandleCancelChanneling( WorldPacket & recv_data) @@ -509,8 +521,8 @@ void WorldSession::HandleCancelChanneling( WorldPacket & recv_data) recv_data.read_skip(); // spellid, not used // ignore for remote control state (for player case) - Unit* mover = _player->m_mover; - if(mover != _player && mover->GetTypeId()==TYPEID_PLAYER) + Unit* mover = _player->GetMover(); + if (mover != _player && mover->GetTypeId()==TYPEID_PLAYER) return; mover->InterruptSpell(CURRENT_CHANNELED_SPELL); @@ -518,14 +530,14 @@ void WorldSession::HandleCancelChanneling( WorldPacket & recv_data) void WorldSession::HandleTotemDestroyed( WorldPacket& recvPacket) { - // ignore for remote control state - if(_player->m_mover != _player) - return; - uint8 slotId; recvPacket >> slotId; + // ignore for remote control state + if (!_player->IsSelfMover()) + return; + if (int(slotId) >= MAX_TOTEM_SLOT) return; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index a4df4b082..de2ac7352 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10058" + #define REVISION_NR "10059" #endif // __REVISION_NR_H__ From 16ae6a2f85b73b39b5ca7eacc5ee767dc9059d14 Mon Sep 17 00:00:00 2001 From: Lynx3d Date: Tue, 15 Jun 2010 15:05:07 +0400 Subject: [PATCH 09/42] [10060] Drop unused ACE_Stack_Trace in Error.h This also can fix possible build problem in case use at system old ACE version. Signed-off-by: VladimirMangos --- src/shared/Errors.h | 1 - src/shared/revision_nr.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/shared/Errors.h b/src/shared/Errors.h index 16ffff9b5..6764c1858 100644 --- a/src/shared/Errors.h +++ b/src/shared/Errors.h @@ -62,7 +62,6 @@ if (!(CONDITION)) \ #define WPWarning(CONDITION) \ if (!(CONDITION)) \ { \ - ACE_Stack_Trace st; \ printf("%s:%i: Warning: Assertion in %s failed: %s",\ __FILE__, __LINE__, __FUNCTION__, STRINGIZE(CONDITION)); \ } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index de2ac7352..bdf9246fe 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10059" + #define REVISION_NR "10060" #endif // __REVISION_NR_H__ From 9811858d44762932a7ad503851047eb530b9aab6 Mon Sep 17 00:00:00 2001 From: Laise Date: Tue, 15 Jun 2010 15:26:29 +0300 Subject: [PATCH 10/42] Implement 49220 and ranks --- src/game/Player.cpp | 9 +++++++++ src/game/Player.h | 2 ++ src/game/Unit.cpp | 18 +++++++++++++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 6abae6f6a..0d8735637 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -21209,6 +21209,15 @@ void Player::UpdateAchievementCriteria( AchievementCriteriaTypes type, uint32 mi GetAchievementMgr().UpdateAchievementCriteria(type, miscvalue1,miscvalue2,unit,time); } +PlayerTalent const* Player::GetTalentById(int32 talentId) const +{ + PlayerTalentMap::const_iterator itr = m_talents[m_activeSpec].find(talentId); + if (itr != m_talents[m_activeSpec].end()) + return &itr->second; + else + NULL; +} + void Player::LearnTalent(uint32 talentId, uint32 talentRank) { uint32 CurTalentPoints = GetFreeTalentPoints(); diff --git a/src/game/Player.h b/src/game/Player.h index 8d6d64a36..a58357b2d 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1664,6 +1664,8 @@ class MANGOS_DLL_SPEC Player : public Unit SpellCooldowns const& GetSpellCooldownMap() const { return m_spellCooldowns; } + PlayerTalent const* GetTalentById(int32 talentId) const; + void AddSpellMod(SpellModifier* mod, bool apply); bool IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod, Spell const* spell = NULL); template T ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell const* spell = NULL); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index d0c82d8f7..4138ca6cd 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -8925,7 +8925,23 @@ int32 Unit::SpellBonusWithCoeffs(SpellEntry const *spellProto, int32 total, int3 // apply ap bonus at done part calculation only (it flat total mod so common with taken) if (donePart && bonus->ap_bonus) - total += int32(bonus->ap_bonus * (GetTotalAttackPowerValue(BASE_ATTACK) + ap_benefit)); + { + float ap_bonus = bonus->ap_bonus; + + // Impurity + if (GetTypeId() == TYPEID_PLAYER && spellProto->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT) + { + PlayerTalent const* talent = ((Player*)this)->GetTalentById(2005); + if (talent && talent->state != PLAYERSPELL_REMOVED) + { + SpellEntry const* spell = sSpellStore.LookupEntry(talent->m_talentEntry->RankID[talent->currentRank]); + if (spell) + ap_bonus += ((spell->CalculateSimpleValue(EFFECT_INDEX_0) * ap_bonus) / 100.0f); + } + } + + total += int32(ap_bonus * (GetTotalAttackPowerValue(BASE_ATTACK) + ap_benefit)); + } } // Default calculation else if (benefit) From 38dbd27569a674a18e1fd57357ff759b543585b9 Mon Sep 17 00:00:00 2001 From: ApoC Date: Tue, 15 Jun 2010 14:48:32 +0200 Subject: [PATCH 11/42] Added missing return statement. Signed-off-by: ApoC --- src/game/Player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 0d8735637..c231e7d8d 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -21215,7 +21215,7 @@ PlayerTalent const* Player::GetTalentById(int32 talentId) const if (itr != m_talents[m_activeSpec].end()) return &itr->second; else - NULL; + return NULL; } void Player::LearnTalent(uint32 talentId, uint32 talentRank) From 61959d285e8182249acefb0ddf75bc49eaee796a Mon Sep 17 00:00:00 2001 From: ApoC Date: Tue, 15 Jun 2010 14:50:34 +0200 Subject: [PATCH 12/42] [10061] Revision increase. I am sorry, i forget to apply git_id :( Signed-off-by: ApoC --- src/shared/revision_nr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index bdf9246fe..0d020a7d0 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10060" + #define REVISION_NR "10061" #endif // __REVISION_NR_H__ From c781dbbadaa4774f530fa5f175cb1109a7a6a061 Mon Sep 17 00:00:00 2001 From: ApoC Date: Tue, 15 Jun 2010 14:52:47 +0200 Subject: [PATCH 13/42] [10062] Removed wrong method const. Signed-off-by: ApoC --- src/framework/GameSystem/NGrid.h | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/framework/GameSystem/NGrid.h b/src/framework/GameSystem/NGrid.h index b3422c8bc..1ac8aa1c2 100644 --- a/src/framework/GameSystem/NGrid.h +++ b/src/framework/GameSystem/NGrid.h @@ -109,7 +109,7 @@ class MANGOS_DLL_DECL NGrid } const uint32& GetGridId() const { return i_gridId; } - void SetGridId(const uint32 id) const { i_gridId = id; } + void SetGridId(const uint32 id) { i_gridId = id; } grid_state_t GetGridState() const { return i_cellstate; } void SetGridState(grid_state_t s) { i_cellstate = s; } uint32 getX() const { return i_x; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 0d020a7d0..790ea9529 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10061" + #define REVISION_NR "10062" #endif // __REVISION_NR_H__ From 5b15cd5dd24722b9caa72623c6453242238ee389 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Tue, 15 Jun 2010 16:52:02 +0400 Subject: [PATCH 14/42] [10063] Cleanup recent added code. --- src/game/Player.cpp | 24 +++++++++++++++--------- src/game/Player.h | 3 ++- src/game/Unit.cpp | 9 ++------- src/shared/revision_nr.h | 2 +- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index c231e7d8d..23379ca6a 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -21209,15 +21209,23 @@ void Player::UpdateAchievementCriteria( AchievementCriteriaTypes type, uint32 mi GetAchievementMgr().UpdateAchievementCriteria(type, miscvalue1,miscvalue2,unit,time); } -PlayerTalent const* Player::GetTalentById(int32 talentId) const +PlayerTalent const* Player::GetKnownTalentById(int32 talentId) const { PlayerTalentMap::const_iterator itr = m_talents[m_activeSpec].find(talentId); - if (itr != m_talents[m_activeSpec].end()) + if (itr != m_talents[m_activeSpec].end() && itr->second.state != PLAYERSPELL_REMOVED) return &itr->second; else return NULL; } +SpellEntry const* Player::GetKnownTalentRankById(int32 talentId) const +{ + if (PlayerTalent const* talent = GetKnownTalentById(talentId)) + return sSpellStore.LookupEntry(talent->m_talentEntry->RankID[talent->currentRank]); + else + return NULL; +} + void Player::LearnTalent(uint32 talentId, uint32 talentRank) { uint32 CurTalentPoints = GetFreeTalentPoints(); @@ -21244,9 +21252,8 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank) // find current max talent rank uint32 curtalent_maxrank = 0; - PlayerTalentMap::iterator itr = m_talents[m_activeSpec].find(talentId); - if (itr != m_talents[m_activeSpec].end() && itr->second.state != PLAYERSPELL_REMOVED) - curtalent_maxrank = itr->second.currentRank + 1; + if (PlayerTalent const* talent = GetKnownTalentById(talentId)) + curtalent_maxrank = talent->currentRank + 1; // we already have same or higher talent rank learned if(curtalent_maxrank >= (talentRank + 1)) @@ -21882,17 +21889,16 @@ void Player::ActivateSpec(uint8 specNum) // learn talent spells if they not in new spec (old spec copy) // and if they have different rank - PlayerTalentMap::iterator specIter = m_talents[m_activeSpec].find(tempIter->first); - if (specIter != m_talents[m_activeSpec].end() && specIter->second.state != PLAYERSPELL_REMOVED) + if (PlayerTalent const* cur_talent = GetKnownTalentById(tempIter->first)) { - if ((*specIter).second.currentRank != talent.currentRank) + if (cur_talent->currentRank != talent.currentRank) learnSpell(talentSpellId, false); } else learnSpell(talentSpellId, false); // sync states - original state is changed in addSpell that learnSpell calls - specIter = m_talents[m_activeSpec].find(tempIter->first); + PlayerTalentMap::iterator specIter = m_talents[m_activeSpec].find(tempIter->first); if (specIter != m_talents[m_activeSpec].end()) (*specIter).second.state = talent.state; else diff --git a/src/game/Player.h b/src/game/Player.h index a58357b2d..8a03ecc97 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1664,7 +1664,8 @@ class MANGOS_DLL_SPEC Player : public Unit SpellCooldowns const& GetSpellCooldownMap() const { return m_spellCooldowns; } - PlayerTalent const* GetTalentById(int32 talentId) const; + PlayerTalent const* GetKnownTalentById(int32 talentId) const; + SpellEntry const* GetKnownTalentRankById(int32 talentId) const; void AddSpellMod(SpellModifier* mod, bool apply); bool IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod, Spell const* spell = NULL); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 4138ca6cd..4bd300cbf 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -8931,13 +8931,8 @@ int32 Unit::SpellBonusWithCoeffs(SpellEntry const *spellProto, int32 total, int3 // Impurity if (GetTypeId() == TYPEID_PLAYER && spellProto->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT) { - PlayerTalent const* talent = ((Player*)this)->GetTalentById(2005); - if (talent && talent->state != PLAYERSPELL_REMOVED) - { - SpellEntry const* spell = sSpellStore.LookupEntry(talent->m_talentEntry->RankID[talent->currentRank]); - if (spell) - ap_bonus += ((spell->CalculateSimpleValue(EFFECT_INDEX_0) * ap_bonus) / 100.0f); - } + if (SpellEntry const* spell = ((Player*)this)->GetKnownTalentRankById(2005)) + ap_bonus += ((spell->CalculateSimpleValue(EFFECT_INDEX_0) * ap_bonus) / 100.0f); } total += int32(ap_bonus * (GetTotalAttackPowerValue(BASE_ATTACK) + ap_benefit)); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 790ea9529..41f589ff8 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10062" + #define REVISION_NR "10063" #endif // __REVISION_NR_H__ From 0304448b8528ec43a2708b52f946f627ac3a8c30 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Tue, 15 Jun 2010 19:12:44 +0400 Subject: [PATCH 15/42] [10064] Fixed recently show up crash in Unit::StopMoving. --- src/game/MotionMaster.cpp | 5 ++++- src/game/Unit.cpp | 4 ++++ src/shared/revision_nr.h | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/game/MotionMaster.cpp b/src/game/MotionMaster.cpp index 1728d1009..58e242564 100644 --- a/src/game/MotionMaster.cpp +++ b/src/game/MotionMaster.cpp @@ -40,8 +40,11 @@ inline bool isStatic(MovementGenerator *mv) void MotionMaster::Initialize() { + // stop current move + if (!i_owner->IsStopped()) + i_owner->StopMoving(); + // clear ALL movement generators (including default) - i_owner->StopMoving(); Clear(false,true); // set new default movement generator diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 4bd300cbf..22d07678a 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -12777,6 +12777,10 @@ void Unit::StopMoving() { clearUnitState(UNIT_STAT_MOVING); + // not need send any packets if not in world + if (!IsInWorld()) + return; + // send explicit stop packet // player expected for correct work SPLINEFLAG_WALKMODE SendMonsterMove(GetPositionX(), GetPositionY(), GetPositionZ(), SPLINETYPE_NORMAL, GetTypeId() == TYPEID_PLAYER ? SPLINEFLAG_WALKMODE : SPLINEFLAG_NONE, 0); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 41f589ff8..ab25bd094 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10063" + #define REVISION_NR "10064" #endif // __REVISION_NR_H__ From d967af654911f0d6e1f963065bf8c00aa0b7a841 Mon Sep 17 00:00:00 2001 From: ApoC Date: Tue, 15 Jun 2010 18:13:32 +0200 Subject: [PATCH 16/42] [10065] Some return values fixes. Signed-off-by: ApoC --- src/game/Chat.cpp | 6 +++--- src/shared/revision_nr.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index 97506963b..893959977 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -2057,7 +2057,7 @@ GameTele const* ChatHandler::extractGameTeleFromLink(char* text) // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r char* cId = extractKeyFromLink(text,"Htele"); if(!cId) - return false; + return NULL; // id case (explicit or from shift link) if(cId[0] >= '0' || cId[0] >= '9') @@ -2079,7 +2079,7 @@ static char const* const guidKeys[] = "Hplayer", "Hcreature", "Hgameobject", - 0 + NULL }; uint64 ChatHandler::extractGuidFromLink(char* text) @@ -2229,7 +2229,7 @@ char* ChatHandler::extractQuotedArg( char* args ) { char* space = strtok(args, "\""); if(!space) - return false; + return NULL; return strtok(NULL, "\""); } } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index ab25bd094..c166a3537 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10064" + #define REVISION_NR "10065" #endif // __REVISION_NR_H__ From 7dd5456401c7ce7e329acdf2b25badd5db42a311 Mon Sep 17 00:00:00 2001 From: ApoC Date: Wed, 16 Jun 2010 23:26:53 +0200 Subject: [PATCH 17/42] [10066] Some tuning in consts. Signed-off-by: ApoC --- src/game/Player.cpp | 2 +- src/game/Player.h | 4 ++-- src/game/Unit.cpp | 2 +- src/game/Unit.h | 8 ++++---- src/shared/revision_nr.h | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 23379ca6a..f5aefac83 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -17595,7 +17595,7 @@ void Player::RemoveMiniPet() } } -Pet* Player::GetMiniPet() +Pet* Player::GetMiniPet() const { if (!m_miniPet) return NULL; diff --git a/src/game/Player.h b/src/game/Player.h index 8a03ecc97..f4e258a62 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1189,7 +1189,7 @@ class MANGOS_DLL_SPEC Player : public Unit void RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent = false); void RemoveMiniPet(); - Pet* GetMiniPet(); + Pet* GetMiniPet() const; void SetMiniPet(Pet* pet) { m_miniPet = pet->GetGUID(); } template @@ -2716,7 +2716,7 @@ template bool Player::CheckAllControlledUnits(Func const& func, bool withTotems, bool withGuardians, bool withCharms, bool withMiniPet) const { if (withMiniPet) - if(Unit* mini = GetMiniPet()) + if(Unit const* mini = GetMiniPet()) if (func(mini)) return true; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 22d07678a..ca8e033af 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -8549,7 +8549,7 @@ void Unit::CombatStopWithPets(bool includingCast) struct IsAttackingPlayerHelper { explicit IsAttackingPlayerHelper() {} - bool operator()(Unit* unit) const { return unit->isAttackingPlayer(); } + inline bool operator()(Unit const* unit) const { return unit->isAttackingPlayer(); } }; bool Unit::isAttackingPlayer() const diff --git a/src/game/Unit.h b/src/game/Unit.h index d02235dd6..76533ffcb 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1950,14 +1950,14 @@ void Unit::CallForAllControlledUnits(Func const& func, bool withTotems, bool wit template bool Unit::CheckAllControlledUnits(Func const& func, bool withTotems, bool withGuardians, bool withCharms) const { - if (Pet* pet = GetPet()) + if (Pet const* pet = GetPet()) if (func(pet)) return true; if (withGuardians) { for(GuardianPetList::const_iterator itr = m_guardianPets.begin(); itr != m_guardianPets.end(); ++itr) - if (Unit* guardian = Unit::GetUnit(*this,*itr)) + if (Unit const* guardian = Unit::GetUnit(*this,*itr)) if (func(guardian)) return true; @@ -1966,13 +1966,13 @@ bool Unit::CheckAllControlledUnits(Func const& func, bool withTotems, bool withG if (withTotems) { for (int i = 0; i < MAX_TOTEM_SLOT; ++i) - if (Unit *totem = _GetTotem(TotemSlot(i))) + if (Unit const* totem = _GetTotem(TotemSlot(i))) if (func(totem)) return true; } if (withCharms) - if(Unit* charm = GetCharm()) + if(Unit const* charm = GetCharm()) if (func(charm)) return true; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index c166a3537..ff8a742d6 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10065" + #define REVISION_NR "10066" #endif // __REVISION_NR_H__ From a0bbb0fec576d88cd7a217870a4c33166e8a0e54 Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Thu, 17 Jun 2010 00:29:05 +0200 Subject: [PATCH 18/42] [10067] Allow item INVTYPE_RELIC to be equipped by npc from creature_equip_template Signed-off-by: NoFantasy --- src/game/ObjectMgr.cpp | 3 ++- src/shared/revision_nr.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index dad541015..9874aece3 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -929,7 +929,8 @@ void ObjectMgr::LoadEquipmentTemplates() dbcitem->InventoryType != INVTYPE_WEAPONOFFHAND && dbcitem->InventoryType != INVTYPE_HOLDABLE && dbcitem->InventoryType != INVTYPE_THROWN && - dbcitem->InventoryType != INVTYPE_RANGEDRIGHT) + dbcitem->InventoryType != INVTYPE_RANGEDRIGHT && + dbcitem->InventoryType != INVTYPE_RELIC) { sLog.outErrorDb("Item (entry=%u) in creature_equip_template.equipentry%u for entry = %u is not equipable in a hand, forced to 0.", eqInfo->equipentry[j], j+1, i); const_cast(eqInfo)->equipentry[j] = 0; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index ff8a742d6..aeef1c1f4 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10066" + #define REVISION_NR "10067" #endif // __REVISION_NR_H__ From 492f467bccb1fb95f4709eb3ac305cf4d26b1e1c Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Wed, 16 Jun 2010 17:21:15 +0400 Subject: [PATCH 19/42] [10068] Fixes in pet movments * Use proper stop packet as expected. In case 0 trevel time used before move packet can generate infinity move forward (at client side). * Avoid reset top movegen before add idle in pet stay command. * Avoid assign random move to player owned creatures as default movegen. * Finish follow movegen init including need-stay case. --- src/game/Creature.cpp | 25 +------------------------ src/game/Creature.h | 1 - src/game/CreatureAISelector.cpp | 3 ++- src/game/DestinationHolderImp.h | 7 ++++++- src/game/PetHandler.cpp | 2 +- src/game/TargetedMovementGenerator.cpp | 11 ++++++++--- src/game/Traveller.h | 16 +++++++++++++++- src/game/Unit.cpp | 2 +- src/shared/revision_nr.h | 2 +- 9 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index d27c0d826..4d2bc717b 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -791,29 +791,6 @@ bool Creature::isCanTrainingAndResetTalentsOf(Player* pPlayer) const && pPlayer->getClass() == GetCreatureInfo()->trainer_class; } -void Creature::AI_SendMoveToPacket(float x, float y, float z, uint32 time, SplineFlags flags, SplineType type) -{ - /* uint32 timeElap = getMSTime(); - if ((timeElap - m_startMove) < m_moveTime) - { - oX = (dX - oX) * ( (timeElap - m_startMove) / m_moveTime ); - oY = (dY - oY) * ( (timeElap - m_startMove) / m_moveTime ); - } - else - { - oX = dX; - oY = dY; - } - - dX = x; - dY = y; - m_orientation = atan2((oY - dY), (oX - dX)); - - m_startMove = getMSTime(); - m_moveTime = time;*/ - SendMonsterMove(x, y, z, type, flags, time); -} - void Creature::PrepareBodyLootState() { loot.clear(); @@ -2221,4 +2198,4 @@ void Creature::RelocationNotify() MaNGOS::CreatureRelocationNotifier relocationNotifier(*this); float radius = MAX_CREATURE_ATTACK_RADIUS * sWorld.getConfig(CONFIG_FLOAT_RATE_CREATURE_AGGRO); Cell::VisitAllObjects(this, relocationNotifier, radius); -} +} \ No newline at end of file diff --git a/src/game/Creature.h b/src/game/Creature.h index c6dff5dfc..af068e33f 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -444,7 +444,6 @@ class MANGOS_DLL_SPEC Creature : public Unit bool AIM_Initialize(); - void AI_SendMoveToPacket(float x, float y, float z, uint32 time, SplineFlags MovementFlags, SplineType type); CreatureAI* AI() { return i_AI; } void AddSplineFlag(SplineFlags f) diff --git a/src/game/CreatureAISelector.cpp b/src/game/CreatureAISelector.cpp index 4b78c329d..96645c239 100644 --- a/src/game/CreatureAISelector.cpp +++ b/src/game/CreatureAISelector.cpp @@ -90,7 +90,8 @@ namespace FactorySelector { MovementGeneratorRegistry &mv_registry(MovementGeneratorRepository::Instance()); ASSERT( creature->GetCreatureInfo() != NULL ); - const MovementGeneratorCreator *mv_factory = mv_registry.GetRegistryItem( creature->GetDefaultMovementType()); + MovementGeneratorCreator const * mv_factory = mv_registry.GetRegistryItem( + creature->GetOwnerGUID() ? FOLLOW_MOTION_TYPE : creature->GetDefaultMovementType()); /* if( mv_factory == NULL ) { diff --git a/src/game/DestinationHolderImp.h b/src/game/DestinationHolderImp.h index b4932944b..32ca246b4 100644 --- a/src/game/DestinationHolderImp.h +++ b/src/game/DestinationHolderImp.h @@ -86,7 +86,12 @@ DestinationHolder::StartTravel(TRAVELLER &traveller, bool sendMove) i_totalTravelTime = traveller.GetTotalTrevelTimeTo(i_destX,i_destY,i_destZ); i_timeElapsed = 0; if(sendMove) - traveller.MoveTo(i_destX, i_destY, i_destZ, i_totalTravelTime); + { + if (i_totalTravelTime) + traveller.MoveTo(i_destX, i_destY, i_destZ, i_totalTravelTime); + else + traveller.Stop(); + } return i_totalTravelTime; } diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index e306f8078..77b018a52 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -86,7 +86,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) { case COMMAND_STAY: //flat=1792 //STAY pet->StopMoving(); - pet->GetMotionMaster()->Clear(); + pet->GetMotionMaster()->Clear(false); pet->GetMotionMaster()->MoveIdle(); charmInfo->SetCommandState( COMMAND_STAY ); break; diff --git a/src/game/TargetedMovementGenerator.cpp b/src/game/TargetedMovementGenerator.cpp index b59e6c8f1..efc52bfc8 100644 --- a/src/game/TargetedMovementGenerator.cpp +++ b/src/game/TargetedMovementGenerator.cpp @@ -37,12 +37,17 @@ void TargetedMovementGeneratorMedium::_setTargetLocation(T &owner) if (owner.hasUnitState(UNIT_STAT_NOT_MOVE)) return; + float x, y, z; + // prevent redundant micro-movement for pets, other followers. if (i_offset && i_target->IsWithinDistInMap(&owner,2*i_offset)) - return; + { + if (i_destinationHolder.HasDestination()) + return; - float x, y, z; - if (!i_offset) + owner.GetPosition(x, y, z); + } + else if (!i_offset) { // to nearest contact position i_target->GetContactPoint( &owner, x, y, z ); diff --git a/src/game/Traveller.h b/src/game/Traveller.h index dd5fad5a0..d854f3294 100644 --- a/src/game/Traveller.h +++ b/src/game/Traveller.h @@ -55,6 +55,7 @@ struct MANGOS_DLL_DECL Traveller void Relocation(float x, float y, float z, float orientation) {} void Relocation(float x, float y, float z) { Relocation(x, y, z, i_traveller.GetOrientation()); } void MoveTo(float x, float y, float z, uint32 t) {} + void Stop() {} }; template @@ -102,7 +103,13 @@ inline float Traveller::GetMoveDestinationTo(float x, float y, float z template<> inline void Traveller::MoveTo(float x, float y, float z, uint32 t) { - i_traveller.AI_SendMoveToPacket(x, y, z, t, i_traveller.GetSplineFlags(), SPLINETYPE_NORMAL); + i_traveller.SendMonsterMove(x, y, z, SPLINETYPE_NORMAL, i_traveller.GetSplineFlags(), t); +} + +template<> +inline void Traveller::Stop() +{ + i_traveller.SendMonsterMove(i_traveller.GetPositionX(), i_traveller.GetPositionY(), i_traveller.GetPositionZ(), SPLINETYPE_STOP, i_traveller.GetSplineFlags(), 0); } // specialization for players @@ -141,6 +148,13 @@ inline void Traveller::MoveTo(float x, float y, float z, uint32 t) i_traveller.SendMonsterMove(x, y, z, SPLINETYPE_NORMAL, SPLINEFLAG_WALKMODE, t); } +template<> +inline void Traveller::Stop() +{ + //Only send SPLINEFLAG_WALKMODE, client has strange issues with other move flags + i_traveller.SendMonsterMove(i_traveller.GetPositionX(), i_traveller.GetPositionY(), i_traveller.GetPositionZ(), SPLINETYPE_STOP, SPLINEFLAG_WALKMODE, 0); +} + typedef Traveller CreatureTraveller; typedef Traveller PlayerTraveller; #endif diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index ca8e033af..fb064a128 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -12783,7 +12783,7 @@ void Unit::StopMoving() // send explicit stop packet // player expected for correct work SPLINEFLAG_WALKMODE - SendMonsterMove(GetPositionX(), GetPositionY(), GetPositionZ(), SPLINETYPE_NORMAL, GetTypeId() == TYPEID_PLAYER ? SPLINEFLAG_WALKMODE : SPLINEFLAG_NONE, 0); + SendMonsterMove(GetPositionX(), GetPositionY(), GetPositionZ(), SPLINETYPE_STOP, GetTypeId() == TYPEID_PLAYER ? SPLINEFLAG_WALKMODE : SPLINEFLAG_NONE, 0); // update position and orientation for near players WorldPacket data; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index aeef1c1f4..ce3b4eb93 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10067" + #define REVISION_NR "10068" #endif // __REVISION_NR_H__ From b261529d31e055f72c6be15b7d3ff665232d1656 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 17 Jun 2010 02:50:52 +0400 Subject: [PATCH 20/42] [10069] Really do "Avoid assign random move to player owned creatures as default movegen." --- src/game/CreatureAISelector.cpp | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/CreatureAISelector.cpp b/src/game/CreatureAISelector.cpp index 96645c239..87eb1fe97 100644 --- a/src/game/CreatureAISelector.cpp +++ b/src/game/CreatureAISelector.cpp @@ -91,7 +91,7 @@ namespace FactorySelector MovementGeneratorRegistry &mv_registry(MovementGeneratorRepository::Instance()); ASSERT( creature->GetCreatureInfo() != NULL ); MovementGeneratorCreator const * mv_factory = mv_registry.GetRegistryItem( - creature->GetOwnerGUID() ? FOLLOW_MOTION_TYPE : creature->GetDefaultMovementType()); + IS_PLAYER_GUID(creature->GetOwnerGUID()) ? FOLLOW_MOTION_TYPE : creature->GetDefaultMovementType()); /* if( mv_factory == NULL ) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index ce3b4eb93..4bf04c17a 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10068" + #define REVISION_NR "10069" #endif // __REVISION_NR_H__ From 9091d56e70581022d4ce9572bfac708fba383502 Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Thu, 17 Jun 2010 01:03:56 +0200 Subject: [PATCH 21/42] [10070] Remove old, commented code no longer needed in SendMonsterMove Signed-off-by: NoFantasy --- src/game/Unit.cpp | 7 +------ src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index fb064a128..ae445a10a 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -382,12 +382,7 @@ void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, SplineTy break; } - data << uint32(flags); - - // enable me if things goes wrong or looks ugly, it is however an old hack - // if(flags & SPLINEFLAG_WALKMODE) - // moveTime *= 1.05f; - + data << uint32(flags); // splineflags data << uint32(moveTime); // Time in between points data << uint32(1); // 1 single waypoint data << NewPosX << NewPosY << NewPosZ; // the single waypoint Point B diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 4bf04c17a..1d5ff105e 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10069" + #define REVISION_NR "10070" #endif // __REVISION_NR_H__ From 523584766b685de9c5c821905eae334742aabb58 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 17 Jun 2010 05:31:01 +0400 Subject: [PATCH 22/42] [10071] Not need add new cases inline for in-class function definition. This is redundant from current C++ standart point. --- src/game/Unit.cpp | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index ae445a10a..048f7d6a1 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -8544,7 +8544,7 @@ void Unit::CombatStopWithPets(bool includingCast) struct IsAttackingPlayerHelper { explicit IsAttackingPlayerHelper() {} - inline bool operator()(Unit const* unit) const { return unit->isAttackingPlayer(); } + bool operator()(Unit const* unit) const { return unit->isAttackingPlayer(); } }; bool Unit::isAttackingPlayer() const diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 1d5ff105e..7a389e19d 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10070" + #define REVISION_NR "10071" #endif // __REVISION_NR_H__ From 33d73f2efc86084600e68e7df80efd9d9dcfdecd Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 17 Jun 2010 05:58:05 +0400 Subject: [PATCH 23/42] [10072] More methods for access/modify ObjectGuid update fields. * Some related cleanups. * Also drop unused Player::SetFarSightGUID decalration as reported by LordJZ. --- src/game/MiscHandler.cpp | 4 ++-- src/game/Object.h | 11 +++++++---- src/game/Player.h | 3 +-- src/shared/revision_nr.h | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index bf03a3046..461369732 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -1294,10 +1294,10 @@ void WorldSession::HandleFarSightOpcode( WorldPacket & recv_data ) //WorldPacket data(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, 0) //SendPacket(&data); //_player->SetUInt64Value(PLAYER_FARSIGHT, 0); - DEBUG_LOG("Removed FarSight from player %u", _player->GetGUIDLow()); + DEBUG_LOG("Removed FarSight from %s", _player->GetObjectGuid().GetString().c_str()); break; case 1: - DEBUG_LOG("Added FarSight (GUID:%u TypeId:%u) to player %u", GUID_LOPART(_player->GetFarSight()), GuidHigh2TypeId(GUID_HIPART(_player->GetFarSight())), _player->GetGUIDLow()); + DEBUG_LOG("Added FarSight %s to %s", _player->GetFarSightGuid().GetString().c_str(), _player->GetObjectGuid().GetString().c_str()); break; } } diff --git a/src/game/Object.h b/src/game/Object.h index c214a9dd4..22b86ffcf 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -108,11 +108,11 @@ class MANGOS_DLL_SPEC Object m_inWorld = false; } - ObjectGuid const& GetObjectGuid() const { return *reinterpret_cast(&GetUInt64Value(0)); } - - const uint64& GetGUID() const { return GetUInt64Value(0); } - uint32 GetGUIDLow() const { return GUID_LOPART(GetUInt64Value(0)); } + ObjectGuid const& GetObjectGuid() const { return GetGuidValue(OBJECT_FIELD_GUID); } + const uint64& GetGUID() const { return GetUInt64Value(OBJECT_FIELD_GUID); } + uint32 GetGUIDLow() const { return GUID_LOPART(GetUInt64Value(OBJECT_FIELD_GUID)); } PackedGuid const& GetPackGUID() const { return m_PackGUID; } + uint32 GetEntry() const { return GetUInt32Value(OBJECT_FIELD_ENTRY); } void SetEntry(uint32 entry) { SetUInt32Value(OBJECT_FIELD_ENTRY, entry); } @@ -171,6 +171,8 @@ class MANGOS_DLL_SPEC Object return *(((uint16*)&m_uint32Values[ index ])+offset); } + ObjectGuid const& GetGuidValue( uint16 index ) const { return *reinterpret_cast(&GetUInt64Value(index)); } + void SetInt32Value( uint16 index, int32 value ); void SetUInt32Value( uint16 index, uint32 value ); void SetUInt64Value( uint16 index, const uint64 &value ); @@ -178,6 +180,7 @@ class MANGOS_DLL_SPEC Object void SetByteValue( uint16 index, uint8 offset, uint8 value ); void SetUInt16Value( uint16 index, uint8 offset, uint16 value ); void SetInt16Value( uint16 index, uint8 offset, int16 value ) { SetUInt16Value(index,offset,(uint16)value); } + void SetGuidValue( uint16 index, ObjectGuid const& value ) { SetUInt64Value(index, value.GetRawValue()); } void SetStatFloatValue( uint16 index, float value); void SetStatInt32Value( uint16 index, int32 value); diff --git a/src/game/Player.h b/src/game/Player.h index f4e258a62..ef9660483 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -2216,8 +2216,7 @@ class MANGOS_DLL_SPEC Player : public Unit void EnterVehicle(Vehicle *vehicle); void ExitVehicle(Vehicle *vehicle); - uint64 GetFarSight() const { return GetUInt64Value(PLAYER_FARSIGHT); } - void SetFarSightGUID(uint64 guid); + ObjectGuid const& GetFarSightGuid() const { return GetGuidValue(PLAYER_FARSIGHT); } // Transports Transport * GetTransport() const { return m_transport; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 7a389e19d..f02622c7a 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10071" + #define REVISION_NR "10072" #endif // __REVISION_NR_H__ From 6ca609629c131b2f2f6cd1404462517f554edf53 Mon Sep 17 00:00:00 2001 From: SilverIce Date: Thu, 17 Jun 2010 20:24:32 +0400 Subject: [PATCH 24/42] [10073] Make object active at applying view on it also isActiveObject check moved to WorldObject - all worldobjects are inactive by default, excluding players this is a final part of cameras implementation (based on commit efc9623) Signed-off-by: VladimirMangos Also remove template-way code selection for object for Map::AddToActive/Map::RemoveFromActive. This simplify function use from not Map code. --- src/game/Camera.cpp | 17 +++++++--- src/game/Camera.h | 2 ++ src/game/Corpse.h | 2 -- src/game/Creature.cpp | 2 +- src/game/Creature.h | 2 -- src/game/DynamicObject.cpp | 6 +--- src/game/DynamicObject.h | 2 -- src/game/GameObject.h | 1 - src/game/Map.cpp | 67 ++++++++++++++++++++++++-------------- src/game/Map.h | 32 ++---------------- src/game/Object.cpp | 3 +- src/game/Object.h | 3 ++ src/game/Player.cpp | 2 ++ src/game/Player.h | 1 - src/shared/revision_nr.h | 2 +- 15 files changed, 69 insertions(+), 75 deletions(-) diff --git a/src/game/Camera.cpp b/src/game/Camera.cpp index b151ec556..2c37b15e8 100644 --- a/src/game/Camera.cpp +++ b/src/game/Camera.cpp @@ -39,6 +39,9 @@ void Camera::SetView(WorldObject *obj) { 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"); @@ -51,8 +54,16 @@ void Camera::SetView(WorldObject *obj) 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); UpdateForCurrentViewPoint(); @@ -66,11 +77,7 @@ void Camera::Event_ViewPointVisibilityChanged() void Camera::ResetView() { - m_source->GetViewPoint().Detach(this); - m_source = &m_owner; - m_source->GetViewPoint().Attach(this); - - UpdateForCurrentViewPoint(); + SetView(&m_owner); } void Camera::Event_AddedToWorld() diff --git a/src/game/Camera.h b/src/game/Camera.h index 65bd6b88c..a28d71c30 100644 --- a/src/game/Camera.h +++ b/src/game/Camera.h @@ -89,6 +89,8 @@ public: ViewPoint() : m_grid(0), m_camera_iter(m_cameras.end()) {} ~ViewPoint(); + bool hasViewers() const { return !m_cameras.empty(); } + // these events are called when viewpoint changes visibility state void Event_AddedToWorld(GridType *grid) { diff --git a/src/game/Corpse.h b/src/game/Corpse.h index e01523850..fd867e550 100644 --- a/src/game/Corpse.h +++ b/src/game/Corpse.h @@ -90,8 +90,6 @@ class Corpse : public WorldObject GridReference &GetGridRef() { return m_gridRef; } - bool isActiveObject() const { return false; } - bool IsExpired(time_t t) const; private: GridReference m_gridRef; diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 4d2bc717b..4305b3be7 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -117,7 +117,7 @@ m_subtype(subtype), m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m m_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false), m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false), m_needNotify(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), -m_creatureInfo(NULL), m_isActiveObject(false), m_splineFlags(SPLINEFLAG_WALKMODE) +m_creatureInfo(NULL), m_splineFlags(SPLINEFLAG_WALKMODE) { m_regenTimer = 200; m_valuesCount = UNIT_END; diff --git a/src/game/Creature.h b/src/game/Creature.h index af068e33f..23d47e573 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -626,7 +626,6 @@ class MANGOS_DLL_SPEC Creature : public Unit void SetDeadByDefault (bool death_state) { m_isDeadByDefault = death_state; } - bool isActiveObject() const { return m_isActiveObject || HasAuraType(SPELL_AURA_BIND_SIGHT) || HasAuraType(SPELL_AURA_FAR_SIGHT); } void SetActiveObjectState(bool on); void SetNeedNotify() { m_needNotify = true; } @@ -691,7 +690,6 @@ class MANGOS_DLL_SPEC Creature : public Unit private: GridReference m_gridRef; CreatureInfo const* m_creatureInfo; // in difficulty mode > 0 can different from ObjMgr::GetCreatureTemplate(GetEntry()) - bool m_isActiveObject; SplineFlags m_splineFlags; }; diff --git a/src/game/DynamicObject.cpp b/src/game/DynamicObject.cpp index cde2529af..9c55c6b17 100644 --- a/src/game/DynamicObject.cpp +++ b/src/game/DynamicObject.cpp @@ -27,7 +27,7 @@ #include "GridNotifiersImpl.h" #include "SpellMgr.h" -DynamicObject::DynamicObject() : WorldObject(), m_isActiveObject(false) +DynamicObject::DynamicObject() : WorldObject() { m_objectType |= TYPEMASK_DYNAMICOBJECT; m_objectTypeId = TYPEID_DYNAMICOBJECT; @@ -83,10 +83,6 @@ bool DynamicObject::Create( uint32 guidlow, Unit *caster, uint32 spellId, SpellE m_effIndex = effIndex; m_spellId = spellId; - // set to active for far sight case - if(SpellEntry const* spellEntry = sSpellStore.LookupEntry(spellId)) - m_isActiveObject = IsSpellHaveEffect(spellEntry,SPELL_EFFECT_ADD_FARSIGHT); - return true; } diff --git a/src/game/DynamicObject.h b/src/game/DynamicObject.h index fffdbec20..3dbcd66d5 100644 --- a/src/game/DynamicObject.h +++ b/src/game/DynamicObject.h @@ -61,7 +61,6 @@ class DynamicObject : public WorldObject GridReference &GetGridRef() { return m_gridRef; } - bool isActiveObject() const { return m_isActiveObject; } protected: uint32 m_spellId; SpellEffectIndex m_effIndex; @@ -70,6 +69,5 @@ class DynamicObject : public WorldObject AffectedSet m_affected; private: GridReference m_gridRef; - bool m_isActiveObject; }; #endif diff --git a/src/game/GameObject.h b/src/game/GameObject.h index 0e48cb722..657dad3df 100644 --- a/src/game/GameObject.h +++ b/src/game/GameObject.h @@ -703,7 +703,6 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject GridReference &GetGridRef() { return m_gridRef; } - bool isActiveObject() const { return false; } uint64 GetRotation() const { return m_rotation; } protected: uint32 m_spellId; diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 83718c71b..d27e35570 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -1640,44 +1640,63 @@ 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 = MaNGOS::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 = MaNGOS::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 = MaNGOS::ComputeGridPair(x, y); + if(getNGrid(p.x_coord, p.y_coord)) + getNGrid(p.x_coord, p.y_coord)->incUnloadActiveLock(); + else + { + GridPair p2 = MaNGOS::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 = MaNGOS::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 = MaNGOS::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 = MaNGOS::ComputeGridPair(x, y); + if(getNGrid(p.x_coord, p.y_coord)) + getNGrid(p.x_coord, p.y_coord)->decUnloadActiveLock(); + else + { + GridPair p2 = MaNGOS::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); + } } } } diff --git a/src/game/Map.h b/src/game/Map.h index 8ba96e803..1a2efe97a 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -232,16 +232,9 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj void ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* source, Object* target); // must called with AddToWorld - template - void AddToActive(T* obj) { AddToActiveHelper(obj); } - - void AddToActive(Creature* obj); - + void AddToActive(WorldObject* obj); // must called with RemoveFromWorld - template - void RemoveFromActive(T* obj) { RemoveFromActiveHelper(obj); } - - void RemoveFromActive(Creature* obj); + void RemoveFromActive(WorldObject* obj); Creature* GetCreature(ObjectGuid guid); Vehicle* GetVehicle(ObjectGuid guid); @@ -358,27 +351,6 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj template void DeleteFromWorld(T*); - - template - void AddToActiveHelper(T* obj) - { - m_activeNonPlayers.insert(obj); - } - - template - void RemoveFromActiveHelper(T* obj) - { - // 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); - } }; enum InstanceResetMethod diff --git a/src/game/Object.cpp b/src/game/Object.cpp index c78a2e397..191fd3b24 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1085,7 +1085,8 @@ void Object::BuildUpdateData( UpdateDataMapType& /*update_players */) WorldObject::WorldObject() : m_currMap(NULL), m_mapId(0), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL), - m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f) + m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f), + m_isActiveObject(false) { } diff --git a/src/game/Object.h b/src/game/Object.h index 22b86ffcf..5ae719791 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -480,6 +480,8 @@ class MANGOS_DLL_SPEC WorldObject : public Object Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime); + bool isActiveObject() const { return m_isActiveObject || m_viewPoint.hasViewers(); } + ViewPoint& GetViewPoint() { return m_viewPoint; } protected: explicit WorldObject(); @@ -492,6 +494,7 @@ class MANGOS_DLL_SPEC WorldObject : public Object std::string m_name; + bool m_isActiveObject; private: Map * m_currMap; //current object's Map location diff --git a/src/game/Player.cpp b/src/game/Player.cpp index f5aefac83..c8a0f4aad 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -417,6 +417,8 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa m_valuesCount = PLAYER_END; + m_isActiveObject = true; // player is always active object + m_session = session; m_divider = 0; diff --git a/src/game/Player.h b/src/game/Player.h index ef9660483..942d68fdd 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -2355,7 +2355,6 @@ class MANGOS_DLL_SPEC Player : public Unit bool HasTitle(CharTitlesEntry const* title) { return HasTitle(title->bit_index); } void SetTitle(CharTitlesEntry const* title, bool lost = false); - bool isActiveObject() const { return true; } bool canSeeSpellClickOn(Creature const* creature) const; protected: diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index f02622c7a..a01f657a1 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10072" + #define REVISION_NR "10073" #endif // __REVISION_NR_H__ From 07a931e14147b1d1032a0f12c4d0da91dc8f31f9 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Fri, 18 Jun 2010 02:16:29 +0400 Subject: [PATCH 25/42] [10074] Add IsPassive(SpellEntry*) function and use in cases wjern entry already known. Some other small code cleanups --- src/game/Level3.cpp | 2 +- src/game/Object.cpp | 5 ++--- src/game/Pet.cpp | 4 ++-- src/game/PetHandler.cpp | 4 ++-- src/game/Player.cpp | 4 ++-- src/game/Spell.cpp | 6 +++--- src/game/SpellAuras.cpp | 6 +++--- src/game/SpellHandler.cpp | 4 ++-- src/game/SpellMgr.cpp | 13 +++++++++---- src/game/SpellMgr.h | 12 +++++------- src/game/Unit.cpp | 6 +++--- src/shared/revision_nr.h | 2 +- 12 files changed, 35 insertions(+), 33 deletions(-) diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 6ed7809e3..800bea9fb 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -2832,7 +2832,7 @@ void ChatHandler::ShowSpellListHelper(Player* target, SpellEntry const* spellInf uint32 talentCost = GetTalentSpellCost(id); bool talent = (talentCost > 0); - bool passive = IsPassiveSpell(id); + bool passive = IsPassiveSpell(spellInfo); bool active = target && target->HasAura(id); // unit32 used to prevent interpreting uint8 as char at output diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 191fd3b24..5a6492a80 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1084,9 +1084,8 @@ void Object::BuildUpdateData( UpdateDataMapType& /*update_players */) } WorldObject::WorldObject() - : m_currMap(NULL), m_mapId(0), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL), - m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f), - m_isActiveObject(false) + : m_isActiveObject(false), m_currMap(NULL), m_mapId(0), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL), + m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f) { } diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index c077d0a4b..395ea51ed 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -1313,7 +1313,7 @@ bool Pet::addSpell(uint32 spell_id,ActiveStates active /*= ACT_DECIDE*/, PetSpel if(active == ACT_DECIDE) //active was not used before, so we save it's autocast/passive state here { - if(IsPassiveSpell(spell_id)) + if(IsPassiveSpell(spellInfo)) newspell.active = ACT_PASSIVE; else newspell.active = ACT_DISABLED; @@ -1369,7 +1369,7 @@ bool Pet::addSpell(uint32 spell_id,ActiveStates active /*= ACT_DECIDE*/, PetSpel m_spells[spell_id] = newspell; - if (IsPassiveSpell(spell_id)) + if (IsPassiveSpell(spellInfo)) CastSpell(this, spell_id, true); else m_charmInfo->AddSpellToActionBar(spell_id, ActiveStates(newspell.active)); diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index 77b018a52..57356b38a 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -191,7 +191,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) } // do not cast not learned spells - if(!pet->HasSpell(spellid) || IsPassiveSpell(spellid)) + if(!pet->HasSpell(spellid) || IsPassiveSpell(spellInfo)) return; pet->clearUnitState(UNIT_STAT_MOVING); @@ -626,7 +626,7 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket ) } // do not cast not learned spells - if (!pet->HasSpell(spellid) || IsPassiveSpell(spellid)) + if (!pet->HasSpell(spellid) || IsPassiveSpell(spellInfo)) return; SpellCastTargets targets; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index c8a0f4aad..2af1cd7ca 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -3063,7 +3063,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen if(active) { - if (IsPassiveSpell(spell_id) && IsNeedCastPassiveSpellAtLearn(spellInfo)) + if (IsPassiveSpell(spellInfo) && IsNeedCastPassiveSpellAtLearn(spellInfo)) CastSpell (this, spell_id, true); } else if(IsInWorld()) @@ -3254,7 +3254,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen CastSpell(this, spell_id, true); } // also cast passive spells (including all talents without SPELL_EFFECT_LEARN_SPELL) with additional checks - else if (IsPassiveSpell(spell_id)) + else if (IsPassiveSpell(spellInfo)) { if (IsNeedCastPassiveSpellAtLearn(spellInfo)) CastSpell(this, spell_id, true); diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 6597d88e4..0094ef6cd 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -4253,7 +4253,7 @@ SpellCastResult Spell::CheckCast(bool strict) // auto selection spell rank implemented in WorldSession::HandleCastSpellOpcode // this case can be triggered if rank not found (too low-level target for first rank) - if (m_caster->GetTypeId() == TYPEID_PLAYER && !IsPassiveSpell(m_spellInfo->Id) && !m_CastItem) + if (m_caster->GetTypeId() == TYPEID_PLAYER && !IsPassiveSpell(m_spellInfo) && !m_CastItem) { for(int i = 0; i < MAX_EFFECT_INDEX; ++i) { @@ -4448,7 +4448,7 @@ SpellCastResult Spell::CheckCast(bool strict) // not let players cast spells at mount (and let do it to creatures) if (m_caster->IsMounted() && m_caster->GetTypeId()==TYPEID_PLAYER && !m_IsTriggeredSpell && - !IsPassiveSpell(m_spellInfo->Id) && !(m_spellInfo->Attributes & SPELL_ATTR_CASTABLE_WHILE_MOUNTED)) + !IsPassiveSpell(m_spellInfo) && !(m_spellInfo->Attributes & SPELL_ATTR_CASTABLE_WHILE_MOUNTED)) { if (m_caster->isInFlight()) return SPELL_FAILED_NOT_ON_TAXI; @@ -4457,7 +4457,7 @@ SpellCastResult Spell::CheckCast(bool strict) } // always (except passive spells) check items (focus object can be required for any type casts) - if (!IsPassiveSpell(m_spellInfo->Id)) + if (!IsPassiveSpell(m_spellInfo)) { SpellCastResult castResult = CheckItems(); if(castResult != SPELL_CAST_OK) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index c99639ee2..47619f796 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -386,7 +386,7 @@ m_isRemovedOnShapeLost(true), m_in_use(0), m_deleted(false) m_currentBasePoints = currentBasePoints ? *currentBasePoints : m_spellProto->CalculateSimpleValue(eff); - m_isPassive = IsPassiveSpell(GetId()); + m_isPassive = IsPassiveSpell(GetSpellProto()); m_positive = IsPositiveEffect(GetId(), m_effIndex); m_isSingleTargetAura = IsSingleTargetSpell(m_spellProto); @@ -633,7 +633,7 @@ void Aura::Update(uint32 diff) Unit* caster = GetCaster(); if(!caster) { - m_target->RemoveAura(GetId(), GetEffIndex()); + m_target->RemoveAurasByCasterSpell(GetId(), GetEffIndex(), GetCasterGUID()); return; } @@ -648,7 +648,7 @@ void Aura::Update(uint32 diff) if(!caster->IsWithinDistInMap(m_target, max_range)) { - m_target->RemoveAura(GetId(), GetEffIndex()); + m_target->RemoveAurasByCasterSpell(GetId(), GetEffIndex(), GetCasterGUID()); return; } } diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp index f42a18c11..641ac3573 100644 --- a/src/game/SpellHandler.cpp +++ b/src/game/SpellHandler.cpp @@ -332,7 +332,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) if (mover->GetTypeId()==TYPEID_PLAYER) { // not have spell in spellbook or spell passive and not casted by client - if (!((Player*)mover)->HasActiveSpell (spellId) || IsPassiveSpell(spellId) ) + if (!((Player*)mover)->HasActiveSpell (spellId) || IsPassiveSpell(spellInfo)) { sLog.outError("World: Player %u casts spell %u which he shouldn't have", mover->GetGUIDLow(), spellId); //cheater? kick? ban? @@ -343,7 +343,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) else { // not have spell in spellbook or spell passive and not casted by client - if (!((Creature*)mover)->HasSpell(spellId) || IsPassiveSpell(spellId) ) + if (!((Creature*)mover)->HasSpell(spellId) || IsPassiveSpell(spellInfo)) { //cheater? kick? ban? recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index a4c9651ae..aa7d320d2 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -283,6 +283,11 @@ bool IsPassiveSpell(uint32 spellId) SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); if (!spellInfo) return false; + return IsPassiveSpell(spellInfo); +} + +bool IsPassiveSpell(SpellEntry const *spellInfo) +{ return (spellInfo->Attributes & SPELL_ATTR_PASSIVE) != 0; } @@ -1607,7 +1612,7 @@ bool SpellMgr::IsRankSpellDueToSpell(SpellEntry const *spellInfo_1,uint32 spellI bool SpellMgr::canStackSpellRanks(SpellEntry const *spellInfo) { - if(IsPassiveSpell(spellInfo->Id)) // ranked passive spell + if(IsPassiveSpell(spellInfo)) // ranked passive spell return false; if(spellInfo->powerType != POWER_MANA && spellInfo->powerType != POWER_HEALTH) return false; @@ -2214,7 +2219,7 @@ bool SpellMgr::IsSkillBonusSpell(uint32 spellId) const SpellEntry const* SpellMgr::SelectAuraRankForPlayerLevel(SpellEntry const* spellInfo, uint32 playerLevel) const { // ignore passive spells - if(IsPassiveSpell(spellInfo->Id)) + if(IsPassiveSpell(spellInfo)) return spellInfo; bool needRankSelection = false; @@ -2588,7 +2593,7 @@ void SpellMgr::LoadSpellLearnSpells() // talent or passive spells or skill-step spells auto-casted and not need dependent learning, // pet teaching spells don't must be dependent learning (casted) // other required explicit dependent learning - dbc_node.autoLearned = entry->EffectImplicitTargetA[i]==TARGET_PET || GetTalentSpellCost(spell) > 0 || IsPassiveSpell(spell) || IsSpellHaveEffect(entry,SPELL_EFFECT_SKILL_STEP); + dbc_node.autoLearned = entry->EffectImplicitTargetA[i]==TARGET_PET || GetTalentSpellCost(spell) > 0 || IsPassiveSpell(entry) || IsSpellHaveEffect(entry,SPELL_EFFECT_SKILL_STEP); SpellLearnSpellMapBounds db_node_bounds = GetSpellLearnSpellMapBounds(spell); @@ -3974,4 +3979,4 @@ SpellEntry const* GetSpellEntryByDifficulty(uint32 id, Difficulty difficulty) SpellEntry const* spellEntry = sSpellStore.LookupEntry(spellDiff->spellId[difficulty]); return spellEntry; -} +} \ No newline at end of file diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 0108e78d3..2640b447d 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -210,10 +210,11 @@ bool IsSingleFromSpellSpecificSpellRanksPerTarget(SpellSpecific spellSpec1,Spell bool IsSingleFromSpellSpecificPerTarget(SpellSpecific spellSpec1,SpellSpecific spellSpec2); bool IsPassiveSpell(uint32 spellId); +bool IsPassiveSpell(SpellEntry const* spellProto); inline bool IsPassiveSpellStackableWithRanks(SpellEntry const* spellProto) { - if(!IsPassiveSpell(spellProto->Id)) + if(!IsPassiveSpell(spellProto)) return false; return !IsSpellHaveEffect(spellProto,SPELL_EFFECT_APPLY_AURA); @@ -371,12 +372,9 @@ inline bool IsAreaAuraEffect(uint32 effect) inline bool IsDispelSpell(SpellEntry const *spellInfo) { - if (spellInfo->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_DISPEL || - spellInfo->Effect[EFFECT_INDEX_1] == SPELL_EFFECT_DISPEL || - spellInfo->Effect[EFFECT_INDEX_2] == SPELL_EFFECT_DISPEL ) - return true; - return false; + return IsSpellHaveEffect(spellInfo, SPELL_EFFECT_DISPEL); } + inline bool isSpellBreakStealth(SpellEntry const* spellInfo) { return !(spellInfo->AttributesEx & SPELL_ATTR_EX_NOT_BREAK_STEALTH); @@ -1064,4 +1062,4 @@ class SpellMgr }; #define sSpellMgr SpellMgr::Instance() -#endif +#endif \ No newline at end of file diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 048f7d6a1..9f22d733c 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -4006,7 +4006,7 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur) SpellEffectIndex effIndex = Aur->GetEffIndex(); // passive spell special case (only non stackable with ranks) - if(IsPassiveSpell(spellId)) + if(IsPassiveSpell(spellProto)) { if(IsPassiveSpellStackableWithRanks(spellProto)) return true; @@ -4029,7 +4029,7 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur) uint32 i_spellId = i_spellProto->Id; // early checks that spellId is passive non stackable spell - if(IsPassiveSpell(i_spellId)) + if(IsPassiveSpell(i_spellProto)) { // passive non-stackable spells not stackable only for same caster if(Aur->GetCasterGUID()!=i->second->GetCasterGUID()) @@ -8610,7 +8610,7 @@ void Unit::ModifyAuraState(AuraState flag, bool apply) { if(itr->second.state == PLAYERSPELL_REMOVED) continue; SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first); - if (!spellInfo || !IsPassiveSpell(itr->first)) continue; + if (!spellInfo || !IsPassiveSpell(spellInfo)) continue; if (spellInfo->CasterAuraState == flag) CastSpell(this, itr->first, true, NULL); } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index a01f657a1..55d41e6ae 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10073" + #define REVISION_NR "10074" #endif // __REVISION_NR_H__ From 81851074ad077770d78ec748d596f60de8ee1653 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Fri, 18 Jun 2010 04:03:08 +0400 Subject: [PATCH 26/42] [10075] Attempt use more expected by result buffs downranking algo. * In small rate more fast * Not affect non-buff ranked spells like 10909 --- src/game/Spell.cpp | 18 ++++-------------- src/game/SpellAuras.cpp | 2 +- src/game/SpellHandler.cpp | 6 ++---- src/game/SpellMgr.cpp | 27 +++++++++++++++++---------- src/game/SpellMgr.h | 21 ++++++++++++++++++++- src/shared/revision_nr.h | 2 +- 6 files changed, 45 insertions(+), 31 deletions(-) diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 0094ef6cd..3a8abf1be 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -4253,21 +4253,11 @@ SpellCastResult Spell::CheckCast(bool strict) // auto selection spell rank implemented in WorldSession::HandleCastSpellOpcode // this case can be triggered if rank not found (too low-level target for first rank) - if (m_caster->GetTypeId() == TYPEID_PLAYER && !IsPassiveSpell(m_spellInfo) && !m_CastItem) + if (m_caster->GetTypeId() == TYPEID_PLAYER && !m_CastItem && !m_IsTriggeredSpell) { - for(int i = 0; i < MAX_EFFECT_INDEX; ++i) - { - // check only spell that apply positive auras - if (m_spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA && - IsPositiveEffect(m_spellInfo->Id, SpellEffectIndex(i)) && - // at not self target - !IsCasterSourceTarget(m_spellInfo->EffectImplicitTargetA[i]) && - // and target low level - target->getLevel() + 10 < m_spellInfo->spellLevel) - { - return SPELL_FAILED_LOWLEVEL; - } - } + // spell expected to be auto-downranking in cast handle, so must be same + if (m_spellInfo != sSpellMgr.SelectAuraRankForLevel(m_spellInfo, target->getLevel())) + return SPELL_FAILED_LOWLEVEL; } } else if (m_caster == target) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 47619f796..8ff7d2f10 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -813,7 +813,7 @@ void AreaAura::Update(uint32 diff) if(!apply) continue; - if(SpellEntry const *actualSpellInfo = sSpellMgr.SelectAuraRankForPlayerLevel(GetSpellProto(), (*tIter)->getLevel())) + if(SpellEntry const *actualSpellInfo = sSpellMgr.SelectAuraRankForLevel(GetSpellProto(), (*tIter)->getLevel())) { int32 actualBasePoints = m_currentBasePoints; // recalculate basepoints for lower rank (all AreaAura spell not use custom basepoints?) diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp index 641ac3573..b70d1494d 100644 --- a/src/game/SpellHandler.cpp +++ b/src/game/SpellHandler.cpp @@ -376,12 +376,10 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) } // auto-selection buff level base at target level (in spellInfo) - if (targets.getUnitTarget()) + if (Unit* target = targets.getUnitTarget()) { - SpellEntry const *actualSpellInfo = sSpellMgr.SelectAuraRankForPlayerLevel(spellInfo,targets.getUnitTarget()->getLevel()); - // if rank not found then function return NULL but in explicit cast case original spell can be casted and later failed with appropriate error message - if(actualSpellInfo) + if (SpellEntry const *actualSpellInfo = sSpellMgr.SelectAuraRankForLevel(spellInfo, target->getLevel())) spellInfo = actualSpellInfo; } diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index aa7d320d2..008c21cde 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -2216,37 +2216,44 @@ bool SpellMgr::IsSkillBonusSpell(uint32 spellId) const return false; } -SpellEntry const* SpellMgr::SelectAuraRankForPlayerLevel(SpellEntry const* spellInfo, uint32 playerLevel) const +SpellEntry const* SpellMgr::SelectAuraRankForLevel(SpellEntry const* spellInfo, uint32 level) const { - // ignore passive spells - if(IsPassiveSpell(spellInfo)) + // fast case + if (level + 10 >= spellInfo->spellLevel) + return spellInfo; + + // ignore selection for passive spells + if (IsPassiveSpell(spellInfo)) return spellInfo; bool needRankSelection = false; for(int i = 0; i < MAX_EFFECT_INDEX; ++i) { - if (IsPositiveEffect(spellInfo->Id, SpellEffectIndex(i)) && ( - spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA || + // for simple aura in check apply to any non caster based targets, in rank search mode to any explicit targets + if (((spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA && + (IsExplicitPositiveTarget(spellInfo->EffectImplicitTargetA[i]) || + IsAreaEffectPossitiveTarget(Targets(spellInfo->EffectImplicitTargetA[i])))) || spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY || - spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_RAID)) + spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_RAID) && + IsPositiveEffect(spellInfo->Id, SpellEffectIndex(i))) { needRankSelection = true; break; } } - // not required - if(!needRankSelection) + // not required (rank check more slow so check it here) + if (!needRankSelection || GetSpellRank(spellInfo->Id) == 0) return spellInfo; for(uint32 nextSpellId = spellInfo->Id; nextSpellId != 0; nextSpellId = GetPrevSpellInChain(nextSpellId)) { SpellEntry const *nextSpellInfo = sSpellStore.LookupEntry(nextSpellId); - if(!nextSpellInfo) + if (!nextSpellInfo) break; // if found appropriate level - if(playerLevel + 10 >= nextSpellInfo->spellLevel) + if (level + 10 >= spellInfo->spellLevel) return nextSpellInfo; // one rank less then diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 2640b447d..6c5b5508a 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -320,6 +320,25 @@ inline bool IsPointEffectTarget( Targets target ) return false; } +inline bool IsAreaEffectPossitiveTarget( Targets target ) +{ + switch (target ) + { + case TARGET_ALL_PARTY_AROUND_CASTER: + case TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER: + case TARGET_ALL_FRIENDLY_UNITS_IN_AREA: + case TARGET_ALL_PARTY: + case TARGET_ALL_PARTY_AROUND_CASTER_2: + case TARGET_AREAEFFECT_PARTY: + case TARGET_ALL_RAID_AROUND_CASTER: + case TARGET_AREAEFFECT_PARTY_AND_CLASS: + return true; + default: + break; + } + return false; +} + inline bool IsAreaEffectTarget( Targets target ) { switch (target ) @@ -904,7 +923,7 @@ class SpellMgr static bool canStackSpellRanks(SpellEntry const *spellInfo); bool IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) const; - SpellEntry const* SelectAuraRankForPlayerLevel(SpellEntry const* spellInfo, uint32 playerLevel) const; + SpellEntry const* SelectAuraRankForLevel(SpellEntry const* spellInfo, uint32 Level) const; // Spell learning SpellLearnSkillNode const* GetSpellLearnSkill(uint32 spell_id) const diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 55d41e6ae..dfa86d1f4 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10074" + #define REVISION_NR "10075" #endif // __REVISION_NR_H__ From 3e210228f99787efd1d86299b045cfdf0fd3a35e Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sat, 19 Jun 2010 02:24:43 +0400 Subject: [PATCH 27/42] [10076] Fixed crash at remove from world pet under SPELL_AURA_MOD_POSSESS_PET * Prevent crash at camera list update at attempt increment end() iterator. * Properly do unapply SPELL_AURA_MOD_POSSESS_PET (GetPet() can return NULL at call, and not need checked) * Propertly call unapply at delete auras cases for auras that set player-caster mover pointer. --- src/game/Camera.h | 10 ++++++++- src/game/SpellAuras.cpp | 44 ++++++++++++++++++++++++---------------- src/game/Unit.cpp | 15 +++++++++++++- src/shared/revision_nr.h | 2 +- 4 files changed, 50 insertions(+), 21 deletions(-) diff --git a/src/game/Camera.h b/src/game/Camera.h index a28d71c30..98431be04 100644 --- a/src/game/Camera.h +++ b/src/game/Camera.h @@ -80,8 +80,16 @@ class MANGOS_DLL_SPEC ViewPoint void CameraCall(void (Camera::*handler)()) { if (!m_cameras.empty()) - for(m_camera_iter = m_cameras.begin(); m_camera_iter!=m_cameras.end(); ++m_camera_iter) + { + for(m_camera_iter = m_cameras.begin(); m_camera_iter != m_cameras.end(); ++m_camera_iter) + { ((*m_camera_iter)->*handler)(); + + // can be end() after handler + if (m_camera_iter == m_cameras.end()) + break; + } + } } public: diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 8ff7d2f10..533c09805 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -3710,36 +3710,40 @@ void Aura::HandleModPossessPet(bool apply, bool Real) if(!caster || caster->GetTypeId() != TYPEID_PLAYER) return; - Pet *pet = caster->GetPet(); - if(!pet || pet != GetTarget()) + Unit* target = GetTarget(); + if (target->GetTypeId() != TYPEID_UNIT) return; + Creature* pet = (Creature*)target; // not need more stricted type check Player* p_caster = (Player*)caster; Camera& camera = p_caster->GetCamera(); - if(apply) + if (apply) { - pet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); camera.SetView(pet); - } - else - { - pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); - camera.ResetView(); - } + p_caster->SetCharm(pet); + p_caster->SetClientControl(pet, 1); + ((Player*)caster)->SetMover(pet); - p_caster->SetCharm(apply ? pet : NULL); - p_caster->SetClientControl(pet, apply ? 1 : 0); - ((Player*)caster)->SetMover(apply ? pet : NULL); + pet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); - if(apply) - { pet->StopMoving(); - pet->GetMotionMaster()->Clear(); + pet->GetMotionMaster()->Clear(false); pet->GetMotionMaster()->MoveIdle(); } else { + camera.ResetView(); + p_caster->SetCharm(NULL); + p_caster->SetClientControl(pet, 0); + p_caster->SetMover(NULL); + + // on delete only do caster related effects + if(m_removeMode == AURA_REMOVE_BY_DELETE) + return; + + pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); + pet->AttackStop(); pet->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); pet->AddSplineFlag(SPLINEFLAG_WALKMODE); @@ -8272,9 +8276,13 @@ void Aura::HandleAuraControlVehicle(bool apply, bool Real) if(!Real) return; + Unit* target = GetTarget(); + if (target->GetTypeId() != TYPEID_UNIT || !((Creature*)target)->isVehicle()) + return; + Vehicle* vehicle = (Vehicle*)target; + Unit *player = GetCaster(); - Vehicle *vehicle = dynamic_cast(GetTarget()); - if(!player || player->GetTypeId() != TYPEID_PLAYER || !vehicle) + if(!player || player->GetTypeId() != TYPEID_PLAYER) return; if (apply) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 9f22d733c..81f6db4d0 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -4511,7 +4511,20 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Aura %u now is remove mode %d",Aur->GetModifier()->m_auraname, mode); // some auras also need to apply modifier (on caster) on remove - if (mode != AURA_REMOVE_BY_DELETE || Aur->GetModifier()->m_auraname == SPELL_AURA_MOD_POSSESS) + if (mode == AURA_REMOVE_BY_DELETE) + { + switch (Aur->GetModifier()->m_auraname) + { + // need properly undo any auras with player-caster mover set (or will crash at next caster move packet) + case SPELL_AURA_MOD_POSSESS: + case SPELL_AURA_MOD_POSSESS_PET: + case SPELL_AURA_CONTROL_VEHICLE: + Aur->ApplyModifier(false,true); + break; + default: break; + } + } + else Aur->ApplyModifier(false,true); if (Aur->_RemoveAura()) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index dfa86d1f4..c40f920e0 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10075" + #define REVISION_NR "10076" #endif // __REVISION_NR_H__ From d6138f01a6a14cc069ce47856d1d828af0fb2d7a Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sat, 19 Jun 2010 05:52:17 +0400 Subject: [PATCH 28/42] [10077] Add delayed far teleports for opcode handlers Some opcode handlers have many code with possible deep calling far teleports by some reason (death, quest script, etc). This can be triggering unexpected lost Map context and crashs result. Note: player login opcode still have disbled delayed teleports (old way work) just becase Player object created in it and not have flag set. Calling point look not 100% safe but at this commit this way not chnages for while. --- src/game/CharacterHandler.cpp | 1 + src/game/WorldSession.cpp | 47 +++++++++++++++++++++-------------- src/game/WorldSession.h | 4 +++ src/shared/revision_nr.h | 2 +- 4 files changed, 35 insertions(+), 19 deletions(-) diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index 8357ede9e..5e4e2421b 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -703,6 +703,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder *holder) if (!pCurrChar->GetMap()->Add(pCurrChar)) { + // normal delayed teleport protection not applied (and this correct) for this case (Player object just created) AreaTrigger const* at = sObjectMgr.GetGoBackTrigger(pCurrChar->GetMapId()); if(at) pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation()); diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp index 273cf088e..491de312c 100644 --- a/src/game/WorldSession.cpp +++ b/src/game/WorldSession.cpp @@ -184,11 +184,8 @@ bool WorldSession::Update(uint32 /*diff*/) LogUnexpectedOpcode(packet, "the player has not logged in yet"); } else if(_player->IsInWorld()) - { - (this->*opHandle.handler)(*packet); - if (packet->rpos() < packet->wpos() && sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG)) - LogUnprocessedTail(packet); - } + ExecuteOpcode(opHandle, packet); + // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer break; case STATUS_LOGGEDIN_OR_RECENTLY_LOGGEDOUT: @@ -197,12 +194,8 @@ bool WorldSession::Update(uint32 /*diff*/) LogUnexpectedOpcode(packet, "the player has not logged in yet and not recently logout"); } else - { // not expected _player or must checked in packet hanlder - (this->*opHandle.handler)(*packet); - if (packet->rpos() < packet->wpos() && sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG)) - LogUnprocessedTail(packet); - } + ExecuteOpcode(opHandle, packet); break; case STATUS_TRANSFER: if(!_player) @@ -210,11 +203,7 @@ bool WorldSession::Update(uint32 /*diff*/) else if(_player->IsInWorld()) LogUnexpectedOpcode(packet, "the player is still in world"); else - { - (this->*opHandle.handler)(*packet); - if (packet->rpos() < packet->wpos() && sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG)) - LogUnprocessedTail(packet); - } + ExecuteOpcode(opHandle, packet); break; case STATUS_AUTHED: // prevent cheating with skip queue wait @@ -229,9 +218,7 @@ bool WorldSession::Update(uint32 /*diff*/) if (packet->GetOpcode() != CMSG_SET_ACTIVE_VOICE_CHANNEL) m_playerRecentlyLogout = false; - (this->*opHandle.handler)(*packet); - if (packet->rpos() < packet->wpos() && sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG)) - LogUnprocessedTail(packet); + ExecuteOpcode(opHandle, packet); break; case STATUS_NEVER: sLog.outError( "SESSION: received not allowed opcode %s (0x%.4X)", @@ -872,3 +859,27 @@ void WorldSession::SendRedirectClient(std::string& ip, uint16 port) SendPacket(&pkt); } + +void WorldSession::ExecuteOpcode( OpcodeHandler& opHandle, WorldPacket* packet ) +{ + // need prevent do internal far teleports in handlers because some handlers do lot steps + // or call code that can do far teleports in some conditions unexpectedly for generic way work code + if (_player) + _player->SetCanDelayTeleport(true); + + (this->*opHandle.handler)(*packet); + + if (_player) + { + // can be not set in fact for login opcode, but this not create porblems. + _player->SetCanDelayTeleport(false); + + //we should execute delayed teleports only for alive(!) players + //because we don't want player's ghost teleported from graveyard + if (_player->IsHasDelayedTeleport() && _player->isAlive()) + _player->TeleportTo(_player->m_teleport_dest, _player->m_teleport_options); + } + + if (packet->rpos() < packet->wpos() && sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG)) + LogUnprocessedTail(packet); +} \ No newline at end of file diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h index 8aa6ba959..23ae01646 100644 --- a/src/game/WorldSession.h +++ b/src/game/WorldSession.h @@ -43,6 +43,8 @@ class LoginQueryHolder; class CharacterHandler; class GMTicket; +struct OpcodeHandler; + enum AccountDataType { GLOBAL_CONFIG_CACHE = 0, // 0x01 g @@ -773,6 +775,8 @@ class MANGOS_DLL_SPEC WorldSession // private trade methods void moveItems(Item* myItems[], Item* hisItems[]); + void ExecuteOpcode( OpcodeHandler& opHandle, WorldPacket* packet ); + // logging helper void LogUnexpectedOpcode(WorldPacket *packet, const char * reason); void LogUnprocessedTail(WorldPacket *packet); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index c40f920e0..a6b664f8b 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10076" + #define REVISION_NR "10077" #endif // __REVISION_NR_H__ From b62d64e7c715635df72b50b1096742d0cf4369f3 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sat, 19 Jun 2010 06:25:31 +0400 Subject: [PATCH 29/42] [10078] Use const referecne to opcode handle. --- src/game/WorldSession.cpp | 4 ++-- src/game/WorldSession.h | 2 +- src/shared/revision_nr.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp index 491de312c..4bc0aa7d1 100644 --- a/src/game/WorldSession.cpp +++ b/src/game/WorldSession.cpp @@ -171,7 +171,7 @@ bool WorldSession::Update(uint32 /*diff*/) packet->GetOpcode()); #endif*/ - OpcodeHandler& opHandle = opcodeTable[packet->GetOpcode()]; + OpcodeHandler const& opHandle = opcodeTable[packet->GetOpcode()]; try { switch (opHandle.status) @@ -860,7 +860,7 @@ void WorldSession::SendRedirectClient(std::string& ip, uint16 port) SendPacket(&pkt); } -void WorldSession::ExecuteOpcode( OpcodeHandler& opHandle, WorldPacket* packet ) +void WorldSession::ExecuteOpcode( OpcodeHandler const& opHandle, WorldPacket* packet ) { // need prevent do internal far teleports in handlers because some handlers do lot steps // or call code that can do far teleports in some conditions unexpectedly for generic way work code diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h index 23ae01646..af857e236 100644 --- a/src/game/WorldSession.h +++ b/src/game/WorldSession.h @@ -775,7 +775,7 @@ class MANGOS_DLL_SPEC WorldSession // private trade methods void moveItems(Item* myItems[], Item* hisItems[]); - void ExecuteOpcode( OpcodeHandler& opHandle, WorldPacket* packet ); + void ExecuteOpcode( OpcodeHandler const& opHandle, WorldPacket* packet ); // logging helper void LogUnexpectedOpcode(WorldPacket *packet, const char * reason); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index a6b664f8b..b10cee29d 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10077" + #define REVISION_NR "10078" #endif // __REVISION_NR_H__ From 6bfd0aa5b5544c12bc5d3e87e5eea07fc14b38a7 Mon Sep 17 00:00:00 2001 From: Laise Date: Sat, 19 Jun 2010 20:52:18 +0300 Subject: [PATCH 30/42] [10079] Don't allow cancel passive spells --- src/game/SpellHandler.cpp | 3 +++ src/shared/revision_nr.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp index b70d1494d..4a901c579 100644 --- a/src/game/SpellHandler.cpp +++ b/src/game/SpellHandler.cpp @@ -420,6 +420,9 @@ void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket) if (spellInfo->Attributes & SPELL_ATTR_CANT_CANCEL) return; + if (IsPassiveSpell(spellInfo)) + return; + if (!IsPositiveSpell(spellId)) { // ignore for remote control state diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index b10cee29d..b8493141b 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10078" + #define REVISION_NR "10079" #endif // __REVISION_NR_H__ From e63dc32f4d3f9c16406d4de470e0586d2e56e5cc Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sat, 19 Jun 2010 22:38:42 +0400 Subject: [PATCH 31/42] [10080] Fixed ghost teleport and cleanup code. --- src/game/Player.cpp | 32 +++++++++++--------------------- src/game/Player.h | 19 +++++++++++++++---- src/game/WorldSession.cpp | 2 +- src/shared/revision_nr.h | 2 +- 4 files changed, 28 insertions(+), 27 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 2af1cd7ca..fe43768f4 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -480,6 +480,7 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa m_DelayedOperations = 0; m_bCanDelayTeleport = false; m_bHasDelayedTeleport = false; + m_bHasBeenAliveAtDelayedTeleport = true; // overwrite always at setup teleport data, so not used infact m_teleport_options = 0; m_trade = NULL; @@ -1474,9 +1475,7 @@ void Player::Update( uint32 p_time ) RemovePet(pet, PET_SAVE_NOT_IN_SLOT, true); } - //we should execute delayed teleports only for alive(!) players - //because we don't want player's ghost teleported from graveyard - if(IsHasDelayedTeleport() && isAlive()) + if (IsHasDelayedTeleport()) TeleportTo(m_teleport_dest, m_teleport_options); } @@ -1775,10 +1774,9 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati //lets reset far teleport flag if it wasn't reset during chained teleports SetSemaphoreTeleportFar(false); //setup delayed teleport flag - SetDelayedTeleportFlag(IsCanDelayTeleport()); //if teleport spell is casted in Unit::Update() func //then we need to delay it until update process will be finished - if(IsHasDelayedTeleport()) + if (SetDelayedTeleportFlagIfCan()) { SetSemaphoreTeleportNear(true); //lets save teleport destination for player @@ -1794,7 +1792,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati UnsummonPetTemporaryIfAny(); } - if(!(options & TELE_TO_NOT_LEAVE_COMBAT)) + if (!(options & TELE_TO_NOT_LEAVE_COMBAT)) CombatStop(); // this will be used instead of the current location in SaveToDB @@ -1831,10 +1829,9 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati //lets reset near teleport flag if it wasn't reset during chained teleports SetSemaphoreTeleportNear(false); //setup delayed teleport flag - SetDelayedTeleportFlag(IsCanDelayTeleport()); //if teleport spell is casted in Unit::Update() func //then we need to delay it until update process will be finished - if(IsHasDelayedTeleport()) + if (SetDelayedTeleportFlagIfCan()) { SetSemaphoreTeleportFar(true); //lets save teleport destination for player @@ -1850,7 +1847,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati ResetContestedPvP(); // remove player from battleground on far teleport (when changing maps) - if(BattleGround const* bg = GetBattleGround()) + if (BattleGround const* bg = GetBattleGround()) { // Note: at battleground join battleground id set before teleport // and we already will found "current" battleground @@ -1868,14 +1865,14 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati // stop spellcasting // not attempt interrupt teleportation spell at caster teleport - if(!(options & TELE_TO_SPELL)) - if(IsNonMeleeSpellCasted(true)) + if (!(options & TELE_TO_SPELL)) + if (IsNonMeleeSpellCasted(true)) InterruptNonMeleeSpells(true); //remove auras before removing from map... RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CHANGE_MAP | AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_TURNING); - if(!GetSession()->PlayerLogout()) + if (!GetSession()->PlayerLogout()) { // send transfer packets WorldPacket data(SMSG_TRANSFER_PENDING, (4+4+4)); @@ -1909,7 +1906,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati } // remove from old map now - if(oldmap) + if (oldmap) oldmap->Remove(this, false); // new final coordinates @@ -1918,7 +1915,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati float final_z = z; float final_o = orientation; - if(m_transport) + if (m_transport) { final_x += m_movementInfo.GetTransportPos()->x; final_y += m_movementInfo.GetTransportPos()->y; @@ -13538,10 +13535,6 @@ void Player::IncompleteQuest( uint32 quest_id ) void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver, bool announce ) { - //this THING should be here to protect code from quest, which cast on player far teleport as a reward - //should work fine, cause far teleport will be executed in Player::Update() - SetCanDelayTeleport(true); - uint32 quest_id = pQuest->GetQuestId(); for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i ) @@ -13693,9 +13686,6 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver if (!HasAura(itr->second->spellId, EFFECT_INDEX_0)) CastSpell(this,itr->second->spellId,true); } - - //lets remove flag for delayed teleports - SetCanDelayTeleport(false); } void Player::FailQuest(uint32 questId) diff --git a/src/game/Player.h b/src/game/Player.h index 942d68fdd..548d4645f 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -2593,14 +2593,24 @@ class MANGOS_DLL_SPEC Player : public Unit int32 CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, int32 faction, bool for_quest); void AdjustQuestReqItemCount( Quest const* pQuest, QuestStatusData& questStatusData ); - bool IsCanDelayTeleport() const { return m_bCanDelayTeleport; } void SetCanDelayTeleport(bool setting) { m_bCanDelayTeleport = setting; } - bool IsHasDelayedTeleport() const { return m_bHasDelayedTeleport; } - void SetDelayedTeleportFlag(bool setting) { m_bHasDelayedTeleport = setting; } + bool IsHasDelayedTeleport() const + { + // we should not execute delayed teleports for now dead players but has been alive at teleport + // because we don't want player's ghost teleported from graveyard + return m_bHasDelayedTeleport && (isAlive() || !m_bHasBeenAliveAtDelayedTeleport); + } + + bool SetDelayedTeleportFlagIfCan() + { + m_bHasDelayedTeleport = m_bCanDelayTeleport; + m_bHasBeenAliveAtDelayedTeleport = isAlive(); + return m_bHasDelayedTeleport; + } void ScheduleDelayedOperation(uint32 operation) { - if(operation < DELAYED_END) + if (operation < DELAYED_END) m_DelayedOperations |= operation; } @@ -2634,6 +2644,7 @@ class MANGOS_DLL_SPEC Player : public Unit uint32 m_DelayedOperations; bool m_bCanDelayTeleport; bool m_bHasDelayedTeleport; + bool m_bHasBeenAliveAtDelayedTeleport; uint32 m_DetectInvTimer; diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp index 4bc0aa7d1..8a8b3831d 100644 --- a/src/game/WorldSession.cpp +++ b/src/game/WorldSession.cpp @@ -876,7 +876,7 @@ void WorldSession::ExecuteOpcode( OpcodeHandler const& opHandle, WorldPacket* pa //we should execute delayed teleports only for alive(!) players //because we don't want player's ghost teleported from graveyard - if (_player->IsHasDelayedTeleport() && _player->isAlive()) + if (_player->IsHasDelayedTeleport()) _player->TeleportTo(_player->m_teleport_dest, _player->m_teleport_options); } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index b8493141b..2e194d857 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10079" + #define REVISION_NR "10080" #endif // __REVISION_NR_H__ From 41d178ca7b507ec5ebf2b72f890c897f50319e64 Mon Sep 17 00:00:00 2001 From: Astellar Date: Sun, 20 Jun 2010 01:50:19 +0400 Subject: [PATCH 32/42] [10081] Use ACE config library instead dotconfpp NOTE: all config versions update because in old state it's not compatible with new way loading. Look for *.conf.dist.in chnages in commit for update configs. Signed-off-by: VladimirMangos --- src/mangosd/mangosd.conf.dist.in | 4 +- src/realmd/realmd.conf.dist.in | 4 +- src/shared/Config/Config.cpp | 84 ++++++++++++++++---------------- src/shared/Config/Config.h | 7 ++- src/shared/Config/ConfigEnv.h | 1 - src/shared/SystemConfig.h.in | 4 +- src/shared/revision_nr.h | 2 +- 7 files changed, 54 insertions(+), 52 deletions(-) diff --git a/src/mangosd/mangosd.conf.dist.in b/src/mangosd/mangosd.conf.dist.in index f5ba807ed..58d337a00 100644 --- a/src/mangosd/mangosd.conf.dist.in +++ b/src/mangosd/mangosd.conf.dist.in @@ -1,7 +1,9 @@ ##################################### # MaNGOS Configuration file # ##################################### -ConfVersion=2010051901 + +[MangosdConf] +ConfVersion=2010062001 ################################################################################################################### # CONNECTIONS AND DIRECTORIES diff --git a/src/realmd/realmd.conf.dist.in b/src/realmd/realmd.conf.dist.in index 20e179217..99ada0219 100644 --- a/src/realmd/realmd.conf.dist.in +++ b/src/realmd/realmd.conf.dist.in @@ -1,7 +1,9 @@ ############################################ # MaNGOS realmd configuration file # ############################################ -ConfVersion=2007062001 + +[RealmdConf] +ConfVersion=2010062001 ################################################################################################################### # REALMD SETTINGS diff --git a/src/shared/Config/Config.cpp b/src/shared/Config/Config.cpp index b4eeacd2c..80201329a 100644 --- a/src/shared/Config/Config.cpp +++ b/src/shared/Config/Config.cpp @@ -17,12 +17,35 @@ */ #include "ConfigEnv.h" +#include "ace/Configuration_Import_Export.h" + #include "Policies/SingletonImp.h" INSTANTIATE_SINGLETON_1(Config); +static bool GetValueHelper(ACE_Configuration_Heap *mConf, const char *name, ACE_TString &result) +{ + if (!mConf) + return false; + + ACE_TString section_name; + ACE_Configuration_Section_Key section_key; + ACE_Configuration_Section_Key root_key = mConf->root_section(); + + int i = 0; + while (mConf->enumerate_sections(root_key, i, section_name) == 0) + { + mConf->open_section(root_key, section_name.c_str(), 0, section_key); + if (mConf->get_string_value(section_key, name, result) == 0) + return true; + ++i; + } + + return false; +} + Config::Config() -: mIgnoreCase(true), mConf(NULL) +: mConf(NULL) { } @@ -31,9 +54,8 @@ Config::~Config() delete mConf; } -bool Config::SetSource(const char *file, bool ignorecase) +bool Config::SetSource(const char *file) { - mIgnoreCase = ignorecase; mFilename = file; return Reload(); @@ -42,43 +64,33 @@ bool Config::SetSource(const char *file, bool ignorecase) bool Config::Reload() { delete mConf; + mConf = new ACE_Configuration_Heap; - mConf = new DOTCONFDocument(mIgnoreCase ? - DOTCONFDocument::CASEINSENSETIVE : - DOTCONFDocument::CASESENSITIVE); - - if (mConf->setContent(mFilename.c_str()) == -1) + if (mConf->open() == 0) { - delete mConf; - mConf = NULL; - return false; + ACE_Ini_ImpExp config_importer(*mConf); + if (config_importer.import_config(mFilename.c_str()) == 0) + return true; } - return true; + delete mConf; + mConf = NULL; + return false; } std::string Config::GetStringDefault(const char* name, const char* def) { - if (!mConf) - return std::string(def); - - DOTCONFDocumentNode const *node = mConf->findNode(name); - if (!node || !node->getValue()) - return std::string(def); - - return std::string(node->getValue()); + ACE_TString val; + return GetValueHelper(mConf, name, val) ? val.c_str() : def; } bool Config::GetBoolDefault(const char* name, bool def) { - if (!mConf) + ACE_TString val; + if (!GetValueHelper(mConf, name, val)) return def; - DOTCONFDocumentNode const *node = mConf->findNode(name); - if (!node || !node->getValue()) - return def; - - const char* str = node->getValue(); + const char* str = val.c_str(); if (strcmp(str, "true") == 0 || strcmp(str, "TRUE") == 0 || strcmp(str, "yes") == 0 || strcmp(str, "YES") == 0 || strcmp(str, "1") == 0) @@ -90,25 +102,13 @@ bool Config::GetBoolDefault(const char* name, bool def) int32 Config::GetIntDefault(const char* name, int32 def) { - if (!mConf) - return def; - - DOTCONFDocumentNode const *node = mConf->findNode(name); - if (!node || !node->getValue()) - return def; - - return atoi(node->getValue()); + ACE_TString val; + return GetValueHelper(mConf, name, val) ? atoi(val.c_str()) : def; } float Config::GetFloatDefault(const char* name, float def) { - if (!mConf) - return def; - - DOTCONFDocumentNode const *node = mConf->findNode(name); - if (!node || !node->getValue()) - return def; - - return (float)atof(node->getValue()); + ACE_TString val; + return GetValueHelper(mConf, name, val) ? (float)atof(val.c_str()) : def; } diff --git a/src/shared/Config/Config.h b/src/shared/Config/Config.h index 296018408..7f33e99f4 100644 --- a/src/shared/Config/Config.h +++ b/src/shared/Config/Config.h @@ -22,7 +22,7 @@ #include #include "Platform/Define.h" -class DOTCONFDocument; +class ACE_Configuration_Heap; class MANGOS_DLL_SPEC Config { @@ -31,7 +31,7 @@ class MANGOS_DLL_SPEC Config Config(); ~Config(); - bool SetSource(const char *file, bool ignorecase = true); + bool SetSource(const char *file); bool Reload(); std::string GetStringDefault(const char* name, const char* def); @@ -44,8 +44,7 @@ class MANGOS_DLL_SPEC Config private: std::string mFilename; - bool mIgnoreCase; - DOTCONFDocument *mConf; + ACE_Configuration_Heap *mConf; }; #define sConfig MaNGOS::Singleton::Instance() diff --git a/src/shared/Config/ConfigEnv.h b/src/shared/Config/ConfigEnv.h index e9801b641..76f93347d 100644 --- a/src/shared/Config/ConfigEnv.h +++ b/src/shared/Config/ConfigEnv.h @@ -21,7 +21,6 @@ #define CONFIGENVIRONMENT_H #include "Common.h" -#include "dotconfpp/dotconfpp.h" #include "Config.h" #endif diff --git a/src/shared/SystemConfig.h.in b/src/shared/SystemConfig.h.in index 57f7e0b89..85edbc023 100644 --- a/src/shared/SystemConfig.h.in +++ b/src/shared/SystemConfig.h.in @@ -36,10 +36,10 @@ // Format is YYYYMMDDRR where RR is the change in the conf file // for that day. #ifndef _MANGOSDCONFVERSION -# define _MANGOSDCONFVERSION 2010051901 +# define _MANGOSDCONFVERSION 2010062001 #endif #ifndef _REALMDCONFVERSION -# define _REALMDCONFVERSION 2007062001 +# define _REALMDCONFVERSION 2010062001 #endif #if MANGOS_ENDIAN == MANGOS_BIGENDIAN diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 2e194d857..fb8211e82 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10080" + #define REVISION_NR "10081" #endif // __REVISION_NR_H__ From 1eed65d5acf72011c86652b5322bf965087871e5 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sun, 20 Jun 2010 02:19:45 +0400 Subject: [PATCH 33/42] [10082] Drop now unused dotconfpp lib code. --- NEWS | 1 + src/game/GridMap.cpp | 1 - src/game/InstanceSaveMgr.cpp | 1 - src/game/Level3.cpp | 2 +- src/game/Map.cpp | 1 - src/game/World.cpp | 8 +- src/game/WorldSocketMgr.cpp | 2 +- src/mangosd/CliRunnable.cpp | 4 +- src/mangosd/Main.cpp | 20 +- src/mangosd/Master.cpp | 2 +- src/mangosd/RASocket.cpp | 2 +- src/realmd/AuthSocket.cpp | 2 +- src/realmd/Main.cpp | 2 +- src/shared/Config/Config.cpp | 2 +- src/shared/Config/Config.h | 1 + src/shared/Config/ConfigEnv.h | 26 - src/shared/Config/ConfigLibrary.vcproj | 137 ----- src/shared/Config/Makefile.am | 13 +- src/shared/Config/dotconfpp/dotconfpp.cpp | 703 ---------------------- src/shared/Config/dotconfpp/dotconfpp.h | 111 ---- src/shared/Config/dotconfpp/mempool.cpp | 106 ---- src/shared/Config/dotconfpp/mempool.h | 43 -- src/shared/Database/Database.cpp | 2 +- src/shared/Log.cpp | 2 +- src/shared/revision_nr.h | 2 +- win/VC100/shared.vcxproj | 5 - win/VC100/shared.vcxproj.filters | 18 - win/VC80/shared.vcproj | 24 - win/VC90/shared.vcproj | 24 - 29 files changed, 30 insertions(+), 1237 deletions(-) delete mode 100644 src/shared/Config/ConfigEnv.h delete mode 100644 src/shared/Config/ConfigLibrary.vcproj delete mode 100644 src/shared/Config/dotconfpp/dotconfpp.cpp delete mode 100644 src/shared/Config/dotconfpp/dotconfpp.h delete mode 100644 src/shared/Config/dotconfpp/mempool.cpp delete mode 100644 src/shared/Config/dotconfpp/mempool.h diff --git a/NEWS b/NEWS index 0a2d066ce..ec6417f48 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,7 @@ Version 0.16 * Under discussion. * OpenSSL lib upgrade to OpenSSL 1.0.0. * Sockets lib use dropped. + * dotconfpp lib use dropped. * Upgrade to client version 3.3.3a (build 11723). Version 0.15 diff --git a/src/game/GridMap.cpp b/src/game/GridMap.cpp index 4df4083b6..501ad807d 100644 --- a/src/game/GridMap.cpp +++ b/src/game/GridMap.cpp @@ -21,7 +21,6 @@ #include "GridStates.h" #include "CellImpl.h" #include "Map.h" -#include "Config/ConfigEnv.h" #include "DBCEnums.h" #include "DBCStores.h" #include "GridMap.h" diff --git a/src/game/InstanceSaveMgr.cpp b/src/game/InstanceSaveMgr.cpp index 81ebb0106..14befab57 100644 --- a/src/game/InstanceSaveMgr.cpp +++ b/src/game/InstanceSaveMgr.cpp @@ -30,7 +30,6 @@ #include "InstanceSaveMgr.h" #include "Timer.h" #include "GridNotifiersImpl.h" -#include "Config/ConfigEnv.h" #include "Transports.h" #include "ObjectMgr.h" #include "World.h" diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 800bea9fb..e6abfb8b2 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -43,7 +43,7 @@ #include "SkillDiscovery.h" #include "SkillExtraItems.h" #include "SystemConfig.h" -#include "Config/ConfigEnv.h" +#include "Config/Config.h" #include "Mail.h" #include "Util.h" #include "ItemEnchantmentMgr.h" diff --git a/src/game/Map.cpp b/src/game/Map.cpp index d27e35570..57f09ce13 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -26,7 +26,6 @@ #include "InstanceData.h" #include "Map.h" #include "GridNotifiersImpl.h" -#include "Config/ConfigEnv.h" #include "Transports.h" #include "ObjectAccessor.h" #include "ObjectMgr.h" diff --git a/src/game/World.cpp b/src/game/World.cpp index abf273dce..0d0a4c682 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -22,7 +22,7 @@ #include "Common.h" #include "Database/DatabaseEnv.h" -#include "Config/ConfigEnv.h" +#include "Config/Config.h" #include "SystemConfig.h" #include "Log.h" #include "Opcodes.h" @@ -402,9 +402,9 @@ Weather* World::AddWeather(uint32 zone_id) /// Initialize config values void World::LoadConfigSettings(bool reload) { - if(reload) + if (reload) { - if(!sConfig.Reload()) + if (!sConfig.Reload()) { sLog.outError("World settings reload fail: can't read settings from %s.",sConfig.GetFilename().c_str()); return; @@ -413,7 +413,7 @@ void World::LoadConfigSettings(bool reload) ///- Read the version of the configuration file and warn the user in case of emptiness or mismatch uint32 confVersion = sConfig.GetIntDefault("ConfVersion", 0); - if(!confVersion) + if (!confVersion) { sLog.outError("*****************************************************************************"); sLog.outError(" WARNING: mangosd.conf does not include a ConfVersion variable."); diff --git a/src/game/WorldSocketMgr.cpp b/src/game/WorldSocketMgr.cpp index 9f1927ecc..25ff79b10 100644 --- a/src/game/WorldSocketMgr.cpp +++ b/src/game/WorldSocketMgr.cpp @@ -40,7 +40,7 @@ #include "Log.h" #include "Common.h" -#include "Config/ConfigEnv.h" +#include "Config/Config.h" #include "Database/DatabaseEnv.h" #include "WorldSocket.h" diff --git a/src/mangosd/CliRunnable.cpp b/src/mangosd/CliRunnable.cpp index 0f23f71e9..437ff43d5 100644 --- a/src/mangosd/CliRunnable.cpp +++ b/src/mangosd/CliRunnable.cpp @@ -27,7 +27,7 @@ #include "ScriptCalls.h" #include "ObjectMgr.h" #include "WorldSession.h" -#include "Config/ConfigEnv.h" +#include "Config/Config.h" #include "Util.h" #include "AccountMgr.h" #include "CliRunnable.h" @@ -629,7 +629,7 @@ void CliRunnable::run() ///- Display the list of available CLI functions then beep sLog.outString(); - if(sConfig.GetBoolDefault("BeepAtStart", true)) + if (sConfig.GetBoolDefault("BeepAtStart", true)) printf("\a"); // \a = Alert // print this here the first time diff --git a/src/mangosd/Main.cpp b/src/mangosd/Main.cpp index af5daf420..049d2b6f1 100644 --- a/src/mangosd/Main.cpp +++ b/src/mangosd/Main.cpp @@ -22,7 +22,7 @@ #include "Common.h" #include "Database/DatabaseEnv.h" -#include "Config/ConfigEnv.h" +#include "Config/Config.h" #include "Log.h" #include "Master.h" #include "SystemConfig.h" @@ -78,11 +78,11 @@ extern int main(int argc, char **argv) ///- Command line parsing to get the configuration file name char const* cfg_file = _MANGOSD_CONFIG; int c=1; - while( c < argc ) + while(c < argc) { - if( strcmp(argv[c],"-c") == 0) + if (strcmp(argv[c],"-c") == 0) { - if( ++c >= argc ) + if (++c >= argc) { sLog.outError("Runtime-Error: -c option requires an input argument"); usage(argv[0]); @@ -92,7 +92,7 @@ extern int main(int argc, char **argv) cfg_file = argv[c]; } - if( strcmp(argv[c],"--version") == 0) + if (strcmp(argv[c],"--version") == 0) { printf("%s\n", _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_NR,REVISION_ID)); return 0; @@ -102,22 +102,22 @@ extern int main(int argc, char **argv) //////////// //Services// //////////// - if( strcmp(argv[c],"-s") == 0) + if (strcmp(argv[c],"-s") == 0) { - if( ++c >= argc ) + if (++c >= argc) { sLog.outError("Runtime-Error: -s option requires an input argument"); usage(argv[0]); Log::WaitBeforeContinueIfNeed(); return 1; } - if( strcmp(argv[c],"install") == 0) + else if (strcmp(argv[c],"install") == 0) { if (WinServiceInstall()) sLog.outString("Installing service"); return 1; } - else if( strcmp(argv[c],"uninstall") == 0) + else if ( strcmp(argv[c],"uninstall") == 0) { if(WinServiceUninstall()) sLog.outString("Uninstalling service"); @@ -131,7 +131,7 @@ extern int main(int argc, char **argv) return 1; } } - if( strcmp(argv[c],"--service") == 0) + if (strcmp(argv[c],"--service") == 0) { WinServiceRun(); } diff --git a/src/mangosd/Master.cpp b/src/mangosd/Master.cpp index 9478a8d9d..2d9eca5b3 100644 --- a/src/mangosd/Master.cpp +++ b/src/mangosd/Master.cpp @@ -30,7 +30,7 @@ #include "Timer.h" #include "Policies/SingletonImp.h" #include "SystemConfig.h" -#include "Config/ConfigEnv.h" +#include "Config/Config.h" #include "Database/DatabaseEnv.h" #include "CliRunnable.h" #include "RASocket.h" diff --git a/src/mangosd/RASocket.cpp b/src/mangosd/RASocket.cpp index 15952fb97..1d291c23a 100644 --- a/src/mangosd/RASocket.cpp +++ b/src/mangosd/RASocket.cpp @@ -25,7 +25,7 @@ #include "Log.h" #include "RASocket.h" #include "World.h" -#include "Config/ConfigEnv.h" +#include "Config/Config.h" #include "Util.h" #include "AccountMgr.h" #include "Language.h" diff --git a/src/realmd/AuthSocket.cpp b/src/realmd/AuthSocket.cpp index 848579b97..8465eb381 100644 --- a/src/realmd/AuthSocket.cpp +++ b/src/realmd/AuthSocket.cpp @@ -22,7 +22,7 @@ #include "Common.h" #include "Database/DatabaseEnv.h" -#include "Config/ConfigEnv.h" +#include "Config/Config.h" #include "Log.h" #include "RealmList.h" #include "AuthSocket.h" diff --git a/src/realmd/Main.cpp b/src/realmd/Main.cpp index 1807b165f..3243b7fc2 100644 --- a/src/realmd/Main.cpp +++ b/src/realmd/Main.cpp @@ -24,7 +24,7 @@ #include "Database/DatabaseEnv.h" #include "RealmList.h" -#include "Config/ConfigEnv.h" +#include "Config/Config.h" #include "Log.h" #include "AuthSocket.h" #include "SystemConfig.h" diff --git a/src/shared/Config/Config.cpp b/src/shared/Config/Config.cpp index 80201329a..515a5f367 100644 --- a/src/shared/Config/Config.cpp +++ b/src/shared/Config/Config.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "ConfigEnv.h" +#include "Config.h" #include "ace/Configuration_Import_Export.h" #include "Policies/SingletonImp.h" diff --git a/src/shared/Config/Config.h b/src/shared/Config/Config.h index 7f33e99f4..29a524bfd 100644 --- a/src/shared/Config/Config.h +++ b/src/shared/Config/Config.h @@ -19,6 +19,7 @@ #ifndef CONFIG_H #define CONFIG_H +#include "Common.h" #include #include "Platform/Define.h" diff --git a/src/shared/Config/ConfigEnv.h b/src/shared/Config/ConfigEnv.h deleted file mode 100644 index 76f93347d..000000000 --- a/src/shared/Config/ConfigEnv.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2005-2010 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 - */ - -#if !defined(CONFIGENVIRONMENT_H) - -#define CONFIGENVIRONMENT_H - -#include "Common.h" -#include "Config.h" - -#endif diff --git a/src/shared/Config/ConfigLibrary.vcproj b/src/shared/Config/ConfigLibrary.vcproj deleted file mode 100644 index a8f1fc322..000000000 --- a/src/shared/Config/ConfigLibrary.vcproj +++ /dev/null @@ -1,137 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/shared/Config/Makefile.am b/src/shared/Config/Makefile.am index 7d670af90..77ea62b36 100644 --- a/src/shared/Config/Makefile.am +++ b/src/shared/Config/Makefile.am @@ -19,7 +19,7 @@ ## Sub-directories to parse ## CPP flags for includes, defines, etc. -AM_CPPFLAGS = $(MANGOS_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(srcdir)/../../../dep/include -I$(srcdir)/../../framework -I$(srcdir)/../../shared -I$(srcdir)/../../../dep/include/g3dlite +AM_CPPFLAGS = $(MANGOS_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(srcdir)/../../../dep/include -I$(srcdir)/../../framework -I$(srcdir)/../../shared ## Build MaNGOS shared library and its parts as convenience library. # All libraries will be convenience libraries. Might be changed to shared @@ -27,14 +27,5 @@ AM_CPPFLAGS = $(MANGOS_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(sr noinst_LIBRARIES = libmangosconfig.a libmangosconfig_a_SOURCES = \ - dotconfpp/dotconfpp.cpp \ - dotconfpp/dotconfpp.h \ - dotconfpp/mempool.cpp \ - dotconfpp/mempool.h \ Config.cpp \ - Config.h \ - ConfigEnv.h - -# VC++ project workspace for dotconfpp -EXTRA_DIST = \ - ConfigLibrary.vcproj + Config.h diff --git a/src/shared/Config/dotconfpp/dotconfpp.cpp b/src/shared/Config/dotconfpp/dotconfpp.cpp deleted file mode 100644 index 85b515032..000000000 --- a/src/shared/Config/dotconfpp/dotconfpp.cpp +++ /dev/null @@ -1,703 +0,0 @@ -#include "Common.h" -#include "dotconfpp.h" -#include - -#ifdef WIN32 -# define strcasecmp stricmp -# include -#else -# include -# include -# include -# include -#endif - -#if !defined(R_OK) -# define R_OK 04 -#endif - -DOTCONFDocumentNode::DOTCONFDocumentNode() -: previousNode(NULL), nextNode(NULL), parentNode(NULL), childNode(NULL), -values(NULL), valuesCount(0), name(NULL), lineNum(0), -fileName(NULL), closed(true) -{ -} - -DOTCONFDocumentNode::~DOTCONFDocumentNode() -{ - free(name); - - if (values != NULL) - { - for (int i = 0; i < valuesCount; ++i) - free(values[i]); - - free(values); - } -} - -void DOTCONFDocumentNode::pushValue(char* _value) -{ - ++valuesCount; - values = (char**)realloc(values, valuesCount * sizeof(char*)); - values[valuesCount - 1] = strdup(_value); -} - -const char* DOTCONFDocumentNode::getValue(int index) const -{ - if (index >= valuesCount) - return NULL; - - return values[index]; -} - -DOTCONFDocument::DOTCONFDocument(DOTCONFDocument::CaseSensitive caseSensitivity) -: mempool(NULL), curParent(NULL), curPrev(NULL), curLine(0), file(NULL), fileName(NULL) -{ - switch (caseSensitivity) - { - case CASESENSITIVE: - cmp_func = strcmp; - break; - case CASEINSENSETIVE: - cmp_func = strcasecmp; - break; - } - - mempool = new AsyncDNSMemPool(1024); - mempool->initialize(); -} - -DOTCONFDocument::~DOTCONFDocument() -{ - for (NodeList::iterator i = nodeTree.begin(); i != nodeTree.end(); ++i) - delete(*i); - - for (CharList::iterator i = requiredOptions.begin(); i != requiredOptions.end(); ++i) - free(*i); - - for (CharList::iterator i = processedFiles.begin(); i != processedFiles.end(); ++i) - free(*i); - - free(fileName); - delete mempool; -} - -int DOTCONFDocument::cleanupLine(char* line) -{ - char* start = line; - char* bg = line; - bool multiline = false; - bool concat = false; - char* word = NULL; - - if (!words.empty() && quoted) - concat = true; - - while (*line) - { - if ((*line == '#' || *line == ';') && !quoted) - { - *bg = 0; - if (strlen(start)) - { - if (concat) - { - word = (char*)mempool->Alloc(strlen(words.back()) + strlen(start) + 1); - strcpy(word, words.back()); - strcat(word, start); - words.pop_back(); - concat = false; - } - else - word = mempool->Strdup(start); - - words.push_back(word); - } - - break; - } - - if (*line == '=' && !quoted) - { - *line = ' '; - continue; - } - - // Allowing \" in there causes problems with directory paths - // like "C:\MaNGOS\" - //if(*line == '\\' && (*(line+1) == '"' || *(line+1) == '\'')){ - if (*line == '\\' && (*(line + 1) == '\'')) - { - *bg++ = *(line + 1); - line += 2; - continue; - } - - if (*line == '\\' && *(line + 1) == 'n') - { - *bg++ = '\n'; - line += 2; - continue; - } - - if (*line == '\\' && *(line + 1) == 'r') - { - *bg++ = '\r'; - line += 2; - continue; - } - - if (*line == '\\' && (*(line + 1) == '\n' || *(line + 1) == '\r')) - { - *bg = 0; - if (strlen(start)) - { - if (concat) - { - word = (char*)mempool->Alloc(strlen(words.back()) + strlen(start) + 1); - strcpy(word, words.back()); - strcat(word, start); - words.pop_back(); - concat = false; - } - else - word = mempool->Strdup(start); - - words.push_back(word); - } - - multiline = true; - break; - } - - if (*line == '"' || *line == '\'') - { - quoted = !quoted; - ++line; - continue; - } - - if (isspace((unsigned char)*line) && !quoted) - { - *bg++ = 0; - if (strlen(start)) - { - if (concat) - { - word = (char*)mempool->Alloc(strlen(words.back()) + strlen(start) + 1); - strcpy(word, words.back()); - strcat(word, start); - words.pop_back(); - concat = false; - } - else - word = mempool->Strdup(start); - - words.push_back(word); - } - - start = bg; - while (isspace((unsigned char)*++line)) - { - } - - continue; - } - - *bg++ = *line++; - } - - if (quoted && !multiline) - { - error(curLine, fileName, "unterminated quote"); - return -1; - } - - return multiline ? 1 : 0; -} - -int DOTCONFDocument::parseLine() -{ - char* word = NULL; - char* nodeName = NULL; - char* nodeValue = NULL; - DOTCONFDocumentNode* tagNode = NULL; - bool newNode = false; - - for (CharList::iterator i = words.begin(); i != words.end(); ++i) - { - word = *i; - - if (*word == '<') - newNode = true; - - if (newNode) - { - nodeValue = NULL; - nodeName = NULL; - newNode = false; - } - - size_t wordLen = strlen(word); - if (word[wordLen - 1] == '>') - { - word[wordLen - 1] = 0; - newNode = true; - } - - if (nodeName == NULL) - { - nodeName = word; - bool closed = true; - if (*nodeName == '<') - { - if (*(nodeName + 1) != '/') - { - ++nodeName; - closed = false; - } - else - { - NodeList::reverse_iterator itr = nodeTree.rbegin(); - nodeName += 2; - for (; itr != nodeTree.rend(); ++itr) - { - if (!cmp_func(nodeName, (*itr)->name) && !(*itr)->closed) - { - (*itr)->closed = true; - curParent = (*itr)->parentNode; - curPrev = *itr; - break; - } - } - - if(itr == nodeTree.rend()) - { - error(curLine, fileName, "not matched closing tag ", nodeName); - return -1; - } - - continue; - } - } - - tagNode = new DOTCONFDocumentNode; - tagNode->name = strdup(nodeName); - tagNode->document = this; - tagNode->fileName = processedFiles.back(); - tagNode->lineNum = curLine; - tagNode->closed = closed; - - if(!nodeTree.empty()) - { - DOTCONFDocumentNode* prev = nodeTree.back(); - if (prev->closed) - { - curPrev->nextNode = tagNode; - tagNode->previousNode = curPrev; - tagNode->parentNode = curParent; - } - else - { - prev->childNode = tagNode; - tagNode->parentNode = prev; - curParent = prev; - } - } - - nodeTree.push_back(tagNode); - curPrev = tagNode; - } - else - { - nodeValue = word; - tagNode->pushValue(nodeValue); - } - } - - return 0; -} - -int DOTCONFDocument::parseFile(DOTCONFDocumentNode* _parent) -{ - char str[512]; - int ret = 0; - curLine = 0; - curParent = _parent; - - quoted = false; - size_t slen = 0; - - while (fgets(str, 511, file)) - { - ++curLine; - slen = strlen(str); - if (slen >= 510) - error(curLine, fileName, "warning: line too long"); - - if (str[slen - 1] != '\n') - { - str[slen] = '\n'; - str[slen + 1] = 0; - } - - if ((ret = cleanupLine(str)) == -1) - break; - - if (ret == 0) - { - if (!words.empty()) - { - ret = parseLine(); - mempool->Free(); - words.clear(); - - if(ret == -1) - break; - } - } - } - - return ret; -} - -int DOTCONFDocument::checkConfig(const NodeList::iterator& from) -{ - int ret = 0; - - DOTCONFDocumentNode* tagNode = NULL; - int vi = 0; - for (NodeList::iterator i = from; i != nodeTree.end(); ++i) - { - tagNode = *i; - if (!tagNode->closed) - { - error(tagNode->lineNum, tagNode->fileName, "unclosed tag %s", tagNode->name); - ret = -1; - break; - } - - vi = 0; - while (vi < tagNode->valuesCount) - { - if (strstr(tagNode->values[vi], "${") && strchr(tagNode->values[vi], '}')) - { - ret = macroSubstitute(tagNode, vi); - mempool->Free(); - if (ret == -1) - break; - } - - ++vi; - } - - if (ret == -1) - break; - } - - return ret; -} - -int DOTCONFDocument::setContent(const char* _fileName) -{ - int ret = 0; - char realpathBuf[MANGOS_PATH_MAX]; - - if (ACE_OS::realpath(_fileName, realpathBuf) == NULL) - { - error(0, NULL, "realpath (%s) failed: %s", _fileName, strerror(errno)); - return -1; - } - - fileName = strdup(realpathBuf); - - processedFiles.push_back(strdup(realpathBuf)); - - if ((file = fopen(fileName, "r")) == NULL) - { - error(0, NULL, "failed to open file '%s': %s", fileName, strerror(errno)); - return -1; - } - - // Try read utf8 header and skip it if exist - unsigned int utf8header = 0; - fgets((char*)&utf8header, 4, file); // Try read header - if (utf8header != 0x00BFBBEF) // If not exist - fseek(file, 0, SEEK_SET); // Reset read position - - ret = parseFile(); - - fclose(file); - - if (!ret) - { - if ((ret = checkConfig(nodeTree.begin())) == -1) - return -1; - - NodeList::iterator from; - DOTCONFDocumentNode* tagNode = NULL; - int vi = 0; - for (NodeList::iterator i = nodeTree.begin(); i != nodeTree.end(); ++i) - { - tagNode = *i; - if (!cmp_func("DOTCONFPPIncludeFile", tagNode->name)) - { - vi = 0; - while (vi < tagNode->valuesCount) - { - if (access(tagNode->values[vi], R_OK) == -1) - { - error(tagNode->lineNum, tagNode->fileName, "%s: %s", tagNode->values[vi], strerror(errno)); - return -1; - } - - if (ACE_OS::realpath(tagNode->values[vi], realpathBuf) == NULL) - { - error(tagNode->lineNum, tagNode->fileName, "realpath (%s) failed: %s", tagNode->values[vi], strerror(errno)); - return -1; - } - - bool processed = false; - for (CharList::const_iterator itInode = processedFiles.begin(); itInode != processedFiles.end(); ++itInode) - { - if (!strcmp(*itInode, realpathBuf)) - { - processed = true; - break; - } - } - - if(processed) - break; - - processedFiles.push_back(strdup(realpathBuf)); - - file = fopen(tagNode->values[vi], "r"); - if(file == NULL) - { - error(tagNode->lineNum, fileName, "failed to open file '%s': %s", tagNode->values[vi], strerror(errno)); - return -1; - } - - fileName = strdup(realpathBuf); - from = nodeTree.end(); - --from; - - ret = parseFile(); - fclose(file); - - if (ret == -1) - return -1; - if (checkConfig(++from) == -1) - return -1; - - ++vi; - } - } - } - - if (!requiredOptions.empty()) - ret = checkRequiredOptions(); - } - - return ret; -} - -int DOTCONFDocument::checkRequiredOptions() -{ - for (CharList::const_iterator ci = requiredOptions.begin(); ci != requiredOptions.end(); ++ci) - { - bool matched = false; - for (NodeList::iterator i = nodeTree.begin(); i != nodeTree.end(); ++i) - { - if (!cmp_func((*i)->name, *ci)) - { - matched = true; - break; - } - } - - if(!matched) - { - error(0, NULL, "required option '%s' not specified", *ci); - return -1; - } - } - - return 0; -} - -void DOTCONFDocument::error(int lineNum, const char* fileName_, const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - - size_t len = (lineNum != 0 ? strlen(fileName_) : 0) + strlen(fmt) + 50; - char* buf = (char*)mempool->Alloc(len); - - if (lineNum) - snprintf(buf, len, "DOTCONF++: file '%s', line %d: %s\n", fileName_, lineNum, fmt); - else - snprintf(buf, len, "DOTCONF++: %s\n", fmt); - - vfprintf(stderr, buf, args); - - va_end(args); -} - -char* DOTCONFDocument::getSubstitution(char* macro, int lineNum) -{ - char* buf = NULL; - char* variable = macro + 2; - - char* endBr = strchr(macro, '}'); - - if (!endBr) - { - error(lineNum, fileName, "unterminated '{'"); - return NULL; - } - - *endBr = 0; - - char* defaultValue = strchr(variable, ':'); - - if (defaultValue) - { - *defaultValue++ = 0; - if (*defaultValue != '-') - { - error(lineNum, fileName, "incorrect macro substitution syntax"); - return NULL; - } - - ++defaultValue; - if (*defaultValue == '"' || *defaultValue == '\'') - { - ++defaultValue; - defaultValue[strlen(defaultValue) - 1] = 0; - } - } - else - defaultValue = NULL; - - char* subs = getenv(variable); - if (subs) - buf = mempool->Strdup(subs); - else - { - NodeList::iterator i = nodeTree.begin(); - DOTCONFDocumentNode* tagNode = NULL; - for (; i != nodeTree.end(); ++i) - { - tagNode = *i; - if (!cmp_func(tagNode->name, variable)) - { - if (tagNode->valuesCount != 0) - { - buf = mempool->Strdup(tagNode->values[0]); - break; - } - } - } - - if (i == nodeTree.end()) - { - if (defaultValue) - buf = mempool->Strdup(defaultValue); - else - { - error(lineNum, fileName, "substitution not found and default value not given"); - return NULL; - } - } - } - - return buf; -} - -int DOTCONFDocument::macroSubstitute(DOTCONFDocumentNode* tagNode, int valueIndex) -{ - int ret = 0; - char* macro = tagNode->values[valueIndex]; - size_t valueLen = strlen(tagNode->values[valueIndex]) + 1; - char* value = (char*)mempool->Alloc(valueLen); - char* v = value; - char* subs = NULL; - - while (*macro) - { - if (*macro == '$' && *(macro + 1) == '{') - { - char* m = strchr(macro, '}'); - subs = getSubstitution(macro, tagNode->lineNum); - if(subs == NULL) - { - ret = -1; - break; - } - - macro = m + 1; - *v = 0; - v = (char*)mempool->Alloc(strlen(value) + strlen(subs) + valueLen); - strcpy(v, value); - value = strcat(v, subs); - v = value + strlen(value); - continue; - } - - *v++ = *macro++; - } - - *v = 0; - - free(tagNode->values[valueIndex]); - tagNode->values[valueIndex] = strdup(value); - return ret; -} - -const DOTCONFDocumentNode* DOTCONFDocument::getFirstNode() const -{ - if (!nodeTree.empty()) - return *nodeTree.begin(); - else - return NULL; -} - -const DOTCONFDocumentNode* DOTCONFDocument::findNode(const char* nodeName, const DOTCONFDocumentNode* parentNode, const DOTCONFDocumentNode* startNode) const -{ - NodeList::const_iterator i = nodeTree.begin(); - - if (startNode == NULL) - startNode = parentNode; - - if (startNode != NULL) - { - while (i != nodeTree.end() && (*i) != startNode) - ++i; - - if (i != nodeTree.end()) - ++i; - } - - for (; i != nodeTree.end(); ++i) - { - if ((*i)->parentNode != parentNode) - continue; - - if (!cmp_func(nodeName, (*i)->name)) - return *i; - } - - return NULL; -} - -void DOTCONFDocument::setRequiredOptionNames(const char** requiredOptionNames) -{ - while (*requiredOptionNames) - { - requiredOptions.push_back(strdup(*requiredOptionNames)); - ++requiredOptionNames; - } -} diff --git a/src/shared/Config/dotconfpp/dotconfpp.h b/src/shared/Config/dotconfpp/dotconfpp.h deleted file mode 100644 index 55e6dd75d..000000000 --- a/src/shared/Config/dotconfpp/dotconfpp.h +++ /dev/null @@ -1,111 +0,0 @@ -#ifndef DOTCONFPP_H -#define DOTCONFPP_H - -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include "mempool.h" - -class DOTCONFDocument; - -class DOTCONFDocumentNode -{ - friend class DOTCONFDocument; - - private: - - DOTCONFDocumentNode* previousNode; - DOTCONFDocumentNode* nextNode; - DOTCONFDocumentNode* parentNode; - DOTCONFDocumentNode* childNode; - char** values; - int valuesCount; - char* name; - const DOTCONFDocument* document; - int lineNum; - char* fileName; - bool closed; - - void pushValue(char* _value); - - public: - - DOTCONFDocumentNode(); - ~DOTCONFDocumentNode(); - - const char* getConfigurationFileName() const { return fileName; } - int getConfigurationLineNumber() const { return lineNum; } - - const DOTCONFDocumentNode* getNextNode() const { return nextNode; } - const DOTCONFDocumentNode* getPreviuosNode() const { return previousNode; } - const DOTCONFDocumentNode* getParentNode() const { return parentNode; } - const DOTCONFDocumentNode* getChildNode() const { return childNode; } - const char* getValue(int index = 0) const; - const char* getName() const { return name; } - const DOTCONFDocument * getDocument() const { return document; } -}; - -class DOTCONFDocument -{ - public: - - enum CaseSensitive - { - CASESENSITIVE, - CASEINSENSETIVE - }; - - protected: - - AsyncDNSMemPool* mempool; - - private: - - typedef std::list CharList; - typedef std::list NodeList; - - DOTCONFDocumentNode* curParent; - DOTCONFDocumentNode* curPrev; - int curLine; - bool quoted; - NodeList nodeTree; - CharList requiredOptions; - CharList processedFiles; - FILE* file; - char* fileName; - CharList words; - int (*cmp_func)(const char*, const char*); - - int checkRequiredOptions(); - int parseLine(); - int parseFile(DOTCONFDocumentNode* _parent = NULL); - int checkConfig(const NodeList::iterator& from); - int cleanupLine(char* line); - char* getSubstitution(char* macro, int lineNum); - int macroSubstitute(DOTCONFDocumentNode* tagNode, int valueIndex); - - protected: - - virtual void error(int lineNum, const char* fileName, const char* fmt, ...) ATTR_PRINTF(4,5); - - public: - - DOTCONFDocument(CaseSensitive caseSensitivity = CASESENSITIVE); - virtual ~DOTCONFDocument(); - - int setContent(const char* _fileName); - - void setRequiredOptionNames(const char** requiredOptionNames); - const DOTCONFDocumentNode * getFirstNode() const; - const DOTCONFDocumentNode * findNode(const char* nodeName, const DOTCONFDocumentNode* parentNode = NULL, const DOTCONFDocumentNode* startNode = NULL) const; -}; - -#endif diff --git a/src/shared/Config/dotconfpp/mempool.cpp b/src/shared/Config/dotconfpp/mempool.cpp deleted file mode 100644 index 45bdee24c..000000000 --- a/src/shared/Config/dotconfpp/mempool.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include "mempool.h" - -AsyncDNSMemPool::PoolChunk::PoolChunk(size_t _size) -: pool(NULL), pos(0), size(_size) -{ - pool = malloc(size); -} - -AsyncDNSMemPool::PoolChunk::~PoolChunk() -{ - ::free(pool); -} - -AsyncDNSMemPool::AsyncDNSMemPool(size_t _defaultSize) -: chunks(NULL), chunksCount(0), defaultSize(_defaultSize), -poolUsage(0), poolUsageCounter(0) -{ -} - -AsyncDNSMemPool::~AsyncDNSMemPool() -{ - for (size_t i = 0; i < chunksCount; ++i) - delete chunks[i]; - - ::free(chunks); -} - -bool AsyncDNSMemPool::initialize() -{ - chunksCount = 1; - chunks = (PoolChunk**)malloc(sizeof(PoolChunk*)); - if (chunks == NULL) - return false; - - chunks[chunksCount - 1] = new PoolChunk(defaultSize); - - return true; -} - -void AsyncDNSMemPool::addNewChunk(size_t size) -{ - ++chunksCount; - - chunks = (PoolChunk**)realloc(chunks, chunksCount * sizeof(PoolChunk*)); - if (size <= defaultSize) - chunks[chunksCount - 1] = new PoolChunk(defaultSize); - else - chunks[chunksCount - 1] = new PoolChunk(size); -} - -void* AsyncDNSMemPool::Alloc(size_t size) -{ - PoolChunk* chunk = NULL; - for (size_t i = 0; i < chunksCount; ++i) - { - chunk = chunks[i]; - if ((chunk->size - chunk->pos) >= size) - { - chunk->pos += size; - return ((char*)chunk->pool) + chunk->pos - size; - } - } - - addNewChunk(size); - chunks[chunksCount - 1]->pos = size; - return chunks[chunksCount - 1]->pool; -} - -void AsyncDNSMemPool::Free() -{ - size_t pu = 0; - size_t psz = 0; - ++poolUsageCounter; - - for (size_t i = 0; i < chunksCount; ++i) - { - pu += chunks[i]->pos; - psz += chunks[i]->size; - chunks[i]->pos = 0; - } - - poolUsage = poolUsage > pu ? poolUsage : pu; - - if (poolUsageCounter >= 10 && chunksCount > 1) - { - psz -= chunks[chunksCount - 1]->size; - if (poolUsage < psz) - { - --chunksCount; - delete chunks[chunksCount]; - } - - poolUsage = 0; - poolUsageCounter = 0; - } -} - -void* AsyncDNSMemPool::Calloc(size_t size) -{ - return ::memset(Alloc(size), 0, size); -} - -char* AsyncDNSMemPool::Strdup(const char *str) -{ - return ::strcpy((char*)Alloc(strlen(str) + 1), str); -} diff --git a/src/shared/Config/dotconfpp/mempool.h b/src/shared/Config/dotconfpp/mempool.h deleted file mode 100644 index 44b789551..000000000 --- a/src/shared/Config/dotconfpp/mempool.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef ASYNC_DNS_MEMPOOL_H -#define ASYNC_DNS_MEMPOOL_H - -#include -#include -#include - -class AsyncDNSMemPool -{ - private: - - struct PoolChunk - { - void* pool; - size_t pos; - size_t size; - - PoolChunk(size_t _size); - ~PoolChunk(); - }; - - PoolChunk** chunks; - size_t chunksCount; - size_t defaultSize; - - size_t poolUsage; - size_t poolUsageCounter; - - void addNewChunk(size_t size); - - public: - - AsyncDNSMemPool(size_t _defaultSize = 4096); - virtual ~AsyncDNSMemPool(); - - bool initialize(); - void Free(); - void* Alloc(size_t size); - void* Calloc(size_t size); - char* Strdup(const char *str); -}; - -#endif diff --git a/src/shared/Database/Database.cpp b/src/shared/Database/Database.cpp index 8bb729745..a0d9cc8b8 100644 --- a/src/shared/Database/Database.cpp +++ b/src/shared/Database/Database.cpp @@ -17,7 +17,7 @@ */ #include "DatabaseEnv.h" -#include "Config/ConfigEnv.h" +#include "Config/Config.h" #include #include diff --git a/src/shared/Log.cpp b/src/shared/Log.cpp index ebeee267d..c64199e4c 100644 --- a/src/shared/Log.cpp +++ b/src/shared/Log.cpp @@ -19,7 +19,7 @@ #include "Common.h" #include "Log.h" #include "Policies/SingletonImp.h" -#include "Config/ConfigEnv.h" +#include "Config/Config.h" #include "Util.h" #include "ByteBuffer.h" #include "ProgressBar.h" diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index fb8211e82..4b40ecede 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10081" + #define REVISION_NR "10082" #endif // __REVISION_NR_H__ diff --git a/win/VC100/shared.vcxproj b/win/VC100/shared.vcxproj index c67029dd2..6d1e05f74 100644 --- a/win/VC100/shared.vcxproj +++ b/win/VC100/shared.vcxproj @@ -437,8 +437,6 @@ - - @@ -475,9 +473,6 @@ - - - diff --git a/win/VC100/shared.vcxproj.filters b/win/VC100/shared.vcxproj.filters index a72367461..8733657b2 100644 --- a/win/VC100/shared.vcxproj.filters +++ b/win/VC100/shared.vcxproj.filters @@ -16,9 +16,6 @@ {adb98dec-d22a-40b3-84be-51eaf2974a15} - - {dff0e90b-cab5-4d0b-bd5d-3cacbb638630} - {e35fd108-bd39-46ae-83f9-09cf1ebf4ea8} @@ -66,12 +63,6 @@ Config - - Config\dotconfpp - - - Config\dotconfpp - Auth @@ -194,15 +185,6 @@ Config - - Config - - - Config\dotconfpp - - - Config\dotconfpp - Auth diff --git a/win/VC80/shared.vcproj b/win/VC80/shared.vcproj index f23732b84..fbba29694 100644 --- a/win/VC80/shared.vcproj +++ b/win/VC80/shared.vcproj @@ -672,30 +672,6 @@ RelativePath="..\..\src\shared\Config\Config.h" > - - - - - - - - - - - - - - - - - - - - - - - - Date: Sun, 20 Jun 2010 03:52:49 +0400 Subject: [PATCH 34/42] [10083] Made some Spell.h dependences more explicit. --- src/game/Spell.h | 7 +++++-- src/shared/revision_nr.h | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/game/Spell.h b/src/game/Spell.h index 1ec5d7c14..27aaf4dd8 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -23,11 +23,14 @@ #include "SharedDefines.h" #include "DBCEnums.h" #include "ObjectGuid.h" +#include "LootMgr.h" +#include "Unit.h" +#include "Player.h" class WorldSession; -class Unit; +class WorldPacket; class DynamicObj; -class Player; +class Item; class GameObject; class Group; class Aura; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 4b40ecede..238c02834 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10082" + #define REVISION_NR "10083" #endif // __REVISION_NR_H__ From c3cf10893820876cadf48286eb1407809bf98908 Mon Sep 17 00:00:00 2001 From: LordJZ Date: Sun, 20 Jun 2010 04:34:18 +0400 Subject: [PATCH 35/42] [10084] Resync. opcode names in Opcodes.cpp/.h Signed-off-by: VladimirMangos --- src/game/Opcodes.cpp | 26 +++++++++++++------------- src/game/Opcodes.h | 2 +- src/shared/revision_nr.h | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/game/Opcodes.cpp b/src/game/Opcodes.cpp index e1c0c7ddb..6c26ded59 100644 --- a/src/game/Opcodes.cpp +++ b/src/game/Opcodes.cpp @@ -359,7 +359,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x14A*/ { "SMSG_ATTACKERSTATEUPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x14B*/ { "SMSG_BATTLEFIELD_PORT_DENIED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x14C*/ { "SMSG_DAMAGE_DONE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x14D*/ { "SMSG_DAMAGE_TAKEN_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x14D*/ { "SMSG_UNIT_SPELLCAST_START", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x14E*/ { "SMSG_CANCEL_COMBAT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x14F*/ { "SMSG_SPELLBREAKLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x150*/ { "SMSG_SPELLHEALLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, @@ -568,7 +568,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x21B*/ { "SMSG_GMTICKET_SYSTEMSTATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x21C*/ { "CMSG_SPIRIT_HEALER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleSpiritHealerActivateOpcode}, /*0x21D*/ { "CMSG_SET_STAT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x21E*/ { "SMSG_SET_REST_START_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x21E*/ { "SMSG_QUEST_FORCE_REMOVE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x21F*/ { "CMSG_SKILL_BUY_STEP", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x220*/ { "CMSG_SKILL_BUY_RANK", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x221*/ { "CMSG_XP_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, @@ -1146,8 +1146,8 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x45D*/ { "CMSG_FORCE_PITCH_RATE_CHANGE_ACK", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x45E*/ { "SMSG_SPLINE_SET_PITCH_RATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x45F*/ { "SMSG_MOVE_ABANDON_TRANSPORT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x460*/ { "MSG_MOVE_ABANDON_TRANSPORT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x461*/ { "CMSG_MOVE_ABANDON_TRANSPORT_ACK", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x460*/ { "SMSG_CALENDAR_UPDATE_INVITE_LIST", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x461*/ { "SMSG_CALENDAR_UPDATE_INVITE_LIST2", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x462*/ { "CMSG_UPDATE_MISSILE_TRAJECTORY", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x463*/ { "SMSG_UPDATE_ACCOUNT_DATA_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x464*/ { "SMSG_TRIGGER_MOVIE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, @@ -1163,7 +1163,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x46E*/ { "CMSG_COMPLETE_ACHIEVEMENT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x46F*/ { "SMSG_QUESTUPDATE_ADD_PVP_KILL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x470*/ { "CMSG_SET_CRITERIA_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x471*/ { "SMSG_GROUP_SWAP_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x471*/ { "SMSG_CALENDAR_UPDATE_INVITE_LIST3", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x472*/ { "CMSG_UNITANIMTIER_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x473*/ { "CMSG_CHAR_CUSTOMIZE", STATUS_AUTHED, &WorldSession::HandleCharCustomize }, /*0x474*/ { "SMSG_CHAR_CUSTOMIZE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, @@ -1256,13 +1256,13 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x4CB*/ { "UMSG_UNKNOWN_1227", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x4CC*/ { "UMSG_UNKNOWN_1228", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x4CD*/ { "SMSG_MULTIPLE_PACKETS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x4CE*/ { "SMSG_UNKNOWN_1230", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x4CF*/ { "CMSG_UNKNOWN_1231_ACK", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x4D0*/ { "SMSG_UNKNOWN_1232", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x4D1*/ { "CMSG_UNKNOWN_1233_ACK", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x4D2*/ { "SMSG_UNKNOWN_1234", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x4D3*/ { "SMSG_UNKNOWN_1235", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x4D4*/ { "SMSG_UNKNOWN_1236", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4CE*/ { "SMSG_FORCE_UNK1_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4CF*/ { "CMSG_FORCE_UNK1_SPEED_CHANGE_ACK", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4D0*/ { "SMSG_FORCE_UNK2_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4D1*/ { "CMSG_FORCE_UNK2_SPEED_CHANGE_ACK", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4D2*/ { "MSG_MOVE_UNKNOWN_1234", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4D3*/ { "SMSG_SPLINE_MOVE_UNKNOWN_1235", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4D4*/ { "SMSG_SPLINE_MOVE_UNKNOWN_1236", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x4D5*/ { "CMSG_EQUIPMENT_SET_USE", STATUS_LOGGEDIN, &WorldSession::HandleEquipmentSetUse }, /*0x4D6*/ { "SMSG_EQUIPMENT_SET_USE_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x4D7*/ { "UMSG_UNKNOWN_1239", STATUS_NEVER, &WorldSession::Handle_NULL }, @@ -1273,7 +1273,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x4DC*/ { "UMSG_UNKNOWN_1244", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x4DD*/ { "UMSG_UNKNOWN_1245", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x4DE*/ { "SMSG_BATTLEFIELD_MGR_ENTRY_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x4DF*/ { "CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONS", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4DF*/ { "CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONSE", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x4E0*/ { "SMSG_BATTLEFIELD_MGR_ENTERED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x4E1*/ { "SMSG_BATTLEFIELD_MGR_QUEUE_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x4E2*/ { "CMSG_BATTLEFIELD_MGR_QUEUE_INVITE_RESPONSE", STATUS_NEVER, &WorldSession::Handle_NULL }, diff --git a/src/game/Opcodes.h b/src/game/Opcodes.h index 2a0d6417a..8b09eb2dc 100644 --- a/src/game/Opcodes.h +++ b/src/game/Opcodes.h @@ -1242,7 +1242,7 @@ enum Opcodes SMSG_ITEM_REFUND_RESULT = 0x4B5, // refund item result CMSG_CORPSE_MAP_POSITION_QUERY = 0x4B6, // CMSG, uint32 SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE = 0x4B7, // SMSG, 3*float+float - UMSG_UNKNOWN_1208 = 0x4B8, // not found + CMSG_LFG_SET_ROLES_2 = 0x4B8, // not found UMSG_UNKNOWN_1209 = 0x4B9, // not found CMSG_CALENDAR_CONTEXT_EVENT_SIGNUP = 0x4BA, // CMSG, uint64, lua: CalendarContextEventSignUp SMSG_CALENDAR_ACTION_PENDING = 0x4BB, // SMSG, calendar related EVENT_CALENDAR_ACTION_PENDING diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 238c02834..ccacbd7c7 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10083" + #define REVISION_NR "10084" #endif // __REVISION_NR_H__ From f28bc74e66350e7ae72a095bd89da3fc5d461108 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sun, 20 Jun 2010 05:21:50 +0400 Subject: [PATCH 36/42] [10085] Allow loot roll value 100 --- src/game/Group.cpp | 4 ++-- src/shared/revision_nr.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/game/Group.cpp b/src/game/Group.cpp index 7aa97e10b..e6db94f59 100644 --- a/src/game/Group.cpp +++ b/src/game/Group.cpp @@ -771,7 +771,7 @@ void Group::CountTheRoll(Rolls::iterator& rollI) if (itr->second != ROLL_NEED) continue; - uint8 randomN = urand(1, 99); + uint8 randomN = urand(1, 100); SendLootRoll(itr->first, randomN, ROLL_NEED, *roll); if (maxresul < randomN) { @@ -819,7 +819,7 @@ void Group::CountTheRoll(Rolls::iterator& rollI) if (itr->second != ROLL_GREED && itr->second != ROLL_DISENCHANT) continue; - uint8 randomN = urand(1, 99); + uint8 randomN = urand(1, 100); SendLootRoll(itr->first, randomN, itr->second, *roll); if (maxresul < randomN) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index ccacbd7c7..0a7acb120 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10084" + #define REVISION_NR "10085" #endif // __REVISION_NR_H__ From 619f01e1505dc1e3064ee6d907ecee828d023504 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sun, 20 Jun 2010 07:06:30 +0400 Subject: [PATCH 37/42] [10086] Implement use .go command with shiftlinks or player name. * Now if for .go command provided no X Y Z args command will not teleport player to nowhere. * Instead command allow used with player name and work as simplifed .goname (teleport to player _point_ in user instance binding, not to player instance) * Also command can be used with diferent point coordinates provided shift-links: - player (result for example .lookup player account) - creature (result .list creature command) - gameobject (result .list object command) - tele (result .lookup tele) - taxinode (result .lookup taxinode) --- sql/mangos.sql | 3 +- sql/updates/10086_01_mangos_command.sql | 5 + sql/updates/Makefile.am | 2 + src/game/Chat.cpp | 126 +++++++++++++- src/game/Chat.h | 3 + src/game/Level1.cpp | 209 ++++++++++++------------ src/shared/revision_nr.h | 2 +- src/shared/revision_sql.h | 2 +- 8 files changed, 239 insertions(+), 113 deletions(-) create mode 100644 sql/updates/10086_01_mangos_command.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 9bdd88f1a..c77906245 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -24,7 +24,7 @@ CREATE TABLE `db_version` ( `version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL, `cache_id` int(10) default '0', - `required_10056_01_mangos_spell_proc_event` bit(1) default NULL + `required_10086_01_mangos_command` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -577,6 +577,7 @@ INSERT INTO `command` VALUES ('gm ingame',0,'Syntax: .gm ingame\r\n\r\nDisplay a list of available in game Game Masters.'), ('gm list',3,'Syntax: .gm list\r\n\r\nDisplay a list of all Game Masters accounts and security levels.'), ('gm visible',1,'Syntax: .gm visible on/off\r\n\r\nOutput current visibility state or make GM visible(on) and invisible(off) for other players.'), +('go',1,'Syntax: .go [$playername|pointlink|#x #y #z [#mapid]]\r\nTeleport your character to point with coordinates of player $playername, or coordinates of one from shift-link types: player, tele, taxinode, creature, gameobject, or explicit #x #y #z #mapid coordinates.'), ('go creature',1,'Syntax: .go creature #creature_guid\r\nTeleport your character to creature with guid #creature_guid.\r\n.gocreature #creature_name\r\nTeleport your character to creature with this name.\r\n.gocreature id #creature_id\r\nTeleport your character to a creature that was spawned from the template with this entry.\r\n*If* more than one creature is found, then you are teleported to the first that is found inside the database.'), ('go graveyard',1,'Syntax: .go graveyard #graveyardId\r\n Teleport to graveyard with the graveyardId specified.'), ('go grid',1,'Syntax: .go grid #gridX #gridY [#mapId]\r\n\r\nTeleport the gm to center of grid with provided indexes at map #mapId (or current map if it not provided).'), diff --git a/sql/updates/10086_01_mangos_command.sql b/sql/updates/10086_01_mangos_command.sql new file mode 100644 index 000000000..ae505e125 --- /dev/null +++ b/sql/updates/10086_01_mangos_command.sql @@ -0,0 +1,5 @@ +ALTER TABLE db_version CHANGE COLUMN required_10056_01_mangos_spell_proc_event required_10086_01_mangos_command bit; + +DELETE FROM command WHERE name IN('go'); +INSERT INTO command (name, security, help) VALUES +('go',1,'Syntax: .go [$playername|pointlink|#x #y #z [#mapid]]\r\nTeleport your character to point with coordinates of player $playername, or coordinates of one from shift-link types: player, tele, taxinode, creature, gameobject, or explicit #x #y #z #mapid coordinates.'); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index af7404e6c..ff1c377bc 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -89,6 +89,7 @@ pkgdata_DATA = \ 10045_01_mangos_spell_proc_event.sql \ 10051_01_characters_character_aura.sql \ 10056_01_mangos_spell_proc_event.sql \ + 10086_01_mangos_command.sql \ README ## Additional files to include when running 'make dist' @@ -158,4 +159,5 @@ EXTRA_DIST = \ 10045_01_mangos_spell_proc_event.sql \ 10051_01_characters_character_aura.sql \ 10056_01_mangos_spell_proc_event.sql \ + 10086_01_mangos_command.sql \ README diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index 893959977..e1491b9e8 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -216,7 +216,7 @@ ChatCommand * ChatHandler::getCommandTable() { "zonexy", SEC_MODERATOR, false, &ChatHandler::HandleGoZoneXYCommand, "", NULL }, { "xy", SEC_MODERATOR, false, &ChatHandler::HandleGoXYCommand, "", NULL }, { "xyz", SEC_MODERATOR, false, &ChatHandler::HandleGoXYZCommand, "", NULL }, - { "", SEC_MODERATOR, false, &ChatHandler::HandleGoXYZCommand, "", NULL }, + { "", SEC_MODERATOR, false, &ChatHandler::HandleGoCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; @@ -2133,6 +2133,130 @@ uint64 ChatHandler::extractGuidFromLink(char* text) return 0; } +enum LocationLinkType +{ + LOCATION_LINK_PLAYER = 0, // must be first for selection in not link case + LOCATION_LINK_TELE = 1, + LOCATION_LINK_TAXINODE = 2, + LOCATION_LINK_CREATURE = 3, + LOCATION_LINK_GAMEOBJECT = 4 +}; + +static char const* const locationKeys[] = +{ + "Htele", + "Htaxinode", + "Hplayer", + "Hcreature", + "Hgameobject", + NULL +}; + +bool ChatHandler::extractLocationFromLink(char* text, uint32& mapid, float& x, float& y, float& z) +{ + int type = 0; + + // |color|Hplayer:name|h[name]|h|r + // |color|Htele:id|h[name]|h|r + // |color|Htaxinode:id|h[name]|h|r + // |color|Hcreature:creature_guid|h[name]|h|r + // |color|Hgameobject:go_guid|h[name]|h|r + char* idS = extractKeyFromLink(text,locationKeys,&type); + if(!idS) + return false; + + switch(type) + { + // it also fail case + case LOCATION_LINK_PLAYER: + { + // not link and not name, possible coordinates/etc + if (isNumeric(idS[0])) + return false; + + std::string name = idS; + if(!normalizePlayerName(name)) + return false; + + if(Player* player = sObjectMgr.GetPlayer(name.c_str())) + { + mapid = player->GetMapId(); + x = player->GetPositionX(); + y = player->GetPositionY(); + z = player->GetPositionZ(); + return true; + } + + if(uint64 guid = sObjectMgr.GetPlayerGUIDByName(name)) + { + // to point where player stay (if loaded) + float o; + bool in_flight; + return Player::LoadPositionFromDB(mapid, x, y, z, o, in_flight, guid); + } + + return false; + } + case LOCATION_LINK_TELE: + { + uint32 id = (uint32)atol(idS); + GameTele const* tele = sObjectMgr.GetGameTele(id); + if (!tele) + return false; + mapid = tele->mapId; + x = tele->position_x; + y = tele->position_y; + z = tele->position_z; + return true; + } + case LOCATION_LINK_TAXINODE: + { + uint32 id = (uint32)atol(idS); + TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(id); + if (!node) + return false; + mapid = node->map_id; + x = node->x; + y = node->y; + z = node->z; + return true; + } + case LOCATION_LINK_CREATURE: + { + uint32 lowguid = (uint32)atol(idS); + + if(CreatureData const* data = sObjectMgr.GetCreatureData(lowguid) ) + { + mapid = data->mapid; + x = data->posX; + y = data->posY; + z = data->posZ; + return true; + } + else + return false; + } + case LOCATION_LINK_GAMEOBJECT: + { + uint32 lowguid = (uint32)atol(idS); + + if(GameObjectData const* data = sObjectMgr.GetGOData(lowguid) ) + { + mapid = data->mapid; + x = data->posX; + y = data->posY; + z = data->posZ; + return true; + } + else + return false; + } + } + + // unknown type? + return false; +} + std::string ChatHandler::extractPlayerNameFromLink(char* text) { // |color|Hplayer:name|h[name]|h|r diff --git a/src/game/Chat.h b/src/game/Chat.h index 87aa895cf..5250a857b 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -535,6 +535,7 @@ class ChatHandler uint32 extractSpellIdFromLink(char* text); uint64 extractGuidFromLink(char* text); GameTele const* extractGameTeleFromLink(char* text); + bool extractLocationFromLink(char* text, uint32& mapid, float& x, float& y, float& z); std::string extractPlayerNameFromLink(char* text); // select by arg (name/link) or in-game selection online/offline player bool extractPlayerTarget(char* args, Player** player, uint64* player_guid = NULL, std::string* player_name = NULL); @@ -558,6 +559,8 @@ class ChatHandler void HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel); void HandleLearnSkillRecipesHelper(Player* player,uint32 skill_id); void ShowSpellListHelper(Player* target, SpellEntry const* spellInfo, LocaleConstant loc); + bool HandleGoHelper(Player* _player, uint32 mapid, float x, float y, float const* zPtr = NULL); + /** * Stores informations about a deleted character diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp index 603032f13..a19c7ed7c 100644 --- a/src/game/Level1.cpp +++ b/src/game/Level1.cpp @@ -2226,6 +2226,51 @@ bool ChatHandler::HandleGroupgoCommand(const char* args) return true; } +bool ChatHandler::HandleGoHelper( Player* player, uint32 mapid, float x, float y, float const* zPtr ) +{ + float z; + + if (zPtr) + { + z = *zPtr; + + // check full provided coordinates + if(!MapManager::IsValidMapCoord(mapid,x,y,z)) + { + PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid); + SetSentErrorMessage(true); + return false; + } + } + else + { + // we need check x,y before ask Z or can crash at invalide coordinates + if(!MapManager::IsValidMapCoord(mapid,x,y)) + { + PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid); + SetSentErrorMessage(true); + return false; + } + + Map const *map = sMapMgr.CreateBaseMap(mapid); + z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); + } + + // stop flight if need + if(player->isInFlight()) + { + player->GetMotionMaster()->MovementExpired(); + player->m_taxi.ClearTaxiDestinations(); + } + // save only in non-flight case + else + player->SaveRecallPosition(); + + player->TeleportTo(mapid, x, y, z, player->GetOrientation()); + + return true; +} + bool ChatHandler::HandleGoTaxinodeCommand(const char* args) { Player* _player = m_session->GetPlayer(); @@ -2249,28 +2294,55 @@ bool ChatHandler::HandleGoTaxinodeCommand(const char* args) return false; } - if ((node->x == 0.0f && node->y == 0.0f && node->z == 0.0f) || - !MapManager::IsValidMapCoord(node->map_id,node->x,node->y,node->z)) + if (node->x == 0.0f && node->y == 0.0f && node->z == 0.0f) { PSendSysMessage(LANG_INVALID_TARGET_COORD,node->x,node->y,node->map_id); SetSentErrorMessage(true); return false; } - // stop flight if need - if (_player->isInFlight()) - { - _player->GetMotionMaster()->MovementExpired(); - _player->m_taxi.ClearTaxiDestinations(); - } - // save only in non-flight case - else - _player->SaveRecallPosition(); - - _player->TeleportTo(node->map_id, node->x, node->y, node->z, _player->GetOrientation()); - return true; + return HandleGoHelper(_player, node->map_id, node->x, node->y, &node->z); } +bool ChatHandler::HandleGoCommand(const char* args) +{ + if(!*args) + return false; + + Player* _player = m_session->GetPlayer(); + + uint32 mapid; + float x, y, z; + + // raw coordinates case + if (isNumeric(args[0])) + { + char* px = strtok((char*)args, " "); + char* py = strtok(NULL, " "); + char* pz = strtok(NULL, " "); + char* pmapid = strtok(NULL, " "); + + if (!px || !py || !pz) + return false; + + x = (float)atof(px); + y = (float)atof(py); + z = (float)atof(pz); + if (pmapid) + mapid = (uint32)atoi(pmapid); + else + mapid = _player->GetMapId(); + + } + // link case + else if (!extractLocationFromLink((char*)args, mapid, x, y, z)) + return false; + + return HandleGoHelper(_player, mapid, x, y, &z); +} + + + //teleport at coordinates bool ChatHandler::HandleGoXYCommand(const char* args) { @@ -2293,29 +2365,7 @@ bool ChatHandler::HandleGoXYCommand(const char* args) mapid = (uint32)atoi(pmapid); else mapid = _player->GetMapId(); - if(!MapManager::IsValidMapCoord(mapid,x,y)) - { - PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid); - SetSentErrorMessage(true); - return false; - } - - // stop flight if need - if(_player->isInFlight()) - { - _player->GetMotionMaster()->MovementExpired(); - _player->m_taxi.ClearTaxiDestinations(); - } - // save only in non-flight case - else - _player->SaveRecallPosition(); - - Map const *map = sMapMgr.CreateBaseMap(mapid); - float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); - - _player->TeleportTo(mapid, x, y, z, _player->GetOrientation()); - - return true; + return HandleGoHelper(_player, mapid, x, y); } //teleport at coordinates, including Z @@ -2343,26 +2393,7 @@ bool ChatHandler::HandleGoXYZCommand(const char* args) else mapid = _player->GetMapId(); - if(!MapManager::IsValidMapCoord(mapid,x,y,z)) - { - PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid); - SetSentErrorMessage(true); - return false; - } - - // stop flight if need - if(_player->isInFlight()) - { - _player->GetMotionMaster()->MovementExpired(); - _player->m_taxi.ClearTaxiDestinations(); - } - // save only in non-flight case - else - _player->SaveRecallPosition(); - - _player->TeleportTo(mapid, x, y, z, _player->GetOrientation()); - - return true; + return HandleGoHelper(_player, mapid, x, y, &z); } //teleport at coordinates @@ -2403,49 +2434,33 @@ bool ChatHandler::HandleGoZoneXYCommand(const char* args) // update to parent zone if exist (client map show only zones without parents) AreaTableEntry const* zoneEntry = areaEntry->zone ? GetAreaEntryByAreaID(areaEntry->zone) : areaEntry; - Map const *map = sMapMgr.CreateBaseMap(zoneEntry->mapid); + MapEntry const *mapEntry = sMapStore.LookupEntry(zoneEntry->mapid); - if(map->Instanceable()) + if (mapEntry->Instanceable()) { - PSendSysMessage(LANG_INVALID_ZONE_MAP,areaEntry->ID,areaEntry->area_name[GetSessionDbcLocale()],map->GetId(),map->GetMapName()); + PSendSysMessage(LANG_INVALID_ZONE_MAP, areaEntry->ID, areaEntry->area_name[GetSessionDbcLocale()], + mapEntry->MapID, mapEntry->name[GetSessionDbcLocale()]); SetSentErrorMessage(true); return false; } if (!Zone2MapCoordinates(x,y,zoneEntry->ID)) { - PSendSysMessage(LANG_INVALID_ZONE_MAP,areaEntry->ID,areaEntry->area_name[GetSessionDbcLocale()],map->GetId(),map->GetMapName()); + PSendSysMessage(LANG_INVALID_ZONE_MAP, areaEntry->ID, areaEntry->area_name[GetSessionDbcLocale()], + mapEntry->MapID, mapEntry->name[GetSessionDbcLocale()]); SetSentErrorMessage(true); return false; } - if(!MapManager::IsValidMapCoord(zoneEntry->mapid,x,y)) - { - PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,zoneEntry->mapid); - SetSentErrorMessage(true); - return false; - } - - // stop flight if need - if(_player->isInFlight()) - { - _player->GetMotionMaster()->MovementExpired(); - _player->m_taxi.ClearTaxiDestinations(); - } - // save only in non-flight case - else - _player->SaveRecallPosition(); - - float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); - _player->TeleportTo(zoneEntry->mapid, x, y, z, _player->GetOrientation()); - - return true; + return HandleGoHelper(_player, mapEntry->MapID, x, y); } //teleport to grid bool ChatHandler::HandleGoGridCommand(const char* args) { - if(!*args) return false; + if (!*args) + return false; + Player* _player = m_session->GetPlayer(); char* px = strtok((char*)args, " "); @@ -2457,37 +2472,13 @@ bool ChatHandler::HandleGoGridCommand(const char* args) float grid_x = (float)atof(px); float grid_y = (float)atof(py); - uint32 mapid; - if (pmapid) - mapid = (uint32)atoi(pmapid); - else mapid = _player->GetMapId(); + uint32 mapid = pmapid ? (uint32)atoi(pmapid) : _player->GetMapId(); // center of grid float x = (grid_x-CENTER_GRID_ID+0.5f)*SIZE_OF_GRIDS; float y = (grid_y-CENTER_GRID_ID+0.5f)*SIZE_OF_GRIDS; - if(!MapManager::IsValidMapCoord(mapid,x,y)) - { - PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid); - SetSentErrorMessage(true); - return false; - } - - // stop flight if need - if(_player->isInFlight()) - { - _player->GetMotionMaster()->MovementExpired(); - _player->m_taxi.ClearTaxiDestinations(); - } - // save only in non-flight case - else - _player->SaveRecallPosition(); - - Map const *map = sMapMgr.CreateBaseMap(mapid); - float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); - _player->TeleportTo(mapid, x, y, z, _player->GetOrientation()); - - return true; + return HandleGoHelper(_player, mapid, x, y); } bool ChatHandler::HandleModifyDrunkCommand(const char* args) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 0a7acb120..e28b4c859 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10085" + #define REVISION_NR "10086" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index 3e7586ffb..8c440e80e 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_10051_01_characters_character_aura" - #define REVISION_DB_MANGOS "required_10056_01_mangos_spell_proc_event" + #define REVISION_DB_MANGOS "required_10086_01_mangos_command" #define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version" #endif // __REVISION_SQL_H__ From a2a50c11be777f4a558c401a17e210be07e6f402 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sun, 20 Jun 2010 21:48:05 +0400 Subject: [PATCH 38/42] [10087] Move table in more expected mangos.sql part --- sql/mangos.sql | 40 ++++++++++++++++++++-------------------- src/shared/revision_nr.h | 2 +- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/sql/mangos.sql b/sql/mangos.sql index c77906245..0a33b4e7b 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -1648,6 +1648,26 @@ LOCK TABLES `game_event_model_equip` WRITE; /*!40000 ALTER TABLE `game_event_model_equip` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `game_event_pool` +-- + +DROP TABLE IF EXISTS `game_event_pool`; +CREATE TABLE `game_event_pool` ( + `pool_entry` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Id of the pool', + `event` smallint(6) NOT NULL default '0' COMMENT 'Put negatives values to remove during event', + PRIMARY KEY (`pool_entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `game_event_pool` +-- + +LOCK TABLES `game_event_pool` WRITE; +/*!40000 ALTER TABLE `game_event_pool` DISABLE KEYS */; +/*!40000 ALTER TABLE `game_event_pool` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `game_graveyard_zone` -- @@ -13705,26 +13725,6 @@ LOCK TABLES `pool_template` WRITE; /*!40000 ALTER TABLE `pool_template` ENABLE KEYS */; UNLOCK TABLES; --- --- Table structure for table `game_event_pool` --- - -DROP TABLE IF EXISTS `game_event_pool`; -CREATE TABLE `game_event_pool` ( - `pool_entry` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Id of the pool', - `event` smallint(6) NOT NULL default '0' COMMENT 'Put negatives values to remove during event', - PRIMARY KEY (`pool_entry`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - --- --- Dumping data for table `game_event_pool` --- - -LOCK TABLES `game_event_pool` WRITE; -/*!40000 ALTER TABLE `game_event_pool` DISABLE KEYS */; -/*!40000 ALTER TABLE `game_event_pool` ENABLE KEYS */; -UNLOCK TABLES; - -- -- Table structure for table `prospecting_loot_template` -- diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index e28b4c859..6f0d599ff 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10086" + #define REVISION_NR "10087" #endif // __REVISION_NR_H__ From 407156cbaff9a0d612efd15c71777485b9d2f198 Mon Sep 17 00:00:00 2001 From: Laise Date: Sun, 20 Jun 2010 22:28:51 +0300 Subject: [PATCH 39/42] [10088] Restore work of 1120 and ranks. (Revert of [9962]) --- src/game/SpellAuras.cpp | 10 ---------- src/game/Unit.cpp | 8 ++++++++ src/shared/revision_nr.h | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 533c09805..263e473b3 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -4959,16 +4959,6 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real) } break; } - case SPELLFAMILY_WARLOCK: - { - // Drain Soul - if (spellProto->SpellFamilyFlags & UI64LIT(0x0000000000004000)) - { - if (target->GetHealth() * 100 / target->GetMaxHealth() <= 25) - m_modifier.m_amount *= 4; - } - break; - } case SPELLFAMILY_DRUID: { // Rake diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 81f6db4d0..a280dd8d6 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -9177,7 +9177,15 @@ uint32 Unit::SpellDamageBonusDone(Unit *pVictim, SpellEntry const *spellProto, u break; } case SPELLFAMILY_WARLOCK: + { + // Drain Soul + if (spellProto->SpellFamilyFlags & UI64LIT(0x0000000000004000)) + { + if (pVictim->GetHealth() * 100 / pVictim->GetMaxHealth() <= 25) + DoneTotalMod *= 4; + } break; + } case SPELLFAMILY_PRIEST: { // Glyph of Smite diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 6f0d599ff..c3210f870 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10087" + #define REVISION_NR "10088" #endif // __REVISION_NR_H__ From 8e6410d6392cd61d5b51e2654d133d9c7344a176 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 21 Jun 2010 05:23:13 +0400 Subject: [PATCH 40/42] [10089] Change in event system work with pool system. * `game_event_pool` dropped and related in momory data generated based by another pool tables content. * Pool work with spawed at event and despawned at event object now different. - If object listed in `game_event_*` as spawned at event start and it's part of some pool then all other pool object must be listed as spawned with this event start, and more, if pool has mother pool, then all mother pool members must have objects spawned at this event start. More short: all object of some top (not have mother pool) mitbe or listed for some event start spawn, or not listed for any event start spawn. - If object listed in `game_event_*` as DEspawned at event start and it's part of some pool then nothing special required for other pool objects. Event systemwil command to pool system exclude for spawning and despawn referenced object until event end. * Many checks has been added at event/pool data loading. * Changes fix crashes related to event/pool common work. Thanks to NoFantasy for help in research original problems and ways for improve code. --- sql/mangos.sql | 26 +-- .../10089_01_mangos_game_event_pool.sql | 3 + sql/updates/Makefile.am | 2 + src/game/GameEventMgr.cpp | 211 ++++++++++++------ src/game/GameEventMgr.h | 10 +- src/game/PoolManager.cpp | 109 ++++++++- src/game/PoolManager.h | 32 ++- src/game/World.cpp | 2 +- src/shared/revision_nr.h | 2 +- src/shared/revision_sql.h | 2 +- 10 files changed, 290 insertions(+), 109 deletions(-) create mode 100644 sql/updates/10089_01_mangos_game_event_pool.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 0a33b4e7b..098d2bb8a 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -24,7 +24,7 @@ CREATE TABLE `db_version` ( `version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL, `cache_id` int(10) default '0', - `required_10086_01_mangos_command` bit(1) default NULL + `required_10089_01_mangos_game_event_pool` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -1572,7 +1572,7 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `game_event_creature`; CREATE TABLE `game_event_creature` ( `guid` int(10) unsigned NOT NULL, - `event` smallint(6) NOT NULL default '0' COMMENT 'Put negatives values to remove during event', + `event` smallint(6) NOT NULL default '0' COMMENT 'Negatives value to remove during event and ignore pool grouping, positive value for spawn during event and if guid is part of pool then al pool memebers must be listed as part of event spawn.', PRIMARY KEY (`guid`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; @@ -1613,7 +1613,7 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `game_event_gameobject`; CREATE TABLE `game_event_gameobject` ( `guid` int(10) unsigned NOT NULL, - `event` smallint(6) NOT NULL default '0' COMMENT 'Put negatives values to remove during event', + `event` smallint(6) NOT NULL default '0' COMMENT 'Negatives value to remove during event and ignore pool grouping, positive value for spawn during event and if guid is part of pool then al pool memebers must be listed as part of event spawn.', PRIMARY KEY (`guid`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; @@ -1648,26 +1648,6 @@ LOCK TABLES `game_event_model_equip` WRITE; /*!40000 ALTER TABLE `game_event_model_equip` ENABLE KEYS */; UNLOCK TABLES; --- --- Table structure for table `game_event_pool` --- - -DROP TABLE IF EXISTS `game_event_pool`; -CREATE TABLE `game_event_pool` ( - `pool_entry` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Id of the pool', - `event` smallint(6) NOT NULL default '0' COMMENT 'Put negatives values to remove during event', - PRIMARY KEY (`pool_entry`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - --- --- Dumping data for table `game_event_pool` --- - -LOCK TABLES `game_event_pool` WRITE; -/*!40000 ALTER TABLE `game_event_pool` DISABLE KEYS */; -/*!40000 ALTER TABLE `game_event_pool` ENABLE KEYS */; -UNLOCK TABLES; - -- -- Table structure for table `game_graveyard_zone` -- diff --git a/sql/updates/10089_01_mangos_game_event_pool.sql b/sql/updates/10089_01_mangos_game_event_pool.sql new file mode 100644 index 000000000..f51d71e37 --- /dev/null +++ b/sql/updates/10089_01_mangos_game_event_pool.sql @@ -0,0 +1,3 @@ +ALTER TABLE db_version CHANGE COLUMN required_10086_01_mangos_command required_10089_01_mangos_game_event_pool bit; + +DROP TABLE IF EXISTS `game_event_pool`; diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index ff1c377bc..0703cd7eb 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -90,6 +90,7 @@ pkgdata_DATA = \ 10051_01_characters_character_aura.sql \ 10056_01_mangos_spell_proc_event.sql \ 10086_01_mangos_command.sql \ + 10089_01_mangos_game_event_pool.sql \ README ## Additional files to include when running 'make dist' @@ -160,4 +161,5 @@ EXTRA_DIST = \ 10051_01_characters_character_aura.sql \ 10056_01_mangos_spell_proc_event.sql \ 10086_01_mangos_command.sql \ + 10089_01_mangos_game_event_pool.sql \ README diff --git a/src/game/GameEventMgr.cpp b/src/game/GameEventMgr.cpp index 04275c311..2bcbbd1a8 100644 --- a/src/game/GameEventMgr.cpp +++ b/src/game/GameEventMgr.cpp @@ -171,6 +171,13 @@ void GameEventMgr::LoadFromDB() sLog.outString( ">> Loaded %u game events", count ); } + std::map pool2event; // for check unique spawn event associated with pool + std::map creature2event; // for check unique spawn event associated with creature + std::map go2event; // for check unique spawn event associated with gameobject + + // list only positive event top pools, filled at creature/gameobject loading + mGameEventSpawnPoolIds.resize(mGameEvent.size()); + mGameEventCreatureGuids.resize(mGameEvent.size()*2-1); // 1 2 result = WorldDatabase.Query("SELECT creature.guid, game_event_creature.event " @@ -198,6 +205,12 @@ void GameEventMgr::LoadFromDB() uint32 guid = fields[0].GetUInt32(); int16 event_id = fields[1].GetInt16(); + if (event_id == 0) + { + sLog.outErrorDb("`game_event_creature` game event id (%i) not allowed",event_id); + continue; + } + int32 internal_event_id = mGameEvent.size() + event_id - 1; if(internal_event_id < 0 || (size_t)internal_event_id >= mGameEventCreatureGuids.size()) @@ -207,6 +220,32 @@ void GameEventMgr::LoadFromDB() } ++count; + + // spawn objects at event can be grouped in pools and then affected pools have stricter requirements for this case + if (event_id > 0) + { + creature2event[guid] = event_id; + + // not list explicitly creatures from pools in event creature list + if (uint16 topPoolId = sPoolMgr.IsPartOfTopPool(guid)) + { + int16& eventRef = pool2event[topPoolId]; + if (eventRef != 0) + { + if (eventRef != event_id) + sLog.outErrorDb("`game_event_creature` have creature (GUID: %u) for event %i from pool or subpool of pool (ID: %u) but pool have already content from event %i. Pool don't must have content for different events!", guid, event_id, topPoolId, eventRef); + } + else + { + eventRef = event_id; + mGameEventSpawnPoolIds[event_id].push_back(topPoolId); + sPoolMgr.RemoveAutoSpawnForPool(topPoolId); + } + + continue; + } + } + GuidList& crelist = mGameEventCreatureGuids[internal_event_id]; crelist.push_back(guid); @@ -244,6 +283,12 @@ void GameEventMgr::LoadFromDB() uint32 guid = fields[0].GetUInt32(); int16 event_id = fields[1].GetInt16(); + if (event_id == 0) + { + sLog.outErrorDb("`game_event_gameobject` game event id (%i) not allowed",event_id); + continue; + } + int32 internal_event_id = mGameEvent.size() + event_id - 1; if(internal_event_id < 0 || (size_t)internal_event_id >= mGameEventGameobjectGuids.size()) @@ -253,6 +298,32 @@ void GameEventMgr::LoadFromDB() } ++count; + + // spawn objects at event can be grouped in pools and then affected pools have stricter requirements for this case + if (event_id > 0) + { + go2event[guid] = event_id; + + // not list explicitly gameobjects from pools in event gameobject list + if (uint16 topPoolId = sPoolMgr.IsPartOfTopPool(guid)) + { + int16& eventRef = pool2event[topPoolId]; + if (eventRef != 0) + { + if (eventRef != event_id) + sLog.outErrorDb("`game_event_gameobject` have gameobject (GUID: %u) for event %i from pool or subpool of pool (ID: %u) but pool have already content from event %i. Pool don't must have content for different events!", guid, event_id, topPoolId, eventRef); + } + else + { + eventRef = event_id; + mGameEventSpawnPoolIds[event_id].push_back(topPoolId); + sPoolMgr.RemoveAutoSpawnForPool(topPoolId); + } + + continue; + } + } + GuidList& golist = mGameEventGameobjectGuids[internal_event_id]; golist.push_back(guid); @@ -263,6 +334,15 @@ void GameEventMgr::LoadFromDB() sLog.outString( ">> Loaded %u gameobjects in game events", count ); } + // now recheck that all eventPools linked with events after our skip pools with parents + for(std::map::const_iterator itr = pool2event.begin(); itr != pool2event.end(); ++itr) + { + uint16 pool_id = itr->first; + int16 event_id = itr->second; + + sPoolMgr.CheckEventLinkAndReport(pool_id, event_id, creature2event, go2event); + } + mGameEventModelEquip.resize(mGameEvent.size()); // 0 1 2 result = WorldDatabase.Query("SELECT creature.guid, game_event_model_equip.event, game_event_model_equip.modelid," @@ -365,57 +445,6 @@ void GameEventMgr::LoadFromDB() sLog.outString(); sLog.outString( ">> Loaded %u quests additions in game events", count ); } - - mGameEventPoolIds.resize(mGameEvent.size()*2-1); - // 1 2 - result = WorldDatabase.Query("SELECT pool_template.entry, game_event_pool.event " - "FROM pool_template JOIN game_event_pool ON pool_template.entry = game_event_pool.pool_entry"); - - count = 0; - if( !result ) - { - barGoLink bar2(1); - bar2.step(); - - sLog.outString(); - sLog.outString(">> Loaded %u pools in game events", count ); - } - else - { - - barGoLink bar2( (int)result->GetRowCount() ); - do - { - Field *fields = result->Fetch(); - - bar2.step(); - - uint32 entry = fields[0].GetUInt16(); - int16 event_id = fields[1].GetInt16(); - - int32 internal_event_id = mGameEvent.size() + event_id - 1; - - if (internal_event_id < 0 || (size_t)internal_event_id >= mGameEventPoolIds.size()) - { - sLog.outErrorDb("`game_event_pool` game event id (%i) is out of range compared to max event id in `game_event`",event_id); - continue; - } - - if (!sPoolMgr.CheckPool(entry)) - { - sLog.outErrorDb("Pool Id (%u) has all creatures or gameobjects with explicit chance sum <>100 and no equal chance defined. The pool system cannot pick one to spawn.", entry); - continue; - } - - ++count; - IdList& poollist = mGameEventPoolIds[internal_event_id]; - poollist.push_back(entry); - - } while( result->NextRow() ); - sLog.outString(); - sLog.outString( ">> Loaded %u pools in game events", count ); - delete result; - } } uint32 GameEventMgr::Initialize() // return the next event delay in ms @@ -516,6 +545,18 @@ void GameEventMgr::GameEventSpawn(int16 event_id) CreatureData const* data = sObjectMgr.GetCreatureData(*itr); if (data) { + // negative event id for pool element meaning allow be used in next pool spawn + if (event_id < 0) + { + if (uint16 pool_id = sPoolMgr.IsPartOfAPool(*itr)) + { + // will have chance at next pool update + sPoolMgr.SetExcludeObject(pool_id, *itr, false); + sPoolMgr.UpdatePool(pool_id); + continue; + } + } + sObjectMgr.AddCreatureToGrid(*itr, data); // Spawn if necessary (loaded grids only) @@ -549,7 +590,20 @@ void GameEventMgr::GameEventSpawn(int16 event_id) GameObjectData const* data = sObjectMgr.GetGOData(*itr); if (data) { + // negative event id for pool element meaning allow be used in next pool spawn + if (event_id < 0) + { + if (uint16 pool_id = sPoolMgr.IsPartOfAPool(*itr)) + { + // will have chance at next pool update + sPoolMgr.SetExcludeObject(pool_id, *itr, false); + sPoolMgr.UpdatePool(pool_id); + continue; + } + } + sObjectMgr.AddGameobjectToGrid(*itr, data); + // Spawn if necessary (loaded grids only) // this base map checked as non-instanced and then only existed Map* map = const_cast(sMapMgr.CreateBaseMap(data->mapid)); @@ -571,14 +625,17 @@ void GameEventMgr::GameEventSpawn(int16 event_id) } } - if (internal_event_id < 0 || (size_t)internal_event_id >= mGameEventPoolIds.size()) + if (event_id > 0) { - sLog.outError("GameEventMgr::GameEventSpawn attempt access to out of range mGameEventPoolIds element %i (size: " SIZEFMTD ")",internal_event_id,mGameEventPoolIds.size()); - return; - } + if((size_t)event_id >= mGameEventSpawnPoolIds.size()) + { + sLog.outError("GameEventMgr::GameEventSpawn attempt access to out of range mGameEventSpawnPoolIds element %i (size: " SIZEFMTD ")", event_id, mGameEventSpawnPoolIds.size()); + return; + } - for (IdList::iterator itr = mGameEventPoolIds[internal_event_id].begin();itr != mGameEventPoolIds[internal_event_id].end();++itr) - sPoolMgr.SpawnPool(*itr, true); + for (IdList::iterator itr = mGameEventSpawnPoolIds[event_id].begin();itr != mGameEventSpawnPoolIds[event_id].end();++itr) + sPoolMgr.SpawnPool(*itr, true); + } } void GameEventMgr::GameEventUnspawn(int16 event_id) @@ -596,6 +653,17 @@ void GameEventMgr::GameEventUnspawn(int16 event_id) // Remove the creature from grid if( CreatureData const* data = sObjectMgr.GetCreatureData(*itr) ) { + // negative event id for pool element meaning unspawn in pool and exclude for next spawns + if (event_id < 0) + { + if (uint16 poolid = sPoolMgr.IsPartOfAPool(*itr)) + { + sPoolMgr.SetExcludeObject(poolid, *itr, true); + sPoolMgr.UpdatePool(poolid, *itr); + continue; + } + } + sObjectMgr.RemoveCreatureFromGrid(*itr, data); if (Creature* pCreature = ObjectAccessor::GetCreatureInWorld(ObjectGuid(HIGHGUID_UNIT, data->id, *itr))) @@ -614,21 +682,36 @@ void GameEventMgr::GameEventUnspawn(int16 event_id) // Remove the gameobject from grid if(GameObjectData const* data = sObjectMgr.GetGOData(*itr)) { + // negative event id for pool element meaning unspawn in pool and exclude for next spawns + if (event_id < 0) + { + if (uint16 poolid = sPoolMgr.IsPartOfAPool(*itr)) + { + sPoolMgr.SetExcludeObject(poolid, *itr, true); + sPoolMgr.UpdatePool(poolid, *itr); + continue; + } + } + sObjectMgr.RemoveGameobjectFromGrid(*itr, data); if( GameObject* pGameobject = ObjectAccessor::GetGameObjectInWorld(ObjectGuid(HIGHGUID_GAMEOBJECT, data->id, *itr)) ) pGameobject->AddObjectToRemoveList(); } } - if (internal_event_id < 0 || (size_t)internal_event_id >= mGameEventPoolIds.size()) - { - sLog.outError("GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventPoolIds element %i (size: " SIZEFMTD ")",internal_event_id,mGameEventPoolIds.size()); - return; - } - for (IdList::iterator itr = mGameEventPoolIds[internal_event_id].begin();itr != mGameEventPoolIds[internal_event_id].end();++itr) + if (event_id > 0) { - sPoolMgr.DespawnPool(*itr); + if ((size_t)event_id >= mGameEventSpawnPoolIds.size()) + { + sLog.outError("GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventSpawnPoolIds element %i (size: " SIZEFMTD ")", event_id, mGameEventSpawnPoolIds.size()); + return; + } + + for (IdList::iterator itr = mGameEventSpawnPoolIds[event_id].begin();itr != mGameEventSpawnPoolIds[event_id].end();++itr) + { + sPoolMgr.DespawnPool(*itr); + } } } diff --git a/src/game/GameEventMgr.h b/src/game/GameEventMgr.h index 39480a9f4..e236768bb 100644 --- a/src/game/GameEventMgr.h +++ b/src/game/GameEventMgr.h @@ -88,11 +88,11 @@ class GameEventMgr typedef std::pair QuestRelation; typedef std::list QuestRelList; typedef std::vector GameEventQuestMap; - GameEventQuestMap mGameEventQuests; - GameEventModelEquipMap mGameEventModelEquip; - GameEventGuidMap mGameEventCreatureGuids; - GameEventGuidMap mGameEventGameobjectGuids; - GameEventIdMap mGameEventPoolIds; + GameEventQuestMap mGameEventQuests; // events*2-1 + GameEventModelEquipMap mGameEventModelEquip; // events*2-1 + GameEventGuidMap mGameEventCreatureGuids; // events*2-1 + GameEventGuidMap mGameEventGameobjectGuids; // events*2-1 + GameEventIdMap mGameEventSpawnPoolIds; // events size, only positive event case GameEventDataMap mGameEvent; ActiveEvents m_ActiveEvents; bool m_IsGameEventsInit; diff --git a/src/game/PoolManager.cpp b/src/game/PoolManager.cpp index b0b30308b..ba8c76897 100644 --- a/src/game/PoolManager.cpp +++ b/src/game/PoolManager.cpp @@ -106,6 +106,30 @@ void SpawnedPoolData::RemoveSpawn(uint32 sub_pool_id, uint32 pool_id) --val; } +//////////////////////////////////////////////////////////// +// Methods of class PoolObject +template<> +void PoolObject::CheckEventLinkAndReport(uint32 poolId, int16 event_id, std::map const& creature2event, std::map const& /*go2event*/) const +{ + std::map::const_iterator itr = creature2event.find(guid); + if (itr == creature2event.end() || itr->second != event_id) + sLog.outErrorDb("Creature (GUID: %u) expected to be listed in `game_event_creature` for event %u as part pool %u", guid, event_id, poolId); +} + +template<> +void PoolObject::CheckEventLinkAndReport(uint32 poolId, int16 event_id, std::map const& /*creature2event*/, std::map const& go2event) const +{ + std::map::const_iterator itr = go2event.find(guid); + if (itr == go2event.end() || itr->second != event_id) + sLog.outErrorDb("Gameobject (GUID: %u) expected to be listed in `game_event_gameobject` for event %u as part pool %u", guid, event_id, poolId); +} + +template<> +void PoolObject::CheckEventLinkAndReport(uint32 poolId, int16 event_id, std::map const& creature2event, std::map const& go2event) const +{ + sPoolMgr.CheckEventLinkAndReport(guid, event_id, creature2event, go2event); +} + //////////////////////////////////////////////////////////// // Methods of template class PoolGroup @@ -134,6 +158,40 @@ bool PoolGroup::CheckPool() const return true; } +// Method to check event linking +template +void PoolGroup::CheckEventLinkAndReport(int16 event_id, std::map const& creature2event, std::map const& go2event) const +{ + for (uint32 i=0; i < EqualChanced.size(); ++i) + EqualChanced[i].CheckEventLinkAndReport(poolId, event_id, creature2event, go2event); + + for (uint32 i=0; i(poolId, event_id, creature2event, go2event); +} + +template +void PoolGroup::SetExcludeObject(uint32 guid, bool state) +{ + for (uint32 i=0; i < EqualChanced.size(); ++i) + { + if (EqualChanced[i].guid == guid) + { + EqualChanced[i].exclude = state; + return; + } + } + + for (uint32 i=0; i PoolObject* PoolGroup::RollOne(SpawnedPoolData& spawns, uint32 triggerFrom) { @@ -146,7 +204,7 @@ PoolObject* PoolGroup::RollOne(SpawnedPoolData& spawns, uint32 triggerFrom) roll -= ExplicitlyChanced[i].chance; // Triggering object is marked as spawned at this time and can be also rolled (respawn case) // so this need explicit check for this case - if (roll < 0 && (ExplicitlyChanced[i].guid == triggerFrom || !spawns.IsSpawnedObject(ExplicitlyChanced[i].guid))) + if (roll < 0 && !ExplicitlyChanced[i].exclude && (ExplicitlyChanced[i].guid == triggerFrom || !spawns.IsSpawnedObject(ExplicitlyChanced[i].guid))) return &ExplicitlyChanced[i]; } } @@ -156,7 +214,7 @@ PoolObject* PoolGroup::RollOne(SpawnedPoolData& spawns, uint32 triggerFrom) int32 index = irand(0, EqualChanced.size()-1); // Triggering object is marked as spawned at this time and can be also rolled (respawn case) // so this need explicit check for this case - if (EqualChanced[index].guid == triggerFrom || !spawns.IsSpawnedObject(EqualChanced[index].guid)) + if (!EqualChanced[index].exclude && (EqualChanced[index].guid == triggerFrom || !spawns.IsSpawnedObject(EqualChanced[index].guid))) return &EqualChanced[index]; } @@ -263,7 +321,12 @@ void PoolGroup::SpawnObject(SpawnedPoolData& spawns, uint32 limit, uint32 tri // and also counted into m_SpawnedPoolAmount so we need increase count to be // spawned by 1 if (triggerFrom) - ++count; + { + if (spawns.IsSpawnedObject(triggerFrom)) + ++count; + else + triggerFrom = 0; + } // This will try to spawn the rest of pool, not guaranteed for (int i = 0; i < count; ++i) @@ -462,6 +525,7 @@ void PoolManager::LoadFromDB() PoolTemplateData& pPoolTemplate = mPoolTemplate[pool_id]; pPoolTemplate.MaxLimit = fields[1].GetUInt32(); + pPoolTemplate.AutoSpawn = true; // will update and later data loading } while (result->NextRow()); @@ -661,6 +725,9 @@ void PoolManager::LoadFromDB() SearchPair p(child_pool_id, mother_pool_id); mPoolSearchMap.insert(p); + // update top independent pool flag + mPoolTemplate[child_pool_id].AutoSpawn = false; + } while( result->NextRow() ); // Now check for circular reference @@ -692,17 +759,15 @@ void PoolManager::LoadFromDB() } } -// The initialize method will spawn all pools not in an event and not in another pool, this is why there is 2 left joins with 2 null checks +// The initialize method will spawn all pools not in an event and not in another pool void PoolManager::Initialize() { - QueryResult *result = WorldDatabase.Query("SELECT DISTINCT pool_template.entry FROM pool_template LEFT JOIN game_event_pool ON pool_template.entry=game_event_pool.pool_entry LEFT JOIN pool_pool ON pool_template.entry=pool_pool.pool_id WHERE game_event_pool.pool_entry IS NULL AND pool_pool.pool_id IS NULL"); - uint32 count=0; - if (result) + uint32 count = 0; + + for(uint16 pool_entry = 0; pool_entry < mPoolTemplate.size(); ++pool_entry) { - do + if (mPoolTemplate[pool_entry].AutoSpawn) { - Field *fields = result->Fetch(); - uint16 pool_entry = fields[0].GetUInt16(); if (!CheckPool(pool_entry)) { sLog.outErrorDb("Pool Id (%u) has all creatures or gameobjects with explicit chance sum <>100 and no equal chance defined. The pool system cannot pick one to spawn.", pool_entry); @@ -710,8 +775,7 @@ void PoolManager::Initialize() } SpawnPool(pool_entry, true); count++; - } while (result->NextRow()); - delete result; + } } BASIC_LOG("Pool handling system initialized, %u pools spawned.", count); @@ -775,6 +839,27 @@ bool PoolManager::CheckPool(uint16 pool_id) const mPoolPoolGroups[pool_id].CheckPool(); } +// Method that check linking all elements to event +void PoolManager::CheckEventLinkAndReport(uint16 pool_id, int16 event_id, std::map const& creature2event, std::map const& go2event) const +{ + mPoolGameobjectGroups[pool_id].CheckEventLinkAndReport(event_id, creature2event, go2event); + mPoolCreatureGroups[pool_id].CheckEventLinkAndReport(event_id, creature2event, go2event); + mPoolPoolGroups[pool_id].CheckEventLinkAndReport(event_id, creature2event, go2event); +} + +// Method that exclude some elements from next spawn +template<> +void PoolManager::SetExcludeObject(uint16 pool_id, uint32 db_guid_or_pool_id, bool state) +{ + mPoolCreatureGroups[pool_id].SetExcludeObject(db_guid_or_pool_id, state); +} + +template<> +void PoolManager::SetExcludeObject(uint16 pool_id, uint32 db_guid_or_pool_id, bool state) +{ + mPoolGameobjectGroups[pool_id].SetExcludeObject(db_guid_or_pool_id, state); +} + // Call to update the pool when a gameobject/creature part of pool [pool_id] is ready to respawn // Here we cache only the creature/gameobject whose guid is passed as parameter // Then the spawn pool call will use this cache to decide diff --git a/src/game/PoolManager.h b/src/game/PoolManager.h index 5cdeeda7d..278cdd701 100644 --- a/src/game/PoolManager.h +++ b/src/game/PoolManager.h @@ -27,13 +27,19 @@ struct PoolTemplateData { uint32 MaxLimit; + bool AutoSpawn; // spawn at pool system start (not part of another pool and not part of event spawn) }; struct PoolObject { uint32 guid; float chance; - PoolObject(uint32 _guid, float _chance): guid(_guid), chance(fabs(_chance)) {} + bool exclude; + + PoolObject(uint32 _guid, float _chance): guid(_guid), chance(fabs(_chance)), exclude(false) {} + + template + void CheckEventLinkAndReport(uint32 poolId, int16 event_id, std::map const& creature2event, std::map const& go2event) const; }; class Pool // for Pool of Pool case @@ -73,10 +79,12 @@ class PoolGroup bool isEmpty() const { return ExplicitlyChanced.empty() && EqualChanced.empty(); } void AddEntry(PoolObject& poolitem, uint32 maxentries); bool CheckPool() const; + void CheckEventLinkAndReport(int16 event_id, std::map const& creature2event, std::map const& go2event) const; PoolObject* RollOne(SpawnedPoolData& spawns, uint32 triggerFrom); void DespawnObject(SpawnedPoolData& spawns, uint32 guid=0); void Despawn1Object(uint32 guid); void SpawnObject(SpawnedPoolData& spawns, uint32 limit, uint32 triggerFrom, bool instantly); + void SetExcludeObject(uint32 guid, bool state); void Spawn1Object(PoolObject* obj, bool instantly); void ReSpawn1Object(PoolObject* obj); @@ -99,17 +107,37 @@ class PoolManager template uint16 IsPartOfAPool(uint32 db_guid_or_pool_id) const; + // Method that tell if the creature/gameobject/pool is part of top level pool and return the pool id if yes + template + uint16 IsPartOfTopPool(uint32 db_guid_or_pool_id) const + { + if (uint16 pool_id = IsPartOfAPool(db_guid_or_pool_id)) + { + if (uint16 top_pool_id = IsPartOfTopPool(pool_id)) + return top_pool_id; + + return pool_id; + } + + return 0; + } + template bool IsSpawnedObject(uint32 db_guid_or_pool_id) const { return mSpawnedData.IsSpawnedObject(db_guid_or_pool_id); } + template + void SetExcludeObject(uint16 pool_id, uint32 db_guid_or_pool_id, bool state); + bool CheckPool(uint16 pool_id) const; + void CheckEventLinkAndReport(uint16 pool_id, int16 event_id, std::map const& creature2event, std::map const& go2event) const; void SpawnPool(uint16 pool_id, bool instantly); void DespawnPool(uint16 pool_id); template - void UpdatePool(uint16 pool_id, uint32 db_guid_or_pool_id); + void UpdatePool(uint16 pool_id, uint32 db_guid_or_pool_id = 0); + void RemoveAutoSpawnForPool(uint16 pool_id) { mPoolTemplate[pool_id].AutoSpawn = false; } protected: template void SpawnPoolGroup(uint16 pool_id, uint32 db_guid_or_pool_id, bool instantly); diff --git a/src/game/World.cpp b/src/game/World.cpp index 0d0a4c682..9a0071b8c 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1032,7 +1032,7 @@ void World::SetInitialWorldSettings() sLog.outString( "Loading Objects Pooling Data..."); sPoolMgr.LoadFromDB(); - sLog.outString( "Loading Game Event Data..."); + sLog.outString( "Loading Game Event Data..."); // must be after sPoolMgr.LoadFromDB for proper load pool events sLog.outString(); sGameEventMgr.LoadFromDB(); sLog.outString( ">>> Game Event Data loaded" ); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index c3210f870..2b429896a 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10088" + #define REVISION_NR "10089" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index 8c440e80e..eb8a6c0c2 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_10051_01_characters_character_aura" - #define REVISION_DB_MANGOS "required_10086_01_mangos_command" + #define REVISION_DB_MANGOS "required_10089_01_mangos_game_event_pool" #define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version" #endif // __REVISION_SQL_H__ From 9d8dd578caab248a0e95257a8388d0be90ba9e87 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 21 Jun 2010 06:23:52 +0400 Subject: [PATCH 41/42] [10090] Really output log level at ".server log level" command. --- src/mangosd/CliRunnable.cpp | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mangosd/CliRunnable.cpp b/src/mangosd/CliRunnable.cpp index 437ff43d5..5aa82edb8 100644 --- a/src/mangosd/CliRunnable.cpp +++ b/src/mangosd/CliRunnable.cpp @@ -593,7 +593,7 @@ bool ChatHandler::HandleServerLogLevelCommand(const char *args) { if(!*args) { - PSendSysMessage("Log level: %u"); + PSendSysMessage("Log level: %u", sLog.GetLogLevel()); return true; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 2b429896a..3b9ed240d 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10089" + #define REVISION_NR "10090" #endif // __REVISION_NR_H__ From 78400f8406c82ab739e0628582b2cce62a8e4f66 Mon Sep 17 00:00:00 2001 From: Astellar Date: Mon, 21 Jun 2010 06:37:25 +0400 Subject: [PATCH 42/42] [10091] Use ACE for command line options parse. Note: "--service run" renamed to "-s run" in consistence with other serrvice options. Signed-off-by: VladimirMangos --- src/mangosd/Main.cpp | 107 +++++++++++++++++------------------ src/realmd/Main.cpp | 108 ++++++++++++++++++------------------ src/shared/ServiceWin32.cpp | 2 +- src/shared/revision_nr.h | 2 +- 4 files changed, 110 insertions(+), 109 deletions(-) diff --git a/src/mangosd/Main.cpp b/src/mangosd/Main.cpp index 049d2b6f1..abd5daebd 100644 --- a/src/mangosd/Main.cpp +++ b/src/mangosd/Main.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #ifdef WIN32 #include "ServiceWin32.h" @@ -56,11 +57,11 @@ uint32 realmID; ///< Id of the realm void usage(const char *prog) { sLog.outString("Usage: \n %s []\n" - " --version print version and exist\n\r" + " -v, --version print version and exist\n\r" " -c config_file use config_file as configuration file\n\r" #ifdef WIN32 " Running as service functions:\n\r" - " --service run as service\n\r" + " -s run run as service\n\r" " -s install install service\n\r" " -s uninstall uninstall service\n\r" #endif @@ -75,69 +76,69 @@ extern int main(int argc, char **argv) //char *leak = new char[1000]; // test leak detection - ///- Command line parsing to get the configuration file name + ///- Command line parsing char const* cfg_file = _MANGOSD_CONFIG; - int c=1; - while(c < argc) + +#ifdef WIN32 + char const *options = ":c:s:"; +#else + char const *options = ":c:"; +#endif + + ACE_Get_Opt cmd_opts(argc, argv, options); + cmd_opts.long_option("version", 'v'); + + int option; + while ((option = cmd_opts()) != EOF) { - if (strcmp(argv[c],"-c") == 0) + switch (option) { - if (++c >= argc) + case 'c': + cfg_file = cmd_opts.opt_arg(); + break; + case 'v': + printf("%s\n", _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_NR,REVISION_ID)); + return 0; +#ifdef WIN32 + case 's': { - sLog.outError("Runtime-Error: -c option requires an input argument"); - usage(argv[0]); - return 1; + const char *mode = cmd_opts.opt_arg(); + + if (!strcmp(mode, "install")) + { + if (WinServiceInstall()) + sLog.outString("Installing service"); + return 1; + } + else if (!strcmp(mode, "uninstall")) + { + if (WinServiceUninstall()) + sLog.outString("Uninstalling service"); + return 1; + } + else if (!strcmp(mode, "run")) + WinServiceRun(); + else + { + sLog.outError("Runtime-Error: -%c unsupported argument %s", cmd_opts.opt_opt(), mode); + usage(argv[0]); + Log::WaitBeforeContinueIfNeed(); + return 1; + } + break; } - else - cfg_file = argv[c]; - } - - if (strcmp(argv[c],"--version") == 0) - { - printf("%s\n", _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_NR,REVISION_ID)); - return 0; - } - - #ifdef WIN32 - //////////// - //Services// - //////////// - if (strcmp(argv[c],"-s") == 0) - { - if (++c >= argc) - { - sLog.outError("Runtime-Error: -s option requires an input argument"); +#endif + case ':': + sLog.outError("Runtime-Error: -%c option requires an input argument", cmd_opts.opt_opt()); usage(argv[0]); Log::WaitBeforeContinueIfNeed(); return 1; - } - else if (strcmp(argv[c],"install") == 0) - { - if (WinServiceInstall()) - sLog.outString("Installing service"); - return 1; - } - else if ( strcmp(argv[c],"uninstall") == 0) - { - if(WinServiceUninstall()) - sLog.outString("Uninstalling service"); - return 1; - } - else - { - sLog.outError("Runtime-Error: unsupported option %s",argv[c]); + default: + sLog.outError("Runtime-Error: bad format of commandline arguments"); usage(argv[0]); Log::WaitBeforeContinueIfNeed(); return 1; - } } - if (strcmp(argv[c],"--service") == 0) - { - WinServiceRun(); - } - //// - #endif - ++c; } if (!sConfig.SetSource(cfg_file)) diff --git a/src/realmd/Main.cpp b/src/realmd/Main.cpp index 3243b7fc2..e83fe15e6 100644 --- a/src/realmd/Main.cpp +++ b/src/realmd/Main.cpp @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -67,11 +68,11 @@ DatabaseType loginDatabase; ///< Accessor to the void usage(const char *prog) { sLog.outString("Usage: \n %s []\n" - " --version print version and exist\n\r" + " -v, --version print version and exist\n\r" " -c config_file use config_file as configuration file\n\r" #ifdef WIN32 " Running as service functions:\n\r" - " --service run as service\n\r" + " -s run run as service\n\r" " -s install install service\n\r" " -s uninstall uninstall service\n\r" #endif @@ -81,70 +82,69 @@ void usage(const char *prog) /// Launch the realm server extern int main(int argc, char **argv) { - ///- Command line parsing to get the configuration file name + ///- Command line parsing char const* cfg_file = _REALMD_CONFIG; - int c=1; - while( c < argc ) + +#ifdef WIN32 + char const *options = ":c:s:"; +#else + char const *options = ":c:"; +#endif + + ACE_Get_Opt cmd_opts(argc, argv, options); + cmd_opts.long_option("version", 'v'); + + int option; + while ((option = cmd_opts()) != EOF) { - if( strcmp(argv[c],"-c") == 0) + switch (option) { - if( ++c >= argc ) + case 'c': + cfg_file = cmd_opts.opt_arg(); + break; + case 'v': + printf("%s\n", _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_NR,REVISION_ID)); + return 0; +#ifdef WIN32 + case 's': { - sLog.outError("Runtime-Error: -c option requires an input argument"); - usage(argv[0]); - Log::WaitBeforeContinueIfNeed(); - return 1; - } - else - cfg_file = argv[c]; - } + const char *mode = cmd_opts.opt_arg(); - if( strcmp(argv[c],"--version") == 0) - { - printf("%s\n", _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_NR,REVISION_ID)); - return 0; - } - - #ifdef WIN32 - //////////// - //Services// - //////////// - if( strcmp(argv[c],"-s") == 0) - { - if( ++c >= argc ) - { - sLog.outError("Runtime-Error: -s option requires an input argument"); + if (!strcmp(mode, "install")) + { + if (WinServiceInstall()) + sLog.outString("Installing service"); + return 1; + } + else if (!strcmp(mode, "uninstall")) + { + if (WinServiceUninstall()) + sLog.outString("Uninstalling service"); + return 1; + } + else if (!strcmp(mode, "run")) + WinServiceRun(); + else + { + sLog.outError("Runtime-Error: -%c unsupported argument %s", cmd_opts.opt_opt(), mode); + usage(argv[0]); + Log::WaitBeforeContinueIfNeed(); + return 1; + } + break; + } +#endif + case ':': + sLog.outError("Runtime-Error: -%c option requires an input argument", cmd_opts.opt_opt()); usage(argv[0]); Log::WaitBeforeContinueIfNeed(); return 1; - } - if( strcmp(argv[c],"install") == 0) - { - if (WinServiceInstall()) - sLog.outString("Installing service"); - return 1; - } - else if( strcmp(argv[c],"uninstall") == 0) - { - if(WinServiceUninstall()) - sLog.outString("Uninstalling service"); - return 1; - } - else - { - sLog.outError("Runtime-Error: unsupported option %s",argv[c]); + default: + sLog.outError("Runtime-Error: bad format of commandline arguments"); usage(argv[0]); Log::WaitBeforeContinueIfNeed(); return 1; - } } - if( strcmp(argv[c],"--service") == 0) - { - WinServiceRun(); - } - //// - #endif - ++c; } if (!sConfig.SetSource(cfg_file)) diff --git a/src/shared/ServiceWin32.cpp b/src/shared/ServiceWin32.cpp index 843b6b074..36ba014f6 100644 --- a/src/shared/ServiceWin32.cpp +++ b/src/shared/ServiceWin32.cpp @@ -57,7 +57,7 @@ bool WinServiceInstall() if (GetModuleFileName( 0, path, sizeof(path)/sizeof(path[0]) ) > 0) { SC_HANDLE service; - std::strcat(path, " --service"); + std::strcat(path, " -s run"); service = CreateService(serviceControlManager, serviceName, // name of service serviceLongName, // service name to display diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 3b9ed240d..d1f9f0c75 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10090" + #define REVISION_NR "10091" #endif // __REVISION_NR_H__