mirror of
https://github.com/mangosfour/server.git
synced 2025-12-15 01: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
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue