コード例 #1
0
        static bool HandleGoInstanceCommand(StringArguments args, CommandHandler handler)
        {
            if (args.Empty())
            {
                return(false);
            }

            uint   mapId = 0;
            string mapIdOrScriptNameStr = args.NextString();

            if (mapIdOrScriptNameStr.IsNumber())
            {
                mapId = uint.Parse(mapIdOrScriptNameStr);
            }

            if (mapId == 0)
            {
                List <Tuple <uint, string> > matches = new();
                foreach (var pair in Global.ObjectMgr.GetInstanceTemplates())
                {
                    string scriptName = Global.ObjectMgr.GetScriptName(pair.Value.ScriptId);
                    if (scriptName.Contains(mapIdOrScriptNameStr))
                    {
                        matches.Add(Tuple.Create(pair.Key, scriptName));
                    }
                }

                if (matches.Empty())
                {
                    handler.SendSysMessage(CypherStrings.CommandNoInstancesMatch);
                    return(false);
                }

                if (matches.Count > 1)
                {
                    handler.SendSysMessage(CypherStrings.CommandMultipleInstancesMatch);
                    return(false);
                }

                mapId = matches[0].Item1;
            }

            if (mapId == 0)
            {
                return(false);
            }

            InstanceTemplate temp = Global.ObjectMgr.GetInstanceTemplate(mapId);

            if (temp == null)
            {
                handler.SendSysMessage(CypherStrings.CommandMapNotInstance, mapId);
                return(false);
            }
            string scriptname = Global.ObjectMgr.GetScriptName(temp.ScriptId);

            Player player = handler.GetSession().GetPlayer();

            if (player.IsInFlight())
            {
                player.FinishTaxiFlight();
            }
            else
            {
                player.SaveRecallPosition();
            }

            // try going to entrance
            AreaTriggerStruct exit = Global.ObjectMgr.GetGoBackTrigger(mapId);

            if (exit == null)
            {
                handler.SendSysMessage(CypherStrings.CommandInstanceNoExit, mapId, scriptname);
            }

            if (exit != null && player.TeleportTo(exit.target_mapId, exit.target_X, exit.target_Y, exit.target_Z, exit.target_Orientation + MathF.PI))
            {
                handler.SendSysMessage(CypherStrings.CommandWentToInstanceGate, mapId, scriptname);
                return(true);
            }

            // try going to start
            AreaTriggerStruct entrance = Global.ObjectMgr.GetMapEntranceTrigger(mapId);

            if (entrance == null)
            {
                handler.SendSysMessage(CypherStrings.CommandInstanceNoEntrance, mapId, scriptname);
            }

            if (entrance != null && player.TeleportTo(entrance.target_mapId, entrance.target_X, entrance.target_Y, entrance.target_Z, entrance.target_Orientation))
            {
                handler.SendSysMessage(CypherStrings.CommandWentToInstanceStart, mapId, scriptname);
                return(true);
            }

            handler.SendSysMessage(CypherStrings.CommandGoInstanceFailed, mapId, scriptname, exit != null ? exit.target_mapId : -1);
            return(false);
        }
