diff --git a/src/game/AccountMgr.cpp b/src/game/AccountMgr.cpp index a10b0575f..b3ed91c7e 100644 --- a/src/game/AccountMgr.cpp +++ b/src/game/AccountMgr.cpp @@ -75,7 +75,7 @@ AccountOpResult AccountMgr::DeleteAccount(uint32 accid) uint64 guid = MAKE_NEW_GUID(guidlo, 0, HIGHGUID_PLAYER); // kick if player currently - if(Player* p = ObjectAccessor::FindPlayer(guid)) + if(Player* p = ObjectAccessor::GetObjectInWorld(guid, (Player*)NULL)) { WorldSession* s = p->GetSession(); s->KickPlayer(); // mark session to remove at next session list update diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index f350d6df5..727ecce6b 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -32,6 +32,7 @@ #include "GridNotifiersImpl.h" #include "CellImpl.h" #include "Language.h" +#include "MapManager.h" #include "Policies/SingletonImp.h" @@ -825,8 +826,8 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if(!miscvalue1) continue; - Map const* map = GetPlayer()->GetMap(); - if(!map->IsDungeon()) + Map const* map = GetPlayer()->IsInWorld() ? GetPlayer()->GetMap() : MapManager::Instance().FindMap(GetPlayer()->GetMapId(), GetPlayer()->GetInstanceId()); + if(!map || !map->IsDungeon()) continue; // search case diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index 493b4eaca..cda2b5f3f 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -70,7 +70,13 @@ void GameObject::CleanupsBeforeDelete() // Possible crash at access to deleted GO in Unit::m_gameobj if(uint64 owner_guid = GetOwnerGUID()) { - if(Unit* owner = ObjectAccessor::GetUnit(*this,owner_guid)) + Unit* owner = NULL; + if(IS_PLAYER_GUID(owner_guid)) + owner = ObjectAccessor::GetObjectInWorld(owner_guid, (Player*)NULL); + else + owner = ObjectAccessor::GetUnit(*this,owner_guid); + + if(owner) owner->RemoveGameObject(this,false); else { diff --git a/src/game/Group.cpp b/src/game/Group.cpp index 0e4cb4e87..12e416d0b 100644 --- a/src/game/Group.cpp +++ b/src/game/Group.cpp @@ -963,7 +963,7 @@ void Group::SendUpdate() void Group::UpdatePlayerOutOfRange(Player* pPlayer) { - if(!pPlayer) + if(!pPlayer || !pPlayer->IsInWorld()) return; Player *player; diff --git a/src/game/LFGHandler.cpp b/src/game/LFGHandler.cpp index 17792dba5..5175fa4a3 100644 --- a/src/game/LFGHandler.cpp +++ b/src/game/LFGHandler.cpp @@ -40,6 +40,10 @@ static void AttemptJoin(Player* _player) if(!plr || plr==_player || plr->GetTeam() != _player->GetTeam()) continue; + //skip players not in world + if(!plr->IsInWorld()) + continue; + // skip not auto add, not group leader cases if(!plr->GetSession()->LookingForGroup_auto_add || plr->GetGroup() && plr->GetGroup()->GetLeaderGUID()!=plr->GetGUID()) continue; @@ -96,6 +100,9 @@ static void AttemptAddMore(Player* _player) if(!plr || plr==_player || plr->GetTeam() != _player->GetTeam()) continue; + if(!plr->IsInWorld()) + continue; + // skip not auto join or in group if(!plr->GetSession()->LookingForGroup_auto_join || plr->GetGroup() ) continue; @@ -309,6 +316,9 @@ void WorldSession::SendLfgResult(uint32 type, uint32 entry, uint8 lfg_type) if(!plr || plr->GetTeam() != _player->GetTeam()) continue; + if(!plr->IsInWorld()) + continue; + if(!plr->m_lookingForGroup.HaveInSlot(entry, type)) continue; diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index 0f0c9e547..4fd91ee27 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -170,6 +170,10 @@ void WorldSession::HandleWhoOpcode( WorldPacket & recv_data ) continue; } + //do not process players which are not in world + if(!(itr->second->IsInWorld())) + continue; + // check if target is globally visible for player if (!(itr->second->IsVisibleGloballyFor(_player))) continue; diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index fd38c76bb..1638c9cb0 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -154,6 +154,9 @@ void WorldSession::HandleMoveWorldportAckOpcode() // resummon pet GetPlayer()->ResummonPetTemporaryUnSummonedIfAny(); + + //lets process all delayed operations on successful teleport + GetPlayer()->ProcessDelayedOperations(); } void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data) @@ -200,6 +203,9 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data) // resummon pet GetPlayer()->ResummonPetTemporaryUnSummonedIfAny(); + + //lets process all delayed operations on successful teleport + GetPlayer()->ProcessDelayedOperations(); } void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) @@ -329,8 +335,8 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) } else // creature charmed { - if(Map *map = mover->GetMap()) - map->CreatureRelocation((Creature*)mover, movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); + if(mover->IsInWorld()) + mover->GetMap()->CreatureRelocation((Creature*)mover, movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); } } diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp index f36fa96b9..e5fb150bd 100644 --- a/src/game/NPCHandler.cpp +++ b/src/game/NPCHandler.cpp @@ -415,7 +415,7 @@ void WorldSession::HandleBinderActivateOpcode( WorldPacket & recv_data ) uint64 npcGUID; recv_data >> npcGUID; - if(!GetPlayer()->isAlive()) + if(!GetPlayer()->IsInWorld() || !GetPlayer()->isAlive()) return; Creature *unit = GetPlayer()->GetNPCIfCanInteractWith(npcGUID,UNIT_NPC_FLAG_INNKEEPER); @@ -435,7 +435,7 @@ void WorldSession::HandleBinderActivateOpcode( WorldPacket & recv_data ) void WorldSession::SendBindPoint(Creature *npc) { // prevent set homebind to instances in any case - if(sMapStore.LookupEntry(GetPlayer()->GetMapId())->Instanceable()) + if(GetPlayer()->GetMap()->Instanceable()) return; uint32 bindspell = 3286; diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp index 43c38dde0..43eb02a8a 100644 --- a/src/game/ObjectAccessor.cpp +++ b/src/game/ObjectAccessor.cpp @@ -58,7 +58,7 @@ ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const &u, uint64 guid) if(IS_VEHICLE_GUID(guid)) return GetVehicle(guid); - return u.GetMap()->GetCreature(guid); + return u.IsInWorld() ? u.GetMap()->GetCreature(guid) : NULL; } Unit* @@ -131,7 +131,11 @@ Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const &p, uint64 guid, u Player* ObjectAccessor::FindPlayer(uint64 guid) { - return GetObjectInWorld(guid, (Player*)NULL); + Player * plr = GetObjectInWorld(guid, (Player*)NULL); + if(!plr || !plr->IsInWorld()) + return NULL; + + return plr; } Player* @@ -141,7 +145,7 @@ ObjectAccessor::FindPlayerByName(const char *name) HashMapHolder::MapType& m = HashMapHolder::GetContainer(); HashMapHolder::MapType::iterator iter = m.begin(); for(; iter != m.end(); ++iter) - if( ::strcmp(name, iter->second->GetName()) == 0 ) + if(iter->second->IsInWorld() && ( ::strcmp(name, iter->second->GetName()) == 0 )) return iter->second; return NULL; } diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h index c2a37be05..6ed1b26cf 100644 --- a/src/game/ObjectAccessor.h +++ b/src/game/ObjectAccessor.h @@ -102,10 +102,16 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton::Find(guid); + { + Unit * u = (Unit*)HashMapHolder::Find(guid); + if(!u || !u->IsInWorld()) + return NULL; - if (Unit* u = (Unit*)HashMapHolder::Find(guid)) return u; + } + + if (IS_PET_GUID(guid)) + return (Unit*)HashMapHolder::Find(guid); return (Unit*)HashMapHolder::Find(guid); } diff --git a/src/game/ObjectGridLoader.cpp b/src/game/ObjectGridLoader.cpp index de73ee183..a3e5145f0 100644 --- a/src/game/ObjectGridLoader.cpp +++ b/src/game/ObjectGridLoader.cpp @@ -254,6 +254,10 @@ template void ObjectGridUnloader::Visit(GridRefManager &m) { + // remove all cross-reference before deleting + for(GridRefManager::iterator iter=m.begin(); iter != m.end(); ++iter) + iter->getSource()->CleanupsBeforeDelete(); + while(!m.isEmpty()) { T *obj = m.getFirst()->getSource(); @@ -267,25 +271,6 @@ ObjectGridUnloader::Visit(GridRefManager &m) } } -template<> -void -ObjectGridUnloader::Visit(CreatureMapType &m) -{ - // remove all cross-reference before deleting - for(CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter) - iter->getSource()->CleanupsBeforeDelete(); - - while(!m.isEmpty()) - { - Creature *obj = m.getFirst()->getSource(); - // if option set then object already saved at this moment - if(!sWorld.getConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATLY)) - obj->SaveRespawnTime(); - ///- object will get delinked from the manager when deleted - delete obj; - } -} - void ObjectGridStoper::Stop(GridType &grid) { diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index 441e40072..a9f464b40 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -463,6 +463,9 @@ void WorldSession::HandlePetAbandon( WorldPacket & recv_data ) recv_data >> guid; //pet guid sLog.outDetail( "HandlePetAbandon. CMSG_PET_ABANDON pet guid is %u", GUID_LOPART(guid) ); + if(!_player->IsInWorld()) + return; + // pet/charmed Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid); if(pet) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 0836685e6..72b2a7062 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -338,6 +338,11 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa mSemaphoreTeleport_Near = false; mSemaphoreTeleport_Far = false; + m_DelayedOperations = 0; + m_bCanDelayTeleport = false; + m_bHasDelayedTeleport = false; + m_teleport_options = 0; + pTrader = 0; ClearTrade(); @@ -1064,7 +1069,10 @@ void Player::Update( uint32 p_time ) m_nextMailDelivereTime = 0; } + //used to implement delayed far teleports + SetCanDelayTeleport(true); Unit::Update( p_time ); + SetCanDelayTeleport(false); // update player only attacks if(uint32 ranged_att = getAttackTimer(RANGED_ATTACK)) @@ -1326,8 +1334,12 @@ void Player::Update( uint32 p_time ) if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE) && (GetCharmGUID() && (pet->GetGUID() != GetCharmGUID()))) { RemovePet(pet, PET_SAVE_NOT_IN_SLOT, true); - return; } + + //we should execute delayed teleports only for alive(!) players + //because we don't want player's ghost teleported from graveyard + if(IsHasDelayedTeleport() && isAlive()) + TeleportTo(m_teleport_dest, m_teleport_options); } void Player::setDeathState(DeathState s) @@ -1611,6 +1623,21 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati if ((GetMapId() == mapid) && (!m_transport)) { + //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()) + { + SetSemaphoreTeleportNear(true); + //lets save teleport destination for player + m_teleport_dest = WorldLocation(mapid, x, y, z, orientation); + m_teleport_options = options; + return true; + } + if (!(options & TELE_TO_NOT_UNSUMMON_PET)) { //same map, only remove pet if out of range for new position @@ -1652,6 +1679,21 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati Map *map = MapManager::Instance().FindMap(mapid); if (!map || map->CanEnter(this)) { + //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()) + { + SetSemaphoreTeleportFar(true); + //lets save teleport destination for player + m_teleport_dest = WorldLocation(mapid, x, y, z, orientation); + m_teleport_options = options; + return true; + } + SetSelection(0); CombatStop(); @@ -1681,6 +1723,9 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati 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()) { // send transfer packets @@ -1727,8 +1772,6 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati // if the player is saved before worldportack (at logout for example) // this will be used instead of the current location in SaveToDB - RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CHANGE_MAP | AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_TURNING); - // move packet sent by client always after far teleport // code for finish transfer to new map called in WorldSession::HandleMoveWorldportAckOpcode at client packet SetSemaphoreTeleportFar(true); @@ -1739,6 +1782,53 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati return true; } +void Player::ProcessDelayedOperations() +{ + if(m_DelayedOperations == 0) + return; + + if(m_DelayedOperations & DELAYED_RESURRECT_PLAYER) + { + ResurrectPlayer(0.0f, false); + + if(GetMaxHealth() > m_resurrectHealth) + SetHealth( m_resurrectHealth ); + else + SetHealth( GetMaxHealth() ); + + if(GetMaxPower(POWER_MANA) > m_resurrectMana) + SetPower(POWER_MANA, m_resurrectMana ); + else + SetPower(POWER_MANA, GetMaxPower(POWER_MANA) ); + + SetPower(POWER_RAGE, 0 ); + SetPower(POWER_ENERGY, GetMaxPower(POWER_ENERGY) ); + + SpawnCorpseBones(); + } + + if(m_DelayedOperations & DELAYED_SAVE_PLAYER) + { + SaveToDB(); + } + + if(m_DelayedOperations & DELAYED_SPELL_CAST_DESERTER) + { + CastSpell(this, 26013, true); // Deserter + } + + //we have executed ALL delayed ops, so clear the flag + m_DelayedOperations = 0; +} + +void Player::ScheduleDelayedOperation(uint32 operation) +{ + if(operation >= DELAYED_END) + return; + + m_DelayedOperations |= operation; +} + void Player::AddToWorld() { ///- Do not add/remove the player from the object storage @@ -12081,7 +12171,11 @@ Quest const * Player::GetNextQuest( uint64 guid, Quest const *pQuest ) } else { - GameObject *pGameObject = GetMap()->GetGameObject(guid); + //we should obtain map pointer from GetMap() in 99% of cases. Special case + //only for quests which cast teleport spells on player + Map * _map = IsInWorld() ? GetMap() : MapManager::Instance().FindMap(GetMapId(), GetInstanceId()); + ASSERT(_map); + GameObject *pGameObject = _map->GetGameObject(guid); if( pGameObject ) { pObject = (Object*)pGameObject; @@ -12415,6 +12509,10 @@ 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_OBJECTIVES_COUNT; ++i ) @@ -12607,6 +12705,9 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver if( !HasAura(itr->second->spellId,0) ) CastSpell(this,itr->second->spellId,true); } + + //lets remove flag for delayed teleports + SetCanDelayTeleport(false); } void Player::FailQuest( uint32 quest_id ) @@ -15377,6 +15478,13 @@ void Player::SaveToDB() // delay auto save at any saves (manual, in code, or autosave) m_nextSave = sWorld.getConfig(CONFIG_INTERVAL_SAVE); + //lets allow only players in world to be saved + if(IsBeingTeleportedFar()) + { + ScheduleDelayedOperation(DELAYED_SAVE_PLAYER); + return; + } + // first save/honor gain after midnight will also update the player's honor fields UpdateHonorFields(); @@ -17641,7 +17749,16 @@ void Player::LeaveBattleground(bool teleportToEntryPoint) if( bg->isBattleGround() && !isGameMaster() && sWorld.getConfig(CONFIG_BATTLEGROUND_CAST_DESERTER) ) { if( bg->GetStatus() == STATUS_IN_PROGRESS || bg->GetStatus() == STATUS_WAIT_JOIN ) + { + //lets check if player was teleported from BG and schedule delayed Deserter spell cast + if(IsBeingTeleportedFar()) + { + ScheduleDelayedOperation(DELAYED_SPELL_CAST_DESERTER); + return; + } + CastSpell(this, 26013, true); // Deserter + } } } } @@ -18868,6 +18985,14 @@ void Player::ResurectUsingRequestData() if(IS_PLAYER_GUID(m_resurrectGUID)) TeleportTo(m_resurrectMap, m_resurrectX, m_resurrectY, m_resurrectZ, GetOrientation()); + //we cannot resurrect player when we triggered far teleport + //player will be resurrected upon teleportation + if(IsBeingTeleportedFar()) + { + ScheduleDelayedOperation(DELAYED_RESURRECT_PLAYER); + return; + } + ResurrectPlayer(0.0f,false); if(GetMaxHealth() > m_resurrectHealth) diff --git a/src/game/Player.h b/src/game/Player.h index 66c119396..714766cdd 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -858,6 +858,14 @@ enum PlayerLoginQueryIndex MAX_PLAYER_LOGIN_QUERY = 21 }; +enum PlayerDelayedOperations +{ + DELAYED_SAVE_PLAYER = 1, + DELAYED_RESURRECT_PLAYER = 2, + DELAYED_SPELL_CAST_DESERTER = 4, + DELAYED_END +}; + // Player summoning auto-decline time (in secs) #define MAX_PLAYER_SUMMON_DELAY (2*MINUTE) #define MAX_MONEY_AMOUNT (0x7FFFFFFF-1) @@ -1757,6 +1765,7 @@ class MANGOS_DLL_SPEC Player : public Unit bool IsBeingTeleportedFar() const { return mSemaphoreTeleport_Far; } void SetSemaphoreTeleportNear(bool semphsetting) { mSemaphoreTeleport_Near = semphsetting; } void SetSemaphoreTeleportFar(bool semphsetting) { mSemaphoreTeleport_Far = semphsetting; } + void ProcessDelayedOperations(); void CheckExploreSystem(void); @@ -2397,6 +2406,13 @@ 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; } + + void ScheduleDelayedOperation(uint32 operation); + GridReference m_gridRef; MapReference m_mapRef; @@ -2410,9 +2426,14 @@ class MANGOS_DLL_SPEC Player : public Unit // Current teleport data WorldLocation m_teleport_dest; + uint32 m_teleport_options; bool mSemaphoreTeleport_Near; bool mSemaphoreTeleport_Far; + uint32 m_DelayedOperations; + bool m_bCanDelayTeleport; + bool m_bHasDelayedTeleport; + // Temporary removed pet cache uint32 m_temporaryUnsummonedPetNumber; uint32 m_oldpetspell; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index fb91db413..7bd089463 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -176,6 +176,9 @@ Unit::~Unit() void Unit::Update( uint32 p_time ) { + if(!IsInWorld()) + return; + /*if(p_time > m_AurasCheck) { m_AurasCheck = 2000; @@ -7248,7 +7251,7 @@ bool Unit::Attack(Unit *victim, bool meleeAttack) return false; // dead units can neither attack nor be attacked - if(!isAlive() || !victim->isAlive()) + if(!isAlive() || !victim->IsInWorld() || !victim->isAlive()) return false; // player cannot attack in mount state @@ -8906,7 +8909,7 @@ bool Unit::isTargetableForAttack() const if(HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE)) return false; - return isAlive() && !hasUnitState(UNIT_STAT_DIED)&& !isInFlight() /*&& !isStealth()*/; + return IsInWorld() && isAlive() && !hasUnitState(UNIT_STAT_DIED)&& !isInFlight() /*&& !isStealth()*/; } int32 Unit::ModifyHealth(int32 dVal) diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp index f0d11f587..89f6bb895 100644 --- a/src/game/WorldSession.cpp +++ b/src/game/WorldSession.cpp @@ -307,7 +307,13 @@ void WorldSession::LogoutPlayer(bool Save) ///- Teleport to home if the player is in an invalid instance if(!_player->m_InstanceValid && !_player->isGameMaster()) + { _player->TeleportTo(_player->m_homebindMapId, _player->m_homebindX, _player->m_homebindY, _player->m_homebindZ, _player->GetOrientation()); + //this is a bad place to call for far teleport because we need player to be in world for successful logout + //maybe we should implement delayed far teleport logout? + while(_player->IsBeingTeleportedFar()) + HandleMoveWorldportAckOpcode(); + } for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index d7e5066f2..104d40568 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 "8102" + #define REVISION_NR "8103" #endif // __REVISION_NR_H__