示例#1
0
        void _ResetSave(KeyValuePair <uint, InstanceSave> pair)
        {
            // unbind all players bound to the instance
            // do not allow UnbindInstance to automatically unload the InstanceSaves
            lock_instLists = true;

            bool          shouldDelete = true;
            var           pList        = pair.Value.m_playerList;
            List <Player> temp         = new List <Player>(); // list of expired binds that should be unbound

            foreach (var player in pList)
            {
                InstanceBind bind = player.GetBoundInstance(pair.Value.GetMapId(), pair.Value.GetDifficultyID());
                if (bind != null)
                {
                    Cypher.Assert(bind.save == pair.Value);
                    if (bind.perm && bind.extendState != 0) // permanent and not already expired
                    {
                        // actual promotion in DB already happened in caller
                        bind.extendState = bind.extendState == BindExtensionState.Extended ? BindExtensionState.Normal : BindExtensionState.Expired;
                        shouldDelete     = false;
                        continue;
                    }
                }
                temp.Add(player);
            }

            var gList = pair.Value.m_groupList;

            while (!gList.Empty())
            {
                Group group = gList.First();
                group.UnbindInstance(pair.Value.GetMapId(), pair.Value.GetDifficultyID(), true);
            }

            if (shouldDelete)
            {
                m_instanceSaveById.Remove(pair.Key);
            }

            lock_instLists = false;
        }
示例#2
0
        public Map CreateInstanceForPlayer(uint mapId, Player player, uint loginInstanceId = 0)
        {
            if (GetId() != mapId || player == null)
            {
                return(null);
            }

            Map  map           = null;
            uint newInstanceId = 0;                       // instanceId of the resulting map

            if (IsBattlegroundOrArena())
            {
                // instantiate or find existing bg map for player
                // the instance id is set in Battlegroundid
                newInstanceId = player.GetBattlegroundId();
                if (newInstanceId == 0)
                {
                    return(null);
                }

                map = Global.MapMgr.FindMap(mapId, newInstanceId);
                if (map == null)
                {
                    Battleground bg = player.GetBattleground();
                    if (bg)
                    {
                        map = CreateBattleground(newInstanceId, bg);
                    }
                    else
                    {
                        player.TeleportToBGEntryPoint();
                        return(null);
                    }
                }
            }
            else if (!IsGarrison())
            {
                InstanceBind pBind = player.GetBoundInstance(GetId(), player.GetDifficultyID(GetEntry()));
                InstanceSave pSave = pBind != null ? pBind.save : null;

                // priority:
                // 1. player's permanent bind
                // 2. player's current instance id if this is at login
                // 3. group's current bind
                // 4. player's current bind
                if (pBind == null || !pBind.perm)
                {
                    if (loginInstanceId != 0) // if the player has a saved instance id on login, we either use this instance or relocate him out (return null)
                    {
                        map = FindInstanceMap(loginInstanceId);
                        return((map && map.GetId() == GetId()) ? map : null); // is this check necessary? or does MapInstanced only find instances of itself?
                    }

                    InstanceBind 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);
                        if (groupBind != null)
                        {
                            // solo saves should be reset when entering a group's instance
                            player.UnbindInstance(GetId(), player.GetDifficultyID(GetEntry()));
                            pSave = groupBind.save;
                        }
                    }
                }
                if (pSave != null)
                {
                    // solo/perm/group
                    newInstanceId = pSave.GetInstanceId();
                    map           = FindInstanceMap(newInstanceId);
                    // it is possible that the save exists but the map doesn't
                    if (map == null)
                    {
                        map = CreateInstance(newInstanceId, pSave, pSave.GetDifficultyID(), player.GetTeamId());
                    }
                }
                else
                {
                    // if no instanceId via group members or instance saves is found
                    // the instance will be created for the first time
                    newInstanceId = Global.MapMgr.GenerateInstanceId();

                    Difficulty diff = player.GetGroup() != null?player.GetGroup().GetDifficultyID(GetEntry()) : player.GetDifficultyID(GetEntry());

                    //Seems it is now possible, but I do not know if it should be allowed
                    map = FindInstanceMap(newInstanceId);
                    if (map == null)
                    {
                        map = CreateInstance(newInstanceId, null, diff, player.GetTeamId());
                    }
                }
            }
            else
            {
                newInstanceId = (uint)player.GetGUID().GetCounter();
                map           = FindInstanceMap(newInstanceId);
                if (!map)
                {
                    map = CreateGarrison(newInstanceId, player);
                }
            }

            return(map);
        }