diff --git a/dep b/dep index 389b4bce..93df4a0e 160000 --- a/dep +++ b/dep @@ -1 +1 @@ -Subproject commit 389b4bce897402edc0bf2a9ec3f6b111dd42c06f +Subproject commit 93df4a0e5d9841ecf91427aff83849feaa278d81 diff --git a/src/framework/Platform/Define.h b/src/framework/Platform/Define.h index 0b493302..8f42f941 100644 --- a/src/framework/Platform/Define.h +++ b/src/framework/Platform/Define.h @@ -27,10 +27,6 @@ #include -#if defined(__APPLE__) -# define ACE_UINT64_TYPE unsigned long long -#endif - #include #include #include diff --git a/src/game/Object/Creature.cpp b/src/game/Object/Creature.cpp index 2dd5d009..99282f77 100644 --- a/src/game/Object/Creature.cpp +++ b/src/game/Object/Creature.cpp @@ -383,7 +383,8 @@ bool Creature::InitEntry(uint32 Entry, Team team, CreatureData const* data /*=NU // check if we need to add swimming movement. TODO: i thing movement flags should be computed automatically at each movement of creature so we need a sort of UpdateMovementFlags() method if (cinfo->InhabitType & INHABIT_WATER && // check inhabit type water data && // check if there is data to get creature spawn pos - GetMap()->GetTerrain()->IsInWater(data->posX, data->posY, data->posZ)) // check if creature is in water + !(cinfo->ExtraFlags & CREATURE_EXTRA_FLAG_WALK_IN_WATER) && // check if creature is forced to walk (crabs, giant,...) + GetMap()->GetTerrain()->IsSwimable(data->posX, data->posY, data->posZ, minfo->bounding_radius)) // check if creature is in water and have enough space to swim m_movementInfo.AddMovementFlag(MOVEFLAG_SWIMMING); // add swimming movement // checked at loading @@ -422,6 +423,11 @@ bool Creature::UpdateEntry(uint32 Entry, Team team, const CreatureData* data /*= if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT)) { unitFlags |= UNIT_FLAG_IN_COMBAT; } + if (m_movementInfo.HasMovementFlag(MOVEFLAG_SWIMMING) && (GetCreatureInfo()->ExtraFlags & CREATURE_EXTRA_FLAG_HAVE_NO_SWIM_ANIMATION) == 0) + unitFlags |= UNIT_FLAG_UNK_15; + else + unitFlags &= ~UNIT_FLAG_UNK_15; + SetUInt32Value(UNIT_FIELD_FLAGS, unitFlags); // preserve all current dynamic flags if exist diff --git a/src/game/Object/Creature.h b/src/game/Object/Creature.h index 64be93c1..418cfea5 100644 --- a/src/game/Object/Creature.h +++ b/src/game/Object/Creature.h @@ -49,21 +49,23 @@ struct GameEventCreatureData; enum CreatureFlagsExtra { - CREATURE_EXTRA_FLAG_INSTANCE_BIND = 0x00000001, // creature kill bind instance with killer and killer's group - CREATURE_EXTRA_FLAG_NO_AGGRO = 0x00000002, // not aggro (ignore faction/reputation hostility) - CREATURE_EXTRA_FLAG_NO_PARRY = 0x00000004, // creature can't parry - CREATURE_EXTRA_FLAG_NO_PARRY_HASTEN = 0x00000008, // creature can't counter-attack at parry - CREATURE_EXTRA_FLAG_NO_BLOCK = 0x00000010, // creature can't block - CREATURE_EXTRA_FLAG_NO_CRUSH = 0x00000020, // creature can't do crush attacks - CREATURE_EXTRA_FLAG_NO_XP_AT_KILL = 0x00000040, // creature kill not provide XP - CREATURE_EXTRA_FLAG_INVISIBLE = 0x00000080, // creature is always invisible for player (mostly trigger creatures) - CREATURE_EXTRA_FLAG_NOT_TAUNTABLE = 0x00000100, // creature is immune to taunt auras and effect attack me - CREATURE_EXTRA_FLAG_AGGRO_ZONE = 0x00000200, // creature sets itself in combat with zone on aggro - CREATURE_EXTRA_FLAG_GUARD = 0x00000400, // creature is a guard - CREATURE_EXTRA_FLAG_NO_CALL_ASSIST = 0x00000800, // creature shouldn't call for assistance on aggro - CREATURE_EXTRA_FLAG_ACTIVE = 0x00001000, // creature is active object. Grid of this creature will be loaded and creature set as active - CREATURE_EXTRA_FLAG_MMAP_FORCE_ENABLE = 0x00002000, // creature is forced to use MMaps - CREATURE_EXTRA_FLAG_MMAP_FORCE_DISABLE = 0x00004000, // creature is forced to NOT use MMaps + CREATURE_EXTRA_FLAG_INSTANCE_BIND = 0x00000001, // creature kill bind instance with killer and killer's group + CREATURE_EXTRA_FLAG_NO_AGGRO = 0x00000002, // not aggro (ignore faction/reputation hostility) + CREATURE_EXTRA_FLAG_NO_PARRY = 0x00000004, // creature can't parry + CREATURE_EXTRA_FLAG_NO_PARRY_HASTEN = 0x00000008, // creature can't counter-attack at parry + CREATURE_EXTRA_FLAG_NO_BLOCK = 0x00000010, // creature can't block + CREATURE_EXTRA_FLAG_NO_CRUSH = 0x00000020, // creature can't do crush attacks + CREATURE_EXTRA_FLAG_NO_XP_AT_KILL = 0x00000040, // creature kill not provide XP + CREATURE_EXTRA_FLAG_INVISIBLE = 0x00000080, // creature is always invisible for player (mostly trigger creatures) + CREATURE_EXTRA_FLAG_NOT_TAUNTABLE = 0x00000100, // creature is immune to taunt auras and effect attack me + CREATURE_EXTRA_FLAG_AGGRO_ZONE = 0x00000200, // creature sets itself in combat with zone on aggro + CREATURE_EXTRA_FLAG_GUARD = 0x00000400, // creature is a guard + CREATURE_EXTRA_FLAG_NO_CALL_ASSIST = 0x00000800, // creature shouldn't call for assistance on aggro + CREATURE_EXTRA_FLAG_ACTIVE = 0x00001000, // creature is active object. Grid of this creature will be loaded and creature set as active + CREATURE_EXTRA_FLAG_MMAP_FORCE_ENABLE = 0x00002000, // creature is forced to use MMaps + CREATURE_EXTRA_FLAG_MMAP_FORCE_DISABLE = 0x00004000, // creature is forced to NOT use MMaps + CREATURE_EXTRA_FLAG_WALK_IN_WATER = 0x00008000, // creature is forced to walk in water even it can swim + CREATURE_EXTRA_FLAG_HAVE_NO_SWIM_ANIMATION = 0x00010000, // we have to not set "swim" animation or creature will have "no animation" }; // GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform diff --git a/src/game/Object/ObjectAccessor.cpp b/src/game/Object/ObjectAccessor.cpp index 0c4993f6..83217106 100644 --- a/src/game/Object/ObjectAccessor.cpp +++ b/src/game/Object/ObjectAccessor.cpp @@ -43,7 +43,10 @@ INSTANTIATE_SINGLETON_2(ObjectAccessor, CLASS_LOCK); INSTANTIATE_CLASS_MUTEX(ObjectAccessor, ACE_Thread_Mutex); -ObjectAccessor::ObjectAccessor() {} +ObjectAccessor::ObjectAccessor() : i_playerGuard(), i_corpseGuard() +{ +} + ObjectAccessor::~ObjectAccessor() { for (Player2CorpsesMapType::const_iterator itr = i_player2corpse.begin(); itr != i_player2corpse.end(); ++itr) @@ -284,7 +287,7 @@ void ObjectAccessor::RemoveOldCorpses() /// Define the static member of HashMapHolder template typename HashMapHolder::MapType HashMapHolder::m_objectMap; -template ACE_RW_Thread_Mutex HashMapHolder::i_lock; +template typename HashMapHolder::LockType HashMapHolder::i_lock; /// Global definitions for the hashmap storage diff --git a/src/game/Object/ObjectAccessor.h b/src/game/Object/ObjectAccessor.h index 18d3b6f9..8b5bfa6d 100644 --- a/src/game/Object/ObjectAccessor.h +++ b/src/game/Object/ObjectAccessor.h @@ -137,6 +137,7 @@ class ObjectAccessor : public MaNGOS::Singleton m_player->GetMoney()) + { + TradeStatusInfo info; + info.Status = TRADE_STATUS_CLOSE_WINDOW; + info.Result = EQUIP_ERR_NOT_ENOUGH_MONEY; + m_player->GetSession()->SendTradeStatus(info); + return; + } + m_money = money; SetAccepted(false); @@ -357,10 +366,12 @@ void TradeData::SetAccepted(bool state, bool crosssend /*= false*/) if (!state) { + TradeStatusInfo info; + info.Status = TRADE_STATUS_BACK_TO_TRADE; if (crosssend) - { m_trader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); } + m_trader->GetSession()->SendTradeStatus(info); else - { m_player->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); } + m_player->GetSession()->SendTradeStatus(info); } } @@ -9150,7 +9161,7 @@ InventoryResult Player::CanStoreItems(Item** pItems, int count) const // no free slot found? if (!b_found) - { return EQUIP_ERR_INVENTORY_FULL; } + { return EQUIP_ERR_BAG_FULL; } } return EQUIP_ERR_OK; diff --git a/src/game/Object/Player.h b/src/game/Object/Player.h index 841e9ada..05e3f052 100644 --- a/src/game/Object/Player.h +++ b/src/game/Object/Player.h @@ -814,6 +814,19 @@ struct BGData bool m_needSave; ///< true, if saved to DB fields modified after prev. save (marked as "saved" above) }; +struct TradeStatusInfo +{ + TradeStatusInfo() : Status(TRADE_STATUS_BUSY), TraderGuid(), Result(EQUIP_ERR_OK), + IsTargetResult(false), ItemLimitCategoryId(0), Slot(0) { } + + TradeStatus Status; + ObjectGuid TraderGuid; + InventoryResult Result; + bool IsTargetResult; + uint32 ItemLimitCategoryId; + uint8 Slot; +}; + class TradeData { public: // constructors diff --git a/src/game/Server/SharedDefines.h b/src/game/Server/SharedDefines.h index 8912bc6d..55449569 100644 --- a/src/game/Server/SharedDefines.h +++ b/src/game/Server/SharedDefines.h @@ -2506,7 +2506,7 @@ enum TradeStatus TRADE_STATUS_NO_TARGET = 6, TRADE_STATUS_BACK_TO_TRADE = 7, TRADE_STATUS_TRADE_COMPLETE = 8, - // 9? + TRADE_STATUS_TRADE_REJECTED = 9, TRADE_STATUS_TARGET_TO_FAR = 10, TRADE_STATUS_WRONG_FACTION = 11, TRADE_STATUS_CLOSE_WINDOW = 12, @@ -2519,7 +2519,8 @@ enum TradeStatus TRADE_STATUS_YOU_LOGOUT = 19, TRADE_STATUS_TARGET_LOGOUT = 20, TRADE_STATUS_TRIAL_ACCOUNT = 21, // Trial accounts can not perform that action - TRADE_STATUS_ONLY_CONJURED = 22 // You can only trade conjured items... (cross realm BG related). + TRADE_STATUS_WRONG_REALM = 22, // You can only trade conjured items... (cross realm BG related). + TRADE_STATUS_NOT_ON_TAPLIST = 23 }; enum WorldStateType diff --git a/src/game/Server/WorldSession.h b/src/game/Server/WorldSession.h index 9cc76ad2..aba423f4 100644 --- a/src/game/Server/WorldSession.h +++ b/src/game/Server/WorldSession.h @@ -39,6 +39,7 @@ struct ItemPrototype; struct AuctionEntry; struct AuctionHouseEntry; +struct TradeStatusInfo; class ObjectGuid; class Creature; @@ -250,7 +251,7 @@ class WorldSession void SendBattlegGroundList(ObjectGuid guid, BattleGroundTypeId bgTypeId); - void SendTradeStatus(TradeStatus status); + void SendTradeStatus(const TradeStatusInfo& status); void SendUpdateTrade(bool trader_state = true); void SendCancelTrade(); diff --git a/src/game/Server/WorldSocket.h b/src/game/Server/WorldSocket.h index 537985e0..b9bfc1d3 100644 --- a/src/game/Server/WorldSocket.h +++ b/src/game/Server/WorldSocket.h @@ -31,10 +31,6 @@ #ifndef MANGOS_H_WORLDSOCKET #define MANGOS_H_WORLDSOCKET -#if defined(__APPLE__) -# define ACE_UINT64_TYPE unsigned long long -#endif - #include #include #include diff --git a/src/game/WorldHandlers/GridMap.cpp b/src/game/WorldHandlers/GridMap.cpp index 5a6b5c91..6dbe48c7 100644 --- a/src/game/WorldHandlers/GridMap.cpp +++ b/src/game/WorldHandlers/GridMap.cpp @@ -730,7 +730,7 @@ bool GridMap::ExistVMap(uint32 mapid, int gx, int gy) } ////////////////////////////////////////////////////////////////////////// -TerrainInfo::TerrainInfo(uint32 mapid) : m_mapId(mapid) +TerrainInfo::TerrainInfo(uint32 mapid) : m_mapId(mapid), m_refMutex(), m_mutex() { for (int k = 0; k < MAX_NUMBER_OF_GRIDS; ++k) { @@ -831,7 +831,7 @@ int TerrainInfo::RefGrid(const uint32& x, const uint32& y) MANGOS_ASSERT(x < MAX_NUMBER_OF_GRIDS); MANGOS_ASSERT(y < MAX_NUMBER_OF_GRIDS); - LOCK_GUARD _lock(m_refMutex); + ACE_GUARD_RETURN(LOCK_TYPE, _lock, m_refMutex, -1) return (m_GridRef[x][y] += 1); } @@ -842,7 +842,7 @@ int TerrainInfo::UnrefGrid(const uint32& x, const uint32& y) int16& iRef = m_GridRef[x][y]; - LOCK_GUARD _lock(m_refMutex); + ACE_GUARD_RETURN(LOCK_TYPE, _lock, m_refMutex, -1) if (iRef > 0) { return (iRef -= 1); } @@ -1075,6 +1075,23 @@ bool TerrainInfo::IsInWater(float x, float y, float pZ, GridMapLiquidData* data) return false; } +// check if creature is in water and have enough space to swim +bool TerrainInfo::IsSwimable(float x, float y, float pZ, float radius /*= 1.5f*/, GridMapLiquidData* data /*= 0*/) const +{ + // Check surface in x, y point for liquid + if (const_cast(this)->GetGrid(x, y)) + { + GridMapLiquidData liquid_status; + GridMapLiquidData* liquid_ptr = data ? data : &liquid_status; + if (getLiquidStatus(x, y, pZ, MAP_ALL_LIQUIDS, liquid_ptr)) + { + if (liquid_ptr->level - liquid_ptr->depth_level > radius) // is unit have enough space to swim + return true; + } + } + return false; +} + bool TerrainInfo::IsUnderWater(float x, float y, float z) const { if (const_cast(this)->GetGrid(x, y)) @@ -1134,7 +1151,7 @@ GridMap* TerrainInfo::LoadMapAndVMap(const uint32 x, const uint32 y) // double checked lock pattern if (!m_GridMaps[x][y]) { - LOCK_GUARD lock(m_mutex); + ACE_GUARD_RETURN(LOCK_TYPE, lock, m_mutex, NULL) if (!m_GridMaps[x][y]) { @@ -1208,7 +1225,7 @@ float TerrainInfo::GetWaterLevel(float x, float y, float z, float* pGround /*= N INSTANTIATE_SINGLETON_2(TerrainManager, CLASS_LOCK); INSTANTIATE_CLASS_MUTEX(TerrainManager, ACE_Thread_Mutex); -TerrainManager::TerrainManager() +TerrainManager::TerrainManager() : m_mutex() { } @@ -1220,7 +1237,7 @@ TerrainManager::~TerrainManager() TerrainInfo* TerrainManager::LoadTerrain(const uint32 mapId) { - Guard _guard(*this); + ACE_GUARD_RETURN(LOCK_TYPE, _guard, m_mutex, NULL) TerrainInfo* ptr = NULL; TerrainDataMap::const_iterator iter = i_TerrainMap.find(mapId); @@ -1240,7 +1257,7 @@ void TerrainManager::UnloadTerrain(const uint32 mapId) if (sWorld.getConfig(CONFIG_BOOL_GRID_UNLOAD) == 0) { return; } - Guard _guard(*this); + ACE_GUARD(LOCK_TYPE, _guard, m_mutex) TerrainDataMap::iterator iter = i_TerrainMap.find(mapId); if (iter != i_TerrainMap.end()) diff --git a/src/game/WorldHandlers/GridMap.h b/src/game/WorldHandlers/GridMap.h index 3681648f..a648df49 100644 --- a/src/game/WorldHandlers/GridMap.h +++ b/src/game/WorldHandlers/GridMap.h @@ -234,6 +234,7 @@ class TerrainInfo : public Referencable float GetWaterLevel(float x, float y, float z, float* pGround = NULL) const; float GetWaterOrGroundLevel(float x, float y, float z, float* pGround = NULL, bool swim = false) const; bool IsInWater(float x, float y, float z, GridMapLiquidData* data = 0) const; + bool IsSwimable(float x, float y, float pZ, float radius = 1.5f, GridMapLiquidData* data = 0) const; bool IsUnderWater(float x, float y, float z) const; GridMapLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, GridMapLiquidData* data = 0) const; @@ -280,8 +281,8 @@ class TerrainInfo : public Referencable ShortIntervalTimer i_timer; typedef ACE_Thread_Mutex LOCK_TYPE; - typedef ACE_Guard LOCK_GUARD; LOCK_TYPE m_mutex; + char _cache_guard[1024]; LOCK_TYPE m_refMutex; }; @@ -327,7 +328,8 @@ class TerrainManager : public MaNGOS::Singleton::Lock Guard; + typedef ACE_Thread_Mutex LOCK_TYPE; + LOCK_TYPE m_mutex; TerrainDataMap i_TerrainMap; }; diff --git a/src/game/WorldHandlers/GridStates.cpp b/src/game/WorldHandlers/GridStates.cpp index 9b7420f7..694325ee 100644 --- a/src/game/WorldHandlers/GridStates.cpp +++ b/src/game/WorldHandlers/GridStates.cpp @@ -27,6 +27,11 @@ #include "GameSystem/Grid.h" #include "Log.h" +GridState::~GridState() +{ + DEBUG_LOG("GridState destroyed"); +} + void InvalidState::Update(Map&, NGridType&, GridInfo&, const uint32& /*x*/, const uint32& /*y*/, const uint32&) const { diff --git a/src/game/WorldHandlers/GridStates.h b/src/game/WorldHandlers/GridStates.h index 408c5c6d..0fa92d4d 100644 --- a/src/game/WorldHandlers/GridStates.h +++ b/src/game/WorldHandlers/GridStates.h @@ -32,6 +32,7 @@ class GridState public: virtual void Update(Map&, NGridType&, GridInfo&, const uint32& x, const uint32& y, const uint32& t_diff) const = 0; + virtual ~GridState(); }; class InvalidState : public GridState diff --git a/src/game/WorldHandlers/MapManager.cpp b/src/game/WorldHandlers/MapManager.cpp index d7eb8686..5dea36c7 100644 --- a/src/game/WorldHandlers/MapManager.cpp +++ b/src/game/WorldHandlers/MapManager.cpp @@ -39,7 +39,7 @@ INSTANTIATE_SINGLETON_2(MapManager, CLASS_LOCK); INSTANTIATE_CLASS_MUTEX(MapManager, ACE_Recursive_Thread_Mutex); MapManager::MapManager() - : i_gridCleanUpDelay(sWorld.getConfig(CONFIG_UINT32_INTERVAL_GRIDCLEAN)) + : i_gridCleanUpDelay(sWorld.getConfig(CONFIG_UINT32_INTERVAL_GRIDCLEAN)), m_lock() { i_timer.SetInterval(sWorld.getConfig(CONFIG_UINT32_INTERVAL_MAPUPDATE)); } @@ -101,7 +101,7 @@ void MapManager::InitializeVisibilityDistanceInfo() /// @param id - MapId of the to be created map. @param obj WorldObject for which the map is to be created. Must be player for Instancable maps. Map* MapManager::CreateMap(uint32 id, const WorldObject* obj) { - Guard _guard(*this); + ACE_GUARD_RETURN(LOCK_TYPE, _guard, m_lock, NULL) Map* m = NULL; @@ -139,13 +139,13 @@ Map* MapManager::CreateBgMap(uint32 mapid, BattleGround* bg) { sTerrainMgr.LoadTerrain(mapid); - Guard _guard(*this); + ACE_GUARD_RETURN(LOCK_TYPE, _guard, m_lock, NULL) return CreateBattleGroundMap(mapid, sMapMgr.GenerateInstanceId(), bg); } Map* MapManager::FindMap(uint32 mapid, uint32 instanceId) const { - Guard guard(*this); + ACE_GUARD_RETURN(LOCK_TYPE, _guard, m_lock, NULL) MapMapType::const_iterator iter = i_maps.find(MapID(mapid, instanceId)); if (iter == i_maps.end()) @@ -163,7 +163,7 @@ Map* MapManager::FindMap(uint32 mapid, uint32 instanceId) const void MapManager::DeleteInstance(uint32 mapid, uint32 instanceId) { - Guard _guard(*this); + ACE_GUARD(LOCK_TYPE, _guard, m_lock) MapMapType::iterator iter = i_maps.find(MapID(mapid, instanceId)); if (iter != i_maps.end()) @@ -276,9 +276,9 @@ void MapManager::InitMaxInstanceId() uint32 MapManager::GetNumInstances() { - Guard guard(*this); - uint32 ret = 0; + + ACE_GUARD_RETURN(LOCK_TYPE, _guard, m_lock, ret) for (MapMapType::iterator itr = i_maps.begin(); itr != i_maps.end(); ++itr) { Map* map = itr->second; @@ -290,9 +290,9 @@ uint32 MapManager::GetNumInstances() uint32 MapManager::GetNumPlayersInInstances() { - Guard guard(*this); - uint32 ret = 0; + + ACE_GUARD_RETURN(LOCK_TYPE, _guard, m_lock, ret) for (MapMapType::iterator itr = i_maps.begin(); itr != i_maps.end(); ++itr) { Map* map = itr->second; diff --git a/src/game/WorldHandlers/MapManager.h b/src/game/WorldHandlers/MapManager.h index 38a365d1..36b2469a 100644 --- a/src/game/WorldHandlers/MapManager.h +++ b/src/game/WorldHandlers/MapManager.h @@ -59,10 +59,6 @@ class MapManager : public MaNGOS::Singleton; - typedef ACE_Recursive_Thread_Mutex LOCK_TYPE; - typedef ACE_Guard LOCK_TYPE_GUARD; - typedef MaNGOS::ClassLevelLockable::Lock Guard; - public: typedef std::map MapMapType; @@ -185,8 +181,10 @@ class MapManager : public MaNGOS::Singleton diff --git a/src/game/WorldHandlers/TradeHandler.cpp b/src/game/WorldHandlers/TradeHandler.cpp index 201aeb37..21ea515f 100644 --- a/src/game/WorldHandlers/TradeHandler.cpp +++ b/src/game/WorldHandlers/TradeHandler.cpp @@ -36,36 +36,26 @@ #include "Language.h" #include "DBCStores.h" -void WorldSession::SendTradeStatus(TradeStatus status) +void WorldSession::SendTradeStatus(const TradeStatusInfo& info) { - WorldPacket data; + WorldPacket data(SMSG_TRADE_STATUS, 13); + data << uint32(info.Status); - switch (status) + switch (info.Status) { case TRADE_STATUS_BEGIN_TRADE: - data.Initialize(SMSG_TRADE_STATUS, 4 + 8); - data << uint32(status); - data << uint64(0); - break; - case TRADE_STATUS_OPEN_WINDOW: - data.Initialize(SMSG_TRADE_STATUS, 4 + 4); - data << uint32(status); + data << info.TraderGuid; // CGTradeInfo::m_tradingPlayer break; case TRADE_STATUS_CLOSE_WINDOW: - data.Initialize(SMSG_TRADE_STATUS, 4 + 4 + 1 + 4); - data << uint32(status); - data << uint32(0); - data << uint8(0); - data << uint32(0); + data << uint32(info.Result); // InventoryResult + data << uint8(info.IsTargetResult); // bool isTargetError; used for: EQUIP_ERR_BAG_FULL, EQUIP_ERR_CANT_CARRY_MORE_OF_THIS, EQUIP_ERR_MISSING_REAGENT, EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED + data << uint32(info.ItemLimitCategoryId); // ItemLimitCategory.dbc entry break; - case TRADE_STATUS_ONLY_CONJURED: - data.Initialize(SMSG_TRADE_STATUS, 4 + 1); - data << uint32(status); - data << uint8(0); + case TRADE_STATUS_WRONG_REALM: + case TRADE_STATUS_NOT_ON_TAPLIST: + data << uint8(info.Slot); // Trade slot; -1 here clears CGTradeInfo::m_tradeMoney break; default: - data.Initialize(SMSG_TRADE_STATUS, 4); - data << uint32(status); break; } @@ -273,26 +263,31 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& recvPacket) // set before checks to properly undo at problems (it already set in to client) my_trade->SetAccepted(true); - // not accept case incorrect money amount - if (my_trade->GetMoney() > _player->GetMoney()) - { - SendNotification(LANG_NOT_ENOUGH_GOLD); - my_trade->SetAccepted(false, true); - return; - } - + TradeStatusInfo info; if (!_player->IsWithinDistInMap(trader, TRADE_DISTANCE, false)) { - SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); + info.Status = TRADE_STATUS_TARGET_TO_FAR; + SendTradeStatus(info); my_trade->SetAccepted(false); return; } + // not accept case incorrect money amount + if (my_trade->GetMoney() > _player->GetMoney()) + { + info.Status = TRADE_STATUS_CLOSE_WINDOW; + info.Result = EQUIP_ERR_NOT_ENOUGH_MONEY; + SendTradeStatus(info); + my_trade->SetAccepted(false, true); + return; + } // not accept case incorrect money amount if (his_trade->GetMoney() > trader->GetMoney()) { - trader->GetSession()->SendNotification(LANG_NOT_ENOUGH_GOLD); + info.Status = TRADE_STATUS_CLOSE_WINDOW; + info.Result = EQUIP_ERR_NOT_ENOUGH_MONEY; + trader->GetSession()->SendTradeStatus(info); his_trade->SetAccepted(false, true); return; } @@ -304,7 +299,8 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& recvPacket) { if (!item->CanBeTraded()) { - SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); + info.Status = TRADE_STATUS_TRADE_CANCELED; + SendTradeStatus(info); return; } } @@ -313,7 +309,8 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& recvPacket) { if (!item->CanBeTraded()) { - SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); + info.Status = TRADE_STATUS_TRADE_CANCELED; + SendTradeStatus(info); return; } } @@ -336,7 +333,7 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& recvPacket) Item* castItem = my_trade->GetSpellCastItem(); if (!spellEntry || !his_trade->GetItem(TRADE_SLOT_NONTRADED) || - (my_trade->HasSpellCastItem() && !castItem)) + (my_trade->HasSpellCastItem() && !castItem)) { clearAcceptTradeMode(my_trade, his_trade); clearAcceptTradeMode(myItems, hisItems); @@ -371,7 +368,7 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& recvPacket) Item* castItem = his_trade->GetSpellCastItem(); if (!spellEntry || !my_trade->GetItem(TRADE_SLOT_NONTRADED) || - (his_trade->HasSpellCastItem() && !castItem)) + (his_trade->HasSpellCastItem() && !castItem)) { delete my_spell; his_trade->SetSpell(0); @@ -403,31 +400,37 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& recvPacket) } // inform partner client - trader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_ACCEPT); + info.Status = TRADE_STATUS_TRADE_ACCEPT; + trader->GetSession()->SendTradeStatus(info); // test if item will fit in each inventory - bool hisCanCompleteTrade = (trader->CanStoreItems(myItems, TRADE_SLOT_TRADED_COUNT) == EQUIP_ERR_OK); - bool myCanCompleteTrade = (_player->CanStoreItems(hisItems, TRADE_SLOT_TRADED_COUNT) == EQUIP_ERR_OK); + TradeStatusInfo myCanCompleteInfo, hisCanCompleteInfo; + hisCanCompleteInfo.Result = trader->CanStoreItems(myItems, TRADE_SLOT_TRADED_COUNT); + myCanCompleteInfo.Result = _player->CanStoreItems(hisItems, TRADE_SLOT_TRADED_COUNT); clearAcceptTradeMode(myItems, hisItems); // in case of missing space report error - if (!myCanCompleteTrade) + if (myCanCompleteInfo.Result != EQUIP_ERR_OK) { clearAcceptTradeMode(my_trade, his_trade); - SendNotification(LANG_NOT_FREE_TRADE_SLOTS); - trader->GetSession()->SendNotification(LANG_NOT_PARTNER_FREE_TRADE_SLOTS); + myCanCompleteInfo.Status = TRADE_STATUS_CLOSE_WINDOW; + trader->GetSession()->SendTradeStatus(myCanCompleteInfo); + myCanCompleteInfo.IsTargetResult = true; + SendTradeStatus(myCanCompleteInfo); my_trade->SetAccepted(false); his_trade->SetAccepted(false); return; } - else if (!hisCanCompleteTrade) + else if (hisCanCompleteInfo.Result != EQUIP_ERR_OK) { clearAcceptTradeMode(my_trade, his_trade); - SendNotification(LANG_NOT_PARTNER_FREE_TRADE_SLOTS); - trader->GetSession()->SendNotification(LANG_NOT_FREE_TRADE_SLOTS); + hisCanCompleteInfo.Status = TRADE_STATUS_CLOSE_WINDOW; + SendTradeStatus(hisCanCompleteInfo); + hisCanCompleteInfo.IsTargetResult = true; + trader->GetSession()->SendTradeStatus(hisCanCompleteInfo); my_trade->SetAccepted(false); his_trade->SetAccepted(false); return; @@ -477,10 +480,10 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& recvPacket) trader->ModifyMoney(my_trade->GetMoney()); if (my_spell) - { my_spell->prepare(&my_targets); } + my_spell->prepare(&my_targets); if (his_spell) - { his_spell->prepare(&his_targets); } + his_spell->prepare(&his_targets); // cleanup clearAcceptTradeMode(my_trade, his_trade); @@ -495,12 +498,14 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& recvPacket) trader->SaveInventoryAndGoldToDB(); CharacterDatabase.CommitTransaction(); - trader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_COMPLETE); - SendTradeStatus(TRADE_STATUS_TRADE_COMPLETE); + info.Status = TRADE_STATUS_TRADE_COMPLETE; + trader->GetSession()->SendTradeStatus(info); + SendTradeStatus(info); } else { - trader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_ACCEPT); + info.Status = TRADE_STATUS_TRADE_ACCEPT; + trader->GetSession()->SendTradeStatus(info); } } @@ -519,8 +524,10 @@ void WorldSession::HandleBeginTradeOpcode(WorldPacket& /*recvPacket*/) if (!my_trade) { return; } - my_trade->GetTrader()->GetSession()->SendTradeStatus(TRADE_STATUS_OPEN_WINDOW); - SendTradeStatus(TRADE_STATUS_OPEN_WINDOW); + TradeStatusInfo info; + info.Status = TRADE_STATUS_OPEN_WINDOW; + my_trade->GetTrader()->GetSession()->SendTradeStatus(info); + SendTradeStatus(info); } void WorldSession::SendCancelTrade() @@ -528,7 +535,9 @@ void WorldSession::SendCancelTrade() if (m_playerRecentlyLogout) { return; } - SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); + TradeStatusInfo info; + info.Status = TRADE_STATUS_TRADE_CANCELED; + SendTradeStatus(info); } void WorldSession::HandleCancelTradeOpcode(WorldPacket& /*recvPacket*/) @@ -546,27 +555,32 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) if (GetPlayer()->m_trade) { return; } + TradeStatusInfo info; if (!GetPlayer()->IsAlive()) { - SendTradeStatus(TRADE_STATUS_YOU_DEAD); + info.Status = TRADE_STATUS_YOU_DEAD; + SendTradeStatus(info); return; } if (GetPlayer()->hasUnitState(UNIT_STAT_STUNNED)) { - SendTradeStatus(TRADE_STATUS_YOU_STUNNED); + info.Status = TRADE_STATUS_YOU_STUNNED; + SendTradeStatus(info); return; } if (isLogingOut()) { - SendTradeStatus(TRADE_STATUS_YOU_LOGOUT); + info.Status = TRADE_STATUS_YOU_LOGOUT; + SendTradeStatus(info); return; } if (GetPlayer()->IsTaxiFlying()) { - SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); + info.Status = TRADE_STATUS_TARGET_TO_FAR; + SendTradeStatus(info); return; } @@ -574,55 +588,64 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) if (!pOther) { - SendTradeStatus(TRADE_STATUS_NO_TARGET); + info.Status = TRADE_STATUS_NO_TARGET; + SendTradeStatus(info); return; } if (pOther == GetPlayer() || pOther->m_trade) { - SendTradeStatus(TRADE_STATUS_BUSY); + info.Status = TRADE_STATUS_BUSY; + SendTradeStatus(info); return; } if (!pOther->IsAlive()) { - SendTradeStatus(TRADE_STATUS_TARGET_DEAD); + info.Status = TRADE_STATUS_TARGET_DEAD; + SendTradeStatus(info); return; } if (pOther->IsTaxiFlying()) { - SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); + info.Status = TRADE_STATUS_TARGET_TO_FAR; + SendTradeStatus(info); return; } if (pOther->hasUnitState(UNIT_STAT_STUNNED)) { - SendTradeStatus(TRADE_STATUS_TARGET_STUNNED); + info.Status = TRADE_STATUS_TARGET_STUNNED; + SendTradeStatus(info); return; } if (pOther->GetSession()->isLogingOut()) { - SendTradeStatus(TRADE_STATUS_TARGET_LOGOUT); + info.Status = TRADE_STATUS_TARGET_LOGOUT; + SendTradeStatus(info); return; } if (pOther->GetSocial()->HasIgnore(GetPlayer()->GetObjectGuid())) { - SendTradeStatus(TRADE_STATUS_IGNORE_YOU); + info.Status = TRADE_STATUS_IGNORE_YOU; + SendTradeStatus(info); return; } if (!sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_TRADE) && pOther->GetTeam() != _player->GetTeam()) { - SendTradeStatus(TRADE_STATUS_WRONG_FACTION); + info.Status = TRADE_STATUS_WRONG_FACTION; + SendTradeStatus(info); return; } if (!pOther->IsWithinDistInMap(_player, TRADE_DISTANCE, false)) { - SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); + info.Status = TRADE_STATUS_TARGET_TO_FAR; + SendTradeStatus(info); return; } @@ -630,10 +653,9 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) _player->m_trade = new TradeData(_player, pOther); pOther->m_trade = new TradeData(pOther, _player); - WorldPacket data(SMSG_TRADE_STATUS, 12); - data << uint32(TRADE_STATUS_BEGIN_TRADE); - data << ObjectGuid(_player->GetObjectGuid()); - pOther->GetSession()->SendPacket(&data); + info.Status = TRADE_STATUS_BEGIN_TRADE; + info.TraderGuid = _player->GetObjectGuid(); + pOther->GetSession()->SendTradeStatus(info); } void WorldSession::HandleSetTradeGoldOpcode(WorldPacket& recvPacket) @@ -665,10 +687,12 @@ void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket) if (!my_trade) { return; } + TradeStatusInfo info; // invalid slot number if (tradeSlot >= TRADE_SLOT_COUNT) { - SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); + info.Status = TRADE_STATUS_TRADE_CANCELED; + SendTradeStatus(info); return; } @@ -676,7 +700,8 @@ void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket) Item* item = _player->GetItemByPos(bag, slot); if (!item || (tradeSlot != TRADE_SLOT_NONTRADED && !item->CanBeTraded())) { - SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); + info.Status = TRADE_STATUS_TRADE_CANCELED; + SendTradeStatus(info); return; } @@ -684,7 +709,8 @@ void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket) if (my_trade->HasItem(item->GetObjectGuid())) { // cheating attempt - SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); + info.Status = TRADE_STATUS_TRADE_CANCELED; + SendTradeStatus(info); return; } diff --git a/src/game/vmap/BIH.h b/src/game/vmap/BIH.h index 866d6467..1a01e5a8 100644 --- a/src/game/vmap/BIH.h +++ b/src/game/vmap/BIH.h @@ -25,18 +25,18 @@ #ifndef MANGOS_H_BIH #define MANGOS_H_BIH -#include -#include -#include - -#include - #include #include #include #include #include +#include + +#include +#include +#include + #define MAX_STACK_SIZE 64 #ifdef _MSC_VER diff --git a/src/game/vmap/BIHWrap.h b/src/game/vmap/BIHWrap.h index 3016c0a3..16518e62 100644 --- a/src/game/vmap/BIHWrap.h +++ b/src/game/vmap/BIHWrap.h @@ -24,10 +24,10 @@ #pragma once +#include "BIH.h" #include #include #include -#include "BIH.h" template > /** diff --git a/src/game/vmap/GameObjectModel.h b/src/game/vmap/GameObjectModel.h index 0f5ebdc9..c6441623 100644 --- a/src/game/vmap/GameObjectModel.h +++ b/src/game/vmap/GameObjectModel.h @@ -25,6 +25,8 @@ #ifndef MANGOSSERVER_GAMEOBJECTMODEL_H #define MANGOSSERVER_GAMEOBJECTMODEL_H +#include "Platform/Define.h" + #include #include #include @@ -32,7 +34,6 @@ #include "DBCStructure.h" #include "GameObject.h" -#include "Platform/Define.h" namespace VMAP { diff --git a/src/game/vmap/ModelInstance.h b/src/game/vmap/ModelInstance.h index 6682105a..46304e64 100644 --- a/src/game/vmap/ModelInstance.h +++ b/src/game/vmap/ModelInstance.h @@ -25,12 +25,13 @@ #ifndef MANGOS_H_MODELINSTANCE #define MANGOS_H_MODELINSTANCE +#include "Platform/Define.h" + #include #include #include #include -#include "Platform/Define.h" namespace VMAP { diff --git a/src/game/vmap/TileAssembler.cpp b/src/game/vmap/TileAssembler.cpp index 0418a71c..17716001 100644 --- a/src/game/vmap/TileAssembler.cpp +++ b/src/game/vmap/TileAssembler.cpp @@ -22,15 +22,16 @@ * and lore are copyrighted by Blizzard Entertainment, Inc. */ +#include +#include +#include +#include + #include "TileAssembler.h" #include "MapTree.h" #include "BIH.h" #include "VMapDefinitions.h" -#include -#include -#include -#include using G3D::Vector3; using G3D::AABox; diff --git a/src/game/vmap/TileAssembler.h b/src/game/vmap/TileAssembler.h index 1902e258..1b41da73 100644 --- a/src/game/vmap/TileAssembler.h +++ b/src/game/vmap/TileAssembler.h @@ -25,13 +25,13 @@ #ifndef MANGOS_H_TILEASSEMBLER #define MANGOS_H_TILEASSEMBLER -#include -#include #include #include #include "ModelInstance.h" #include "WorldModel.h" +#include +#include namespace VMAP { diff --git a/src/game/vmap/WorldModel.h b/src/game/vmap/WorldModel.h index cb17f457..bd8d9699 100644 --- a/src/game/vmap/WorldModel.h +++ b/src/game/vmap/WorldModel.h @@ -25,13 +25,14 @@ #ifndef MANGOS_H_WORLDMODEL #define MANGOS_H_WORLDMODEL +#include "Platform/Define.h" + #include #include #include #include #include "BIH.h" -#include "Platform/Define.h" namespace VMAP {