Merge pull request #100 from H0zen/develop21

Various external fixes - part 6
This commit is contained in:
Antz 2016-03-12 08:42:34 +00:00
commit 1f37bc0bc6
25 changed files with 227 additions and 144 deletions

2
dep

@ -1 +1 @@
Subproject commit 389b4bce897402edc0bf2a9ec3f6b111dd42c06f
Subproject commit 93df4a0e5d9841ecf91427aff83849feaa278d81

View File

@ -27,10 +27,6 @@
#include <sys/types.h>
#if defined(__APPLE__)
# define ACE_UINT64_TYPE unsigned long long
#endif
#include <ace/Basic_Types.h>
#include <ace/Default_Constants.h>
#include <ace/OS_NS_dlfcn.h>

View File

@ -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

View File

@ -64,6 +64,8 @@ enum CreatureFlagsExtra
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

View File

@ -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 <class T> typename HashMapHolder<T>::MapType HashMapHolder<T>::m_objectMap;
template <class T> ACE_RW_Thread_Mutex HashMapHolder<T>::i_lock;
template <class T> typename HashMapHolder<T>::LockType HashMapHolder<T>::i_lock;
/// Global definitions for the hashmap storage

View File

@ -137,6 +137,7 @@ class ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor, MaNGOS::ClassLev
typedef ACE_Thread_Mutex LockType;
LockType i_playerGuard;
char _cache_guard[1024];
LockType i_corpseGuard;
};

View File

@ -335,6 +335,15 @@ void TradeData::SetMoney(uint32 money)
if (m_money == money)
{ return; }
if (money > 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;

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -31,10 +31,6 @@
#ifndef MANGOS_H_WORLDSOCKET
#define MANGOS_H_WORLDSOCKET
#if defined(__APPLE__)
# define ACE_UINT64_TYPE unsigned long long
#endif
#include <ace/Basic_Types.h>
#include <ace/Synch_Traits.h>
#include <ace/Svc_Handler.h>

View File

@ -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<TerrainInfo*>(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<TerrainInfo*>(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())

View File

@ -234,6 +234,7 @@ class TerrainInfo : public Referencable<AtomicLong>
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<AtomicLong>
ShortIntervalTimer i_timer;
typedef ACE_Thread_Mutex LOCK_TYPE;
typedef ACE_Guard<LOCK_TYPE> LOCK_GUARD;
LOCK_TYPE m_mutex;
char _cache_guard[1024];
LOCK_TYPE m_refMutex;
};
@ -327,7 +328,8 @@ class TerrainManager : public MaNGOS::Singleton<TerrainManager, MaNGOS::ClassLev
TerrainManager(const TerrainManager&);
TerrainManager& operator=(const TerrainManager&);
typedef MaNGOS::ClassLevelLockable<TerrainManager, ACE_Thread_Mutex>::Lock Guard;
typedef ACE_Thread_Mutex LOCK_TYPE;
LOCK_TYPE m_mutex;
TerrainDataMap i_TerrainMap;
};

View File

@ -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
{

View File

@ -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

View File

@ -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;

View File

@ -59,10 +59,6 @@ class MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::ClassLevelLockab
{
friend class MaNGOS::OperatorNew<MapManager>;
typedef ACE_Recursive_Thread_Mutex LOCK_TYPE;
typedef ACE_Guard<LOCK_TYPE> LOCK_TYPE_GUARD;
typedef MaNGOS::ClassLevelLockable<MapManager, ACE_Recursive_Thread_Mutex>::Lock Guard;
public:
typedef std::map<MapID, Map* > MapMapType;
@ -185,8 +181,10 @@ class MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::ClassLevelLockab
MapMapType i_maps;
IntervalTimer i_timer;
MapUpdater m_updater;
uint32 i_MaxInstanceId;
typedef ACE_Recursive_Thread_Mutex LOCK_TYPE;
mutable LOCK_TYPE m_lock;
};
template<typename Do>

View File

@ -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;
}
}
@ -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;
}

View File

@ -25,18 +25,18 @@
#ifndef MANGOS_H_BIH
#define MANGOS_H_BIH
#include <G3D/Vector3.h>
#include <G3D/Ray.h>
#include <G3D/AABox.h>
#include <Platform/Define.h>
#include <stdexcept>
#include <vector>
#include <algorithm>
#include <limits>
#include <cmath>
#include <Platform/Define.h>
#include <G3D/Vector3.h>
#include <G3D/Ray.h>
#include <G3D/AABox.h>
#define MAX_STACK_SIZE 64
#ifdef _MSC_VER

View File

@ -24,10 +24,10 @@
#pragma once
#include "BIH.h"
#include <G3D/Table.h>
#include <G3D/Array.h>
#include <G3D/Set.h>
#include "BIH.h"
template<class T, class BoundsFunc = BoundsTrait<T> >
/**

View File

@ -25,6 +25,8 @@
#ifndef MANGOSSERVER_GAMEOBJECTMODEL_H
#define MANGOSSERVER_GAMEOBJECTMODEL_H
#include "Platform/Define.h"
#include <G3D/Matrix3.h>
#include <G3D/Vector3.h>
#include <G3D/AABox.h>
@ -32,7 +34,6 @@
#include "DBCStructure.h"
#include "GameObject.h"
#include "Platform/Define.h"
namespace VMAP
{

View File

@ -25,12 +25,13 @@
#ifndef MANGOS_H_MODELINSTANCE
#define MANGOS_H_MODELINSTANCE
#include "Platform/Define.h"
#include <G3D/Matrix3.h>
#include <G3D/Vector3.h>
#include <G3D/AABox.h>
#include <G3D/Ray.h>
#include "Platform/Define.h"
namespace VMAP
{

View File

@ -22,15 +22,16 @@
* and lore are copyrighted by Blizzard Entertainment, Inc.
*/
#include <set>
#include <iomanip>
#include <sstream>
#include <iomanip>
#include "TileAssembler.h"
#include "MapTree.h"
#include "BIH.h"
#include "VMapDefinitions.h"
#include <set>
#include <iomanip>
#include <sstream>
#include <iomanip>
using G3D::Vector3;
using G3D::AABox;

View File

@ -25,13 +25,13 @@
#ifndef MANGOS_H_TILEASSEMBLER
#define MANGOS_H_TILEASSEMBLER
#include <G3D/Vector3.h>
#include <G3D/Matrix3.h>
#include <map>
#include <set>
#include "ModelInstance.h"
#include "WorldModel.h"
#include <G3D/Vector3.h>
#include <G3D/Matrix3.h>
namespace VMAP
{

View File

@ -25,13 +25,14 @@
#ifndef MANGOS_H_WORLDMODEL
#define MANGOS_H_WORLDMODEL
#include "Platform/Define.h"
#include <G3D/HashTrait.h>
#include <G3D/Vector3.h>
#include <G3D/AABox.h>
#include <G3D/Ray.h>
#include "BIH.h"
#include "Platform/Define.h"
namespace VMAP
{