コード例 #2
0
ファイル: MiscHandler.cs プロジェクト: spadd/CypherCore
        void HandleAreaTrigger(AreaTriggerPkt packet)
        {
            Player player = GetPlayer();

            if (player.IsInFlight())
            {
                Log.outDebug(LogFilter.Network, "HandleAreaTrigger: Player '{0}' (GUID: {1}) in flight, ignore Area Trigger ID:{2}",
                             player.GetName(), player.GetGUID().ToString(), packet.AreaTriggerID);
                return;
            }

            AreaTriggerRecord atEntry = CliDB.AreaTriggerStorage.LookupByKey(packet.AreaTriggerID);

            if (atEntry == null)
            {
                Log.outDebug(LogFilter.Network, "HandleAreaTrigger: Player '{0}' (GUID: {1}) send unknown (by DBC) Area Trigger ID:{2}",
                             player.GetName(), player.GetGUID().ToString(), packet.AreaTriggerID);
                return;
            }

            if (packet.Entered && !player.IsInAreaTriggerRadius(atEntry))
            {
                Log.outDebug(LogFilter.Network, "HandleAreaTrigger: Player '{0}' ({1}) too far, ignore Area Trigger ID: {2}",
                             player.GetName(), player.GetGUID().ToString(), packet.AreaTriggerID);
                return;
            }

            if (player.IsDebugAreaTriggers)
            {
                player.SendSysMessage(packet.Entered ? CypherStrings.DebugAreatriggerEntered : CypherStrings.DebugAreatriggerLeft, packet.AreaTriggerID);
            }

            if (Global.ScriptMgr.OnAreaTrigger(player, atEntry, packet.Entered))
            {
                return;
            }

            if (player.IsAlive())
            {
                List <uint> quests = Global.ObjectMgr.GetQuestsForAreaTrigger(packet.AreaTriggerID);
                if (quests != null)
                {
                    foreach (uint questId in quests)
                    {
                        Quest qInfo = Global.ObjectMgr.GetQuestTemplate(questId);
                        if (qInfo != null && player.GetQuestStatus(questId) == QuestStatus.Incomplete)
                        {
                            foreach (QuestObjective obj in qInfo.Objectives)
                            {
                                if (obj.Type == QuestObjectiveType.AreaTrigger && !player.IsQuestObjectiveComplete(obj))
                                {
                                    player.SetQuestObjectiveData(obj, 1);
                                    player.SendQuestUpdateAddCreditSimple(obj);
                                    break;
                                }
                            }

                            if (player.CanCompleteQuest(questId))
                            {
                                player.CompleteQuest(questId);
                            }
                        }
                    }
                }
            }

            if (Global.ObjectMgr.IsTavernAreaTrigger(packet.AreaTriggerID))
            {
                // set resting flag we are in the inn
                player.GetRestMgr().SetRestFlag(RestFlag.Tavern, atEntry.Id);

                if (Global.WorldMgr.IsFFAPvPRealm())
                {
                    player.RemovePvpFlag(UnitPVPStateFlags.FFAPvp);
                }

                return;
            }
            Battleground bg = player.GetBattleground();

            if (bg)
            {
                bg.HandleAreaTrigger(player, packet.AreaTriggerID, packet.Entered);
            }

            OutdoorPvP pvp = player.GetOutdoorPvP();

            if (pvp != null)
            {
                if (pvp.HandleAreaTrigger(player, packet.AreaTriggerID, packet.Entered))
                {
                    return;
                }
            }

            AreaTriggerStruct at = Global.ObjectMgr.GetAreaTrigger(packet.AreaTriggerID);

            if (at == null)
            {
                return;
            }

            bool teleported = false;

            if (player.GetMapId() != at.target_mapId)
            {
                EnterState denyReason = Global.MapMgr.PlayerCannotEnter(at.target_mapId, player, false);
                if (denyReason != 0)
                {
                    bool reviveAtTrigger = false; // should we revive the player if he is trying to enter the correct instance?
                    switch (denyReason)
                    {
                    case EnterState.CannotEnterNoEntry:
                        Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' attempted to enter map with id {1} which has no entry", player.GetName(), at.target_mapId);
                        break;

                    case EnterState.CannotEnterUninstancedDungeon:
                        Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' attempted to enter dungeon map {1} but no instance template was found", player.GetName(), at.target_mapId);
                        break;

                    case EnterState.CannotEnterDifficultyUnavailable:
                    {
                        Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' attempted to enter instance map {1} but the requested difficulty was not found", player.GetName(), at.target_mapId);
                        MapRecord entry = CliDB.MapStorage.LookupByKey(at.target_mapId);
                        if (entry != null)
                        {
                            player.SendTransferAborted(entry.Id, TransferAbortReason.Difficulty, (byte)player.GetDifficultyID(entry));
                        }
                    }
                    break;

                    case EnterState.CannotEnterNotInRaid:
                        Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' must be in a raid group to enter map {1}", player.GetName(), at.target_mapId);
                        player.SendRaidGroupOnlyMessage(RaidGroupReason.Only, 0);
                        reviveAtTrigger = true;
                        break;

                    case EnterState.CannotEnterCorpseInDifferentInstance:
                        player.SendPacket(new AreaTriggerNoCorpse());
                        Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' does not have a corpse in instance map {1} and cannot enter", player.GetName(), at.target_mapId);
                        break;

                    case EnterState.CannotEnterInstanceBindMismatch:
                    {
                        MapRecord entry = CliDB.MapStorage.LookupByKey(at.target_mapId);
                        if (entry != null)
                        {
                            string mapName = entry.MapName[player.GetSession().GetSessionDbcLocale()];
                            Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' cannot enter instance map '{1}' because their permanent bind is incompatible with their group's", player.GetName(), mapName);
                            // is there a special opcode for this?
                            // @todo figure out how to get player localized difficulty string (e.g. "10 player", "Heroic" etc)
                            player.SendSysMessage(CypherStrings.InstanceBindMismatch, mapName);
                        }
                        reviveAtTrigger = true;
                    }
                    break;

                    case EnterState.CannotEnterTooManyInstances:
                        player.SendTransferAborted(at.target_mapId, TransferAbortReason.TooManyInstances);
                        Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' cannot enter instance map {1} because he has exceeded the maximum number of instances per hour.", player.GetName(), at.target_mapId);
                        reviveAtTrigger = true;
                        break;

                    case EnterState.CannotEnterMaxPlayers:
                        player.SendTransferAborted(at.target_mapId, TransferAbortReason.MaxPlayers);
                        reviveAtTrigger = true;
                        break;

                    case EnterState.CannotEnterZoneInCombat:
                        player.SendTransferAborted(at.target_mapId, TransferAbortReason.ZoneInCombat);
                        reviveAtTrigger = true;
                        break;

                    default:
                        break;
                    }

                    if (reviveAtTrigger) // check if the player is touching the areatrigger leading to the map his corpse is on
                    {
                        if (!player.IsAlive() && player.HasCorpse())
                        {
                            if (player.GetCorpseLocation().GetMapId() == at.target_mapId)
                            {
                                player.ResurrectPlayer(0.5f);
                                player.SpawnCorpseBones();
                            }
                        }
                    }

                    return;
                }

                Group group = player.GetGroup();
                if (group)
                {
                    if (group.IsLFGGroup() && player.GetMap().IsDungeon())
                    {
                        teleported = player.TeleportToBGEntryPoint();
                    }
                }
            }

            if (!teleported)
            {
                WorldSafeLocsEntry entranceLocation = null;
                InstanceSave       instanceSave     = player.GetInstanceSave(at.target_mapId);
                if (instanceSave != null)
                {
                    // Check if we can contact the instancescript of the instance for an updated entrance location
                    Map map = Global.MapMgr.FindMap(at.target_mapId, player.GetInstanceSave(at.target_mapId).GetInstanceId());
                    if (map)
                    {
                        InstanceMap instanceMap = map.ToInstanceMap();
                        if (instanceMap != null)
                        {
                            InstanceScript instanceScript = instanceMap.GetInstanceScript();
                            if (instanceScript != null)
                            {
                                entranceLocation = Global.ObjectMgr.GetWorldSafeLoc(instanceScript.GetEntranceLocation());
                            }
                        }
                    }

                    // Finally check with the instancesave for an entrance location if we did not get a valid one from the instancescript
                    if (entranceLocation == null)
                    {
                        entranceLocation = Global.ObjectMgr.GetWorldSafeLoc(instanceSave.GetEntranceLocation());
                    }
                }

                if (entranceLocation != null)
                {
                    player.TeleportTo(entranceLocation.Loc, TeleportToOptions.NotLeaveTransport);
                }
                else
                {
                    player.TeleportTo(at.target_mapId, at.target_X, at.target_Y, at.target_Z, at.target_Orientation, TeleportToOptions.NotLeaveTransport);
                }
            }
        }
