mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 04:37:00 +00:00
Use reset time for normal/heroic from new DBC. Improve basic support for raid difficalties.
This commit is contained in:
parent
9850551751
commit
a9af7f2b1c
24 changed files with 340 additions and 173 deletions
|
|
@ -196,10 +196,10 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
|
|||
}
|
||||
return true;
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY:
|
||||
if (difficalty.difficalty >= TOTAL_DUNGEON_DIFFICULTIES)
|
||||
if (difficulty.difficulty >= MAX_DIFFICULTY)
|
||||
{
|
||||
sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY (%u) have wrong difficulty in value1 (%u), ignore.",
|
||||
criteria->ID, criteria->requiredType,dataType,difficalty.difficalty);
|
||||
criteria->ID, criteria->requiredType,dataType,difficulty.difficulty);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -294,7 +294,7 @@ bool AchievementCriteriaData::Meets(Player const* source, Unit const* target, ui
|
|||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_DISABLED:
|
||||
return false; // always fail
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY:
|
||||
return source->GetMap()->GetSpawnMode()==difficalty.difficalty;
|
||||
return source->GetMap()->GetSpawnMode()==difficulty.difficulty;
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT:
|
||||
return source->GetMap()->GetPlayersCountExceptGMs() <= map_players.maxcount;
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM:
|
||||
|
|
|
|||
|
|
@ -125,8 +125,8 @@ struct AchievementCriteriaData
|
|||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY = 12
|
||||
struct
|
||||
{
|
||||
uint32 difficalty;
|
||||
} difficalty;
|
||||
uint32 difficulty;
|
||||
} difficulty;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT = 13
|
||||
struct
|
||||
{
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ void WorldSession::HandleCalendarGetCalendar(WorldPacket &recv_data)
|
|||
size_t p_counter = data.wpos();
|
||||
data << uint32(counter); // instance save count
|
||||
|
||||
for(int i = 0; i < TOTAL_DUNGEON_DIFFICULTIES; ++i)
|
||||
for(int i = 0; i < MAX_DIFFICULTY; ++i)
|
||||
{
|
||||
for (Player::BoundInstancesMap::const_iterator itr = _player->m_boundInstances[i].begin(); itr != _player->m_boundInstances[i].end(); ++itr)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -96,6 +96,12 @@ DBCStorage <LockEntry> sLockStore(LockEntryfmt);
|
|||
|
||||
DBCStorage <MailTemplateEntry> sMailTemplateStore(MailTemplateEntryfmt);
|
||||
DBCStorage <MapEntry> sMapStore(MapEntryfmt);
|
||||
|
||||
// DBC used only for initialization sMapDifficultyMap at startup.
|
||||
DBCStorage <MapDifficultyEntry> sMapDifficultyStore(MapDifficultyEntryfmt); // only for loading
|
||||
typedef std::map<uint32/*pair32(map,diff)*/,MapDifficulty> MapDifficultyMap;
|
||||
MapDifficultyMap sMapDifficultyMap;
|
||||
|
||||
DBCStorage <MovieEntry> sMovieStore(MovieEntryfmt);
|
||||
|
||||
DBCStorage <QuestSortEntry> sQuestSortStore(QuestSortEntryfmt);
|
||||
|
|
@ -129,7 +135,7 @@ TalentSpellPosMap sTalentSpellPosMap;
|
|||
DBCStorage <TalentTabEntry> sTalentTabStore(TalentTabEntryfmt);
|
||||
|
||||
// store absolute bit position for first rank for talent inspect
|
||||
static uint32 sTalentTabPages[12/*MAX_CLASSES*/][3];
|
||||
static uint32 sTalentTabPages[MAX_CLASSES][3];
|
||||
|
||||
DBCStorage <TaxiNodesEntry> sTaxiNodesStore(TaxiNodesEntryfmt);
|
||||
TaxiMask sTaxiNodesMask;
|
||||
|
|
@ -139,10 +145,10 @@ TaxiMask sOldContinentsNodesMask;
|
|||
TaxiPathSetBySource sTaxiPathSetBySource;
|
||||
DBCStorage <TaxiPathEntry> sTaxiPathStore(TaxiPathEntryfmt);
|
||||
|
||||
// DBC used only for initialization sTaxiPathSetBySource at startup.
|
||||
// DBC used only for initialization sTaxiPathNodeStore at startup.
|
||||
TaxiPathNodesByPath sTaxiPathNodesByPath;
|
||||
|
||||
static DBCStorage <TaxiPathNodeEntry> sTaxiPathNodeStore(TaxiPathNodeEntryfmt);
|
||||
|
||||
DBCStorage <TotemCategoryEntry> sTotemCategoryStore(TotemCategoryEntryfmt);
|
||||
DBCStorage <VehicleEntry> sVehicleStore(VehicleEntryfmt);
|
||||
DBCStorage <VehicleSeatEntry> sVehicleSeatStore(VehicleSeatEntryfmt);
|
||||
|
|
@ -200,7 +206,7 @@ void LoadDBCStores(const std::string& dataPath)
|
|||
{
|
||||
std::string dbcPath = dataPath+"dbc/";
|
||||
|
||||
const uint32 DBCFilesCount = 79;
|
||||
const uint32 DBCFilesCount = 80;
|
||||
|
||||
barGoLink bar( DBCFilesCount );
|
||||
|
||||
|
|
@ -232,7 +238,6 @@ void LoadDBCStores(const std::string& dataPath)
|
|||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBattlemasterListStore, dbcPath,"BattlemasterList.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBarberShopStyleStore, dbcPath,"BarberShopStyle.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharStartOutfitStore, dbcPath,"CharStartOutfit.dbc");
|
||||
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharTitlesStore, dbcPath,"CharTitles.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChatChannelsStore, dbcPath,"ChatChannels.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrClassesStore, dbcPath,"ChrClasses.dbc");
|
||||
|
|
@ -290,6 +295,14 @@ void LoadDBCStores(const std::string& dataPath)
|
|||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sLockStore, dbcPath,"Lock.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMailTemplateStore, dbcPath,"MailTemplate.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMapStore, dbcPath,"Map.dbc");
|
||||
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMapDifficultyStore, dbcPath,"MapDifficulty.dbc");
|
||||
// fill data
|
||||
for(uint32 i = 1; i < sMapDifficultyStore.GetNumRows(); ++i)
|
||||
if(MapDifficultyEntry const* entry = sMapDifficultyStore.LookupEntry(i))
|
||||
sMapDifficultyMap[MAKE_PAIR32(entry->MapId,entry->Difficulty)] = MapDifficulty(entry->resetTime,entry->maxPlayers);
|
||||
sMapDifficultyStore.Clear();
|
||||
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMovieStore, dbcPath,"Movie.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestSortStore, dbcPath,"QuestSort.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sRandomPropertiesPointsStore, dbcPath,"RandPropPoints.dbc");
|
||||
|
|
@ -659,6 +672,12 @@ void Map2ZoneCoordinates(float& x,float& y,uint32 zone)
|
|||
std::swap(x,y); // client have map coords swapped
|
||||
}
|
||||
|
||||
MapDifficulty const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty)
|
||||
{
|
||||
MapDifficultyMap::const_iterator itr = sMapDifficultyMap.find(MAKE_PAIR32(mapId,difficulty));
|
||||
return itr != sMapDifficultyMap.end() ? &itr->second : NULL;
|
||||
}
|
||||
|
||||
uint32 const* GetTalentTabPages(uint32 cls)
|
||||
{
|
||||
return sTalentTabPages[cls];
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredT
|
|||
void Zone2MapCoordinates(float& x,float& y,uint32 zone);
|
||||
void Map2ZoneCoordinates(float& x,float& y,uint32 zone);
|
||||
|
||||
MapDifficulty const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty);
|
||||
|
||||
uint32 const* /*[3]*/ GetTalentTabPages(uint32 cls);
|
||||
|
||||
extern DBCStorage <AchievementEntry> sAchievementStore;
|
||||
|
|
@ -109,6 +111,7 @@ extern DBCStorage <ItemSetEntry> sItemSetStore;
|
|||
extern DBCStorage <LockEntry> sLockStore;
|
||||
extern DBCStorage <MailTemplateEntry> sMailTemplateStore;
|
||||
extern DBCStorage <MapEntry> sMapStore;
|
||||
//extern DBCStorage <MapDifficultyEntry> sMapDifficultyStore; -- use GetMapDifficultyData insteed
|
||||
extern DBCStorage <MovieEntry> sMovieStore;
|
||||
extern DBCStorage <QuestSortEntry> sQuestSortStore;
|
||||
extern DBCStorage <RandomPropertiesPointsEntry> sRandomPropertiesPointsStore;
|
||||
|
|
|
|||
|
|
@ -1105,8 +1105,6 @@ struct MapEntry
|
|||
bool IsBattleGround() const { return map_type == MAP_BATTLEGROUND; }
|
||||
bool IsBattleArena() const { return map_type == MAP_ARENA; }
|
||||
bool IsBattleGroundOrArena() const { return map_type == MAP_BATTLEGROUND || map_type == MAP_ARENA; }
|
||||
bool SupportsHeroicMode() const { return true; }
|
||||
bool HasResetTime() const { return true; }
|
||||
|
||||
bool IsMountAllowed() const
|
||||
{
|
||||
|
|
@ -1125,14 +1123,14 @@ struct MapEntry
|
|||
|
||||
struct MapDifficultyEntry
|
||||
{
|
||||
uint32 Id; // 0
|
||||
//uint32 Id; // 0
|
||||
uint32 MapId; // 1
|
||||
uint32 Difficulty; // 2
|
||||
char* areaTriggerText[16]; // 3-18 text showed when transfer to map failed (missing requirements)
|
||||
uint32 textFlags; // 19
|
||||
uint32 Difficulty; // 2 (for arenas: arena slot)
|
||||
//char* areaTriggerText[16]; // 3-18 text showed when transfer to map failed (missing requirements)
|
||||
//uint32 textFlags; // 19
|
||||
uint32 resetTime; // 20
|
||||
uint32 maxPlayers; // 21
|
||||
char* difficultyString; // 22
|
||||
//char* difficultyString; // 22
|
||||
};
|
||||
|
||||
struct MovieEntry
|
||||
|
|
@ -1769,6 +1767,15 @@ struct WorldSafeLocsEntry
|
|||
#endif
|
||||
|
||||
// Structures not used for casting to loaded DBC data and not required then packing
|
||||
struct MapDifficulty
|
||||
{
|
||||
MapDifficulty() : resetTime(0), maxPlayers(0) {}
|
||||
MapDifficulty(uint32 _resetTime, uint32 _maxPlayers) : resetTime(_resetTime), maxPlayers(_maxPlayers) {}
|
||||
|
||||
uint32 resetTime;
|
||||
uint32 maxPlayers;
|
||||
};
|
||||
|
||||
struct TalentSpellPos
|
||||
{
|
||||
TalentSpellPos() : talent_id(0), rank(0) {}
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ const char ItemSetEntryfmt[]="dssssssssssssssssxxxxxxxxxxxxxxxxxxiiiiiiiiiiiiiii
|
|||
const char LockEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx";
|
||||
const char MailTemplateEntryfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
const char MapEntryfmt[]="nxixssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixiffxixx";
|
||||
const char MapDifficultyEntryfmt[]="diixxxxxxxxxxxxxxxxxiix";
|
||||
const char MovieEntryfmt[]="nxx";
|
||||
const char QuestSortEntryfmt[]="nxxxxxxxxxxxxxxxxx";
|
||||
const char RandomPropertiesPointsfmt[]="niiiiiiiiiiiiiii";
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ Group::~Group()
|
|||
// it is undefined whether objectmgr (which stores the groups) or instancesavemgr
|
||||
// will be unloaded first so we must be prepared for both cases
|
||||
// this may unload some instance saves
|
||||
for(uint8 i = 0; i < TOTAL_DUNGEON_DIFFICULTIES; ++i)
|
||||
for(uint8 i = 0; i < MAX_DIFFICULTY; ++i)
|
||||
for(BoundInstancesMap::iterator itr2 = m_boundInstances[i].begin(); itr2 != m_boundInstances[i].end(); ++itr2)
|
||||
itr2->second.save->RemoveGroup(this);
|
||||
|
||||
|
|
@ -112,7 +112,7 @@ bool Group::Create(const uint64 &guid, const char * name)
|
|||
CharacterDatabase.PExecute("INSERT INTO groups (leaderGuid,mainTank,mainAssistant,lootMethod,looterGuid,lootThreshold,icon1,icon2,icon3,icon4,icon5,icon6,icon7,icon8,isRaid,difficulty,raiddifficulty) "
|
||||
"VALUES ('%u','%u','%u','%u','%u','%u','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','%u','%u','%u')",
|
||||
GUID_LOPART(m_leaderGuid), GUID_LOPART(m_mainTank), GUID_LOPART(m_mainAssistant), uint32(m_lootMethod),
|
||||
GUID_LOPART(m_looterGuid), uint32(m_lootThreshold), m_targetIcons[0], m_targetIcons[1], m_targetIcons[2], m_targetIcons[3], m_targetIcons[4], m_targetIcons[5], m_targetIcons[6], m_targetIcons[7], isRaidGroup(), m_dungeonDifficulty, m_raidDifficulty);
|
||||
GUID_LOPART(m_looterGuid), uint32(m_lootThreshold), m_targetIcons[0], m_targetIcons[1], m_targetIcons[2], m_targetIcons[3], m_targetIcons[4], m_targetIcons[5], m_targetIcons[6], m_targetIcons[7], isRaidGroup(), uint32(m_dungeonDifficulty), m_raidDifficulty);
|
||||
}
|
||||
|
||||
if(!AddMember(guid, name))
|
||||
|
|
@ -152,8 +152,16 @@ bool Group::LoadGroupFromDB(const uint64 &leaderGuid, QueryResult *result, bool
|
|||
if (m_groupType == GROUPTYPE_RAID)
|
||||
_initRaidSubGroupsCounter();
|
||||
|
||||
m_dungeonDifficulty = (*result)[14].GetUInt8();
|
||||
m_raidDifficulty = (*result)[15].GetUInt8();
|
||||
uint32 diff = (*result)[14].GetUInt8();
|
||||
if (diff >= MAX_DUNGEON_DIFFICULTY)
|
||||
diff = DUNGEON_DIFFICULTY_NORMAL;
|
||||
m_dungeonDifficulty = Difficulty(diff);
|
||||
|
||||
uint32 r_diff = (*result)[15].GetUInt8();
|
||||
if (r_diff >= MAX_RAID_DIFFICULTY)
|
||||
r_diff = RAID_DIFFICULTY_10MAN_NORMAL;
|
||||
m_raidDifficulty = Difficulty(r_diff);
|
||||
|
||||
m_mainTank = (*result)[0].GetUInt64();
|
||||
m_mainAssistant = (*result)[1].GetUInt64();
|
||||
m_lootMethod = (LootMethod)(*result)[2].GetUInt8();
|
||||
|
|
@ -295,13 +303,22 @@ bool Group::AddMember(const uint64 &guid, const char* name)
|
|||
{
|
||||
// reset the new member's instances, unless he is currently in one of them
|
||||
// including raid/heroic instances that they are not permanently bound to!
|
||||
player->ResetInstances(INSTANCE_RESET_GROUP_JOIN);
|
||||
player->ResetInstances(INSTANCE_RESET_GROUP_JOIN,false);
|
||||
player->ResetInstances(INSTANCE_RESET_GROUP_JOIN,true);
|
||||
|
||||
if(player->getLevel() >= LEVELREQUIREMENT_HEROIC && player->GetDungeonDifficulty() != GetDungeonDifficulty() )
|
||||
if (player->getLevel() >= LEVELREQUIREMENT_HEROIC)
|
||||
{
|
||||
player->SetDungeonDifficulty(m_dungeonDifficulty);
|
||||
if (player->GetDungeonDifficulty() != GetDungeonDifficulty())
|
||||
{
|
||||
player->SetDungeonDifficulty(GetDungeonDifficulty());
|
||||
player->SendDungeonDifficulty(true);
|
||||
}
|
||||
if (player->GetRaidDifficulty() != GetRaidDifficulty())
|
||||
{
|
||||
player->SetRaidDifficulty(GetRaidDifficulty());
|
||||
player->SendRaidDifficulty(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
player->SetGroupUpdateFlag(GROUP_UPDATE_FULL);
|
||||
UpdatePlayerOutOfRange(player);
|
||||
|
|
@ -443,7 +460,8 @@ void Group::Disband(bool hideDestroy)
|
|||
CharacterDatabase.PExecute("DELETE FROM groups WHERE leaderGuid='%u'", GUID_LOPART(m_leaderGuid));
|
||||
CharacterDatabase.PExecute("DELETE FROM group_member WHERE leaderGuid='%u'", GUID_LOPART(m_leaderGuid));
|
||||
CharacterDatabase.CommitTransaction();
|
||||
ResetInstances(INSTANCE_RESET_GROUP_DISBAND, NULL);
|
||||
ResetInstances(INSTANCE_RESET_GROUP_DISBAND, false, NULL);
|
||||
ResetInstances(INSTANCE_RESET_GROUP_DISBAND, true, NULL);
|
||||
}
|
||||
|
||||
m_leaderGuid = 0;
|
||||
|
|
@ -1079,7 +1097,7 @@ bool Group::_addMember(const uint64 &guid, const char* name, bool isAssistant, u
|
|||
else
|
||||
player->SetGroup(this, group);
|
||||
// if the same group invites the player back, cancel the homebind timer
|
||||
InstanceGroupBind *bind = GetBoundInstance(player->GetMapId(), player->GetDungeonDifficulty());
|
||||
InstanceGroupBind *bind = GetBoundInstance(player);
|
||||
if(bind && bind->save->GetInstanceId() == player->GetInstanceId())
|
||||
player->m_InstanceValid = true;
|
||||
}
|
||||
|
|
@ -1165,7 +1183,7 @@ void Group::_setLeader(const uint64 &guid)
|
|||
Player *player = objmgr.GetPlayer(slot->guid);
|
||||
if(player)
|
||||
{
|
||||
for(uint8 i = 0; i < TOTAL_DUNGEON_DIFFICULTIES; ++i)
|
||||
for(uint8 i = 0; i < MAX_DIFFICULTY; ++i)
|
||||
{
|
||||
for(BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end();)
|
||||
{
|
||||
|
|
@ -1452,10 +1470,11 @@ void Roll::targetObjectBuildLink()
|
|||
getTarget()->addLootValidatorRef(this);
|
||||
}
|
||||
|
||||
void Group::SetDungeonDifficulty(uint8 difficulty)
|
||||
void Group::SetDungeonDifficulty(Difficulty difficulty)
|
||||
{
|
||||
m_dungeonDifficulty = difficulty;
|
||||
if(!isBGGroup()) CharacterDatabase.PExecute("UPDATE groups SET difficulty = %u WHERE leaderGuid ='%u'", m_dungeonDifficulty, GUID_LOPART(m_leaderGuid));
|
||||
if(!isBGGroup())
|
||||
CharacterDatabase.PExecute("UPDATE groups SET difficulty = %u WHERE leaderGuid ='%u'", m_dungeonDifficulty, GUID_LOPART(m_leaderGuid));
|
||||
|
||||
for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
{
|
||||
|
|
@ -1467,10 +1486,11 @@ void Group::SetDungeonDifficulty(uint8 difficulty)
|
|||
}
|
||||
}
|
||||
|
||||
void Group::SetRaidDifficulty(uint8 difficulty)
|
||||
void Group::SetRaidDifficulty(Difficulty difficulty)
|
||||
{
|
||||
m_raidDifficulty = difficulty;
|
||||
if(!isBGGroup()) CharacterDatabase.PExecute("UPDATE groups SET raiddifficulty = %u WHERE leaderGuid ='%u'", m_raidDifficulty, GUID_LOPART(m_leaderGuid));
|
||||
if(!isBGGroup())
|
||||
CharacterDatabase.PExecute("UPDATE groups SET raiddifficulty = %u WHERE leaderGuid ='%u'", m_raidDifficulty, GUID_LOPART(m_leaderGuid));
|
||||
|
||||
for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
{
|
||||
|
|
@ -1493,7 +1513,7 @@ bool Group::InCombatToInstance(uint32 instanceId)
|
|||
return false;
|
||||
}
|
||||
|
||||
void Group::ResetInstances(uint8 method, Player* SendMsgTo)
|
||||
void Group::ResetInstances(uint8 method, bool isRaid, Player* SendMsgTo)
|
||||
{
|
||||
if(isBGGroup())
|
||||
return;
|
||||
|
|
@ -1501,13 +1521,13 @@ void Group::ResetInstances(uint8 method, Player* SendMsgTo)
|
|||
// method can be INSTANCE_RESET_ALL, INSTANCE_RESET_CHANGE_DIFFICULTY, INSTANCE_RESET_GROUP_DISBAND
|
||||
|
||||
// we assume that when the difficulty changes, all instances that can be reset will be
|
||||
uint8 dif = GetDungeonDifficulty();
|
||||
Difficulty diff = GetDifficulty(isRaid);
|
||||
|
||||
for(BoundInstancesMap::iterator itr = m_boundInstances[dif].begin(); itr != m_boundInstances[dif].end();)
|
||||
for(BoundInstancesMap::iterator itr = m_boundInstances[diff].begin(); itr != m_boundInstances[diff].end();)
|
||||
{
|
||||
InstanceSave *p = itr->second.save;
|
||||
const MapEntry *entry = sMapStore.LookupEntry(itr->first);
|
||||
if(!entry || (!p->CanReset() && method != INSTANCE_RESET_GROUP_DISBAND))
|
||||
if(!entry || entry->IsRaid() != isRaid || !p->CanReset() && method != INSTANCE_RESET_GROUP_DISBAND)
|
||||
{
|
||||
++itr;
|
||||
continue;
|
||||
|
|
@ -1516,7 +1536,7 @@ void Group::ResetInstances(uint8 method, Player* SendMsgTo)
|
|||
if(method == INSTANCE_RESET_ALL)
|
||||
{
|
||||
// the "reset all instances" method can only reset normal maps
|
||||
if(dif == DUNGEON_DIFFICULTY_HEROIC || entry->map_type == MAP_RAID)
|
||||
if (entry->map_type == MAP_RAID || diff == DUNGEON_DIFFICULTY_HEROIC)
|
||||
{
|
||||
++itr;
|
||||
continue;
|
||||
|
|
@ -1541,8 +1561,8 @@ void Group::ResetInstances(uint8 method, Player* SendMsgTo)
|
|||
if(p->CanReset()) p->DeleteFromDB();
|
||||
else CharacterDatabase.PExecute("DELETE FROM group_instance WHERE instance = '%u'", p->GetInstanceId());
|
||||
// i don't know for sure if hash_map iterators
|
||||
m_boundInstances[dif].erase(itr);
|
||||
itr = m_boundInstances[dif].begin();
|
||||
m_boundInstances[diff].erase(itr);
|
||||
itr = m_boundInstances[diff].begin();
|
||||
// this unloads the instance save unless online players are bound to it
|
||||
// (eg. permanent binds or GM solo binds)
|
||||
p->RemoveGroup(this);
|
||||
|
|
@ -1552,11 +1572,19 @@ void Group::ResetInstances(uint8 method, Player* SendMsgTo)
|
|||
}
|
||||
}
|
||||
|
||||
InstanceGroupBind* Group::GetBoundInstance(uint32 mapid, uint8 difficulty)
|
||||
InstanceGroupBind* Group::GetBoundInstance(Player* player)
|
||||
{
|
||||
uint32 mapid = player->GetMapId();
|
||||
MapEntry const* mapEntry = sMapStore.LookupEntry(mapid);
|
||||
if(!mapEntry)
|
||||
return NULL;
|
||||
|
||||
Difficulty difficulty = player->GetDifficulty(mapEntry->IsRaid());
|
||||
|
||||
// some instances only have one difficulty
|
||||
const MapEntry* entry = sMapStore.LookupEntry(mapid);
|
||||
if(!entry || !entry->SupportsHeroicMode()) difficulty = DUNGEON_DIFFICULTY_NORMAL;
|
||||
MapDifficulty const* mapDiff = GetMapDifficultyData(mapid,difficulty);
|
||||
if(!mapDiff)
|
||||
difficulty = DUNGEON_DIFFICULTY_NORMAL;
|
||||
|
||||
BoundInstancesMap::iterator itr = m_boundInstances[difficulty].find(mapid);
|
||||
if(itr != m_boundInstances[difficulty].end())
|
||||
|
|
@ -1565,6 +1593,23 @@ InstanceGroupBind* Group::GetBoundInstance(uint32 mapid, uint8 difficulty)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
InstanceGroupBind* Group::GetBoundInstance(Map* aMap)
|
||||
{
|
||||
// Currently spawn numbering not different from map difficulty
|
||||
Difficulty difficulty = Difficulty(aMap->GetSpawnMode());
|
||||
|
||||
// some instances only have one difficulty
|
||||
MapDifficulty const* mapDiff = GetMapDifficultyData(aMap->GetId(),difficulty);
|
||||
if(!mapDiff)
|
||||
return NULL;
|
||||
|
||||
BoundInstancesMap::iterator itr = m_boundInstances[difficulty].find(aMap->GetId());
|
||||
if(itr != m_boundInstances[difficulty].end())
|
||||
return &itr->second;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
InstanceGroupBind* Group::BindToInstance(InstanceSave *save, bool permanent, bool load)
|
||||
{
|
||||
if(save && !isBGGroup())
|
||||
|
|
|
|||
|
|
@ -279,13 +279,15 @@ class MANGOS_DLL_SPEC Group
|
|||
}
|
||||
|
||||
void SetTargetIcon(uint8 id, uint64 guid);
|
||||
void SetDungeonDifficulty(uint8 difficulty);
|
||||
uint8 GetDungeonDifficulty() { return m_dungeonDifficulty; }
|
||||
void SetRaidDifficulty(uint8 difficulty);
|
||||
uint8 GetRaidDifficulty() { return m_raidDifficulty; }
|
||||
|
||||
Difficulty GetDifficulty(bool isRaid) const { return isRaid ? m_raidDifficulty : m_dungeonDifficulty; }
|
||||
Difficulty GetDungeonDifficulty() const { return m_dungeonDifficulty; }
|
||||
Difficulty GetRaidDifficulty() const { return m_raidDifficulty; }
|
||||
void SetDungeonDifficulty(Difficulty difficulty);
|
||||
void SetRaidDifficulty(Difficulty difficulty);
|
||||
uint16 InInstance();
|
||||
bool InCombatToInstance(uint32 instanceId);
|
||||
void ResetInstances(uint8 method, Player* SendMsgTo);
|
||||
void ResetInstances(uint8 method, bool isRaid, Player* SendMsgTo);
|
||||
|
||||
// -no description-
|
||||
//void SendInit(WorldSession *session);
|
||||
|
|
@ -329,8 +331,9 @@ class MANGOS_DLL_SPEC Group
|
|||
|
||||
InstanceGroupBind* BindToInstance(InstanceSave *save, bool permanent, bool load = false);
|
||||
void UnbindInstance(uint32 mapid, uint8 difficulty, bool unload = false);
|
||||
InstanceGroupBind* GetBoundInstance(uint32 mapid, uint8 difficulty);
|
||||
BoundInstancesMap& GetBoundInstances(uint8 difficulty) { return m_boundInstances[difficulty]; }
|
||||
InstanceGroupBind* GetBoundInstance(Player* player);
|
||||
InstanceGroupBind* GetBoundInstance(Map* aMap);
|
||||
BoundInstancesMap& GetBoundInstances(Difficulty difficulty) { return m_boundInstances[difficulty]; }
|
||||
|
||||
protected:
|
||||
bool _addMember(const uint64 &guid, const char* name, bool isAssistant=false);
|
||||
|
|
@ -399,15 +402,15 @@ class MANGOS_DLL_SPEC Group
|
|||
uint64 m_mainTank;
|
||||
uint64 m_mainAssistant;
|
||||
GroupType m_groupType;
|
||||
uint8 m_dungeonDifficulty;
|
||||
uint8 m_raidDifficulty;
|
||||
Difficulty m_dungeonDifficulty;
|
||||
Difficulty m_raidDifficulty;
|
||||
BattleGround* m_bgGroup;
|
||||
uint64 m_targetIcons[TARGETICONCOUNT];
|
||||
LootMethod m_lootMethod;
|
||||
ItemQualities m_lootThreshold;
|
||||
uint64 m_looterGuid;
|
||||
Rolls RollId;
|
||||
BoundInstancesMap m_boundInstances[TOTAL_DUNGEON_DIFFICULTIES];
|
||||
BoundInstancesMap m_boundInstances[MAX_DIFFICULTY];
|
||||
uint8* m_subGroupsCounts;
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -72,15 +72,27 @@ InstanceSaveManager::~InstanceSaveManager()
|
|||
- adding instance into manager
|
||||
- called from InstanceMap::Add, _LoadBoundInstances, LoadGroups
|
||||
*/
|
||||
InstanceSave* InstanceSaveManager::AddInstanceSave(uint32 mapId, uint32 instanceId, uint8 difficulty, time_t resetTime, bool canReset, bool load)
|
||||
InstanceSave* InstanceSaveManager::AddInstanceSave(uint32 mapId, uint32 instanceId, Difficulty difficulty, time_t resetTime, bool canReset, bool load)
|
||||
{
|
||||
InstanceSave *save = GetInstanceSave(instanceId);
|
||||
if(save) return save;
|
||||
if(InstanceSave *old_save = GetInstanceSave(instanceId))
|
||||
return old_save;
|
||||
|
||||
const MapEntry* entry = sMapStore.LookupEntry(mapId);
|
||||
if(!entry || instanceId == 0)
|
||||
if (!entry)
|
||||
{
|
||||
sLog.outError("InstanceSaveManager::AddInstanceSave: mapid = %d, instanceid = %d!", mapId, instanceId);
|
||||
sLog.outError("InstanceSaveManager::AddInstanceSave: wrong mapid = %d!", mapId, instanceId);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (instanceId == 0)
|
||||
{
|
||||
sLog.outError("InstanceSaveManager::AddInstanceSave: mapid = %d, wrong instanceid = %d!", mapId, instanceId);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (difficulty >= (entry->IsRaid() ? MAX_RAID_DIFFICULTY : MAX_DUNGEON_DIFFICULTY))
|
||||
{
|
||||
sLog.outError("InstanceSaveManager::AddInstanceSave: mapid = %d, instanceid = %d, wrong dificalty %u!", mapId, instanceId, difficulty);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -100,7 +112,7 @@ InstanceSave* InstanceSaveManager::AddInstanceSave(uint32 mapId, uint32 instance
|
|||
|
||||
sLog.outDebug("InstanceSaveManager::AddInstanceSave: mapid = %d, instanceid = %d", mapId, instanceId);
|
||||
|
||||
save = new InstanceSave(mapId, instanceId, difficulty, resetTime, canReset);
|
||||
InstanceSave *save = new InstanceSave(mapId, instanceId, difficulty, resetTime, canReset);
|
||||
if(!load) save->SaveToDB();
|
||||
|
||||
m_instanceSaveById[instanceId] = save;
|
||||
|
|
@ -136,7 +148,7 @@ void InstanceSaveManager::RemoveInstanceSave(uint32 InstanceId)
|
|||
}
|
||||
}
|
||||
|
||||
InstanceSave::InstanceSave(uint16 MapId, uint32 InstanceId, uint8 difficulty, time_t resetTime, bool canReset)
|
||||
InstanceSave::InstanceSave(uint16 MapId, uint32 InstanceId, Difficulty difficulty, time_t resetTime, bool canReset)
|
||||
: m_resetTime(resetTime), m_instanceid(InstanceId), m_mapid(MapId),
|
||||
m_difficulty(difficulty), m_canReset(canReset)
|
||||
{
|
||||
|
|
@ -446,10 +458,7 @@ void InstanceSaveManager::LoadResetTimes()
|
|||
for(uint32 i = 0; i < sInstanceTemplate.MaxEntry; i++)
|
||||
{
|
||||
InstanceTemplate const* temp = objmgr.GetInstanceTemplate(i);
|
||||
if(!temp) continue;
|
||||
// only raid/heroic maps have a global reset time
|
||||
const MapEntry* entry = sMapStore.LookupEntry(temp->map);
|
||||
if(!entry || !entry->HasResetTime())
|
||||
if(!temp || temp->reset_delay == 0)
|
||||
continue;
|
||||
|
||||
uint32 period = temp->reset_delay * DAY;
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ class InstanceSave
|
|||
- any new instance is being generated
|
||||
- the first time a player bound to InstanceId logs in
|
||||
- when a group bound to the instance is loaded */
|
||||
InstanceSave(uint16 MapId, uint32 InstanceId, uint8 difficulty, time_t resetTime, bool canReset);
|
||||
InstanceSave(uint16 MapId, uint32 InstanceId, Difficulty difficulty, time_t resetTime, bool canReset);
|
||||
|
||||
/* Unloaded when m_playerList and m_groupList become empty
|
||||
or when the instance is reset */
|
||||
|
|
@ -92,7 +92,7 @@ class InstanceSave
|
|||
|
||||
/* currently it is possible to omit this information from this structure
|
||||
but that would depend on a lot of things that can easily change in future */
|
||||
uint8 GetDifficulty() { return m_difficulty; }
|
||||
Difficulty GetDifficulty() { return m_difficulty; }
|
||||
|
||||
typedef std::list<Player*> PlayerListType;
|
||||
typedef std::list<Group*> GroupListType;
|
||||
|
|
@ -105,8 +105,8 @@ class InstanceSave
|
|||
GroupListType m_groupList;
|
||||
time_t m_resetTime;
|
||||
uint32 m_instanceid;
|
||||
uint16 m_mapid;
|
||||
uint8 m_difficulty;
|
||||
uint32 m_mapid;
|
||||
Difficulty m_difficulty;
|
||||
bool m_canReset;
|
||||
};
|
||||
|
||||
|
|
@ -143,7 +143,7 @@ class MANGOS_DLL_DECL InstanceSaveManager : public MaNGOS::Singleton<InstanceSav
|
|||
|
||||
void Update();
|
||||
|
||||
InstanceSave* AddInstanceSave(uint32 mapId, uint32 instanceId, uint8 difficulty, time_t resetTime, bool canReset, bool load = false);
|
||||
InstanceSave* AddInstanceSave(uint32 mapId, uint32 instanceId, Difficulty difficulty, time_t resetTime, bool canReset, bool load = false);
|
||||
void RemoveInstanceSave(uint32 InstanceId);
|
||||
static void DeleteInstanceFromDB(uint32 instanceid);
|
||||
|
||||
|
|
|
|||
|
|
@ -537,18 +537,21 @@ bool ChatHandler::HandleGonameCommand(const char* args)
|
|||
|
||||
// if the player or the player's group is bound to another instance
|
||||
// the player will not be bound to another one
|
||||
InstancePlayerBind *pBind = _player->GetBoundInstance(target->GetMapId(), target->GetDungeonDifficulty());
|
||||
InstancePlayerBind *pBind = _player->GetBoundInstance(target->GetMapId(), target->GetDifficulty(cMap->IsRaid()));
|
||||
if (!pBind)
|
||||
{
|
||||
Group *group = _player->GetGroup();
|
||||
// if no bind exists, create a solo bind
|
||||
InstanceGroupBind *gBind = group ? group->GetBoundInstance(target->GetMapId(), target->GetDungeonDifficulty()) : NULL;
|
||||
InstanceGroupBind *gBind = group ? group->GetBoundInstance(target) : NULL;
|
||||
// if no bind exists, create a solo bind
|
||||
if (!gBind)
|
||||
if (InstanceSave *save = sInstanceSaveManager.GetInstanceSave(target->GetInstanceId()))
|
||||
_player->BindToInstance(save, !save->CanReset());
|
||||
}
|
||||
|
||||
if(cMap->IsRaid())
|
||||
_player->SetRaidDifficulty(target->GetRaidDifficulty());
|
||||
else
|
||||
_player->SetDungeonDifficulty(target->GetDungeonDifficulty());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5912,9 +5912,9 @@ bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/)
|
|||
Player* player = getSelectedPlayer();
|
||||
if (!player) player = m_session->GetPlayer();
|
||||
uint32 counter = 0;
|
||||
for(uint8 i = 0; i < TOTAL_DUNGEON_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;
|
||||
|
|
@ -5928,9 +5928,9 @@ bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/)
|
|||
Group *group = player->GetGroup();
|
||||
if(group)
|
||||
{
|
||||
for(uint8 i = 0; i < TOTAL_DUNGEON_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;
|
||||
|
|
@ -5956,9 +5956,9 @@ bool ChatHandler::HandleInstanceUnbindCommand(const char* args)
|
|||
Player* player = getSelectedPlayer();
|
||||
if (!player) player = m_session->GetPlayer();
|
||||
uint32 counter = 0;
|
||||
for(uint8 i = 0; i < TOTAL_DUNGEON_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())
|
||||
|
|
@ -5966,7 +5966,7 @@ bool ChatHandler::HandleInstanceUnbindCommand(const char* args)
|
|||
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() == DUNGEON_DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str());
|
||||
player->UnbindInstance(itr, i);
|
||||
player->UnbindInstance(itr, Difficulty(i));
|
||||
counter++;
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -2334,11 +2334,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
|
||||
|
|
@ -2354,7 +2354,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());
|
||||
|
|
@ -2573,7 +2573,7 @@ void InstanceMap::UnloadAll(bool pForce)
|
|||
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()->GetDungeonDifficulty(), timeLeft);
|
||||
itr->getSource()->SendInstanceResetWarning(GetId(), itr->getSource()->GetDifficulty(IsRaid()), timeLeft);
|
||||
}
|
||||
|
||||
void InstanceMap::SetResetSchedule(bool on)
|
||||
|
|
|
|||
|
|
@ -365,7 +365,7 @@ 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 == DUNGEON_DIFFICULTY_HEROIC; }
|
||||
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(); }
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ Map* MapInstanced::CreateInstance(const uint32 mapId, Player * player)
|
|||
}
|
||||
else
|
||||
{
|
||||
InstancePlayerBind *pBind = player->GetBoundInstance(GetId(), player->GetDungeonDifficulty());
|
||||
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
|
||||
|
|
@ -149,7 +149,7 @@ Map* MapInstanced::CreateInstance(const uint32 mapId, Player * player)
|
|||
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(GetId(), player->GetDungeonDifficulty())))
|
||||
if(group && (groupBind = group->GetBoundInstance(this)))
|
||||
pSave = groupBind->save;
|
||||
}
|
||||
|
||||
|
|
@ -167,14 +167,14 @@ Map* MapInstanced::CreateInstance(const uint32 mapId, Player * player)
|
|||
// if no instanceId via group members or instance saves is found
|
||||
// the instance will be created for the first time
|
||||
NewInstanceId = MapManager::Instance().GenerateInstanceId();
|
||||
map = CreateInstance(NewInstanceId, NULL, player->GetDungeonDifficulty());
|
||||
map = CreateInstance(NewInstanceId, NULL, player->GetDifficulty(IsRaid()));
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
@ -194,7 +194,9 @@ InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave *save,
|
|||
}
|
||||
|
||||
// some instances only have one difficulty
|
||||
if (entry && !entry->SupportsHeroicMode()) difficulty = DUNGEON_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");
|
||||
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ class MANGOS_DLL_DECL MapInstanced : public Map
|
|||
|
||||
private:
|
||||
|
||||
InstanceMap* CreateInstance(uint32 InstanceId, InstanceSave *save, uint8 difficulty);
|
||||
InstanceMap* CreateInstance(uint32 InstanceId, InstanceSave *save, Difficulty difficulty);
|
||||
BattleGroundMap* CreateBattleGroundMap(uint32 InstanceId, BattleGround* bg);
|
||||
|
||||
InstancedMaps m_InstancedMaps;
|
||||
|
|
|
|||
|
|
@ -182,10 +182,16 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player)
|
|||
}
|
||||
|
||||
//The player has a heroic mode and tries to enter into instance which has no a heroic mode
|
||||
if (!entry->SupportsHeroicMode() && player->GetDungeonDifficulty() == DUNGEON_DIFFICULTY_HEROIC)
|
||||
MapDifficulty const* mapDiff = GetMapDifficultyData(entry->MapID,player->GetDifficulty(entry->map_type == MAP_RAID));
|
||||
if (!mapDiff)
|
||||
{
|
||||
bool isHeroicTargetMap = entry->map_type == MAP_RAID
|
||||
? (player->GetRaidDifficulty() >= RAID_DIFFICULTY_10MAN_HEROIC)
|
||||
: (player->GetDungeonDifficulty() >= DUNGEON_DIFFICULTY_HEROIC);
|
||||
|
||||
//Send aborted message
|
||||
player->SendTransferAborted(mapid, TRANSFER_ABORT_DIFFICULTY, DUNGEON_DIFFICULTY_HEROIC);
|
||||
// FIX ME: what about absent normal/heroic mode with specific players limit...
|
||||
player->SendTransferAborted(mapid, TRANSFER_ABORT_DIFFICULTY, isHeroicTargetMap ? DUNGEON_DIFFICULTY_HEROIC : DUNGEON_DIFFICULTY_NORMAL);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -809,8 +809,16 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data)
|
|||
else if(at->requiredItem2 && !GetPlayer()->HasItemCount(at->requiredItem2, 1))
|
||||
missingItem = at->requiredItem2;
|
||||
|
||||
MapEntry const* mapEntry = sMapStore.LookupEntry(at->target_mapId);
|
||||
if(!mapEntry)
|
||||
return;
|
||||
|
||||
bool isHeroicTargetMap = mapEntry->IsRaid()
|
||||
? (GetPlayer()->GetRaidDifficulty() >= RAID_DIFFICULTY_10MAN_HEROIC)
|
||||
: (GetPlayer()->GetDungeonDifficulty() >= DUNGEON_DIFFICULTY_HEROIC);
|
||||
|
||||
uint32 missingKey = 0;
|
||||
if(GetPlayer()->GetDungeonDifficulty() == DUNGEON_DIFFICULTY_HEROIC)
|
||||
if(isHeroicTargetMap)
|
||||
{
|
||||
if(at->heroicKey)
|
||||
{
|
||||
|
|
@ -823,7 +831,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data)
|
|||
}
|
||||
|
||||
uint32 missingQuest = 0;
|
||||
if(GetPlayer()->GetDungeonDifficulty() == DUNGEON_DIFFICULTY_HEROIC)
|
||||
if(isHeroicTargetMap)
|
||||
{
|
||||
if (at->requiredQuestHeroic && !GetPlayer()->GetQuestRewardStatus(at->requiredQuestHeroic))
|
||||
missingQuest = at->requiredQuestHeroic;
|
||||
|
|
@ -840,7 +848,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data)
|
|||
if(missingItem)
|
||||
SendAreaTriggerMessage(GetMangosString(LANG_LEVEL_MINREQUIRED_AND_ITEM), at->requiredLevel, objmgr.GetItemPrototype(missingItem)->Name1);
|
||||
else if(missingKey)
|
||||
GetPlayer()->SendTransferAborted(at->target_mapId, TRANSFER_ABORT_DIFFICULTY, DUNGEON_DIFFICULTY_HEROIC);
|
||||
GetPlayer()->SendTransferAborted(at->target_mapId, TRANSFER_ABORT_DIFFICULTY, isHeroicTargetMap ? DUNGEON_DIFFICULTY_HEROIC : DUNGEON_DIFFICULTY_NORMAL);
|
||||
else if(missingQuest)
|
||||
SendAreaTriggerMessage(at->requiredFailedText.c_str());
|
||||
else if(missingLevel)
|
||||
|
|
@ -1383,10 +1391,16 @@ void WorldSession::HandleResetInstancesOpcode( WorldPacket & /*recv_data*/ )
|
|||
if(Group *pGroup = _player->GetGroup())
|
||||
{
|
||||
if(pGroup->IsLeader(_player->GetGUID()))
|
||||
pGroup->ResetInstances(INSTANCE_RESET_ALL, _player);
|
||||
{
|
||||
pGroup->ResetInstances(INSTANCE_RESET_ALL, false, _player);
|
||||
pGroup->ResetInstances(INSTANCE_RESET_ALL, true,_player);
|
||||
}
|
||||
}
|
||||
else
|
||||
_player->ResetInstances(INSTANCE_RESET_ALL);
|
||||
{
|
||||
_player->ResetInstances(INSTANCE_RESET_ALL, false);
|
||||
_player->ResetInstances(INSTANCE_RESET_ALL, true);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleSetDungeonDifficultyOpcode( WorldPacket & recv_data )
|
||||
|
|
@ -1396,15 +1410,15 @@ void WorldSession::HandleSetDungeonDifficultyOpcode( WorldPacket & recv_data )
|
|||
uint32 mode;
|
||||
recv_data >> mode;
|
||||
|
||||
if(mode == _player->GetDungeonDifficulty())
|
||||
return;
|
||||
|
||||
if(mode > DUNGEON_DIFFICULTY_HEROIC)
|
||||
if(mode >= MAX_DUNGEON_DIFFICULTY)
|
||||
{
|
||||
sLog.outError("WorldSession::HandleSetDungeonDifficultyOpcode: player %d sent an invalid instance mode %d!", _player->GetGUIDLow(), mode);
|
||||
return;
|
||||
}
|
||||
|
||||
if(Difficulty(mode) == _player->GetDungeonDifficulty())
|
||||
return;
|
||||
|
||||
// cannot reset while in an instance
|
||||
Map *map = _player->GetMap();
|
||||
if(map && map->IsDungeon())
|
||||
|
|
@ -1422,14 +1436,14 @@ void WorldSession::HandleSetDungeonDifficultyOpcode( WorldPacket & recv_data )
|
|||
{
|
||||
// the difficulty is set even if the instances can't be reset
|
||||
//_player->SendDungeonDifficulty(true);
|
||||
pGroup->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, _player);
|
||||
pGroup->SetDungeonDifficulty(mode);
|
||||
pGroup->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, false, _player);
|
||||
pGroup->SetDungeonDifficulty(Difficulty(mode));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_player->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY);
|
||||
_player->SetDungeonDifficulty(mode);
|
||||
_player->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, false);
|
||||
_player->SetDungeonDifficulty(Difficulty(mode));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1440,15 +1454,15 @@ void WorldSession::HandleSetRaidDifficultyOpcode( WorldPacket & recv_data )
|
|||
uint32 mode;
|
||||
recv_data >> mode;
|
||||
|
||||
if(mode == _player->GetRaidDifficulty())
|
||||
return;
|
||||
|
||||
if(mode > RAID_DIFFICULTY_25MAN_HEROIC)
|
||||
if(mode >= MAX_RAID_DIFFICULTY)
|
||||
{
|
||||
sLog.outError("WorldSession::HandleSetRaidDifficultyOpcode: player %d sent an invalid instance mode %d!", _player->GetGUIDLow(), mode);
|
||||
return;
|
||||
}
|
||||
|
||||
if(RaidDifficulties(mode) == _player->GetRaidDifficulty())
|
||||
return;
|
||||
|
||||
// cannot reset while in an instance
|
||||
Map *map = _player->GetMap();
|
||||
if(map && map->IsDungeon())
|
||||
|
|
@ -1466,14 +1480,14 @@ void WorldSession::HandleSetRaidDifficultyOpcode( WorldPacket & recv_data )
|
|||
{
|
||||
// the difficulty is set even if the instances can't be reset
|
||||
//_player->SendDungeonDifficulty(true);
|
||||
pGroup->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, _player);
|
||||
pGroup->SetRaidDifficulty(mode);
|
||||
pGroup->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, true, _player);
|
||||
pGroup->SetRaidDifficulty(Difficulty(mode));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_player->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY);
|
||||
_player->SetRaidDifficulty(mode);
|
||||
_player->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, true);
|
||||
_player->SetRaidDifficulty(Difficulty(mode));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -137,11 +137,22 @@ void WorldSession::HandleMoveWorldportAckOpcode()
|
|||
}
|
||||
}
|
||||
|
||||
if((mEntry->IsRaid() || (mEntry->IsNonRaidDungeon() && mEntry->SupportsHeroicMode() && GetPlayer()->IsHeroicDungeon())) && mInstance)
|
||||
if (mInstance)
|
||||
{
|
||||
if(mEntry->IsRaid())
|
||||
{
|
||||
uint32 timeleft = sInstanceSaveManager.GetResetTimeFor(GetPlayer()->GetMapId()) - time(NULL);
|
||||
GetPlayer()->SendInstanceResetWarning(GetPlayer()->GetMapId(), GetPlayer()->GetRaidDifficulty(), timeleft);
|
||||
}
|
||||
else if(mEntry->IsNonRaidDungeon() && GetPlayer()->GetDungeonDifficulty() > DUNGEON_DIFFICULTY_NORMAL)
|
||||
{
|
||||
if(MapDifficulty const* mapDiff = GetMapDifficultyData(mEntry->MapID,GetPlayer()->GetDungeonDifficulty()))
|
||||
{
|
||||
uint32 timeleft = sInstanceSaveManager.GetResetTimeFor(GetPlayer()->GetMapId()) - time(NULL);
|
||||
GetPlayer()->SendInstanceResetWarning(GetPlayer()->GetMapId(), GetPlayer()->GetDungeonDifficulty(), timeleft);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// mount allow check
|
||||
if(!mEntry->IsMountAllowed())
|
||||
|
|
|
|||
|
|
@ -3148,7 +3148,14 @@ void ObjectMgr::LoadGroups()
|
|||
continue;
|
||||
}
|
||||
|
||||
InstanceSave *save = sInstanceSaveManager.AddInstanceSave(mapEntry->MapID, fields[2].GetUInt32(), fields[4].GetUInt8(), (time_t)fields[5].GetUInt64(), (fields[6].GetUInt32() == 0), true);
|
||||
uint32 diff = fields[4].GetUInt8();
|
||||
if(diff >= (mapEntry->IsRaid() ? MAX_RAID_DIFFICULTY : MAX_DUNGEON_DIFFICULTY))
|
||||
{
|
||||
sLog.outErrorDb("Wrong dungeon difficulty use in group_instance table: %d", diff);
|
||||
diff = 0; // default for both difficaly types
|
||||
}
|
||||
|
||||
InstanceSave *save = sInstanceSaveManager.AddInstanceSave(mapEntry->MapID, fields[2].GetUInt32(), Difficulty(diff), (time_t)fields[5].GetUInt64(), (fields[6].GetUInt32() == 0), true);
|
||||
group->BindToInstance(save, fields[3].GetBool(), true);
|
||||
}while( result->NextRow() );
|
||||
delete result;
|
||||
|
|
@ -4477,15 +4484,15 @@ void ObjectMgr::LoadInstanceTemplate()
|
|||
for(uint32 i = 0; i < sInstanceTemplate.MaxEntry; i++)
|
||||
{
|
||||
InstanceTemplate* temp = (InstanceTemplate*)GetInstanceTemplate(i);
|
||||
if(!temp) continue;
|
||||
if(!temp)
|
||||
continue;
|
||||
|
||||
const MapEntry* entry = sMapStore.LookupEntry(temp->map);
|
||||
if(!entry)
|
||||
{
|
||||
sLog.outErrorDb("ObjectMgr::LoadInstanceTemplate: bad mapid %d for template!", temp->map);
|
||||
continue;
|
||||
}
|
||||
else if(!entry->HasResetTime())
|
||||
continue;
|
||||
|
||||
//FIXME: now exist heroic instance, normal/heroic raid instances
|
||||
// entry->resetTimeHeroic store reset time for both heroic mode instance (raid and non-raid)
|
||||
|
|
@ -4494,16 +4501,24 @@ void ObjectMgr::LoadInstanceTemplate()
|
|||
// but at some point wee need implement reset time dependent from raid instance mode
|
||||
if(temp->reset_delay == 0)
|
||||
{
|
||||
MapDifficulty const* mapDiffNorm = GetMapDifficultyData(temp->map,DUNGEON_DIFFICULTY_NORMAL);
|
||||
MapDifficulty const* mapDiffHeroic = GetMapDifficultyData(temp->map,DUNGEON_DIFFICULTY_HEROIC);
|
||||
|
||||
// no reset time
|
||||
if ((!mapDiffNorm || mapDiffNorm->resetTime == 0) &&
|
||||
(!mapDiffHeroic || mapDiffHeroic->resetTime == 0))
|
||||
continue;
|
||||
|
||||
// use defaults from the DBC
|
||||
/*if(entry->resetTimeHeroic) // for both raid and non raids, read above
|
||||
if(mapDiffHeroic && mapDiffHeroic->resetTime) // for both raid and non raids, read above
|
||||
{
|
||||
temp->reset_delay = entry->resetTimeHeroic / DAY;
|
||||
temp->reset_delay = mapDiffHeroic->resetTime / DAY;
|
||||
}
|
||||
else if (entry->resetTimeRaid && entry->map_type == MAP_RAID)
|
||||
else if (mapDiffNorm && mapDiffNorm->resetTime && entry->map_type == MAP_RAID)
|
||||
// for normal raid only
|
||||
{
|
||||
temp->reset_delay = entry->resetTimeRaid / DAY;
|
||||
}*/
|
||||
temp->reset_delay = mapDiffNorm->resetTime / DAY;
|
||||
}
|
||||
}
|
||||
|
||||
// the reset_delay must be at least one day
|
||||
|
|
|
|||
|
|
@ -509,7 +509,7 @@ Player::~Player ()
|
|||
delete ItemSetEff[x];
|
||||
|
||||
// clean up player-instance binds, may unload some instance saves
|
||||
for(uint8 i = 0; i < TOTAL_DUNGEON_DIFFICULTIES; ++i)
|
||||
for(uint8 i = 0; i < MAX_DIFFICULTY; ++i)
|
||||
for(BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr)
|
||||
itr->second.save->RemovePlayer(this);
|
||||
|
||||
|
|
@ -14182,7 +14182,11 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
|||
uint32 transGUID = fields[31].GetUInt32();
|
||||
Relocate(fields[13].GetFloat(),fields[14].GetFloat(),fields[15].GetFloat(),fields[17].GetFloat());
|
||||
SetLocationMapId(fields[16].GetUInt32());
|
||||
SetDungeonDifficulty(fields[39].GetUInt32()); // may be changed in _LoadGroup
|
||||
|
||||
uint32 difficulty = fields[39].GetUInt32();
|
||||
if(difficulty >= MAX_DUNGEON_DIFFICULTY)
|
||||
difficulty = DUNGEON_DIFFICULTY_NORMAL;
|
||||
SetDungeonDifficulty(Difficulty(difficulty)); // may be changed in _LoadGroup
|
||||
|
||||
_LoadGroup(holder->GetResult(PLAYER_LOGIN_QUERY_LOADGROUP));
|
||||
|
||||
|
|
@ -15281,19 +15285,20 @@ void Player::_LoadSpells(QueryResult *result)
|
|||
void Player::_LoadGroup(QueryResult *result)
|
||||
{
|
||||
//QueryResult *result = CharacterDatabase.PQuery("SELECT leaderGuid FROM group_member WHERE memberGuid='%u'", GetGUIDLow());
|
||||
if(result)
|
||||
if (result)
|
||||
{
|
||||
uint64 leaderGuid = MAKE_NEW_GUID((*result)[0].GetUInt32(), 0, HIGHGUID_PLAYER);
|
||||
delete result;
|
||||
Group* group = objmgr.GetGroupByLeader(leaderGuid);
|
||||
if(group)
|
||||
|
||||
if (Group* group = objmgr.GetGroupByLeader(leaderGuid))
|
||||
{
|
||||
uint8 subgroup = group->GetMemberGroup(GetGUID());
|
||||
SetGroup(group, subgroup);
|
||||
if(getLevel() >= LEVELREQUIREMENT_HEROIC)
|
||||
if (getLevel() >= LEVELREQUIREMENT_HEROIC)
|
||||
{
|
||||
// the group leader may change the instance difficulty while the player is offline
|
||||
SetDungeonDifficulty(group->GetDungeonDifficulty());
|
||||
SetRaidDifficulty(group->GetRaidDifficulty());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -15301,7 +15306,7 @@ void Player::_LoadGroup(QueryResult *result)
|
|||
|
||||
void Player::_LoadBoundInstances(QueryResult *result)
|
||||
{
|
||||
for(uint8 i = 0; i < TOTAL_DUNGEON_DIFFICULTIES; ++i)
|
||||
for(uint8 i = 0; i < MAX_DIFFICULTY; ++i)
|
||||
m_boundInstances[i].clear();
|
||||
|
||||
Group *group = GetGroup();
|
||||
|
|
@ -15316,6 +15321,7 @@ void Player::_LoadBoundInstances(QueryResult *result)
|
|||
uint32 mapId = fields[2].GetUInt32();
|
||||
uint32 instanceId = fields[0].GetUInt32();
|
||||
uint8 difficulty = fields[3].GetUInt8();
|
||||
|
||||
time_t resetTime = (time_t)fields[4].GetUInt64();
|
||||
// the resettime for normal instances is only saved when the InstanceSave is unloaded
|
||||
// so the value read from the DB may be wrong here but only if the InstanceSave is loaded
|
||||
|
|
@ -15329,6 +15335,21 @@ void Player::_LoadBoundInstances(QueryResult *result)
|
|||
continue;
|
||||
}
|
||||
|
||||
if(difficulty >= MAX_DIFFICULTY)
|
||||
{
|
||||
sLog.outError("_LoadBoundInstances: player %s(%d) has bind to not existed difficulty %d instance for map %u", GetName(), GetGUIDLow(), difficulty, mapId);
|
||||
CharacterDatabase.PExecute("DELETE FROM character_instance WHERE guid = '%d' AND instance = '%d'", GetGUIDLow(), instanceId);
|
||||
continue;
|
||||
}
|
||||
|
||||
MapDifficulty const* mapDiff = GetMapDifficultyData(mapId,Difficulty(difficulty));
|
||||
if(!mapDiff)
|
||||
{
|
||||
sLog.outError("_LoadBoundInstances: player %s(%d) has bind to not existed difficulty %d instance for map %u", GetName(), GetGUIDLow(), difficulty, mapId);
|
||||
CharacterDatabase.PExecute("DELETE FROM character_instance WHERE guid = '%d' AND instance = '%d'", GetGUIDLow(), instanceId);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!perm && group)
|
||||
{
|
||||
sLog.outError("_LoadBoundInstances: player %s(%d) is in group %d but has a non-permanent character bind to map %d,%d,%d", GetName(), GetGUIDLow(), GUID_LOPART(group->GetLeaderGUID()), mapId, instanceId, difficulty);
|
||||
|
|
@ -15337,18 +15358,19 @@ void Player::_LoadBoundInstances(QueryResult *result)
|
|||
}
|
||||
|
||||
// since non permanent binds are always solo bind, they can always be reset
|
||||
InstanceSave *save = sInstanceSaveManager.AddInstanceSave(mapId, instanceId, difficulty, resetTime, !perm, true);
|
||||
InstanceSave *save = sInstanceSaveManager.AddInstanceSave(mapId, instanceId, Difficulty(difficulty), resetTime, !perm, true);
|
||||
if(save) BindToInstance(save, perm, true);
|
||||
} while(result->NextRow());
|
||||
delete result;
|
||||
}
|
||||
}
|
||||
|
||||
InstancePlayerBind* Player::GetBoundInstance(uint32 mapid, uint8 difficulty)
|
||||
InstancePlayerBind* Player::GetBoundInstance(uint32 mapid, Difficulty difficulty)
|
||||
{
|
||||
// some instances only have one difficulty
|
||||
const MapEntry* entry = sMapStore.LookupEntry(mapid);
|
||||
if(!entry || !entry->SupportsHeroicMode()) difficulty = DUNGEON_DIFFICULTY_NORMAL;
|
||||
MapDifficulty const* mapDiff = GetMapDifficultyData(mapid,difficulty);
|
||||
if(!mapDiff)
|
||||
return NULL;
|
||||
|
||||
BoundInstancesMap::iterator itr = m_boundInstances[difficulty].find(mapid);
|
||||
if(itr != m_boundInstances[difficulty].end())
|
||||
|
|
@ -15357,13 +15379,13 @@ InstancePlayerBind* Player::GetBoundInstance(uint32 mapid, uint8 difficulty)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void Player::UnbindInstance(uint32 mapid, uint8 difficulty, bool unload)
|
||||
void Player::UnbindInstance(uint32 mapid, Difficulty difficulty, bool unload)
|
||||
{
|
||||
BoundInstancesMap::iterator itr = m_boundInstances[difficulty].find(mapid);
|
||||
UnbindInstance(itr, difficulty, unload);
|
||||
}
|
||||
|
||||
void Player::UnbindInstance(BoundInstancesMap::iterator &itr, uint8 difficulty, bool unload)
|
||||
void Player::UnbindInstance(BoundInstancesMap::iterator &itr, Difficulty difficulty, bool unload)
|
||||
{
|
||||
if(itr != m_boundInstances[difficulty].end())
|
||||
{
|
||||
|
|
@ -15415,7 +15437,7 @@ void Player::SendRaidInfo()
|
|||
|
||||
time_t now = time(NULL);
|
||||
|
||||
for(int i = 0; i < TOTAL_DUNGEON_DIFFICULTIES; ++i)
|
||||
for(int i = 0; i < MAX_DIFFICULTY; ++i)
|
||||
{
|
||||
for (BoundInstancesMap::const_iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr)
|
||||
{
|
||||
|
|
@ -15444,7 +15466,7 @@ void Player::SendSavedInstances()
|
|||
bool hasBeenSaved = false;
|
||||
WorldPacket data;
|
||||
|
||||
for(uint8 i = 0; i < TOTAL_DUNGEON_DIFFICULTIES; ++i)
|
||||
for(uint8 i = 0; i < MAX_DIFFICULTY; ++i)
|
||||
{
|
||||
for (BoundInstancesMap::const_iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr)
|
||||
{
|
||||
|
|
@ -15464,7 +15486,7 @@ void Player::SendSavedInstances()
|
|||
if(!hasBeenSaved)
|
||||
return;
|
||||
|
||||
for(uint8 i = 0; i < TOTAL_DUNGEON_DIFFICULTIES; ++i)
|
||||
for(uint8 i = 0; i < MAX_DIFFICULTY; ++i)
|
||||
{
|
||||
for (BoundInstancesMap::const_iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr)
|
||||
{
|
||||
|
|
@ -15492,7 +15514,7 @@ void Player::ConvertInstancesToGroup(Player *player, Group *group, uint64 player
|
|||
|
||||
if(player)
|
||||
{
|
||||
for(uint8 i = 0; i < TOTAL_DUNGEON_DIFFICULTIES; ++i)
|
||||
for(uint8 i = 0; i < MAX_DIFFICULTY; ++i)
|
||||
{
|
||||
for (BoundInstancesMap::iterator itr = player->m_boundInstances[i].begin(); itr != player->m_boundInstances[i].end();)
|
||||
{
|
||||
|
|
@ -15501,7 +15523,8 @@ void Player::ConvertInstancesToGroup(Player *player, Group *group, uint64 player
|
|||
// permanent binds are not removed
|
||||
if(!itr->second.perm)
|
||||
{
|
||||
player->UnbindInstance(itr, i, true); // increments itr
|
||||
// increments itr in call
|
||||
player->UnbindInstance(itr, Difficulty(i), true);
|
||||
has_solo = true;
|
||||
}
|
||||
else
|
||||
|
|
@ -16209,18 +16232,18 @@ void Player::SendResetFailedNotify(uint32 mapid)
|
|||
}
|
||||
|
||||
/// Reset all solo instances and optionally send a message on success for each
|
||||
void Player::ResetInstances(uint8 method)
|
||||
void Player::ResetInstances(uint8 method, bool isRaid)
|
||||
{
|
||||
// method can be INSTANCE_RESET_ALL, INSTANCE_RESET_CHANGE_DIFFICULTY, INSTANCE_RESET_GROUP_JOIN
|
||||
|
||||
// we assume that when the difficulty changes, all instances that can be reset will be
|
||||
uint8 dif = GetDungeonDifficulty();
|
||||
Difficulty diff = GetDifficulty(isRaid);
|
||||
|
||||
for (BoundInstancesMap::iterator itr = m_boundInstances[dif].begin(); itr != m_boundInstances[dif].end();)
|
||||
for (BoundInstancesMap::iterator itr = m_boundInstances[diff].begin(); itr != m_boundInstances[diff].end();)
|
||||
{
|
||||
InstanceSave *p = itr->second.save;
|
||||
const MapEntry *entry = sMapStore.LookupEntry(itr->first);
|
||||
if(!entry || !p->CanReset())
|
||||
if(!entry || entry->IsRaid() != isRaid || !p->CanReset())
|
||||
{
|
||||
++itr;
|
||||
continue;
|
||||
|
|
@ -16229,7 +16252,7 @@ void Player::ResetInstances(uint8 method)
|
|||
if(method == INSTANCE_RESET_ALL)
|
||||
{
|
||||
// the "reset all instances" method can only reset normal maps
|
||||
if(dif == DUNGEON_DIFFICULTY_HEROIC || entry->map_type == MAP_RAID)
|
||||
if(entry->map_type == MAP_RAID || diff == DUNGEON_DIFFICULTY_HEROIC)
|
||||
{
|
||||
++itr;
|
||||
continue;
|
||||
|
|
@ -16246,7 +16269,7 @@ void Player::ResetInstances(uint8 method)
|
|||
SendResetInstanceSuccess(p->GetMapId());
|
||||
|
||||
p->DeleteFromDB();
|
||||
m_boundInstances[dif].erase(itr++);
|
||||
m_boundInstances[diff].erase(itr++);
|
||||
|
||||
// the following should remove the instance save from the manager and delete it as well
|
||||
p->RemovePlayer(this);
|
||||
|
|
@ -18325,7 +18348,7 @@ void Player::SendTransferAborted(uint32 mapid, uint8 reason, uint8 arg)
|
|||
GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
void Player::SendInstanceResetWarning( uint32 mapid, uint32 difficulty, uint32 time )
|
||||
void Player::SendInstanceResetWarning( uint32 mapid, Difficulty difficulty, uint32 time )
|
||||
{
|
||||
// type of warning, based on the time remaining until reset
|
||||
uint32 type;
|
||||
|
|
|
|||
|
|
@ -704,6 +704,9 @@ enum TransferAbortReason
|
|||
TRANSFER_ABORT_NEED_GROUP = 0x0B, // 3.1
|
||||
TRANSFER_ABORT_NOT_FOUND2 = 0x0C, // 3.1
|
||||
TRANSFER_ABORT_NOT_FOUND3 = 0x0D, // 3.1
|
||||
TRANSFER_ABORT_NOT_FOUND4 = 0x0E, // 3.2
|
||||
TRANSFER_ABORT_REALM_ONLY = 0x0F, // All players on party must be from the same realm.
|
||||
TRANSFER_ABORT_MAP_NOT_ALLOWED = 0x10, // Map can't be entered at this time.
|
||||
};
|
||||
|
||||
enum InstanceResetWarningType
|
||||
|
|
@ -1039,7 +1042,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
void SendInitialPacketsBeforeAddToMap();
|
||||
void SendInitialPacketsAfterAddToMap();
|
||||
void SendTransferAborted(uint32 mapid, uint8 reason, uint8 arg = 0);
|
||||
void SendInstanceResetWarning(uint32 mapid, uint32 difficulty, uint32 time);
|
||||
void SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time);
|
||||
|
||||
Creature* GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask);
|
||||
bool CanInteractWithNPCs(bool alive = true) const;
|
||||
|
|
@ -1673,11 +1676,11 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
uint32 GetArenaTeamIdInvited() { return m_ArenaTeamIdInvited; }
|
||||
static void LeaveAllArenaTeams(uint64 guid);
|
||||
|
||||
void SetDungeonDifficulty(uint32 dungeon_difficulty) { m_dungeonDifficulty = dungeon_difficulty; }
|
||||
uint8 GetDungeonDifficulty() { return m_dungeonDifficulty; }
|
||||
bool IsHeroicDungeon() { return m_dungeonDifficulty == DUNGEON_DIFFICULTY_HEROIC; }
|
||||
void SetRaidDifficulty(uint32 raid_difficulty) { m_raidDifficulty = raid_difficulty; }
|
||||
uint8 GetRaidDifficulty() { return m_raidDifficulty; }
|
||||
Difficulty GetDifficulty(bool isRaid) const { return isRaid ? m_raidDifficulty : m_dungeonDifficulty; }
|
||||
Difficulty GetDungeonDifficulty() const { return m_dungeonDifficulty; }
|
||||
Difficulty GetRaidDifficulty() const { return m_raidDifficulty; }
|
||||
void SetDungeonDifficulty(Difficulty dungeon_difficulty) { m_dungeonDifficulty = dungeon_difficulty; }
|
||||
void SetRaidDifficulty(Difficulty raid_difficulty) { m_raidDifficulty = raid_difficulty; }
|
||||
|
||||
bool UpdateSkill(uint32 skill_id, uint32 step);
|
||||
bool UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step);
|
||||
|
|
@ -1765,7 +1768,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
|
||||
void SendDungeonDifficulty(bool IsInGroup);
|
||||
void SendRaidDifficulty(bool IsInGroup);
|
||||
void ResetInstances(uint8 method);
|
||||
void ResetInstances(uint8 method, bool isRaid);
|
||||
void SendResetInstanceSuccess(uint32 MapId);
|
||||
void SendResetInstanceFailed(uint32 reason, uint32 MapId);
|
||||
void SendResetFailedNotify(uint32 mapid);
|
||||
|
|
@ -2183,11 +2186,11 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
uint32 m_HomebindTimer;
|
||||
bool m_InstanceValid;
|
||||
// permanent binds and solo binds by difficulty
|
||||
BoundInstancesMap m_boundInstances[TOTAL_DUNGEON_DIFFICULTIES];
|
||||
InstancePlayerBind* GetBoundInstance(uint32 mapid, uint8 difficulty);
|
||||
BoundInstancesMap& GetBoundInstances(uint8 difficulty) { return m_boundInstances[difficulty]; }
|
||||
void UnbindInstance(uint32 mapid, uint8 difficulty, bool unload = false);
|
||||
void UnbindInstance(BoundInstancesMap::iterator &itr, uint8 difficulty, bool unload = false);
|
||||
BoundInstancesMap m_boundInstances[MAX_DIFFICULTY];
|
||||
InstancePlayerBind* GetBoundInstance(uint32 mapid, Difficulty difficulty);
|
||||
BoundInstancesMap& GetBoundInstances(Difficulty difficulty) { return m_boundInstances[difficulty]; }
|
||||
void UnbindInstance(uint32 mapid, Difficulty difficulty, bool unload = false);
|
||||
void UnbindInstance(BoundInstancesMap::iterator &itr, Difficulty difficulty, bool unload = false);
|
||||
InstancePlayerBind* BindToInstance(InstanceSave *save, bool permanent, bool load = false);
|
||||
void SendRaidInfo();
|
||||
void SendSavedInstances();
|
||||
|
|
@ -2339,8 +2342,8 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
uint32 m_nextSave;
|
||||
time_t m_speakTime;
|
||||
uint32 m_speakCount;
|
||||
uint32 m_dungeonDifficulty;
|
||||
uint32 m_raidDifficulty;
|
||||
Difficulty m_dungeonDifficulty;
|
||||
Difficulty m_raidDifficulty;
|
||||
|
||||
uint32 m_atLoginFlags;
|
||||
|
||||
|
|
|
|||
|
|
@ -2408,20 +2408,23 @@ enum DiminishingGroup
|
|||
DIMINISHING_LIMITONLY
|
||||
};
|
||||
|
||||
enum DungeonDifficulties
|
||||
enum Difficulty
|
||||
{
|
||||
DUNGEON_DIFFICULTY_NORMAL = 0,
|
||||
DUNGEON_DIFFICULTY_HEROIC = 1,
|
||||
TOTAL_DUNGEON_DIFFICULTIES
|
||||
|
||||
RAID_DIFFICULTY_10MAN_NORMAL = 0,
|
||||
RAID_DIFFICULTY_25MAN_NORMAL = 1,
|
||||
RAID_DIFFICULTY_10MAN_HEROIC = 2,
|
||||
RAID_DIFFICULTY_25MAN_HEROIC = 3,
|
||||
};
|
||||
|
||||
#define MAX_DUNGEON_DIFFICULTY 2
|
||||
#define MAX_RAID_DIFFICULTY 4
|
||||
#define MAX_DIFFICULTY 4
|
||||
|
||||
enum RaidDifficulties
|
||||
{
|
||||
RAID_DIFFICULTY_10MAN_NORMAL = 0,
|
||||
RAID_DIFFICULTY_10MAN_HEROIC = 1,
|
||||
RAID_DIFFICULTY_25MAN_NORMAL = 2,
|
||||
RAID_DIFFICULTY_25MAN_HEROIC = 3,
|
||||
TOTAL_RAID_DIFFICULTIES
|
||||
};
|
||||
|
||||
enum SummonType
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue