Core/Misc: fixed a scenario when character factionchange create unexpected results, also moved packet generating code into unique methods
(Packet structure not verificated to 6.0.2)
This commit is contained in:
@@ -474,12 +474,23 @@ struct MovementInfo
|
||||
class WorldLocation : public Position
|
||||
{
|
||||
public:
|
||||
explicit WorldLocation(uint32 _mapid = MAPID_INVALID, float _x = 0, float _y = 0, float _z = 0, float _o = 0)
|
||||
: m_mapId(_mapid) { Relocate(_x, _y, _z, _o); }
|
||||
WorldLocation(const WorldLocation &loc) : Position(loc) { WorldRelocate(loc); }
|
||||
explicit WorldLocation(uint32 _mapId = MAPID_INVALID, float _x = 0.f, float _y = 0.f, float _z = 0.f, float _o = 0.f)
|
||||
: Position(_x, _y, _z, _o), m_mapId(_mapId) { }
|
||||
|
||||
void WorldRelocate(const WorldLocation &loc)
|
||||
{ m_mapId = loc.GetMapId(); Relocate(loc); }
|
||||
WorldLocation(WorldLocation const& loc)
|
||||
: Position(loc), m_mapId(loc.GetMapId()) { }
|
||||
|
||||
void WorldRelocate(WorldLocation const& loc)
|
||||
{
|
||||
m_mapId = loc.GetMapId();
|
||||
Relocate(loc);
|
||||
}
|
||||
|
||||
void WorldRelocate(uint32 _mapId = MAPID_INVALID, float _x = 0.f, float _y = 0.f, float _z = 0.f, float _o = 0.f)
|
||||
{
|
||||
m_mapId = _mapId;
|
||||
Relocate(_x, _y, _z, _o);
|
||||
}
|
||||
|
||||
WorldLocation GetWorldLocation() const
|
||||
{
|
||||
|
||||
@@ -20468,19 +20468,19 @@ void Player::SendAttackSwingNotInRange()
|
||||
GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
void Player::SavePositionInDB(uint32 mapid, float x, float y, float z, float o, uint32 zone, ObjectGuid guid)
|
||||
void Player::SavePositionInDB(WorldLocation const& loc, uint16 zoneId, ObjectGuid guid, SQLTransaction& trans)
|
||||
{
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHARACTER_POSITION);
|
||||
|
||||
stmt->setFloat(0, x);
|
||||
stmt->setFloat(1, y);
|
||||
stmt->setFloat(2, z);
|
||||
stmt->setFloat(3, o);
|
||||
stmt->setUInt16(4, uint16(mapid));
|
||||
stmt->setUInt16(5, uint16(zone));
|
||||
stmt->setFloat(0, loc.GetPositionX());
|
||||
stmt->setFloat(1, loc.GetPositionY());
|
||||
stmt->setFloat(2, loc.GetPositionZ());
|
||||
stmt->setFloat(3, loc.GetOrientation());
|
||||
stmt->setUInt16(4, uint16(loc.GetMapId()));
|
||||
stmt->setUInt16(5, zoneId);
|
||||
stmt->setUInt32(6, guid.GetCounter());
|
||||
|
||||
CharacterDatabase.Execute(stmt);
|
||||
CharacterDatabase.ExecuteOrAppend(trans, stmt);
|
||||
}
|
||||
|
||||
void Player::SetUInt32ValueInArray(Tokenizer& Tokenizer, uint16 index, uint32 value)
|
||||
@@ -20494,10 +20494,10 @@ void Player::SetUInt32ValueInArray(Tokenizer& Tokenizer, uint16 index, uint32 va
|
||||
Tokenizer[index] = buf;
|
||||
}
|
||||
|
||||
void Player::Customize(ObjectGuid guid, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair)
|
||||
void Player::Customize(CharacterCustomizeInfo const* customizeInfo, SQLTransaction& trans)
|
||||
{
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PLAYERBYTES2);
|
||||
stmt->setUInt32(0, guid.GetCounter());
|
||||
stmt->setUInt32(0, customizeInfo->Guid.GetCounter());
|
||||
PreparedQueryResult result = CharacterDatabase.Query(stmt);
|
||||
|
||||
if (!result)
|
||||
@@ -20507,16 +20507,16 @@ void Player::Customize(ObjectGuid guid, uint8 gender, uint8 skin, uint8 face, ui
|
||||
|
||||
uint32 playerBytes2 = fields[0].GetUInt32();
|
||||
playerBytes2 &= ~0xFF;
|
||||
playerBytes2 |= facialHair;
|
||||
playerBytes2 |= customizeInfo->FacialHair;
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GENDER_PLAYERBYTES);
|
||||
|
||||
stmt->setUInt8(0, gender);
|
||||
stmt->setUInt32(1, skin | (face << 8) | (hairStyle << 16) | (hairColor << 24));
|
||||
stmt->setUInt8(0, customizeInfo->Gender);
|
||||
stmt->setUInt32(1, customizeInfo->Skin | (customizeInfo->Face << 8) | (customizeInfo->HairStyle << 16) | (customizeInfo->HairColor << 24));
|
||||
stmt->setUInt32(2, playerBytes2);
|
||||
stmt->setUInt32(3, guid.GetCounter());
|
||||
stmt->setUInt32(3, customizeInfo->Guid.GetCounter());
|
||||
|
||||
CharacterDatabase.Execute(stmt);
|
||||
CharacterDatabase.ExecuteOrAppend(trans, stmt);
|
||||
}
|
||||
|
||||
void Player::SendAttackSwingDeadTarget()
|
||||
|
||||
@@ -56,6 +56,8 @@ class PlayerSocial;
|
||||
class SpellCastTargets;
|
||||
class UpdateMask;
|
||||
|
||||
struct CharacterCustomizeInfo;
|
||||
|
||||
typedef std::deque<Mail*> PlayerMails;
|
||||
|
||||
#define PLAYER_MAX_SKILLS 128
|
||||
@@ -1694,8 +1696,8 @@ class Player : public Unit, public GridObject<Player>
|
||||
|
||||
static void SetUInt32ValueInArray(Tokenizer& data, uint16 index, uint32 value);
|
||||
static void SetFloatValueInArray(Tokenizer& data, uint16 index, float value);
|
||||
static void Customize(ObjectGuid guid, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair);
|
||||
static void SavePositionInDB(uint32 mapid, float x, float y, float z, float o, uint32 zone, ObjectGuid guid);
|
||||
static void Customize(CharacterCustomizeInfo const* customizeInfo, SQLTransaction& trans);
|
||||
static void SavePositionInDB(WorldLocation const& loc, uint16 zoneId, ObjectGuid guid, SQLTransaction& trans);
|
||||
|
||||
static void DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRealmChars = true, bool deleteFinally = false);
|
||||
static void DeleteOldCharacters();
|
||||
@@ -1936,7 +1938,7 @@ class Player : public Unit, public GridObject<Player>
|
||||
void SetContestedPvPTimer(uint32 newTime) {m_contestedPvPTimer = newTime;}
|
||||
void ResetContestedPvP();
|
||||
|
||||
/** todo: -maybe move UpdateDuelFlag+DuelComplete to independent DuelHandler.. **/
|
||||
/// @todo: maybe move UpdateDuelFlag+DuelComplete to independent DuelHandler
|
||||
DuelInfo* duel;
|
||||
void UpdateDuelFlag(time_t currTime);
|
||||
void CheckDuelDistance(time_t currTime);
|
||||
|
||||
@@ -1662,7 +1662,7 @@ void ObjectMgr::LoadCreatures()
|
||||
spawnMasks[i] |= (1 << k);
|
||||
|
||||
_creatureDataStore.rehash(result->GetRowCount());
|
||||
uint32 count = 0;
|
||||
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
@@ -1800,12 +1800,10 @@ void ObjectMgr::LoadCreatures()
|
||||
// Add to grid if not managed by the game event or pool system
|
||||
if (gameEvent == 0 && PoolId == 0)
|
||||
AddCreatureToGrid(guid, &data);
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
++count;
|
||||
|
||||
} while (result->NextRow());
|
||||
|
||||
TC_LOG_INFO("server.loading", ">> Loaded %u creatures in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
|
||||
TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " creatures in %u ms", _creatureDataStore.size(), GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
void ObjectMgr::AddCreatureToGrid(uint32 guid, CreatureData const* data)
|
||||
@@ -1976,8 +1974,6 @@ void ObjectMgr::LoadGameobjects()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
uint32 count = 0;
|
||||
|
||||
// 0 1 2 3 4 5 6
|
||||
QueryResult result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation, "
|
||||
// 7 8 9 10 11 12 13 14 15 16 17 18 19
|
||||
@@ -2000,6 +1996,7 @@ void ObjectMgr::LoadGameobjects()
|
||||
spawnMasks[i] |= (1 << k);
|
||||
|
||||
_gameObjectDataStore.rehash(result->GetRowCount());
|
||||
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
@@ -2137,10 +2134,10 @@ void ObjectMgr::LoadGameobjects()
|
||||
|
||||
if (gameEvent == 0 && PoolId == 0) // if not this is to be managed by GameEvent System or Pool system
|
||||
AddGameobjectToGrid(guid, &data);
|
||||
++count;
|
||||
} while (result->NextRow());
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
TC_LOG_INFO("server.loading", ">> Loaded %lu gameobjects in %u ms", (unsigned long)_gameObjectDataStore.size(), GetMSTimeDiffToNow(oldMSTime));
|
||||
TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " gameobjects in %u ms", _gameObjectDataStore.size(), GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
void ObjectMgr::AddGameobjectToGrid(uint32 guid, GameObjectData const* data)
|
||||
@@ -7688,7 +7685,7 @@ bool isValidString(const std::wstring& wstr, uint32 strictMask, bool numericOrSp
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8 ObjectMgr::CheckPlayerName(const std::string& name, bool create)
|
||||
ResponseCodes ObjectMgr::CheckPlayerName(const std::string& name, bool create)
|
||||
{
|
||||
std::wstring wname;
|
||||
if (!Utf8toWStr(name, wname))
|
||||
|
||||
@@ -1234,7 +1234,7 @@ class ObjectMgr
|
||||
bool IsReservedName(std::string const& name) const;
|
||||
|
||||
// name with valid structure and symbols
|
||||
static uint8 CheckPlayerName(std::string const& name, bool create = false);
|
||||
static ResponseCodes CheckPlayerName(std::string const& name, bool create = false);
|
||||
static PetNameInvalidReason CheckPetName(std::string const& name);
|
||||
static bool IsValidCharterName(std::string const& name);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -581,7 +581,7 @@ void WorldSession::LogoutPlayer(bool save)
|
||||
// e.g if he got disconnected during a transfer to another map
|
||||
// calls to GetMap in this case may cause crashes
|
||||
_player->CleanupsBeforeDelete();
|
||||
TC_LOG_INFO("entities.player.character", "Account: %d (IP: %s) Logout Character:[%s] (GUID: %u) Level: %d",
|
||||
TC_LOG_INFO("entities.player.character", "Account: %u (IP: %s) Logout Character:[%s] (GUID: %u) Level: %d",
|
||||
GetAccountId(), GetRemoteAddress().c_str(), _player->GetName().c_str(), _player->GetGUIDLow(), _player->getLevel());
|
||||
|
||||
sBattlenetServer.SendChangeToonOnlineState(GetBattlenetAccountId(), GetAccountId(), _player->GetGUID(), _player->GetName(), false);
|
||||
@@ -1077,10 +1077,11 @@ void WorldSession::ProcessQueryCallbacks()
|
||||
//- HandleCharRenameOpcode
|
||||
if (_charRenameCallback.IsReady())
|
||||
{
|
||||
std::string param = _charRenameCallback.GetParam();
|
||||
_charRenameCallback.GetResult(result);
|
||||
HandleChangePlayerNameOpcodeCallBack(result, param);
|
||||
_charRenameCallback.FreeResult();
|
||||
CharacterRenameInfo* renameInfo = _charRenameCallback.GetParam();
|
||||
HandleChangePlayerNameOpcodeCallBack(result, renameInfo);
|
||||
delete renameInfo;
|
||||
_charRenameCallback.Reset();
|
||||
}
|
||||
|
||||
//- HandleCharAddIgnoreOpcode
|
||||
|
||||
@@ -100,10 +100,18 @@ struct AccountData
|
||||
|
||||
enum PartyOperation
|
||||
{
|
||||
PARTY_OP_INVITE = 0,
|
||||
PARTY_OP_INVITE = 0,
|
||||
PARTY_OP_UNINVITE = 1,
|
||||
PARTY_OP_LEAVE = 2,
|
||||
PARTY_OP_SWAP = 4
|
||||
PARTY_OP_LEAVE = 2,
|
||||
PARTY_OP_SWAP = 4
|
||||
};
|
||||
|
||||
enum BarberShopResult
|
||||
{
|
||||
BARBER_SHOP_RESULT_SUCCESS = 0,
|
||||
BARBER_SHOP_RESULT_NO_MONEY = 1,
|
||||
BARBER_SHOP_RESULT_NOT_ON_CHAIR = 2,
|
||||
BARBER_SHOP_RESULT_NO_MONEY_2 = 3
|
||||
};
|
||||
|
||||
enum BFLeaveReason
|
||||
@@ -131,6 +139,12 @@ enum CharterTypes
|
||||
ARENA_TEAM_CHARTER_5v5_TYPE = 5,
|
||||
};
|
||||
|
||||
enum DeclinedNameResult
|
||||
{
|
||||
DECLINED_NAMES_RESULT_SUCCESS = 0,
|
||||
DECLINED_NAMES_RESULT_ERROR = 1
|
||||
};
|
||||
|
||||
#define DB2_REPLY_SPARSE 2442913102
|
||||
#define DB2_REPLY_ITEM 1344507586
|
||||
|
||||
@@ -183,26 +197,52 @@ class CharacterCreateInfo
|
||||
friend class Player;
|
||||
|
||||
protected:
|
||||
CharacterCreateInfo(std::string const& name, uint8 race, uint8 cclass, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair, uint8 outfitId,
|
||||
WorldPacket& data) : Name(name), Race(race), Class(cclass), Gender(gender), Skin(skin), Face(face), HairStyle(hairStyle), HairColor(hairColor), FacialHair(facialHair),
|
||||
OutfitId(outfitId), Data(std::move(data)), CharCount(0)
|
||||
{ }
|
||||
|
||||
/// User specified variables
|
||||
std::string Name;
|
||||
uint8 Race;
|
||||
uint8 Class;
|
||||
uint8 Gender;
|
||||
uint8 Skin;
|
||||
uint8 Face;
|
||||
uint8 HairStyle;
|
||||
uint8 HairColor;
|
||||
uint8 FacialHair;
|
||||
uint8 OutfitId;
|
||||
WorldPacket Data;
|
||||
uint8 Race = 0;
|
||||
uint8 Class = 0;
|
||||
uint8 Gender = GENDER_NONE;
|
||||
uint8 Skin = 0;
|
||||
uint8 Face = 0;
|
||||
uint8 HairStyle = 0;
|
||||
uint8 HairColor = 0;
|
||||
uint8 FacialHair = 0;
|
||||
uint8 OutfitId = 0;
|
||||
|
||||
/// Server side data
|
||||
uint8 CharCount;
|
||||
uint8 CharCount = 0;
|
||||
};
|
||||
|
||||
struct CharacterRenameInfo
|
||||
{
|
||||
friend class WorldSession;
|
||||
|
||||
protected:
|
||||
ObjectGuid Guid;
|
||||
std::string Name;
|
||||
};
|
||||
|
||||
struct CharacterCustomizeInfo : public CharacterRenameInfo
|
||||
{
|
||||
friend class Player;
|
||||
friend class WorldSession;
|
||||
|
||||
protected:
|
||||
uint8 Gender = GENDER_NONE;
|
||||
uint8 Skin = 0;
|
||||
uint8 Face = 0;
|
||||
uint8 HairStyle = 0;
|
||||
uint8 HairColor = 0;
|
||||
uint8 FacialHair = 0;
|
||||
};
|
||||
|
||||
struct CharacterFactionChangeInfo : public CharacterCustomizeInfo
|
||||
{
|
||||
friend class Player;
|
||||
friend class WorldSession;
|
||||
|
||||
protected:
|
||||
uint8 Race = 0;
|
||||
};
|
||||
|
||||
struct PacketCounter
|
||||
@@ -420,6 +460,13 @@ class WorldSession
|
||||
void HandleRandomizeCharNameOpcode(WorldPacket& recvData);
|
||||
void HandleReorderCharacters(WorldPacket& recvData);
|
||||
void HandleOpeningCinematic(WorldPacket& recvData);
|
||||
void SendCharCreate(ResponseCodes result);
|
||||
void SendCharDelete(ResponseCodes result);
|
||||
void SendCharRename(ResponseCodes result, CharacterRenameInfo const& renameInfo);
|
||||
void SendCharCustomize(ResponseCodes result, CharacterCustomizeInfo const& customizeInfo);
|
||||
void SendCharFactionChange(ResponseCodes result, CharacterFactionChangeInfo const& factionChangeInfo);
|
||||
void SendSetPlayerDeclinedNamesResult(DeclinedNameResult result, ObjectGuid guid);
|
||||
void SendBarberShopResult(BarberShopResult result);
|
||||
|
||||
// played time
|
||||
void HandlePlayedTime(WorldPacket& recvPacket);
|
||||
@@ -789,7 +836,7 @@ class WorldSession
|
||||
void HandleSetActionBarToggles(WorldPacket& recvData);
|
||||
|
||||
void HandleCharRenameOpcode(WorldPacket& recvData);
|
||||
void HandleChangePlayerNameOpcodeCallBack(PreparedQueryResult result, std::string const& newName);
|
||||
void HandleChangePlayerNameOpcodeCallBack(PreparedQueryResult result, CharacterRenameInfo const* renameInfo);
|
||||
void HandleSetPlayerDeclinedNames(WorldPacket& recvData);
|
||||
|
||||
void HandleTotemDestroyed(WorldPacket& recvData);
|
||||
@@ -990,7 +1037,7 @@ class WorldSession
|
||||
PreparedQueryResultFuture _charEnumCallback;
|
||||
PreparedQueryResultFuture _addIgnoreCallback;
|
||||
PreparedQueryResultFuture _stablePetCallback;
|
||||
QueryCallback<PreparedQueryResult, std::string> _charRenameCallback;
|
||||
QueryCallback<PreparedQueryResult, CharacterRenameInfo*> _charRenameCallback;
|
||||
QueryCallback<PreparedQueryResult, std::string> _addFriendCallback;
|
||||
QueryCallback<PreparedQueryResult, uint32> _unstablePetCallback;
|
||||
QueryCallback<PreparedQueryResult, uint32> _stableSwapCallback;
|
||||
|
||||
@@ -132,7 +132,7 @@ public:
|
||||
handler->PSendSysMessage(LANG_ACCOUNT_CREATED, accountName);
|
||||
if (handler->GetSession())
|
||||
{
|
||||
TC_LOG_INFO("entities.player.character", "Account: %d (IP: %s) Character:[%s] (GUID: %u) created Account %s (Email: '%s')",
|
||||
TC_LOG_INFO("entities.player.character", "Account: %u (IP: %s) Character:[%s] (GUID: %u) created Account %s (Email: '%s')",
|
||||
handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(),
|
||||
handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUIDLow(),
|
||||
accountName, email.c_str());
|
||||
|
||||
@@ -87,7 +87,7 @@ public:
|
||||
handler->PSendSysMessage(LANG_ACCOUNT_CREATED, accountName);
|
||||
if (handler->GetSession())
|
||||
{
|
||||
TC_LOG_INFO("entities.player.character", "Battle.net account: %d (IP: %s) Character:[%s] (GUID: %u) created Account %s",
|
||||
TC_LOG_INFO("entities.player.character", "Battle.net account: %u (IP: %s) Character:[%s] (GUID: %u) created Account %s",
|
||||
handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(),
|
||||
handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUIDLow(),
|
||||
accountName);
|
||||
|
||||
@@ -511,13 +511,14 @@ public:
|
||||
handler->PSendSysMessage(LANG_SUMMONING, nameLink.c_str(), handler->GetTrinityString(LANG_OFFLINE));
|
||||
|
||||
// in point where GM stay
|
||||
Player::SavePositionInDB(handler->GetSession()->GetPlayer()->GetMapId(),
|
||||
SQLTransaction dummy;
|
||||
Player::SavePositionInDB(WorldLocation(handler->GetSession()->GetPlayer()->GetMapId(),
|
||||
handler->GetSession()->GetPlayer()->GetPositionX(),
|
||||
handler->GetSession()->GetPlayer()->GetPositionY(),
|
||||
handler->GetSession()->GetPlayer()->GetPositionZ(),
|
||||
handler->GetSession()->GetPlayer()->GetOrientation(),
|
||||
handler->GetSession()->GetPlayer()->GetOrientation()),
|
||||
handler->GetSession()->GetPlayer()->GetZoneId(),
|
||||
targetGuid);
|
||||
targetGuid, dummy);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -141,13 +141,11 @@ public:
|
||||
if (resultDB)
|
||||
{
|
||||
Field* fieldsDB = resultDB->Fetch();
|
||||
uint32 mapId = fieldsDB[0].GetUInt16();
|
||||
WorldLocation loc(fieldsDB[0].GetUInt16(), fieldsDB[2].GetFloat(), fieldsDB[3].GetFloat(), fieldsDB[4].GetFloat(), 0.0f);
|
||||
uint32 zoneId = fieldsDB[1].GetUInt16();
|
||||
float posX = fieldsDB[2].GetFloat();
|
||||
float posY = fieldsDB[3].GetFloat();
|
||||
float posZ = fieldsDB[4].GetFloat();
|
||||
|
||||
Player::SavePositionInDB(mapId, posX, posY, posZ, 0, zoneId, target_guid);
|
||||
SQLTransaction dummy;
|
||||
Player::SavePositionInDB(loc, zoneId, target_guid, dummy);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,8 +201,10 @@ public:
|
||||
std::string nameLink = handler->playerLink(target_name);
|
||||
|
||||
handler->PSendSysMessage(LANG_TELEPORTING_TO, nameLink.c_str(), handler->GetTrinityString(LANG_OFFLINE), tele->name.c_str());
|
||||
Player::SavePositionInDB(tele->mapId, tele->position_x, tele->position_y, tele->position_z, tele->orientation,
|
||||
sMapMgr->GetZoneId(tele->mapId, tele->position_x, tele->position_y, tele->position_z), target_guid);
|
||||
|
||||
SQLTransaction dummy;
|
||||
Player::SavePositionInDB(WorldLocation(tele->mapId, tele->position_x, tele->position_y, tele->position_z, tele->orientation),
|
||||
sMapMgr->GetZoneId(tele->mapId, tele->position_x, tele->position_y, tele->position_z), target_guid, dummy);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user