diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index 0aaa575ad..11ea2b8da 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -491,14 +491,15 @@ void GameObject::getFishLoot(Loot *fishloot, Player* loot_owner) { fishloot->clear(); - uint32 subzone = GetAreaId(); + uint32 zone, subzone; + GetZoneAndAreaId(zone,subzone); // if subzone loot exist use it if(LootTemplates_Fishing.HaveLootFor(subzone)) fishloot->FillLoot(subzone, LootTemplates_Fishing, loot_owner,true); // else use zone loot else - fishloot->FillLoot(GetZoneId(), LootTemplates_Fishing, loot_owner,true); + fishloot->FillLoot(zone, LootTemplates_Fishing, loot_owner,true); } void GameObject::SaveToDB() @@ -1019,11 +1020,12 @@ void GameObject::Use(Unit* user) // 2) if skill == base_zone_skill => 5% chance // 3) chance is linear dependence from (base_zone_skill-skill) - uint32 subzone = GetAreaId(); + uint32 zone, subzone; + GetZoneAndAreaId(zone,subzone); int32 zone_skill = objmgr.GetFishingBaseSkillLevel( subzone ); if(!zone_skill) - zone_skill = objmgr.GetFishingBaseSkillLevel( GetZoneId() ); + zone_skill = objmgr.GetFishingBaseSkillLevel( zone ); //provide error, no fishable zone or area should be 0 if(!zone_skill) diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp index 85eb69920..fd97a033a 100644 --- a/src/game/Level1.cpp +++ b/src/game/Level1.cpp @@ -284,8 +284,8 @@ bool ChatHandler::HandleGPSCommand(const char* args) CellPair cell_val = MaNGOS::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()); Cell cell(cell_val); - uint32 zone_id = obj->GetZoneId(); - uint32 area_id = obj->GetAreaId(); + uint32 zone_id, area_id; + obj->GetZoneAndAreaId(zone_id,area_id); MapEntry const* mapEntry = sMapStore.LookupEntry(obj->GetMapId()); AreaTableEntry const* zoneEntry = GetAreaEntryByAreaID(zone_id); diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index eaaebeb49..68cdb1717 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -3520,7 +3520,7 @@ bool ChatHandler::HandleLinkGraveCommand(const char* args) return false; } - if(objmgr.AddGraveYardLink(g_id,player->GetZoneId(),g_team)) + if(objmgr.AddGraveYardLink(g_id,zoneId,g_team)) PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, g_id,zoneId); else PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, g_id,zoneId); @@ -3544,6 +3544,7 @@ bool ChatHandler::HandleNearGraveCommand(const char* args) return false; Player* player = m_session->GetPlayer(); + uint32 zone_id = player->GetZoneId(); WorldSafeLocsEntry const* graveyard = objmgr.GetClosestGraveYard( player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),player->GetMapId(),g_team); @@ -3552,7 +3553,7 @@ bool ChatHandler::HandleNearGraveCommand(const char* args) { uint32 g_id = graveyard->ID; - GraveYardData const* data = objmgr.FindGraveYardData(g_id,player->GetZoneId()); + GraveYardData const* data = objmgr.FindGraveYardData(g_id,zone_id); if (!data) { PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR,g_id); @@ -3571,7 +3572,7 @@ bool ChatHandler::HandleNearGraveCommand(const char* args) else if(g_team == ALLIANCE) team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE); - PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),player->GetZoneId()); + PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),zone_id); } else { @@ -3585,9 +3586,9 @@ bool ChatHandler::HandleNearGraveCommand(const char* args) team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE); if(g_team == ~uint32(0)) - PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, player->GetZoneId()); + PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, zone_id); else - PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, player->GetZoneId(),team_name.c_str()); + PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, zone_id,team_name.c_str()); } return true; diff --git a/src/game/Map.cpp b/src/game/Map.cpp index da32317e5..f78871d8b 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -1674,7 +1674,7 @@ float Map::GetWaterLevel(float x, float y ) const return 0; } -uint32 Map::GetAreaId(uint16 areaflag,uint32 map_id) +uint32 Map::GetAreaIdByAreaFlag(uint16 areaflag,uint32 map_id) { AreaTableEntry const *entry = GetAreaEntryByAreaFlagAndMap(areaflag,map_id); @@ -1684,7 +1684,7 @@ uint32 Map::GetAreaId(uint16 areaflag,uint32 map_id) return 0; } -uint32 Map::GetZoneId(uint16 areaflag,uint32 map_id) +uint32 Map::GetZoneIdByAreaFlag(uint16 areaflag,uint32 map_id) { AreaTableEntry const *entry = GetAreaEntryByAreaFlagAndMap(areaflag,map_id); @@ -1694,6 +1694,14 @@ uint32 Map::GetZoneId(uint16 areaflag,uint32 map_id) return 0; } +void Map::GetZoneAndAreaIdByAreaFlag(uint32& zoneid, uint32& areaid, uint16 areaflag,uint32 map_id) +{ + AreaTableEntry const *entry = GetAreaEntryByAreaFlagAndMap(areaflag,map_id); + + areaid = entry ? entry->ID : 0; + zoneid = entry ? (( entry->zone != 0 ) ? entry->zone : entry->ID) : 0; +} + bool Map::IsInWater(float x, float y, float pZ) const { // Check surface in x, y point for liquid @@ -2205,7 +2213,6 @@ bool InstanceMap::Add(Player *player) // first player enters (no players yet) SetResetSchedule(false); - player->SendInitWorldStates(); sLog.outDetail("MAP: Player '%s' entered the instance '%u' of map '%s'", player->GetName(), GetInstanceId(), GetMapName()); // initialize unload state m_unloadTimer = 0; diff --git a/src/game/Map.h b/src/game/Map.h index 7aada6e31..b40a46a4a 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -318,17 +318,23 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj float GetWaterLevel(float x, float y ) const; bool IsUnderWater(float x, float y, float z) const; - static uint32 GetAreaId(uint16 areaflag,uint32 map_id); - static uint32 GetZoneId(uint16 areaflag,uint32 map_id); + static uint32 GetAreaIdByAreaFlag(uint16 areaflag,uint32 map_id); + static uint32 GetZoneIdByAreaFlag(uint16 areaflag,uint32 map_id); + static void GetZoneAndAreaIdByAreaFlag(uint32& zoneid, uint32& areaid, uint16 areaflag,uint32 map_id); uint32 GetAreaId(float x, float y, float z) const { - return GetAreaId(GetAreaFlag(x,y,z),i_id); + return GetAreaIdByAreaFlag(GetAreaFlag(x,y,z),i_id); } uint32 GetZoneId(float x, float y, float z) const { - return GetZoneId(GetAreaFlag(x,y,z),i_id); + return GetZoneIdByAreaFlag(GetAreaFlag(x,y,z),i_id); + } + + void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, float x, float y, float z) const + { + GetZoneAndAreaIdByAreaFlag(zoneid,areaid,GetAreaFlag(x,y,z),i_id); } virtual void MoveAllCreaturesInMoveList(); diff --git a/src/game/MapManager.h b/src/game/MapManager.h index 677c26120..24fb222c4 100644 --- a/src/game/MapManager.h +++ b/src/game/MapManager.h @@ -50,8 +50,18 @@ class MANGOS_DLL_DECL MapManager : public MaNGOS::SingletonGetAreaFlag(x, y, z); } - uint32 GetAreaId(uint32 mapid, float x, float y, float z) const { return Map::GetAreaId(GetAreaFlag(mapid, x, y, z),mapid); } - uint32 GetZoneId(uint32 mapid, float x, float y, float z) const { return Map::GetZoneId(GetAreaFlag(mapid, x, y, z),mapid); } + uint32 GetAreaId(uint32 mapid, float x, float y, float z) const + { + return Map::GetAreaIdByAreaFlag(GetAreaFlag(mapid, x, y, z),mapid); + } + uint32 GetZoneId(uint32 mapid, float x, float y, float z) const + { + return Map::GetZoneIdByAreaFlag(GetAreaFlag(mapid, x, y, z),mapid); + } + void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, uint32 mapid, float x, float y, float z) + { + Map::GetZoneAndAreaIdByAreaFlag(zoneid,areaid,GetAreaFlag(mapid, x, y, z),mapid); + } void Initialize(void); void Update(uint32); diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index 6b7582cbc..60fa21d83 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -384,10 +384,10 @@ void WorldSession::HandleZoneUpdateOpcode( WorldPacket & recv_data ) sLog.outDetail("WORLD: Recvd ZONE_UPDATE: %u", newZone); - if(newZone != _player->GetZoneId()) - GetPlayer()->SendInitWorldStates(); // only if really enters to new zone, not just area change, works strange... - - GetPlayer()->UpdateZone(newZone); + // use server size data + uint32 newzone, newarea; + GetPlayer()->GetZoneAndAreaId(newzone,newarea); + GetPlayer()->UpdateZone(newzone,newarea); } void WorldSession::HandleSetTargetOpcode( WorldPacket & recv_data ) diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp index 78308b08c..65163b924 100644 --- a/src/game/NPCHandler.cpp +++ b/src/game/NPCHandler.cpp @@ -433,11 +433,12 @@ void WorldSession::HandleBinderActivateOpcode( WorldPacket & recv_data ) void WorldSession::SendBindPoint(Creature *npc) { uint32 bindspell = 3286; + uint32 zone_id = _player->GetZoneId(); // update sql homebind - CharacterDatabase.PExecute("UPDATE character_homebind SET map = '%u', zone = '%u', position_x = '%f', position_y = '%f', position_z = '%f' WHERE guid = '%u'", _player->GetMapId(), _player->GetZoneId(), _player->GetPositionX(), _player->GetPositionY(), _player->GetPositionZ(), _player->GetGUIDLow()); + CharacterDatabase.PExecute("UPDATE character_homebind SET map = '%u', zone = '%u', position_x = '%f', position_y = '%f', position_z = '%f' WHERE guid = '%u'", _player->GetMapId(), zone_id, _player->GetPositionX(), _player->GetPositionY(), _player->GetPositionZ(), _player->GetGUIDLow()); _player->m_homebindMapId = _player->GetMapId(); - _player->m_homebindZoneId = _player->GetZoneId(); + _player->m_homebindZoneId = zone_id; _player->m_homebindX = _player->GetPositionX(); _player->m_homebindY = _player->GetPositionY(); _player->m_homebindZ = _player->GetPositionZ(); @@ -456,19 +457,19 @@ void WorldSession::SendBindPoint(Creature *npc) data << float(_player->GetPositionY()); data << float(_player->GetPositionZ()); data << uint32(_player->GetMapId()); - data << uint32(_player->GetZoneId()); + data << uint32(zone_id); SendPacket( &data ); DEBUG_LOG("New Home Position X is %f",_player->GetPositionX()); DEBUG_LOG("New Home Position Y is %f",_player->GetPositionY()); DEBUG_LOG("New Home Position Z is %f",_player->GetPositionZ()); DEBUG_LOG("New Home MapId is %u",_player->GetMapId()); - DEBUG_LOG("New Home ZoneId is %u",_player->GetZoneId()); + DEBUG_LOG("New Home ZoneId is %u",zone_id); // zone update data.Initialize( SMSG_PLAYERBOUND, 8+4 ); data << uint64(_player->GetGUID()); - data << uint32(_player->GetZoneId()); + data << uint32(zone_id); SendPacket( &data ); _player->PlayerTalkClass->CloseGossip(); diff --git a/src/game/Object.cpp b/src/game/Object.cpp index c4c8cea87..486d5b214 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1048,6 +1048,11 @@ uint32 WorldObject::GetAreaId() const return MapManager::Instance().GetBaseMap(m_mapId)->GetAreaId(m_positionX,m_positionY,m_positionZ); } +void WorldObject::GetZoneAndAreaId(uint32& zoneid, uint32& areaid) const +{ + MapManager::Instance().GetBaseMap(m_mapId)->GetZoneAndAreaId(zoneid,areaid,m_positionX,m_positionY,m_positionZ); +} + InstanceData* WorldObject::GetInstanceData() { Map *map = GetMap(); diff --git a/src/game/Object.h b/src/game/Object.h index 8786ba611..03e329b0d 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -414,6 +414,7 @@ class MANGOS_DLL_SPEC WorldObject : public Object uint32 GetZoneId() const; uint32 GetAreaId() const; + void GetZoneAndAreaId(uint32& zoneid, uint32& areaid) const; InstanceData* GetInstanceData(); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index af71a306d..65a3cf2b2 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -1242,14 +1242,15 @@ void Player::Update( uint32 p_time ) { if(p_time >= m_zoneUpdateTimer) { - uint32 newzone = GetZoneId(); + uint32 newzone, newarea; + GetZoneAndAreaId(newzone,newarea); + if( m_zoneUpdateId != newzone ) - UpdateZone(newzone); // also update area + UpdateZone(newzone,newarea); // also update area else { // use area updates as well // needed for free far all arenas for example - uint32 newarea = GetAreaId(); if( m_areaUpdateId != newarea ) UpdateArea(newarea); @@ -1653,16 +1654,19 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati } } + uint32 newzone, newarea; + GetZoneAndAreaId(newzone,newarea); + if(!GetSession()->PlayerLogout()) { // don't reset teleport semaphore while logging out, otherwise m_teleport_dest won't be used in Player::SaveToDB SetSemaphoreTeleport(false); - UpdateZone(GetZoneId()); + UpdateZone(newzone,newarea); } // new zone - if(old_zone != GetZoneId()) + if(old_zone != newzone) { // honorless target if(pvpInfo.inHostileArea) @@ -3941,7 +3945,9 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness) } // trigger update zone for alive state zone updates - UpdateZone(GetZoneId()); + uint32 newzone, newarea; + GetZoneAndAreaId(newzone,newarea); + UpdateZone(newzone,newarea); // update visibility ObjectAccessor::UpdateVisibilityForPlayer(this); @@ -6378,13 +6384,16 @@ void Player::UpdateArea(uint32 newArea) UpdateAreaDependentAuras(newArea); } -void Player::UpdateZone(uint32 newZone) +void Player::UpdateZone(uint32 newZone, uint32 newArea) { + if(m_zoneUpdateId != newZone) + SendInitWorldStates(newZone, newArea); // only if really enters to new zone, not just area change, works strange... + m_zoneUpdateId = newZone; m_zoneUpdateTimer = ZONE_UPDATE_INTERVAL; // zone changed, so area changed as well, update it - UpdateArea(GetAreaId()); + UpdateArea(newArea); AreaTableEntry const* zone = GetAreaEntryByAreaID(newZone); if(!zone) @@ -7742,15 +7751,15 @@ void Player::SendUpdateWorldState(uint32 Field, uint32 Value) GetSession()->SendPacket(&data); } -void Player::SendInitWorldStates() +void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid) { // data depends on zoneid/mapid... BattleGround* bg = GetBattleGround(); uint16 NumberOfFields = 0; uint32 mapid = GetMapId(); - uint32 zoneid = GetZoneId(); - uint32 areaid = GetAreaId(); + sLog.outDebug("Sending SMSG_INIT_WORLD_STATES to Map:%u, Zone: %u", mapid, zoneid); + // may be exist better way to do this... switch(zoneid) { @@ -12736,8 +12745,8 @@ void Player::AddQuest( Quest const *pQuest, Object *questGiver ) SpellAreaForQuestMapBounds saBounds = spellmgr.GetSpellAreaForQuestMapBounds(quest_id,true); if(saBounds.first != saBounds.second) { - uint32 zone = GetZoneId(); - uint32 area = GetAreaId(); + uint32 zone, area; + GetZoneAndAreaId(zone,area); for(SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr) if(itr->second->autocast && itr->second->IsFitToRequirements(this,zone,area)) @@ -12951,8 +12960,7 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver SpellAreaForQuestMapBounds saEndBounds = spellmgr.GetSpellAreaForQuestEndMapBounds(quest_id); if(saEndBounds.first != saEndBounds.second) { - uint32 zone = GetZoneId(); - uint32 area = GetAreaId(); + GetZoneAndAreaId(zone,area); for(SpellAreaForAreaMap::const_iterator itr = saEndBounds.first; itr != saEndBounds.second; ++itr) if(!itr->second->IsFitToRequirements(this,zone,area)) @@ -12963,8 +12971,8 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver SpellAreaForQuestMapBounds saBounds = spellmgr.GetSpellAreaForQuestMapBounds(quest_id,false); if(saBounds.first != saBounds.second) { - if(!zone) zone = GetZoneId(); - if(!area) area = GetAreaId(); + if(!zone || !area) + GetZoneAndAreaId(zone,area); for(SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr) if(itr->second->autocast && itr->second->IsFitToRequirements(this,zone,area)) @@ -18343,8 +18351,11 @@ void Player::SendInitialPacketsBeforeAddToMap() SendInitialActionButtons(); SendInitialReputations(); m_achievementMgr.SendAllAchievementData(); - UpdateZone(GetZoneId()); - SendInitWorldStates(); + + // update zone + uint32 newzone, newarea; + GetZoneAndAreaId(newzone,newarea); + UpdateZone(newzone,newarea); // also call SendInitWorldStates(); // SMSG_SET_AURA_SINGLE diff --git a/src/game/Player.h b/src/game/Player.h index 63681ada0..d224c5bd6 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1536,7 +1536,7 @@ class MANGOS_DLL_SPEC Player : public Unit PvPInfo pvpInfo; void UpdatePvP(bool state, bool ovrride=false); - void UpdateZone(uint32 newZone); + void UpdateZone(uint32 newZone,uint32 newArea); void UpdateArea(uint32 newArea); void UpdateZoneDependentAuras( uint32 zone_id ); // zones @@ -1856,7 +1856,7 @@ class MANGOS_DLL_SPEC Player : public Unit void CastItemCombatSpell(Item *item,Unit* Target, WeaponAttackType attType); void CastItemUseSpell(Item *item,SpellCastTargets const& targets,uint8 cast_count, uint32 glyphIndex); - void SendInitWorldStates(); + void SendInitWorldStates(uint32 zone, uint32 area); void SendUpdateWorldState(uint32 Field, uint32 Value); void SendDirectMessage(WorldPacket *data); diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 0e99e9190..71ee209f5 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -3756,7 +3756,10 @@ uint8 Spell::CanCast(bool strict) return SPELL_FAILED_NOT_IN_ARENA; // zone check - if (uint8 res= spellmgr.GetSpellAllowedInLocationError(m_spellInfo,m_caster->GetMapId(),m_caster->GetZoneId(),m_caster->GetAreaId(), + uint32 zone, area; + m_caster->GetZoneAndAreaId(zone,area); + + if (uint8 res= spellmgr.GetSpellAllowedInLocationError(m_spellInfo,m_caster->GetMapId(),zone,area, m_caster->GetTypeId()==TYPEID_PLAYER ? ((Player*)m_caster) : NULL)) return res; diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 0f6cae650..8e4c19084 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -2389,8 +2389,8 @@ void Aura::HandleAuraDummy(bool apply, bool Real) SpellAreaForAreaMapBounds saBounds = spellmgr.GetSpellAreaForAuraMapBounds(GetId()); if(saBounds.first != saBounds.second) { - uint32 zone = m_target->GetZoneId(); - uint32 area = m_target->GetAreaId(); + uint32 zone, area; + m_target->GetZoneAndAreaId(zone,area); for(SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr) { @@ -6678,8 +6678,8 @@ void Aura::HandlePhase(bool apply, bool Real) SpellAreaForAreaMapBounds saBounds = spellmgr.GetSpellAreaForAuraMapBounds(GetId()); if(saBounds.first != saBounds.second) { - uint32 zone = m_target->GetZoneId(); - uint32 area = m_target->GetAreaId(); + uint32 zone, area; + m_target->GetZoneAndAreaId(zone,area); for(SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index b4cca7098..96986cb2e 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 "7439" + #define REVISION_NR "7440" #endif // __REVISION_NR_H__