rendered paste bodyIndex: shared/Database/DBCfmt.cpp===================================================================--- shared/Database/DBCfmt.cpp (revision 5465)+++ shared/Database/DBCfmt.cpp (working copy)@@ -67,5 +67,5 @@ const char TaxiPathEntryfmt[]="niii"; const char TaxiPathNodeEntryfmt[]="diiifffiixx"; const char TotemCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii";-const char WorldMapAreaEntryfmt[]="xxnxffffx";+const char WorldMapAreaEntryfmt[]="xinxffffi"; const char WorldSafeLocsEntryfmt[]="nifffxxxxxxxxxxxxxxxxx";Index: shared/Database/DBCStores.cpp===================================================================--- shared/Database/DBCStores.cpp (revision 5465)+++ shared/Database/DBCStores.cpp (working copy)@@ -529,6 +529,21 @@ std::swap(x,y); // client have map coords swapped } +uint32 GetZoneVirtualMap(uint32 nZoneId)+{+ if (nZoneId == 0)+ return static_cast<uint32>(-1);++ WorldMapAreaEntry const * wma = sWorldMapAreaStore.LookupEntry(nZoneId);++ if (wma)+ return (wma->virtual_map_id != -1) ? static_cast<uint32>(wma->virtual_map_id) : wma->map_id;++ MapEntry const * map = sMapStore.LookupEntry(nZoneId);++ return map ? map->parent_map : static_cast<uint32>(-1);+}+ uint32 GetTalentInspectBitPosInTab(uint32 talentId) { TalentInspectMap::const_iterator itr = sTalentPosInInspect.find(talentId);Index: shared/Database/DBCStructure.h===================================================================--- shared/Database/DBCStructure.h (revision 5465)+++ shared/Database/DBCStructure.h (working copy)@@ -687,14 +687,14 @@ struct WorldMapAreaEntry { //uint32 ID; // 0- //uint32 map_id; // 1+ uint32 map_id; // 1 uint32 area_id; // 2 index (continent 0 areas ignored) //char* internal_name // 3 float y1; // 4 float y2; // 5 float x1; // 6 float x2; // 7- //int32 virtual_map_id; // 8 -1 (map_id have correct map) other: virtual map where zone show (map_id - where zone in fact internally)+ int32 virtual_map_id; // 8 -1 (map_id have correct map) other: virtual map where zone show (map_id - where zone in fact internally) }; struct WorldSafeLocsEntryIndex: shared/Database/DBCStores.h===================================================================--- shared/Database/DBCStores.h (revision 5465)+++ shared/Database/DBCStores.h (working copy)@@ -40,6 +40,7 @@ void Zone2MapCoordinates(float& x,float& y,uint32 zone); void Map2ZoneCoordinates(float& x,float& y,uint32 zone);+uint32 GetZoneVirtualMap(uint32 nZoneId); uint32 GetTalentInspectBitPosInTab(uint32 talentId); uint32 GetTalentTabInspectBitSize(uint32 talentTabId);Index: game/Formulas.h===================================================================--- game/Formulas.h (revision 5465)+++ game/Formulas.h (working copy)@@ -69,17 +69,18 @@ return 17; } - inline uint32 BaseGain(uint32 pl_level, uint32 mob_level)+ inline uint32 BaseGain(uint32 pl_level, uint32 mob_level, ZoneOriginType eOrigin) {+ const uint32 nBaseExp = (eOrigin == ZONE_ORIGIN_OUTLAND) ? 235 : 45; if( mob_level >= pl_level )- return ((pl_level*5 + 45) * (20 + mob_level - pl_level)/10 + 1)/2;+ return ((pl_level*5 + nBaseExp) * (20 + mob_level - pl_level)/10 + 1)/2; else { uint32 gray_level = GetGrayLevel(pl_level); if( mob_level > gray_level ) { uint32 ZD = GetZeroDifference(pl_level);- return (pl_level*5 + 45) * (ZD + mob_level - pl_level)/ZD;+ return (pl_level*5 + nBaseExp) * (ZD + mob_level - pl_level)/ZD; } return 0; }@@ -90,7 +91,7 @@ if(u->GetTypeId()==TYPEID_UNIT && ((Creature*)u)->isTotem() || ((Creature*)u)->isPet()) return 0; - uint32 xp_gain= BaseGain(pl->getLevel(), u->getLevel());+ uint32 xp_gain= BaseGain(pl->getLevel(), u->getLevel(), Map::GetZoneOrigin(u->GetZoneId(), u->GetMapId())); if( xp_gain == 0 ) return 0; Index: game/Map.h===================================================================--- game/Map.h (revision 5465)+++ game/Map.h (working copy)@@ -114,6 +114,13 @@ #define MAX_HEIGHT 100000.0f // can be use for find ground height at surface #define INVALID_HEIGHT -100000.0f // for check, must be equal to VMAP_INVALID_HEIGHT, real value for unknown height is VMAP_INVALID_HEIGHT_VALUE +enum ZoneOriginType+{+ ZONE_ORIGIN_UNKNOWN = 0,+ ZONE_ORIGIN_AZEROTH = 1,+ ZONE_ORIGIN_OUTLAND = 2+};+ class MANGOS_DLL_DECL Map : public GridRefManager<NGridType>, public MaNGOS::ObjectLevelLockable<Map, ZThread::Mutex> { public:@@ -180,6 +187,7 @@ static uint32 GetAreaId(uint16 areaflag,uint32 map_id); static uint32 GetZoneId(uint16 areaflag,uint32 map_id);+ static ZoneOriginType GetZoneOrigin(uint32 nZoneId, uint32 nRealMapId = static_cast<uint32>(-1)); uint32 GetAreaId(float x, float y) const {@@ -230,6 +238,8 @@ bool isCellMarked(uint32 pCellId) { return marked_cells.test(pCellId); } void markCell(uint32 pCellId) { marked_cells.set(pCellId); } private:+ static ZoneOriginType ComputeZoneOrigin(uint32 nZoneId, uint32 nRealMapId);+ void LoadVMap(int pX, int pY); void LoadMap(uint32 mapid, uint32 instanceid, int x,int y); @@ -282,6 +292,8 @@ typedef GridReadGuard ReadGuard; typedef GridWriteGuard WriteGuard; + static std::map<uint32, ZoneOriginType> sm_ZoneOriginCache;+ uint32 i_id; NGridType* i_grids[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS]; GridMap *GridMaps[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS];Index: game/Unit.cpp===================================================================--- game/Unit.cpp (revision 5465)+++ game/Unit.cpp (working copy)@@ -724,7 +724,8 @@ if(pet->GetTypeId()==TYPEID_UNIT && ((Creature*)pet)->isPet()) {- uint32 petxp = MaNGOS::XP::BaseGain(getLevel(), pVictim->getLevel());+ uint32 petxp = MaNGOS::XP::BaseGain(getLevel(), pVictim->getLevel(),+ PvP ? ZONE_ORIGIN_UNKNOWN : Map::GetZoneOrigin(pVictim->GetZoneId(), pVictim->GetMapId())); ((Pet*)pet)->GivePetXP(petxp); } }Index: game/Map.cpp===================================================================--- game/Map.cpp (revision 5465)+++ game/Map.cpp (working copy)@@ -44,6 +44,8 @@ GridState* si_GridStates[MAX_GRID_STATE]; +std::map<uint32, ZoneOriginType> Map::sm_ZoneOriginCache;+ Map::~Map() { UnloadAll(true);@@ -1256,6 +1258,56 @@ return 0; } +ZoneOriginType Map::GetZoneOrigin(uint32 nZoneId, uint32 nRealMapId)+{+ ZoneOriginType eZoneOrigin = ZONE_ORIGIN_UNKNOWN;++ std::map<uint32, ZoneOriginType>::const_iterator pos = sm_ZoneOriginCache.find(nZoneId);+ if (pos != sm_ZoneOriginCache.end())+ {+ eZoneOrigin = pos->second;+ }+ else+ {+ eZoneOrigin = ComputeZoneOrigin(nZoneId, nRealMapId);+ sm_ZoneOriginCache.insert(std::map<uint32, ZoneOriginType>::value_type(nZoneId, eZoneOrigin));+ }++ return eZoneOrigin;+}++ZoneOriginType Map::ComputeZoneOrigin(uint32 nZoneId, uint32 nRealMapId)+{+ if (nRealMapId == static_cast<uint32>(-1))+ {+ AreaTableEntry const * area = GetAreaEntryByAreaID(nZoneId);++ if (!area)+ return ZONE_ORIGIN_UNKNOWN;++ nRealMapId = area->mapid;+ }++ switch (nRealMapId)+ {+ case 550: // Tempest Keep: The Eye+ case 552: // Tempest Keep: The Arcatraz+ case 553: // Tempest Keep: The Botanica+ case 554: // Tempest Keep: The Mechanar+ case 559: // Nagrand Arena+ case 562: // Blade's Edge Arena+ case 566: // Eye of the Storm+ return ZONE_ORIGIN_OUTLAND;+ }++ uint32 nVirtualMapId = GetZoneVirtualMap(nZoneId);++ if (nVirtualMapId == static_cast<uint32>(-1))+ nVirtualMapId = nRealMapId;++ return (nVirtualMapId == 530) ? ZONE_ORIGIN_OUTLAND : ZONE_ORIGIN_AZEROTH;+}+ bool Map::IsInWater(float x, float y, float pZ) const { // This method is called too often to use vamps for that (4. parameter = false).