コード例 #3
0
ファイル: GoCommands.cs プロジェクト: aufbau1/CypherCore
        static bool HandleGoInstanceCommand(CommandHandler handler, string[] labels)
        {
            if (labels.Empty())
            {
                return(false);
            }

            MultiMap <uint, Tuple <uint, string, string> > matches = new();

            foreach (var pair in Global.ObjectMgr.GetInstanceTemplates())
            {
                uint   count      = 0;
                string scriptName = Global.ObjectMgr.GetScriptName(pair.Value.ScriptId);
                string mapName1   = CliDB.MapStorage.LookupByKey(pair.Key).MapName[handler.GetSessionDbcLocale()];
                foreach (var label in labels)
                {
                    if (scriptName.Contains(label))
                    {
                        ++count;
                    }
                }

                if (count != 0)
                {
                    matches.Add(count, Tuple.Create(pair.Key, mapName1, scriptName));
                }
            }

            if (matches.Empty())
            {
                handler.SendSysMessage(CypherStrings.CommandNoInstancesMatch);
                return(false);
            }

            // see if we have multiple equal matches left
            var  keyValueList = matches.KeyValueList;
            uint maxCount     = keyValueList.Last().Key;

            for (var i = keyValueList.Count; i > 0;)
            {
                if ((++i) != 0 && keyValueList[i].Key == maxCount)
                {
                    handler.SendSysMessage(CypherStrings.CommandMultipleInstancesMatch);
                    --i;
                    do
                    {
                        handler.SendSysMessage(CypherStrings.CommandMultipleInstancesEntry, keyValueList[i].Value.Item2, keyValueList[i].Value.Item1, keyValueList[i].Value.Item3);
                    }while (((++i) != 0) && (keyValueList[i].Key == maxCount));
                    return(false);
                }
            }

            var    it      = matches.Last();
            uint   mapId   = it.Value.Item1;
            string mapName = it.Value.Item2;

            Player player = handler.GetSession().GetPlayer();

            if (player.IsInFlight())
            {
                player.FinishTaxiFlight();
            }
            else
            {
                player.SaveRecallPosition();
            }

            // try going to entrance
            AreaTriggerStruct exit = Global.ObjectMgr.GetGoBackTrigger(mapId);

            if (exit != null)
            {
                if (player.TeleportTo(exit.target_mapId, exit.target_X, exit.target_Y, exit.target_Z, exit.target_Orientation + MathF.PI))
                {
                    handler.SendSysMessage(CypherStrings.CommandWentToInstanceGate, mapName, mapId);
                    return(true);
                }
                else
                {
                    uint   parentMapId   = exit.target_mapId;
                    string parentMapName = CliDB.MapStorage.LookupByKey(parentMapId).MapName[handler.GetSessionDbcLocale()];
                    handler.SendSysMessage(CypherStrings.CommandGoInstanceGateFailed, mapName, mapId, parentMapName, parentMapId);
                }
            }
            else
            {
                handler.SendSysMessage(CypherStrings.CommandInstanceNoExit, mapName, mapId);
            }

            // try going to start
            AreaTriggerStruct entrance = Global.ObjectMgr.GetMapEntranceTrigger(mapId);

            if (entrance != null)
            {
                if (player.TeleportTo(entrance.target_mapId, entrance.target_X, entrance.target_Y, entrance.target_Z, entrance.target_Orientation))
                {
                    handler.SendSysMessage(CypherStrings.CommandWentToInstanceStart, mapName, mapId);
                    return(true);
                }
                else
                {
                    handler.SendSysMessage(CypherStrings.CommandGoInstanceStartFailed, mapName, mapId);
                }
            }
            else
            {
                handler.SendSysMessage(CypherStrings.CommandInstanceNoEntrance, mapName, mapId);
            }

            return(false);
        }