[10713] player/group instance binding fixes.

* Use anum instead raw uint8 type in args
* Fixed crash when gm at continent invite to group gm in instance
  and then teleport to instance using .goname.
  When group leader teleport to instance it must get group bind instead solo bind.
* In other semilar cases detection report error as before but replace solo by group bind instead
  assert crash at enter to map.
This commit is contained in:
VladimirMangos 2010-11-10 04:29:15 +03:00
parent a87648c56b
commit 9c96949da9
9 changed files with 33 additions and 20 deletions

View file

@ -1665,7 +1665,7 @@ bool Group::InCombatToInstance(uint32 instanceId)
return false; return false;
} }
void Group::ResetInstances(uint8 method, bool isRaid, Player* SendMsgTo) void Group::ResetInstances(InstanceResetMethod method, bool isRaid, Player* SendMsgTo)
{ {
if(isBGGroup()) if(isBGGroup())
return; return;

View file

@ -26,6 +26,7 @@
#include "BattleGround.h" #include "BattleGround.h"
#include "LootMgr.h" #include "LootMgr.h"
#include "DBCEnums.h" #include "DBCEnums.h"
#include "SharedDefines.h"
#include <map> #include <map>
#include <vector> #include <vector>
@ -325,7 +326,7 @@ class MANGOS_DLL_SPEC Group
void SetRaidDifficulty(Difficulty difficulty); void SetRaidDifficulty(Difficulty difficulty);
uint16 InInstance(); uint16 InInstance();
bool InCombatToInstance(uint32 instanceId); bool InCombatToInstance(uint32 instanceId);
void ResetInstances(uint8 method, bool isRaid, Player* SendMsgTo); void ResetInstances(InstanceResetMethod method, bool isRaid, Player* SendMsgTo);
void SendTargetIconList(WorldSession *session); void SendTargetIconList(WorldSession *session);
void SendUpdate(); void SendUpdate();

View file

@ -553,9 +553,17 @@ bool ChatHandler::HandleGonameCommand(char* args)
InstanceGroupBind *gBind = group ? group->GetBoundInstance(target->GetMapId(), target) : NULL; InstanceGroupBind *gBind = group ? group->GetBoundInstance(target->GetMapId(), target) : NULL;
// if no bind exists, create a solo bind // if no bind exists, create a solo bind
if (!gBind) if (!gBind)
{
if (InstanceSave *save = target->GetMap()->GetInstanceSave()) if (InstanceSave *save = target->GetMap()->GetInstanceSave())
{
// if player is group leader then we need add group bind
if (group && group->IsLeader(_player->GetObjectGuid()))
group->BindToInstance(save, !save->CanReset());
else
_player->BindToInstance(save, !save->CanReset()); _player->BindToInstance(save, !save->CanReset());
} }
}
}
if(cMap->IsRaid()) if(cMap->IsRaid())
_player->SetRaidDifficulty(target->GetRaidDifficulty()); _player->SetRaidDifficulty(target->GetRaidDifficulty());

View file

