diff options
-rw-r--r-- | src/game/Level2.cpp | 19 | ||||
-rw-r--r-- | src/game/Level3.cpp | 79 | ||||
-rw-r--r-- | src/game/LootMgr.cpp | 1 | ||||
-rw-r--r-- | src/game/LootMgr.h | 1 | ||||
-rw-r--r-- | src/game/Map.cpp | 50 | ||||
-rw-r--r-- | src/game/Map.h | 20 | ||||
-rw-r--r-- | src/game/MapInstanced.cpp | 90 | ||||
-rw-r--r-- | src/game/MapInstanced.h | 8 | ||||
-rw-r--r-- | src/game/MapManager.cpp | 49 | ||||
-rw-r--r-- | src/game/MapManager.h | 1 |
10 files changed, 180 insertions, 138 deletions
diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index 3c2a7bf8f1d..f86553dd99b 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -40,7 +40,7 @@ #include <fstream> #include <map> #include "GlobalEvents.h" -#include "OutdoorPvPWG.h" +#include "Wintergrasp.h" #include "OutdoorPvPMgr.h" #include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand @@ -4240,7 +4240,7 @@ bool ChatHandler::HandleNpcSetLinkCommand(const char* args) bool ChatHandler::HandleWintergraspStatusCommand(const char* args) { - OutdoorPvPWG *pvpWG = (OutdoorPvPWG*)sOutdoorPvPMgr.GetOutdoorPvPToZoneId(4197); + OPvPWintergrasp *pvpWG = (OPvPWintergrasp*)sOutdoorPvPMgr.GetOutdoorPvPToZoneId(4197); if (!pvpWG || !sWorld.getConfig(CONFIG_OUTDOORPVP_WINTERGRASP_ENABLED)) { @@ -4250,7 +4250,7 @@ bool ChatHandler::HandleWintergraspStatusCommand(const char* args) } PSendSysMessage(LANG_BG_WG_STATUS, objmgr.GetTrinityStringForDBCLocale( - pvpWG->getDefenderTeam() == TEAM_ALLIANCE ? LANG_BG_AB_ALLY : LANG_BG_AB_HORDE), + pvpWG->GetTeam() == TEAM_ALLIANCE ? LANG_BG_AB_ALLY : LANG_BG_AB_HORDE), secsToTimeString(pvpWG->GetTimer(), true).c_str(), pvpWG->isWarTime() ? "Yes" : "No", pvpWG->GetNumPlayersH(), @@ -4260,7 +4260,7 @@ bool ChatHandler::HandleWintergraspStatusCommand(const char* args) bool ChatHandler::HandleWintergraspStartCommand(const char* args) { - OutdoorPvPWG *pvpWG = (OutdoorPvPWG*)sOutdoorPvPMgr.GetOutdoorPvPToZoneId(4197); + OPvPWintergrasp *pvpWG = (OPvPWintergrasp*)sOutdoorPvPMgr.GetOutdoorPvPToZoneId(4197); if (!pvpWG || !sWorld.getConfig(CONFIG_OUTDOORPVP_WINTERGRASP_ENABLED)) { @@ -4275,7 +4275,7 @@ bool ChatHandler::HandleWintergraspStartCommand(const char* args) bool ChatHandler::HandleWintergraspStopCommand(const char* args) { - OutdoorPvPWG *pvpWG = (OutdoorPvPWG*)sOutdoorPvPMgr.GetOutdoorPvPToZoneId(4197); + OPvPWintergrasp *pvpWG = (OPvPWintergrasp*)sOutdoorPvPMgr.GetOutdoorPvPToZoneId(4197); if (!pvpWG || !sWorld.getConfig(CONFIG_OUTDOORPVP_WINTERGRASP_ENABLED)) { @@ -4293,7 +4293,7 @@ bool ChatHandler::HandleWintergraspEnableCommand(const char* args) if(!*args) return false; - OutdoorPvPWG *pvpWG = (OutdoorPvPWG*)sOutdoorPvPMgr.GetOutdoorPvPToZoneId(4197); + OPvPWintergrasp *pvpWG = (OPvPWintergrasp*)sOutdoorPvPMgr.GetOutdoorPvPToZoneId(4197); if (!pvpWG || !sWorld.getConfig(CONFIG_OUTDOORPVP_WINTERGRASP_ENABLED)) { @@ -4335,7 +4335,7 @@ bool ChatHandler::HandleWintergraspTimerCommand(const char* args) if(!*args) return false; - OutdoorPvPWG *pvpWG = (OutdoorPvPWG*)sOutdoorPvPMgr.GetOutdoorPvPToZoneId(4197); + OPvPWintergrasp *pvpWG = (OPvPWintergrasp*)sOutdoorPvPMgr.GetOutdoorPvPToZoneId(4197); if (!pvpWG) { @@ -4361,13 +4361,14 @@ bool ChatHandler::HandleWintergraspTimerCommand(const char* args) time *= MINUTE * IN_MILISECONDS; pvpWG->setTimer((uint32)time); + PSendSysMessage(LANG_BG_WG_CHANGE_TIMER, secsToTimeString(pvpWG->GetTimer(), true).c_str()); return true; } bool ChatHandler::HandleWintergraspSwitchTeamCommand(const char* args) { - OutdoorPvPWG *pvpWG = (OutdoorPvPWG*)sOutdoorPvPMgr.GetOutdoorPvPToZoneId(4197); + OPvPWintergrasp *pvpWG = (OPvPWintergrasp*)sOutdoorPvPMgr.GetOutdoorPvPToZoneId(4197); if (!pvpWG) { @@ -4378,6 +4379,6 @@ bool ChatHandler::HandleWintergraspSwitchTeamCommand(const char* args) uint32 timer = pvpWG->GetTimer(); pvpWG->forceChangeTeam(); pvpWG->setTimer(timer); - PSendSysMessage(LANG_BG_WG_SWITCH_FACTION, GetTrinityString(pvpWG->getDefenderTeam() == TEAM_ALLIANCE ? LANG_BG_AB_ALLY : LANG_BG_AB_HORDE)); + PSendSysMessage(LANG_BG_WG_SWITCH_FACTION, GetTrinityString(pvpWG->GetTeam() == TEAM_ALLIANCE ? LANG_BG_AB_ALLY : LANG_BG_AB_HORDE)); return true; } diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index a095be0a531..35c73617b56 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -54,6 +54,7 @@ #include "InstanceData.h" #include "AuctionHouseBot.h" #include "CreatureEventAIMgr.h" +#include "DBCEnums.h" bool ChatHandler::HandleAHBotOptionsCommand(const char *args) { @@ -559,7 +560,6 @@ bool ChatHandler::HandleReloadAllCommand(const char*) HandleReloadAllLocalesCommand(""); HandleReloadAccessRequirementCommand(""); - HandleReloadMailLevelRewardCommand(""); HandleReloadCommandCommand(""); HandleReloadReservedNameCommand(""); HandleReloadTrinityStringCommand(""); @@ -881,12 +881,12 @@ bool ChatHandler::HandleReloadLootTemplatesProspectingCommand(const char*) return true; } -bool ChatHandler::HandleReloadLootTemplatesMailCommand(const char*) +bool ChatHandler::HandleReloadLootTemplatesQuestMailCommand(const char*) { - sLog.outString( "Re-Loading Loot Tables... (`mail_loot_template`)" ); - LoadLootTemplates_Mail(); - LootTemplates_Mail.CheckLootRefs(); - SendGlobalSysMessage("DB table `mail_loot_template` reloaded."); + sLog.outString( "Re-Loading Loot Tables... (`quest_mail_loot_template`)" ); + LoadLootTemplates_QuestMail(); + LootTemplates_QuestMail.CheckLootRefs(); + SendGlobalGMSysMessage("DB table `quest_mail_loot_template` reloaded."); return true; } @@ -1366,14 +1366,6 @@ bool ChatHandler::HandleReloadLocalesQuestCommand(const char* /*arg*/) return true; } -bool ChatHandler::HandleReloadMailLevelRewardCommand(const char* /*arg*/) -{ - sLog.outString( "Re-Loading Player level dependent mail rewards..." ); - objmgr.LoadMailLevelRewards(); - SendGlobalSysMessage("DB table `mail_level_reward` reloaded."); - return true; -} - bool ChatHandler::HandleLoadScriptsCommand(const char *args) { if(!LoadScriptingModule(args)) return true; @@ -3108,9 +3100,7 @@ bool ChatHandler::HandleGameObjectStateCommand(const char *args) gobj->SendObjectDeSpawnAnim(gobj->GetGUID()); else if(type == -2) { - WorldPacket data(SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE, 8); - data << gobj->GetGUID(); - gobj->SendMessageToSet(&data,true); + return false; } return true; } @@ -3933,7 +3923,7 @@ bool ChatHandler::HandleLookupMapCommand(const char *args) if(!*args) return false; - std::string namepart = args; + /*std::string namepart = args; std::wstring wnamepart; // converting string that we try to find to lower case @@ -4000,6 +3990,7 @@ bool ChatHandler::HandleLookupMapCommand(const char *args) ss << GetTrinityString(LANG_HEROIC); uint32 ResetTimeRaid = MapInfo->resetTimeRaid; + std::string ResetTimeRaidStr; if(ResetTimeRaid) ResetTimeRaidStr = secsToTimeString(ResetTimeRaid, true, false); @@ -4029,7 +4020,7 @@ bool ChatHandler::HandleLookupMapCommand(const char *args) if(!found) SendSysMessage(LANG_COMMAND_NOMAPFOUND); - + */ return true; } @@ -5410,6 +5401,14 @@ bool ChatHandler::HandleServerShutDownCommand(const char *args) char* time_str = strtok ((char*) args, " "); char* exitcode_str = strtok (NULL, ""); + char* tailStr = *args!='"' ? strtok(NULL, "") : (char*)args; + if(!tailStr) + return false; + + char* reason = extractQuotedArg(tailStr); + if(!reason) + return false; + int32 time = atoi (time_str); ///- Prevent interpret wrong arg value as 0 secs shutdown time @@ -5675,7 +5674,7 @@ bool ChatHandler::HandleQuestComplete(const char *args) } // Add quest items for quests that require items - for (uint8 x = 0; x < QUEST_OBJECTIVES_COUNT; ++x) + for (uint8 x = 0; x < QUEST_ITEM_OBJECTIVES_COUNT; ++x) { uint32 id = pQuest->ReqItemId[x]; uint32 count = pQuest->ReqItemCount[x]; @@ -6800,14 +6799,14 @@ bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/) Player* player = getSelectedPlayer(); if (!player) player = m_session->GetPlayer(); uint32 counter = 0; - for (uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i) + for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) { - Player::BoundInstancesMap &binds = player->GetBoundInstances(i); + Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i)); for (Player::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr) { InstanceSave *save = itr->second.save; std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); - PSendSysMessage("map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str()); + PSendSysMessage("map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str()); counter++; } } @@ -6816,15 +6815,14 @@ bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/) Group *group = player->GetGroup(); if(group) { - for (uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i) + for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) { - Group::BoundInstancesMap &binds = group->GetBoundInstances(i); + Group::BoundInstancesMap &binds = group->GetBoundInstances(Difficulty(i)); for (Group::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr) { InstanceSave *save = itr->second.save; std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); - PSendSysMessage("map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str()); - counter++; + PSendSysMessage("map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str()); counter++; } } } @@ -6844,17 +6842,17 @@ bool ChatHandler::HandleInstanceUnbindCommand(const char *args) Player* player = getSelectedPlayer(); if (!player) player = m_session->GetPlayer(); uint32 counter = 0; - for (uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i) + for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) { - Player::BoundInstancesMap &binds = player->GetBoundInstances(i); + Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i)); for (Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();) { if(itr->first != player->GetMapId()) { InstanceSave *save = itr->second.save; std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); - PSendSysMessage("unbinding map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str()); - player->UnbindInstance(itr, i); + PSendSysMessage("unbinding map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str()); + player->UnbindInstance(itr, Difficulty(i)); counter++; } else @@ -7102,23 +7100,25 @@ bool ChatHandler::HandleSendItemsCommand(const char *args) } // from console show not existed sender - MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM); + uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0; + uint32 messagetype = MAIL_NORMAL; + uint32 stationery = MAIL_STATIONERY_GM; uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0; // fill mail - MailDraft draft(subject, itemTextId); + MailItemsInfo mi; // item list preparing for (ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr) { if(Item* item = Item::CreateItem(itr->first,itr->second,m_session ? m_session->GetPlayer() : 0)) { item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted - draft.AddItem(item); + mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item); } } - draft.SendMailTo(MailReceiver(receiver,GUID_LOPART(receiver_guid)), sender); + WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_NONE); std::string nameLink = playerLink(receiver_name); PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); @@ -7162,13 +7162,13 @@ bool ChatHandler::HandleSendMoneyCommand(const char *args) std::string text = msgText; // from console show not existed sender - MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM); + uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0; + uint32 messagetype = MAIL_NORMAL; + uint32 stationery = MAIL_STATIONERY_GM; uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0; - MailDraft(subject, itemTextId) - .AddMoney(money) - .SendMailTo(MailReceiver(receiver,GUID_LOPART(receiver_guid)),sender); + WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, NULL, money, 0, MAIL_CHECK_MASK_NONE); std::string nameLink = playerLink(receiver_name); PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); @@ -7537,4 +7537,3 @@ bool ChatHandler::HandleUnbindSightCommand(const char *args) m_session->GetPlayer()->StopCastingBindSight(); return true; } - diff --git a/src/game/LootMgr.cpp b/src/game/LootMgr.cpp index 2cfd92f11fc..809df7e9e51 100644 --- a/src/game/LootMgr.cpp +++ b/src/game/LootMgr.cpp @@ -1449,4 +1449,3 @@ void LoadLootTemplates_Reference() // output error for any still listed ids (not referenced from any loot table) LootTemplates_Reference.ReportUnusedIds(ids_set); } - diff --git a/src/game/LootMgr.h b/src/game/LootMgr.h index bcd9b564904..5b383b5265b 100644 --- a/src/game/LootMgr.h +++ b/src/game/LootMgr.h @@ -365,4 +365,3 @@ inline void LoadLootTables() } #endif - diff --git a/src/game/Map.cpp b/src/game/Map.cpp index a34ce673d9a..5a72c6ed8f0 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -38,6 +38,7 @@ #include "MapRefManager.h" #include "Vehicle.h" #include "WaypointManager.h" +#include "DBCEnums.h" #include "MapInstanced.h" #include "InstanceSaveMgr.h" @@ -217,12 +218,12 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _par { m_notifyTimer.SetInterval(IN_MILISECONDS/2); - for (uint8 idx = 0; idx < MAX_NUMBER_OF_GRIDS; ++idx) + for (unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx) { - for (uint8 j = 0; j < MAX_NUMBER_OF_GRIDS; ++j) + for (unsigned int j=0; j < MAX_NUMBER_OF_GRIDS; ++j) { //z code - GridMaps[idx][j] = NULL; + GridMaps[idx][j] =NULL; setNGrid(NULL, idx, j); } } @@ -2384,6 +2385,7 @@ void Map::RemoveAllObjectsInRemoveList() i_objectsToRemove.erase(itr); } + //sLog.outDebug("Object remover 2 check."); } @@ -2584,11 +2586,11 @@ bool InstanceMap::Add(Player *player) if(!mapSave) { sLog.outDetail("InstanceMap::Add: creating instance save for map %d spawnmode %d with instance id %d", GetId(), GetSpawnMode(), GetInstanceId()); - mapSave = sInstanceSaveManager.AddInstanceSave(GetId(), GetInstanceId(), GetSpawnMode(), 0, true); + mapSave = sInstanceSaveManager.AddInstanceSave(GetId(), GetInstanceId(), Difficulty(GetSpawnMode()), 0, true); } // check for existing instance binds - InstancePlayerBind *playerBind = player->GetBoundInstance(GetId(), GetSpawnMode()); + InstancePlayerBind *playerBind = player->GetBoundInstance(GetId(), Difficulty(GetSpawnMode())); if(playerBind && playerBind->perm) { // cannot enter other instances if bound permanently @@ -2604,7 +2606,7 @@ bool InstanceMap::Add(Player *player) if(pGroup) { // solo saves should be reset when entering a group - InstanceGroupBind *groupBind = pGroup->GetBoundInstance(GetId(), GetSpawnMode()); + InstanceGroupBind *groupBind = pGroup->GetBoundInstance(this); if(playerBind) { sLog.outError("InstanceMap::Add: player %s(%d) is being put in instance %d,%d,%d,%d,%d,%d but he is in group %d and is bound to instance %d,%d,%d,%d,%d,%d!", player->GetName(), player->GetGUIDLow(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset(), GUID_LOPART(pGroup->GetLeaderGUID()), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset()); @@ -2811,7 +2813,7 @@ void InstanceMap::UnloadAll() void InstanceMap::SendResetWarnings(uint32 timeLeft) const { for (MapRefManager::const_iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr) - itr->getSource()->SendInstanceResetWarning(GetId(), itr->getSource()->GetDifficulty(), timeLeft); + itr->getSource()->SendInstanceResetWarning(GetId(), itr->getSource()->GetDifficulty(IsRaid()), timeLeft); } void InstanceMap::SetResetSchedule(bool on) @@ -2819,26 +2821,45 @@ void InstanceMap::SetResetSchedule(bool on) // only for normal instances // the reset time is only scheduled when there are no payers inside // it is assumed that the reset time will rarely (if ever) change while the reset is scheduled - if (IsDungeon() && !HavePlayers() && !IsRaid() && !IsHeroic()) + if(IsDungeon() && !HavePlayers() && !IsRaidOrHeroicDungeon()) { InstanceSave *save = sInstanceSaveManager.GetInstanceSave(GetInstanceId()); if (!save) sLog.outError("InstanceMap::SetResetSchedule: cannot turn schedule %s, no save available for instance %d of %d", on ? "on" : "off", GetInstanceId(), GetId()); - else sInstanceSaveManager.ScheduleReset(on, save->GetResetTime(), InstanceSaveManager::InstResetEvent(0, GetId(), GetInstanceId())); + else sInstanceSaveManager.ScheduleReset(on, save->GetResetTime(), InstanceSaveManager::InstResetEvent(0, GetId(), Difficulty(GetSpawnMode()), GetInstanceId())); } } +MapDifficulty const* InstanceMap::GetMapDifficulty() const +{ + return GetMapDifficultyData(GetId(),GetDifficulty()); +} + uint32 InstanceMap::GetMaxPlayers() const { - InstanceTemplate const* iTemplate = objmgr.GetInstanceTemplate(GetId()); - if (!iTemplate) + if(MapDifficulty const* mapDiff = GetMapDifficulty()) + { + if(mapDiff->maxPlayers || IsRegularDifficulty()) // Normal case (expect that regular difficulty always have correct maxplayers) + return mapDiff->maxPlayers; + else // DBC have 0 maxplayers for heroic instances with expansion < 2 + { // The heroic entry exists, so we don't have to check anything, simply return normal max players + MapDifficulty const* normalDiff = GetMapDifficultyData(GetId(), REGULAR_DIFFICULTY); + return normalDiff ? normalDiff->maxPlayers : 0; + } + } + else // I'd rather assert(false); return 0; - return IsHeroic() ? iTemplate->maxPlayersHeroic : iTemplate->maxPlayers; +} + +uint32 InstanceMap::GetMaxResetDelay() const +{ + MapDifficulty const* mapDiff = GetMapDifficulty(); + return mapDiff ? mapDiff->resetTime : 0; } /* ******* Battleground Instance Maps ******* */ -BattleGroundMap::BattleGroundMap(uint32 id, time_t expiry, uint32 InstanceId, Map* _parent) - : Map(id, expiry, InstanceId, DIFFICULTY_NORMAL, _parent) +BattleGroundMap::BattleGroundMap(uint32 id, time_t expiry, uint32 InstanceId, Map* _parent, uint8 spawnMode) + : Map(id, expiry, InstanceId, spawnMode, _parent) { //lets initialize visibility distance for BG/Arenas BattleGroundMap::InitVisibilityDistance(); @@ -3789,4 +3810,3 @@ void Map::UpdateIteratorBack(Player *player) if(m_mapRefIter == player->GetMapRef()) m_mapRefIter = m_mapRefIter->nocheck_prev(); } - diff --git a/src/game/Map.h b/src/game/Map.h index fa4e7a03468..981a48bbbb6 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -51,6 +51,7 @@ class CreatureGroup; struct ScriptInfo; struct ScriptAction; struct Position; +class BattleGround; typedef ACE_RW_Thread_Mutex GridRWLock; @@ -229,9 +230,6 @@ struct InstanceTemplate { uint32 map; uint32 parent; - uint32 maxPlayers; - uint32 maxPlayersHeroic; - uint32 reset_delay; // FIX ME: now exist normal/heroic raids with possible different time of reset. uint32 access_id; float startLocX; float startLocY; @@ -383,7 +381,8 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj // NOTE: this duplicate of Instanceable(), but Instanceable() can be changed when BG also will be instanceable bool IsDungeon() const { return i_mapEntry && i_mapEntry->IsDungeon(); } bool IsRaid() const { return i_mapEntry && i_mapEntry->IsRaid(); } - bool IsHeroic() const { return i_spawnMode == DIFFICULTY_HEROIC; } + bool IsRaidOrHeroicDungeon() const { return IsRaid() || i_spawnMode > DUNGEON_DIFFICULTY_NORMAL; } + bool IsHeroic() const { return IsRaid() ? i_spawnMode >= RAID_DIFFICULTY_10MAN_HEROIC : i_spawnMode >= DUNGEON_DIFFICULTY_HEROIC; } bool IsBattleGround() const { return i_mapEntry && i_mapEntry->IsBattleGround(); } bool IsBattleArena() const { return i_mapEntry && i_mapEntry->IsBattleArena(); } bool IsBattleGroundOrArena() const { return i_mapEntry && i_mapEntry->IsBattleGroundOrArena(); } @@ -610,7 +609,13 @@ class TRINITY_DLL_SPEC InstanceMap : public Map bool CanEnter(Player* player); void SendResetWarnings(uint32 timeLeft) const; void SetResetSchedule(bool on); + + // have meaning only for instanced map (that have set real difficulty) + Difficulty GetDifficulty() const { return Difficulty(GetSpawnMode()); } + bool IsRegularDifficulty() const { return GetDifficulty() == REGULAR_DIFFICULTY; } uint32 GetMaxPlayers() const; + uint32 GetMaxResetDelay() const; + MapDifficulty const* GetMapDifficulty() const; virtual void InitVisibilityDistance(); private: @@ -623,7 +628,7 @@ class TRINITY_DLL_SPEC InstanceMap : public Map class TRINITY_DLL_SPEC BattleGroundMap : public Map { public: - BattleGroundMap(uint32 id, time_t, uint32 InstanceId, Map* _parent); + BattleGroundMap(uint32 id, time_t, uint32 InstanceId, Map* _parent, uint8 spawnMode); ~BattleGroundMap(); bool Add(Player *); @@ -634,6 +639,10 @@ class TRINITY_DLL_SPEC BattleGroundMap : public Map void RemoveAllPlayers(); virtual void InitVisibilityDistance(); + BattleGround* GetBG() { return m_bg; } + void SetBG(BattleGround* bg) { m_bg = bg; } + private: + BattleGround* m_bg; }; /*inline @@ -710,4 +719,3 @@ Map::VisitGrid(const float &x, const float &y, float radius, NOTIFIER ¬ifier) cell_lock->Visit(cell_lock, grid_object_notifier, *this, radius, x_off, y_off); } #endif - diff --git a/src/game/MapInstanced.cpp b/src/game/MapInstanced.cpp index c77e40cb8f9..2fd9564a263 100644 --- a/src/game/MapInstanced.cpp +++ b/src/game/MapInstanced.cpp @@ -26,7 +26,7 @@ #include "InstanceSaveMgr.h" #include "World.h" -MapInstanced::MapInstanced(uint32 id, time_t expiry) : Map(id, expiry, 0, 0) +MapInstanced::MapInstanced(uint32 id, time_t expiry) : Map(id, expiry, 0, DUNGEON_DIFFICULTY_NORMAL) { // initialize instanced maps list m_InstancedMaps.clear(); @@ -40,7 +40,9 @@ void MapInstanced::InitVisibilityDistance() return; //initialize visibility distances for all instance copies for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); ++i) + { (*i).second->InitVisibilityDistance(); + } } void MapInstanced::Update(const uint32& t) @@ -118,46 +120,63 @@ void MapInstanced::UnloadAll() - create the instance if it's not created already - the player is not actually added to the instance (only in InstanceMap::Add) */ -Map* MapInstanced::CreateInstance(const uint32 mapId, Player * player, uint32 instanceId) +Map* MapInstanced::CreateInstance(const uint32 mapId, Player * player) { - if(instanceId) - if(Map *map = _FindMap(instanceId)) - return map; + if(GetId() != mapId || !player) + return NULL; + + Map* map = NULL; + uint32 NewInstanceId = 0; // instanceId of the resulting map if(IsBattleGroundOrArena()) { - instanceId = player->GetBattleGroundId(); - if(instanceId) - if(Map *map = _FindMap(instanceId)) - return map; - return CreateBattleGround(instanceId); + // instantiate or find existing bg map for player + // the instance id is set in battlegroundid + NewInstanceId = player->GetBattleGroundId(); + if(!NewInstanceId) return NULL; + map = _FindMap(NewInstanceId); + if(!map) + map = CreateBattleGround(NewInstanceId, player->GetBattleGround()); } - else if(InstanceSave *pSave = player->GetInstanceSave(GetId())) + else { - if(!instanceId) + InstancePlayerBind *pBind = player->GetBoundInstance(GetId(), player->GetDifficulty(IsRaid())); + InstanceSave *pSave = pBind ? pBind->save : NULL; + + // the player's permanent player bind is taken into consideration first + // then the player's group bind and finally the solo bind. + if(!pBind || !pBind->perm) { - instanceId = pSave->GetInstanceId(); // go from outside to instance - if(Map *map = _FindMap(instanceId)) - return map; + InstanceGroupBind *groupBind = NULL; + Group *group = player->GetGroup(); + // use the player's difficulty setting (it may not be the same as the group's) + if(group && (groupBind = group->GetBoundInstance(this))) + pSave = groupBind->save; } - else if(instanceId != pSave->GetInstanceId()) // cannot go from one instance to another - return NULL; - // else log in at a saved instance - - return CreateInstance(instanceId, pSave, pSave->GetDifficulty()); - } - else if(!player->GetSession()->PlayerLoading()) - { - if(!instanceId) - instanceId = MapManager::Instance().GenerateInstanceId(); + if(pSave) + { + // solo/perm/group + NewInstanceId = pSave->GetInstanceId(); + map = _FindMap(NewInstanceId); + // it is possible that the save exists but the map doesn't + if(!map) + map = CreateInstance(NewInstanceId, pSave, pSave->GetDifficulty()); + } + else + { + // if no instanceId via group members or instance saves is found + // the instance will be created for the first time + NewInstanceId = MapManager::Instance().GenerateInstanceId(); - return CreateInstance(instanceId, NULL, player->GetDifficulty()); + Difficulty diff = player->GetGroup() ? player->GetGroup()->GetDifficulty(IsRaid()) : player->GetDifficulty(IsRaid()); + map = CreateInstance(NewInstanceId, NULL, diff); + } } - return NULL; + return map; } -InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave *save, uint8 difficulty) +InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave *save, Difficulty difficulty) { // load/create a map Guard guard(*this); @@ -177,7 +196,9 @@ InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave *save, } // some instances only have one difficulty - if (entry && !entry->SupportsHeroicMode()) difficulty = DIFFICULTY_NORMAL; + MapDifficulty const* mapDiff = GetMapDifficultyData(GetId(),difficulty); + if (!mapDiff) + difficulty = DUNGEON_DIFFICULTY_NORMAL; sLog.outDebug("MapInstanced::CreateInstance: %s map instance %d for %d created with difficulty %s", save?"":"new ", InstanceId, GetId(), difficulty?"heroic":"normal"); @@ -191,15 +212,21 @@ InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave *save, return map; } -BattleGroundMap* MapInstanced::CreateBattleGround(uint32 InstanceId) +BattleGroundMap* MapInstanced::CreateBattleGround(uint32 InstanceId, BattleGround* bg) { // load/create a map Guard guard(*this); sLog.outDebug("MapInstanced::CreateBattleGround: map bg %d for %d created.", InstanceId, GetId()); - BattleGroundMap *map = new BattleGroundMap(GetId(), GetGridExpiry(), InstanceId, this); + // 0-59 normal spawn 60-69 difficulty_1, 70-79 difficulty_2, 80 dufficulty_3 + uint8 spawnMode = (bg->GetQueueId() > QUEUE_ID_MAX_LEVEL_59) ? (bg->GetQueueId() - QUEUE_ID_MAX_LEVEL_59) : 0; + while (!GetMapDifficultyData(GetId(), Difficulty(spawnMode))) + spawnMode--; + BattleGroundMap *map = new BattleGroundMap(GetId(), GetGridExpiry(), InstanceId, this, spawnMode); ASSERT(map->IsBattleGroundOrArena()); + map->SetBG(bg); + bg->SetBgMap(map); m_InstancedMaps[InstanceId] = map; return map; @@ -235,4 +262,3 @@ bool MapInstanced::CanEnter(Player *player) //assert(false); return true; } - diff --git a/src/game/MapInstanced.h b/src/game/MapInstanced.h index 22622d362ce..90aa5f5508e 100644 --- a/src/game/MapInstanced.h +++ b/src/game/MapInstanced.h @@ -23,6 +23,7 @@ #include "Map.h" #include "InstanceSaveMgr.h" +#include "DBCEnums.h" class TRINITY_DLL_DECL MapInstanced : public Map { @@ -41,7 +42,7 @@ class TRINITY_DLL_DECL MapInstanced : public Map void UnloadAll(); bool CanEnter(Player* player); - Map* CreateInstance(const uint32 mapId, Player * player, uint32 instanceId); + Map* CreateInstance(const uint32 mapId, Player * player); Map* FindMap(uint32 InstanceId) const { return _FindMap(InstanceId); } bool DestroyInstance(InstancedMaps::iterator &itr); @@ -63,8 +64,8 @@ class TRINITY_DLL_DECL MapInstanced : public Map private: - InstanceMap* CreateInstance(uint32 InstanceId, InstanceSave *save, uint8 difficulty); - BattleGroundMap* CreateBattleGround(uint32 InstanceId); + InstanceMap* CreateInstance(uint32 InstanceId, InstanceSave *save, Difficulty difficulty); + BattleGroundMap* CreateBattleGround(uint32 InstanceId, BattleGround* bg); InstancedMaps m_InstancedMaps; @@ -77,4 +78,3 @@ class TRINITY_DLL_DECL MapInstanced : public Map uint16 GridMapReference[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS]; }; #endif - diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp index 5121b9dc574..d1457b5adee 100644 --- a/src/game/MapManager.cpp +++ b/src/game/MapManager.cpp @@ -82,7 +82,7 @@ MapManager::Initialize() void MapManager::InitializeVisibilityDistanceInfo() { - for (MapMapType::iterator iter = i_maps.begin(); iter != i_maps.end(); ++iter) + for (MapMapType::iterator iter=i_maps.begin(); iter != i_maps.end(); ++iter) (*iter).second->InitVisibilityDistance(); } @@ -90,9 +90,9 @@ void MapManager::InitializeVisibilityDistanceInfo() void MapManager::checkAndCorrectGridStatesArray() { bool ok = true; - for (uint8 i = 0; i < MAX_GRID_STATE; ++i) + for (int i=0; i<MAX_GRID_STATE; i++) { - if (i_GridStates[i] != si_GridStates[i]) + if(i_GridStates[i] != si_GridStates[i]) { sLog.outError("MapManager::checkGridStates(), GridState: si_GridStates is currupt !!!"); ok = false; @@ -107,10 +107,8 @@ void MapManager::checkAndCorrectGridStatesArray() } #endif } - if (!ok) + if(!ok) ++i_GridStateErrorCount; - if (i_GridStateErrorCount > 2) - assert(false); // force a crash. Too many errors } Map* @@ -127,13 +125,9 @@ MapManager::_createBaseMap(uint32 id) { m = new MapInstanced(id, i_gridCleanUpDelay); } - else if (entry) - { - m = new Map(id, i_gridCleanUpDelay, 0, 0); - } else { - assert(false); + m = new Map(id, i_gridCleanUpDelay, 0, REGULAR_DIFFICULTY); } i_maps[id] = m; } @@ -148,7 +142,7 @@ Map* MapManager::CreateMap(uint32 id, const WorldObject* obj, uint32 instanceId) //if(!obj->IsInWorld()) sLog.outError("GetMap: called for map %d with object (typeid %d, guid %d, mapid %d, instanceid %d) who is not in world!", id, obj->GetTypeId(), obj->GetGUIDLow(), obj->GetMapId(), obj->GetInstanceId()); Map *m = _createBaseMap(id); - if (m && (obj->GetTypeId() == TYPEID_PLAYER) && m->Instanceable()) m = ((MapInstanced*)m)->CreateInstance(id, (Player*)obj, instanceId); + if (m && (obj->GetTypeId() == TYPEID_PLAYER) && m->Instanceable()) m = ((MapInstanced*)m)->CreateInstance(id, (Player*)obj); return m; } @@ -192,14 +186,22 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player) sLog.outDebug("MAP: Player '%s' must be in a raid group to enter instance of '%s'", player->GetName(), mapName); return false; } + // Если ИК или ИЧ, то проверять уровень шмота одетого на персе. + //if(mapid==649) } } //The player has a heroic mode and tries to enter into instance which has no a heroic mode - if (!entry->SupportsHeroicMode() && player->GetDifficulty() == DIFFICULTY_HEROIC) + MapDifficulty const* mapDiff = GetMapDifficultyData(entry->MapID,player->GetDifficulty(entry->map_type == MAP_RAID)); + if (!mapDiff) { + bool isNormalTargetMap = entry->map_type == MAP_RAID + ? (player->GetRaidDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL) + : (player->GetDungeonDifficulty() == DUNGEON_DIFFICULTY_NORMAL); + //Send aborted message - player->SendTransferAborted(mapid, TRANSFER_ABORT_DIFFICULTY, DIFFICULTY_HEROIC); + // FIX ME: what about absent normal/heroic mode with specific players limit... + player->SendTransferAborted(mapid, TRANSFER_ABORT_DIFFICULTY, isNormalTargetMap ? DUNGEON_DIFFICULTY_NORMAL : DUNGEON_DIFFICULTY_HEROIC); return false; } @@ -240,13 +242,13 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player) //Get instance where player's group is bound & its map if (player->GetGroup()) { - InstanceGroupBind* boundedInstance = player->GetGroup()->GetBoundInstance(mapid, player->GetDifficulty()); + InstanceGroupBind* boundedInstance = player->GetGroup()->GetBoundInstance(player); if (boundedInstance && boundedInstance->save) { if (Map *boundedMap = MapManager::Instance().FindMap(mapid,boundedInstance->save->GetInstanceId())) { //Player permanently bounded to different instance than groups one - InstancePlayerBind* playerBoundedInstance = player->GetBoundInstance(mapid, player->GetDifficulty()); + InstancePlayerBind* playerBoundedInstance = player->GetBoundInstance(mapid, player->GetDungeonDifficulty()); if (playerBoundedInstance && playerBoundedInstance->perm && playerBoundedInstance->save && boundedInstance->save->GetInstanceId() != playerBoundedInstance->save->GetInstanceId()) { @@ -263,7 +265,8 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player) } //Instance is full - int8 maxPlayers = (player->GetDifficulty() == DIFFICULTY_HEROIC) ? instance->maxPlayersHeroic : instance->maxPlayers; + MapDifficulty const* mapDiff = ((InstanceMap*)player)->GetMapDifficulty(); + int8 maxPlayers = mapDiff ? mapDiff->maxPlayers : 0; if (maxPlayers != -1) //-1: unlimited access { if (boundedMap->GetPlayersCountExceptGMs() >= maxPlayers) @@ -336,17 +339,6 @@ MapManager::Update(uint32 diff) void MapManager::DoDelayedMovesAndRemoves() { - /* - std::vector<Map*> update_queue(i_maps.size()); - for (MapMapType::iterator iter = i_maps.begin(), uint32 i = 0; iter != i_maps.end(); ++iter, ++i) - update_queue[i] = iter->second; - - omp_set_num_threads(sWorld.getConfig(CONFIG_NUMTHREADS)); - -#pragma omp parallel for schedule(dynamic) private(i) shared(update_queue) - for (uint32 i = 0; i < i_maps.size(); ++i) - update_queue[i]->DoDelayedMovesAndRemoves(); - */ } bool MapManager::ExistMapAndVMap(uint32 mapid, float x,float y) @@ -427,4 +419,3 @@ uint32 MapManager::GetNumPlayersInInstances() } return ret; } - diff --git a/src/game/MapManager.h b/src/game/MapManager.h index 05fd3db9951..f4bc5feafa2 100644 --- a/src/game/MapManager.h +++ b/src/game/MapManager.h @@ -156,4 +156,3 @@ class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton<MapManager, MaNGOS:: MapUpdater m_updater; }; #endif - |