예제 #1
0
        // Reset all solo instances and optionally send a message on success for each
        public void ResetInstances(InstanceResetMethod method, bool isRaid, bool isLegacy)
        {
            // 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
            Difficulty diff = GetDungeonDifficultyID();

            if (isRaid)
            {
                if (!isLegacy)
                {
                    diff = GetRaidDifficultyID();
                }
                else
                {
                    diff = GetLegacyRaidDifficultyID();
                }
            }

            foreach (var pair in m_boundInstances[(int)diff].ToList())
            {
                InstanceSave p     = pair.Value.save;
                MapRecord    entry = CliDB.MapStorage.LookupByKey(pair.Key);
                if (entry == null || entry.IsRaid() != isRaid || !p.CanReset())
                {
                    continue;
                }

                if (method == InstanceResetMethod.All)
                {
                    // the "reset all instances" method can only reset normal maps
                    if (entry.InstanceType == MapTypes.Raid || diff == Difficulty.Heroic)
                    {
                        continue;
                    }
                }

                // if the map is loaded, reset it
                Map map = Global.MapMgr.FindMap(p.GetMapId(), p.GetInstanceId());
                if (map != null && map.IsDungeon())
                {
                    if (!map.ToInstanceMap().Reset(method))
                    {
                        continue;
                    }
                }

                // since this is a solo instance there should not be any players inside
                if (method == InstanceResetMethod.All || method == InstanceResetMethod.ChangeDifficulty)
                {
                    SendResetInstanceSuccess(p.GetMapId());
                }

                p.DeleteFromDB();
                m_boundInstances[(int)diff].Remove(pair.Key);

                // the following should remove the instance save from the manager and delete it as well
                p.RemovePlayer(this);
            }
        }
예제 #2
0
        public Difficulty GetDifficultyID(MapRecord mapEntry)
        {
            if (!mapEntry.IsRaid())
            {
                return(m_dungeonDifficulty);
            }

            MapDifficultyRecord defaultDifficulty = Global.DB2Mgr.GetDefaultMapDifficulty(mapEntry.Id);

            if (defaultDifficulty == null)
            {
                return(m_legacyRaidDifficulty);
            }

            DifficultyRecord difficulty = CliDB.DifficultyStorage.LookupByKey(defaultDifficulty.DifficultyID);

            if (difficulty == null || difficulty.Flags.HasAnyFlag(DifficultyFlags.Legacy))
            {
                return(m_legacyRaidDifficulty);
            }

            return(m_raidDifficulty);
        }
예제 #3
0
        public EnterState PlayerCannotEnter(uint mapid, Player player, bool loginCheck = false)
        {
            MapRecord entry = CliDB.MapStorage.LookupByKey(mapid);

            if (entry == null)
            {
                return(EnterState.CannotEnterNoEntry);
            }

            if (!entry.IsDungeon())
            {
                return(EnterState.CanEnter);
            }

            InstanceTemplate instance = Global.ObjectMgr.GetInstanceTemplate(mapid);

            if (instance == null)
            {
                return(EnterState.CannotEnterUninstancedDungeon);
            }

            Difficulty targetDifficulty = player.GetDifficultyID(entry);
            // Get the highest available difficulty if current setting is higher than the instance allows
            MapDifficultyRecord mapDiff = Global.DB2Mgr.GetDownscaledMapDifficultyData(entry.Id, ref targetDifficulty);

            if (mapDiff == null)
            {
                return(EnterState.CannotEnterDifficultyUnavailable);
            }

            //Bypass checks for GMs
            if (player.IsGameMaster())
            {
                return(EnterState.CanEnter);
            }

            string mapName = entry.MapName[Global.WorldMgr.GetDefaultDbcLocale()];

            Group group = player.GetGroup();

            if (entry.IsRaid() && entry.Expansion() >= (Expansion)WorldConfig.GetIntValue(WorldCfg.Expansion)) // can only enter in a raid group but raids from old expansion don't need a group
            {
                if ((!group || !group.IsRaidGroup()) && WorldConfig.GetBoolValue(WorldCfg.InstanceIgnoreRaid))
                {
                    return(EnterState.CannotEnterNotInRaid);
                }
            }

            if (!player.IsAlive())
            {
                if (player.HasCorpse())
                {
                    // let enter in ghost mode in instance that connected to inner instance with corpse
                    uint corpseMap = player.GetCorpseLocation().GetMapId();
                    do
                    {
                        if (corpseMap == mapid)
                        {
                            break;
                        }

                        InstanceTemplate corpseInstance = Global.ObjectMgr.GetInstanceTemplate(corpseMap);
                        corpseMap = corpseInstance != null ? corpseInstance.Parent : 0;
                    } while (corpseMap != 0);

                    if (corpseMap == 0)
                    {
                        return(EnterState.CannotEnterCorpseInDifferentInstance);
                    }

                    Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' has corpse in instance '{1}' and can enter.", player.GetName(), mapName);
                }
                else
                {
                    Log.outDebug(LogFilter.Maps, "Map.CanPlayerEnter - player '{0}' is dead but does not have a corpse!", player.GetName());
                }
            }

            //Get instance where player's group is bound & its map
            if (!loginCheck && group)
            {
                InstanceBind boundInstance = group.GetBoundInstance(entry);
                if (boundInstance != null && boundInstance.save != null)
                {
                    Map boundMap = FindMap(mapid, boundInstance.save.GetInstanceId());
                    if (boundMap != null)
                    {
                        EnterState denyReason = boundMap.CannotEnter(player);
                        if (denyReason != 0)
                        {
                            return(denyReason);
                        }
                    }
                }
            }
            // players are only allowed to enter 10 instances per hour
            if (entry.IsDungeon() && (player.GetGroup() == null || (player.GetGroup() != null && !player.GetGroup().IsLFGGroup())))
            {
                uint         instaceIdToCheck = 0;
                InstanceSave save             = player.GetInstanceSave(mapid);
                if (save != null)
                {
                    instaceIdToCheck = save.GetInstanceId();
                }

                // instanceId can never be 0 - will not be found
                if (!player.CheckInstanceCount(instaceIdToCheck) && !player.IsDead())
                {
                    return(EnterState.CannotEnterTooManyInstances);
                }
            }

            //Other requirements
            if (player.Satisfy(Global.ObjectMgr.GetAccessRequirement(mapid, targetDifficulty), mapid, true))
            {
                return(EnterState.CanEnter);
            }
            else
            {
                return(EnterState.CannotEnterUnspecifiedReason);
            }
        }