@ -1740,7 +1740,7 @@ bool InstanceMap::Add(Player *player)
if (IsDungeon()) if (IsDungeon())
{ {
// check for existing instance binds // check for existing instance binds
InstancePlayerBind *playerBind = player->GetBoundInstance(GetId(), Difficulty(GetSpawnMode())); InstancePlayerBind *playerBind = player->GetBoundInstance(GetId(), GetDifficulty());
if (playerBind && playerBind->perm) if (playerBind && playerBind->perm)
{ {
// cannot enter other instances if bound permanently // cannot enter other instances if bound permanently
@ -1778,8 +1778,11 @@ bool InstanceMap::Add(Player *player)
pGroup->GetId(), pGroup->GetId(),
groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty(), groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty(),
groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount(), groupBind->save->CanReset()); groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount(), groupBind->save->CanReset());
MANGOS_ASSERT(false);
// no reason crash if we can fix state
player->UnbindInstance(GetId(), GetDifficulty());
} }
// bind to the group or keep using the group save // bind to the group or keep using the group save
if (!groupBind) if (!groupBind)
pGroup->BindToInstance(GetInstanceSave(), false); pGroup->BindToInstance(GetInstanceSave(), false);
@ -1922,7 +1925,7 @@ void InstanceMap::CreateInstanceData(bool load)
/* /*
Returns true if there are no players in the instance Returns true if there are no players in the instance
*/ */
bool InstanceMap::Reset(uint8 method) bool InstanceMap::Reset(InstanceResetMethod method)
{ {
// note: since the map may not be loaded when the instance needs to be reset // note: since the map may not be loaded when the instance needs to be reset
// the instance must be deleted from the DB by InstanceSaveManager // the instance must be deleted from the DB by InstanceSaveManager

View file

@ -369,16 +369,6 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
void DeleteFromWorld(T*); void DeleteFromWorld(T*);
}; };
enum InstanceResetMethod
{
INSTANCE_RESET_ALL,
INSTANCE_RESET_CHANGE_DIFFICULTY,
INSTANCE_RESET_GLOBAL,
INSTANCE_RESET_GROUP_DISBAND,
INSTANCE_RESET_GROUP_JOIN,
INSTANCE_RESET_RESPAWN_DELAY
};
class MANGOS_DLL_SPEC InstanceMap : public Map class MANGOS_DLL_SPEC InstanceMap : public Map
{ {
public: public:
@ -388,7 +378,7 @@ class MANGOS_DLL_SPEC InstanceMap : public Map
void Remove(Player *, bool); void Remove(Player *, bool);
void Update(uint32 time_, uint32 diff); void Update(uint32 time_, uint32 diff);
void CreateInstanceData(bool load); void CreateInstanceData(bool load);
bool Reset(uint8 method); bool Reset(InstanceResetMethod method);
uint32 GetScriptId() { return i_script_id; } uint32 GetScriptId() { return i_script_id; }
InstanceData* GetInstanceData() { return i_data; } InstanceData* GetInstanceData() { return i_data; }
void PermBindAllPlayers(Player *player); void PermBindAllPlayers(Player *player);

View file

@ -17661,7 +17661,7 @@ void Player::SendResetFailedNotify(uint32 mapid)
} }
/// Reset all solo instances and optionally send a message on success for each /// Reset all solo instances and optionally send a message on success for each
void Player::ResetInstances(uint8 method, bool isRaid) void Player::ResetInstances(InstanceResetMethod method, bool isRaid)
{ {
// method can be INSTANCE_RESET_ALL, INSTANCE_RESET_CHANGE_DIFFICULTY, INSTANCE_RESET_GROUP_JOIN // method can be INSTANCE_RESET_ALL, INSTANCE_RESET_CHANGE_DIFFICULTY, INSTANCE_RESET_GROUP_JOIN

View file

@ -37,6 +37,7 @@
#include "ReputationMgr.h" #include "ReputationMgr.h"
#include "BattleGround.h" #include "BattleGround.h"
#include "DBCEnums.h" #include "DBCEnums.h"
#include "SharedDefines.h"
#include<string> #include<string>
#include<vector> #include<vector>
@ -1919,7 +1920,7 @@ class MANGOS_DLL_SPEC Player : public Unit
void SendDungeonDifficulty(bool IsInGroup); void SendDungeonDifficulty(bool IsInGroup);
void SendRaidDifficulty(bool IsInGroup); void SendRaidDifficulty(bool IsInGroup);
void ResetInstances(uint8 method, bool isRaid); void ResetInstances(InstanceResetMethod method, bool isRaid);
void SendResetInstanceSuccess(uint32 MapId); void SendResetInstanceSuccess(uint32 MapId);
void SendResetInstanceFailed(uint32 reason, uint32 MapId); void SendResetInstanceFailed(uint32 reason, uint32 MapId);
void SendResetFailedNotify(uint32 mapid); void SendResetFailedNotify(uint32 mapid);

View file

@ -2472,6 +2472,16 @@ enum DiminishingGroup
DIMINISHING_LIMITONLY DIMINISHING_LIMITONLY
}; };
enum InstanceResetMethod
{
INSTANCE_RESET_ALL,
INSTANCE_RESET_CHANGE_DIFFICULTY,
INSTANCE_RESET_GLOBAL,
INSTANCE_RESET_GROUP_DISBAND,
INSTANCE_RESET_GROUP_JOIN,
INSTANCE_RESET_RESPAWN_DELAY
};
enum ResponseCodes enum ResponseCodes
{ {
RESPONSE_SUCCESS = 0x00, RESPONSE_SUCCESS = 0x00,

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "10712" #define REVISION_NR "10713"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__