示例#1
0
文件: Model.cs 项目: haimgil1/ap2ex2
        /// <summary>
        /// Solves the maze BFS.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <returns>Solution</returns>
        public Solution <Position> solveMazeBFS(string name)
        {
            modelData.mutexBfs.WaitOne();
            Solution <Position> solution = null;

            // Check if the maze exist.
            if (modelData.Mazes.ContainsKey(name))
            {
                ISearchable <Position> mazeObjectAdapter = new MazeAdapter(modelData.Mazes[name]);
                ISearcher <Position>   BFS = new BestFirstSearch <Position>();
                // Check if the solution exist.
                if (modelData.BfsSolutions.ContainsKey(name))
                {
                    solution = modelData.BfsSolutions[name];
                }
                else
                {
                    // Calculate the solution.
                    solution = BFS.Search(mazeObjectAdapter);
                    modelData.BfsSolutions.Add(name, solution);
                }
            }


            State <Position> .StatePool.Clear();

            modelData.mutexBfs.ReleaseMutex();
            return(solution);
        }
示例#2
0
 /// <summary>
 /// Follow the Monsters target to it's position.
 /// </summary>
 /// <param name="targetSession">The TargetSession to follow</param>
 private void FollowTarget(ClientSession targetSession)
 {
     if (IsMoving)
     {
         if (!Path.Any() && targetSession != null)
         {
             short xoffset = (short)ServerManager.Instance.RandomNumber(-1, 1);
             short yoffset = (short)ServerManager.Instance.RandomNumber(-1, 1);
             try
             {
                 List <Node> list = BestFirstSearch.TracePath(new Node()
                 {
                     X = MapX, Y = MapY
                 }, targetSession.Character.BrushFire, targetSession.Character.MapInstance.Map.Grid);
                 Path = list;
             }
             catch (Exception ex)
             {
                 Logger.Log.Error($"Pathfinding using Pathfinder failed. Map: {MapId} StartX: {MapX} StartY: {MapY} TargetX: {(short)(targetSession.Character.PositionX + xoffset)} TargetY: {(short)(targetSession.Character.PositionY + yoffset)}", ex);
                 RemoveTarget();
             }
         }
         if (targetSession == null || MapId != targetSession.Character.MapInstance.Map.MapId)
         {
             RemoveTarget();
         }
     }
 }
        private static void Main(string[] args)
        {
            // the maze size 100x100
            int col = 100;
            int row = 100;

            // create maze with DFSMazeGenerator
            DFSMazeGenerator generator = new DFSMazeGenerator();
            Maze             maze      = generator.Generate(col, row);

            // print the maze
            Console.Write(maze.ToString());

            // adapt the maze and solve it with BFS
            ISearchable <Position> adapter     = new MazeAdapter(maze);
            ISearcher <Position>   bfsSearcher = new BestFirstSearch <Position>();

            bfsSearcher.Search(adapter);

            int bfsNumOfStases = bfsSearcher.GetNumberOfNodesEvaluated();

            // solve the maze with DFS
            ISearcher <Position> dfsSearcher = new DepthFirstSearch <Position>();

            dfsSearcher.Search(adapter);

            int dfsNumOfStases = dfsSearcher.GetNumberOfNodesEvaluated();

            // print the num of evalueted nodes for BFS and DFS
            Console.WriteLine("number of BFS states:" + bfsNumOfStases);
            Console.WriteLine("number of DFS states:" + dfsNumOfStases);

            Console.Read();
        }
示例#4
0
        /// <summary>
        /// Solves the specified maze.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="algorithmNumber">The algorithm number.</param>
        /// <returns>Solution.</returns>
        public Solution solve(string name, int algorithmNumber)
        {
            var maze           = DictionaryOfMazes[name];
            var searchableMaze = new SearchableMaze(maze);

            if (DictionaryOfMazesAndSolutions.ContainsKey(searchableMaze))
            {
                return(DictionaryOfMazesAndSolutions[searchableMaze]);
            }
            Solution  solution;
            ISearcher searchAlgorithm = null;

            switch (algorithmNumber)
            {
            case 0:
                searchAlgorithm = new BestFirstSearch <PointState>();
                break;

            case 1:
                searchAlgorithm = new DepthFirstSearch <PointState>();
                break;
            }

            solution      = searchAlgorithm.search(searchableMaze);
            EvaluateNodes = searchAlgorithm.getNumberOfNodesEvaluated();
            DictionaryOfMazesAndSolutions.Add(searchableMaze, solution);
            return(solution);
        }
示例#5
0
 public void UpdateBushFire()
 {
     BrushFire = BestFirstSearch.LoadBrushFire(new GridPos()
     {
         X = PositionX,
         Y = PositionY
     }, Owner.MapInstance.Map.Grid);
 }
示例#6
0
        public LinkedList <string> calcFastestWay(string source, string dest)
        {
            BestFirstSearch bfs = new BestFirstSearch();

            bfs.BuildGraph();
            bfs.Search(source, dest, "time");
            return(bfs.path);
        }
示例#7
0
 /// <summary>
 /// Remove the current Target from Npc.
 /// </summary>
 internal void RemoveTarget()
 {
     Target = null;
     Path   = BestFirstSearch.FindPath(new Node {
         X = MapX, Y = MapY
     }, new Node {
         X = FirstX, Y = FirstY
     }, MapInstance.Map.Grid);                                                                                                    // Path To origins
 }
示例#8
0
        static void Main(string[] args)
        {
            Console.BufferWidth  = 300;
            Console.BufferHeight = 240;
            Console.WindowWidth  = 180;

            Console.WriteLine("Press any key to start...");
            Console.ReadKey();

            FileStream mapFileStream = File.Open("Maps/vadim_maze.cmap", FileMode.Open, FileAccess.Read);

            ConsoleMap map = ConsoleMapGenerator.FromText(mapFileStream, 'S', 'E', 'X', '.');

            _map = map;

            InitArrays(2);

            Vector2Int start = map.DefaultStart;
            Vector2Int stop  = map.DefaultStop;

            _start = start;
            _stop  = stop;
            Vector2Int scale   = new Vector2Int(4, 2);
            int        spacing = 4;


            InitConsoleDrawer(map, scale, spacing, start, stop, 0);
            InitConsoleDrawer(map, scale, spacing, start, stop, 1);

            Console.SetCursorPosition(0, map.Height * scale.Y);

            AStarAlgorithm aStarTest = new AStarAlgorithm();
            var            path      = aStarTest.GetPath(_map, start, stop, NeighbourMode.SideOnly);

            if (path != null)
            {
                Console.WriteLine("Path was found");
                DrawPath(path, 0);
            }

            _contestants[0] = new BestFirstSearch();
            _contestants[0].OnCellViewedEvent += OnCellUpdated;

            _contestants[1] = new AStarAlgorithm();
            _contestants[1].OnCellViewedEvent += OnCellUpdated;

            StartPathFinder(0);
            StartPathFinder(1);

            while (_runningTasks > 0)
            {
                Thread.Sleep(100);
            }

            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }
示例#9
0
 public MazeModel()
 {
     _mazes         = new Dictionary <string, Maze>();
     _games         = new Dictionary <string, GameController>();
     _solutions     = new Dictionary <string, MazeSolution>();
     _generator     = new DFSMazeGenerator();
     _algorithms    = new ISearcher <Position> [2];
     _algorithms[0] = new BestFirstSearch <Position>();
     _algorithms[1] = new DepthFirstSearch <Position>();
 }
示例#10
0
        /// <summary>
        /// Follow the Monsters target to it's position.
        /// </summary>
        /// <param name="targetSession">The TargetSession to follow</param>
        private void FollowTarget(ClientSession targetSession)
        {
            if (IsMoving)
            {
                short maxDistance = 22;
                int   distance    = 0;
                if (!Path.Any() && targetSession != null)
                {
                    short xoffset = (short)ServerManager.Instance.RandomNumber(-1, 1);
                    short yoffset = (short)ServerManager.Instance.RandomNumber(-1, 1);
                    try
                    {
                        List <Node> list = BestFirstSearch.TracePath(new Node()
                        {
                            X = MapX, Y = MapY
                        }, targetSession.Character.BrushFire, targetSession.Character.MapInstance.Map.Grid);
                        Path = list;
                    }
                    catch (Exception ex)
                    {
                        Logger.Log.Error($"Pathfinding using Pathfinder failed. Map: {MapId} StartX: {MapX} StartY: {MapY} TargetX: {(short)(targetSession.Character.PositionX + xoffset)} TargetY: {(short)(targetSession.Character.PositionY + yoffset)}", ex);
                        RemoveTarget();
                    }
                }
                if (Monster != null && DateTime.Now > LastMove && Monster.Speed > 0 && Path.Any())
                {
                    int    maxindex    = Path.Count > Monster.Speed / 2 ? Monster.Speed / 2 : Path.Count;
                    short  mapX        = Path.ElementAt(maxindex - 1).X;
                    short  mapY        = Path.ElementAt(maxindex - 1).Y;
                    double waitingtime = Map.GetDistance(new MapCell {
                        X = mapX, Y = mapY
                    }, new MapCell {
                        X = MapX, Y = MapY
                    }) / (double)Monster.Speed;
                    MapInstance.Broadcast(new BroadcastPacket(null, $"mv 3 {MapMonsterId} {mapX} {mapY} {Monster.Speed}", ReceiverType.All, xCoordinate: mapX, yCoordinate: mapY));
                    LastMove = DateTime.Now.AddSeconds(waitingtime > 1 ? 1 : waitingtime);

                    Observable.Timer(TimeSpan.FromMilliseconds((int)((waitingtime > 1 ? 1 : waitingtime) * 1000))).Subscribe(x =>
                    {
                        MapX = mapX;
                        MapY = mapY;
                    });
                    distance = (int)Path.First().F;
                    Path.RemoveRange(0, maxindex);
                }

                if (targetSession == null || MapId != targetSession.Character.MapInstance.Map.MapId || distance > maxDistance)
                {
                    RemoveTarget();
                }
            }
        }
示例#11
0
 /// <summary>
 /// Remove the current Target from Monster.
 /// </summary>
 internal void RemoveTarget()
 {
     GetNearestOponent();
     if (Target != null)
     {
         Path.Clear();
         return;
     }
     Path = BestFirstSearch.FindPath(new Node {
         X = MapX, Y = MapY
     }, new Node {
         X = FirstX, Y = FirstY
     }, MapInstance.Map.Grid);                                                                                                    // Path To origins
 }
示例#12
0
文件: MapNpc.cs 项目: Vorlent/OpenNos
 /// <summary>
 /// Remove the current Target from Npc.
 /// </summary>
 internal void RemoveTarget()
 {
     if (Target != -1)
     {
         Path.Clear();
         Target = -1;
         //return to origin
         Path = BestFirstSearch.FindPath(new Node {
             X = MapX, Y = MapY
         }, new Node {
             X = FirstX, Y = FirstY
         }, MapInstance.Map.Grid);
     }
 }
示例#13
0
        public static void CompareSolvers()
        {
            DFSMazeGenerator generator = new DFSMazeGenerator();
            Maze             m         = generator.Generate(5, 6);

            Console.WriteLine(m.ToString());

            BestFirstSearch <CellType> bfs = new BestFirstSearch <CellType>();
            DFS <CellType>             dfs = new DFS <CellType>();

            Solution <CellType> SolBFS = bfs.search(m);
            Solution <CellType> SolDFS = dfs.search(m);

            Console.ReadLine();
        }
示例#14
0
 public IHttpActionResult SolveMaze(MazeName NameParam)
 {
     try
     {
         Searcher <Position>          algorithm       = new BestFirstSearch <Position>(new StateComparerByCost <Position>());
         Solution <State <Position> > sol             = this.mazeModel.Solve(NameParam.Name, algorithm);
         MazeSolutionAdapter          solutionAdapter = new MazeSolutionAdapter(sol);
         return(Ok(JObject.Parse(solutionAdapter.ToJson(NameParam.Name))));
     }
     catch (ArgumentException)
     {
         // Content bla bla BadRequest blabla
         return(NotFound());
     }
 }
示例#15
0
        /// <summary>
        /// Compares the solvers.
        /// </summary>
        public static void CompareSolvers()
        {
            DFSMazeGenerator generator = new DFSMazeGenerator();
            Maze             maze      = generator.Generate(10, 10);
            //Console.WriteLine(maze);
            ISearchable <Position> mazeAdapter = new MazeAdapter(maze);
            ISearcher <Position>   bfs         = new BestFirstSearch <Position>();
            ISearcher <Position>   dfs         = new Dfs <Position>();
            Solution <Position>    solution    = bfs.Search(mazeAdapter);

            Console.WriteLine("bfs sol:" + solution.EvaluatedNodes);
            Console.WriteLine(mazeAdapter.ToString(solution));
            solution = dfs.Search(mazeAdapter);
            Console.WriteLine("dfs sol:" + solution.EvaluatedNodes);
            Console.WriteLine(mazeAdapter.ToString(solution));
        }
示例#16
0
        internal static Node <TFactor, TStep> Run <TFactor, TStep>(this HeuristicSearchBase <TFactor, TStep> source)
        {
            Debug.WriteLine($"Searching path between {source.From} and {source.To} with {source.AlgorithmName}...");

            var lastNode        = default(Node <TFactor, TStep>);
            var observerFactory = source.AlgorithmObserverFactory;
            var observer        = observerFactory != null?observerFactory.Create(source) : null;

            switch (source.AlgorithmName)
            {
            case nameof(AStar):
                lastNode = observer == null?AStar.Run(source) : AStar.Run(source, observer);

                break;

            case nameof(BestFirstSearch):
                lastNode = observer == null?BestFirstSearch.Run(source) : BestFirstSearch.Run(source, observer);

                break;

            case nameof(IterativeDeepeningAStar):
                lastNode = observer == null?IterativeDeepeningAStar.Run(source) : IterativeDeepeningAStar.Run(source, observer);

                break;

            case nameof(RecursiveBestFirstSearch):
                lastNode = observer == null?RecursiveBestFirstSearch.Run(source) : RecursiveBestFirstSearch.Run(source, observer);

                break;

            default:
                var algorithm = HeuristicSearch.RegisteredAlgorithms[source.AlgorithmName](source.AlgorithmName);

                if (algorithm is IObservableAlgorithm && observer != null)
                {
                    lastNode = (algorithm as IObservableAlgorithm).Run(source, observer);
                }
                else
                {
                    lastNode = algorithm.Run(source);
                }
                break;
            }

            return(lastNode);
        }
示例#17
0
        public override IEnumerator <TFactor> GetEnumerator()
        {
            Debug.WriteLine($"Searching path between {From} and {To} with {AlgorithmName}...");

            var lastNode = default(Node <TFactor, TStep>);

            switch (AlgorithmName)
            {
            case nameof(AStar):
                lastNode = AStar.Run(this);
                break;

            case nameof(BestFirstSearch):
                lastNode = BestFirstSearch.Run(this);
                break;

            case nameof(IterativeDeepeningAStar):
                lastNode = IterativeDeepeningAStar.Run(this);
                break;

            case nameof(RecursiveBestFirstSearch):
                lastNode = RecursiveBestFirstSearch.Run(this);
                break;

            default:
                lastNode = HeuristicSearch.RegisteredAlgorithms[AlgorithmName](AlgorithmName).Run(this);
                break;
            }
            if (lastNode == null) // Solution not found
            {
                return(Enumerable.Empty <TFactor>().GetEnumerator());
            }

            if (IsReversed)
            {
                return(lastNode.EnumerateReverseFactors().GetEnumerator());
            }
            else
            {
                return(lastNode.TraceBack().EnumerateFactors().GetEnumerator());
            }
        }
示例#18
0
    static void Main(string[] args)
    {
        Console.WriteLine("THE START !!");

        ISearcher <int> ser = new BestFirstSearch <int>();


        Dictionary <State <int>, List <State <int> > > Adj = new Dictionary <State <int>, List <State <int> > >();
        State <int> one   = new State <int>(1);
        State <int> two   = new State <int>(2);
        State <int> three = new State <int>(3);
        State <int> four  = new State <int>(4);
        State <int> five  = new State <int>(5);
        State <int> six   = new State <int>(6);
        State <int> seven = new State <int>(7);

        Adj[one] = new List <State <int> > {
            two, three
        };
        Adj[two] = new List <State <int> > {
            four, five
        };
        Adj[three] = new List <State <int> > {
            two, six
        };
        Adj[four] = new List <State <int> >();
        Adj[five] = new List <State <int> > {
            six
        };
        Adj[six] = new List <State <int> > {
            seven
        };
        Adj[seven] = new List <State <int> > {
            three
        };

        TestSearchable <int> test1 = new TestSearchable <int>(one, six, Adj);
        Solution <int>       sol   = ser.search(test1);

        printSol(sol);
        Console.ReadLine();
    }
示例#19
0
 /// <summary>
 /// Follow the Monsters target to it's position.
 /// </summary>
 /// <param name="targetSession">The TargetSession to follow</param>
 private void FollowTarget()
 {
     if (Monster == null || !IsAlive || HasBuff(CardType.Move, (byte)AdditionalTypes.Move.MovementImpossible) || !IsMoving)
     {
         return;
     }
     if (!Target?.IsTargetable(SessionType()) ?? true)
     {
         RemoveTarget();
         return;
     }
     if (!Path.Any() && Target.MapInstance != null)
     {
         Path = BestFirstSearch.TracePath(new Node()
         {
             X = MapX, Y = MapY
         }, Target.GetBrushFire(), MapInstance.Map.Grid);
     }
     Move(); // follow the target
 }
        public override IEnumerator <TResult> GetEnumerator()
        {
            Debug.WriteLine($"Searching path between {From} and {To} with {AlgorithmName}...");

            switch (AlgorithmName)
            {
            case nameof(AStar):
                return(AStar.Run(this).GetEnumerator());

            case nameof(BestFirstSearch):
                return(BestFirstSearch.Run(this).GetEnumerator());

            case nameof(RecursiveBestFirstSearch):
                return(RecursiveBestFirstSearch.Run(this).GetEnumerator());

            case nameof(IterativeDeepeningAStar):
                return(IterativeDeepeningAStar.Run(this).GetEnumerator());
            }
            return(base.GetEnumerator());
        }
示例#21
0
        /// <summary>
        /// Runs this instance.
        /// </summary>
        public static void Run()
        {
            var dfsMazeGenerator = new DFSMazeGenerator();
            var MyMaze           = dfsMazeGenerator.Generate(20, 20);

            var s = MyMaze.ToString();

            Console.WriteLine(s);
            var SM = new SearchableMaze(MyMaze);

            Console.WriteLine("Start:" + new PointState(MyMaze.InitialPos));
            Console.WriteLine("Goal:" + new PointState(MyMaze.GoalPos));


            var DFS         = new DepthFirstSearch <PointState>();
            var solutionDFS = DFS.search(SM);

            Console.WriteLine("The solution path by DFS is:");
            foreach (var state in solutionDFS.Path)
            {
                Console.WriteLine(state.ToString());
            }
            Console.WriteLine("The DFS algorithm treated " + DFS.evaluatedNodes + " nodes.");
            Console.WriteLine();


            var BFS      = new BestFirstSearch <PointState>();
            var solution = BFS.search(SM);

            Console.WriteLine("The solution path by BFS is:");
            foreach (var state in solution.Path)
            {
                Console.WriteLine(state.ToString());
            }
            Console.WriteLine("The BFS algorithm treated " + BFS.evaluatedNodes + " nodes.");
            Console.WriteLine();
        }
示例#22
0
        // Algorithms

        public void Best_First_Search_Alg()
        {
            Clear();

            List <Field> fieldList = new List <Field>();

            foreach (Field field in fieldArray)
            {
                field.prevField = null;
                field.visited   = false;
                field.distance  = int.MaxValue;
                field.fDistance = 0;

                if (field.finish)
                {
                    continue;
                }

                if (!field.wall)
                {
                    field.hDistance = field.point.Distance_To(finishPoint);
                }
                fieldList.Add(field);

                if (!field.wall && !field.start && !field.finish)
                {
                    btnArray[field.point.row, field.point.col].Background = Brushes.White;
                }
            }

            var fieldToVisit = new List <Field>(fieldList);

            BestFirstSearch alg = new BestFirstSearch(fieldToVisit);

            thr = new Thread(() => alg.Algorithm());
            thr.Start();
        }
示例#23
0
        public void RunEvent(EventContainer evt, ClientSession session = null, MapMonster monster = null)
        {
            if (evt != null)
            {
                if (session != null)
                {
                    evt.MapInstance = session.CurrentMapInstance;
                    switch (evt.EventActionType)
                    {
                        #region EventForUser

                    case EventActionType.NPCDIALOG:
                        session.SendPacket(session.Character.GenerateNpcDialog((int)evt.Parameter));
                        break;

                    case EventActionType.SENDPACKET:
                        session.SendPacket((string)evt.Parameter);
                        break;

                        #endregion
                    }
                }
                if (evt.MapInstance != null)
                {
                    switch (evt.EventActionType)
                    {
                        #region EventForUser

                    case EventActionType.NPCDIALOG:
                    case EventActionType.SENDPACKET:
                        if (session == null)
                        {
                            evt.MapInstance.Sessions.ToList().ForEach(e => RunEvent(evt, e));
                        }
                        break;

                        #endregion

                        #region MapInstanceEvent

                    case EventActionType.REGISTEREVENT:
                        Tuple <string, List <EventContainer> > even = (Tuple <string, List <EventContainer> >)evt.Parameter;
                        switch (even.Item1)
                        {
                        case "OnCharacterDiscoveringMap":
                            even.Item2.ForEach(s => evt.MapInstance.OnCharacterDiscoveringMapEvents.Add(new Tuple <EventContainer, List <long> >(s, new List <long>())));
                            break;

                        case "OnMoveOnMap":
                            evt.MapInstance.OnMoveOnMapEvents.AddRange(even.Item2);
                            break;

                        case "OnMapClean":
                            evt.MapInstance.OnMapClean.AddRange(even.Item2);
                            break;

                        case "OnLockerOpen":
                            evt.MapInstance.UnlockEvents.AddRange(even.Item2);
                            break;
                        }
                        break;

                    case EventActionType.REGISTERWAVE:
                        evt.MapInstance.WaveEvents.Add((EventWave)evt.Parameter);
                        break;

                    case EventActionType.SETAREAENTRY:
                        ZoneEvent even2 = (ZoneEvent)evt.Parameter;
                        evt.MapInstance.OnAreaEntryEvents.Add(even2);
                        break;

                    case EventActionType.REMOVEMONSTERLOCKER:
                        EventContainer evt2 = (EventContainer)evt.Parameter;
                        if (evt.MapInstance.InstanceBag.MonsterLocker.Current > 0)
                        {
                            evt.MapInstance.InstanceBag.MonsterLocker.Current--;
                        }
                        if (evt.MapInstance.InstanceBag.MonsterLocker.Current == 0 && evt.MapInstance.InstanceBag.ButtonLocker.Current == 0)
                        {
                            evt.MapInstance.UnlockEvents.ForEach(s => RunEvent(s));
                            evt.MapInstance.UnlockEvents.RemoveAll(s => s != null);
                        }
                        break;

                    case EventActionType.REMOVEBUTTONLOCKER:
                        evt2 = (EventContainer)evt.Parameter;
                        if (evt.MapInstance.InstanceBag.ButtonLocker.Current > 0)
                        {
                            evt.MapInstance.InstanceBag.ButtonLocker.Current--;
                        }
                        if (evt.MapInstance.InstanceBag.MonsterLocker.Current == 0 && evt.MapInstance.InstanceBag.ButtonLocker.Current == 0)
                        {
                            evt.MapInstance.UnlockEvents.ForEach(s => RunEvent(s));
                            evt.MapInstance.UnlockEvents.RemoveAll(s => s != null);
                        }
                        break;

                    case EventActionType.EFFECT:
                        short evt3 = (short)evt.Parameter;
                        if (monster != null)
                        {
                            monster.LastEffect = DateTime.Now;
                            evt.MapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Monster, monster.MapMonsterId, evt3));
                        }
                        break;

                    case EventActionType.CONTROLEMONSTERINRANGE:
                        if (monster != null)
                        {
                            Tuple <short, byte, List <EventContainer> > evnt = (Tuple <short, byte, List <EventContainer> >)evt.Parameter;
                            List <MapMonster> MapMonsters = evt.MapInstance.GetListMonsterInRange(monster.MapX, monster.MapY, evnt.Item2);
                            if (evnt.Item1 != 0)
                            {
                                MapMonsters.RemoveAll(s => s.MonsterVNum != evnt.Item1);
                            }
                            MapMonsters.ForEach(s => evnt.Item3.ForEach(e => RunEvent(e, monster: s)));
                        }
                        break;

                    case EventActionType.ONTARGET:
                        if (monster.MoveEvent?.InZone(monster.MapX, monster.MapY) == true)
                        {
                            monster.MoveEvent = null;
                            monster.Path      = new List <Node>();
                            ((List <EventContainer>)evt.Parameter).ForEach(s => RunEvent(s, monster: monster));
                        }
                        break;

                    case EventActionType.MOVE:
                        ZoneEvent evt4 = (ZoneEvent)evt.Parameter;
                        if (monster != null)
                        {
                            monster.MoveEvent = evt4;
                            monster.Path      = BestFirstSearch.FindPathJagged(new Node {
                                X = monster.MapX, Y = monster.MapY
                            }, new Node {
                                X = evt4.X, Y = evt4.Y
                            }, evt.MapInstance?.Map.JaggedGrid);
                        }
                        break;

                    case EventActionType.CLOCK:
                        evt.MapInstance.InstanceBag.Clock.TotalSecondsAmount = Convert.ToInt32(evt.Parameter);
                        evt.MapInstance.InstanceBag.Clock.SecondsRemaining   = Convert.ToInt32(evt.Parameter);
                        break;

                    case EventActionType.SETMONSTERLOCKERS:
                        evt.MapInstance.InstanceBag.MonsterLocker.Current = Convert.ToByte(evt.Parameter);
                        evt.MapInstance.InstanceBag.MonsterLocker.Initial = Convert.ToByte(evt.Parameter);
                        break;

                    case EventActionType.SETBUTTONLOCKERS:
                        evt.MapInstance.InstanceBag.ButtonLocker.Current = Convert.ToByte(evt.Parameter);
                        evt.MapInstance.InstanceBag.ButtonLocker.Initial = Convert.ToByte(evt.Parameter);
                        break;

                    case EventActionType.SCRIPTEND:
                        switch (evt.MapInstance.MapInstanceType)
                        {
                        case MapInstanceType.TimeSpaceInstance:
                            evt.MapInstance.InstanceBag.EndState = (byte)evt.Parameter;
                            ClientSession client = evt.MapInstance.Sessions.FirstOrDefault();
                            if (client != null)
                            {
                                Guid             MapInstanceId = ServerManager.GetBaseMapInstanceIdByMapId(client.Character.MapId);
                                MapInstance      map           = ServerManager.GetMapInstance(MapInstanceId);
                                ScriptedInstance si            = map.ScriptedInstances.Find(s => s.PositionX == client.Character.MapX && s.PositionY == client.Character.MapY);
                                byte             penalty       = 0;
                                if (penalty > (client.Character.Level - si.LevelMinimum) * 2)
                                {
                                    penalty = penalty > 100 ? (byte)100 : penalty;
                                    client.SendPacket(client.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("TS_PENALTY"), penalty), 10));
                                }
                                int    point      = evt.MapInstance.InstanceBag.Point * (100 - penalty) / 100;
                                string perfection = string.Empty;
                                perfection += evt.MapInstance.InstanceBag.MonstersKilled >= si.MonsterAmount ? 1 : 0;
                                perfection += evt.MapInstance.InstanceBag.NpcsKilled == 0 ? 1 : 0;
                                perfection += evt.MapInstance.InstanceBag.RoomsVisited >= si.RoomAmount ? 1 : 0;
                                evt.MapInstance.Broadcast($"score  {evt.MapInstance.InstanceBag.EndState} {point} 27 47 18 {si.DrawItems.Count} {evt.MapInstance.InstanceBag.MonstersKilled} {si.NpcAmount - evt.MapInstance.InstanceBag.NpcsKilled} {evt.MapInstance.InstanceBag.RoomsVisited} {perfection} 1 1");
                            }
                            break;

                        case MapInstanceType.RaidInstance:
                            evt.MapInstance.InstanceBag.EndState = (byte)evt.Parameter;
                            client = evt.MapInstance.Sessions.FirstOrDefault();
                            if (client != null)
                            {
                                Group grp = client?.Character?.Group;
                                if (grp == null)
                                {
                                    return;
                                }
                                if (evt.MapInstance.InstanceBag.EndState == 1 && evt.MapInstance.Monsters.Any(s => s.IsBoss))
                                {
                                    foreach (ClientSession sess in grp.Characters.Where(s => s.CurrentMapInstance.Monsters.Any(e => e.IsBoss)))
                                    {
                                        foreach (Gift gift in grp?.Raid?.GiftItems)
                                        {
                                            const byte rare = 0;

                                            // TODO: add random rarity for some object
                                            sess.Character.GiftAdd(gift.VNum, gift.Amount, rare, 0, gift.Design, gift.IsRandomRare);
                                        }
                                    }
                                    foreach (MapMonster mon in evt.MapInstance.Monsters)
                                    {
                                        mon.CurrentHp = 0;
                                        evt.MapInstance.Broadcast(StaticPacketHelper.Out(UserType.Monster, mon.MapMonsterId));
                                        evt.MapInstance.RemoveMonster(mon);
                                    }
                                    Logger.LogUserEvent("RAID_SUCCESS", grp.Characters.ElementAt(0).Character.Name, $"RaidId: {grp.GroupId}");

                                    ServerManager.Instance.Broadcast(UserInterfaceHelper.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("RAID_SUCCEED"), grp?.Raid?.Label, grp.Characters.ElementAt(0).Character.Name), 0));
                                }

                                Observable.Timer(TimeSpan.FromSeconds(evt.MapInstance.InstanceBag.EndState == 1 ? 30 : 0)).Subscribe(o =>
                                {
                                    ClientSession[] grpmembers = new ClientSession[40];
                                    grp.Characters.CopyTo(grpmembers);
                                    foreach (ClientSession targetSession in grpmembers)
                                    {
                                        if (targetSession != null)
                                        {
                                            if (targetSession.Character.Hp <= 0)
                                            {
                                                targetSession.Character.Hp = 1;
                                                targetSession.Character.Mp = 1;
                                            }
                                            targetSession.SendPacket(Character.GenerateRaidBf(evt.MapInstance.InstanceBag.EndState));
                                            targetSession.SendPacket(targetSession.Character.GenerateRaid(1, true));
                                            targetSession.SendPacket(targetSession.Character.GenerateRaid(2, true));
                                            grp.LeaveGroup(targetSession);
                                        }
                                    }
                                    ServerManager.Instance.GroupList.RemoveAll(s => s.GroupId == grp.GroupId);
                                    ServerManager.Instance.GroupsThreadSafe.Remove(grp.GroupId);
                                    evt.MapInstance.Dispose();
                                });
                            }
                            break;

                        case MapInstanceType.Act4Morcos:
                        case MapInstanceType.Act4Hatus:
                        case MapInstanceType.Act4Calvina:
                        case MapInstanceType.Act4Berios:
                            client = evt.MapInstance.Sessions.FirstOrDefault();
                            if (client != null)
                            {
                                Family fam = evt.MapInstance.Sessions.FirstOrDefault(s => s?.Character?.Family != null)?.Character.Family;
                                if (fam != null)
                                {
                                    fam.Act4Raid.Portals.RemoveAll(s => s.DestinationMapInstanceId.Equals(fam.Act4RaidBossMap.MapInstanceId));
                                    short destX      = 38;
                                    short destY      = 179;
                                    short rewardVNum = 882;
                                    switch (evt.MapInstance.MapInstanceType)
                                    {
                                    //Morcos is default
                                    case MapInstanceType.Act4Hatus:
                                        destX      = 18;
                                        destY      = 10;
                                        rewardVNum = 185;
                                        break;

                                    case MapInstanceType.Act4Calvina:
                                        destX      = 25;
                                        destY      = 7;
                                        rewardVNum = 942;
                                        break;

                                    case MapInstanceType.Act4Berios:
                                        destX      = 16;
                                        destY      = 25;
                                        rewardVNum = 999;
                                        break;
                                    }
                                    int count = evt.MapInstance.Sessions.Count(s => s?.Character != null);
                                    foreach (ClientSession sess in evt.MapInstance.Sessions)
                                    {
                                        if (sess?.Character != null)
                                        {
                                            sess.Character.GiftAdd(rewardVNum, 1, forceRandom: true, minRare: 1, design: 255);
                                            sess.Character.GenerateFamilyXp(10000 / count);
                                        }
                                    }
                                    Logger.LogEvent("FAMILYRAID_SUCCESS", $"[fam.Name]FamilyRaidId: {evt.MapInstance.MapInstanceType.ToString()}");

                                    //TODO: Famlog
                                    CommunicationServiceClient.Instance.SendMessageToCharacter(new SCSCharacterMessage
                                    {
                                        DestinationCharacterId = fam.FamilyId,
                                        SourceCharacterId      = client.Character.CharacterId,
                                        SourceWorldId          = ServerManager.Instance.WorldId,
                                        Message = UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("FAMILYRAID_SUCCESS"), 0),
                                        Type    = MessageType.Family
                                    });
                                    //ServerManager.Instance.Broadcast(UserInterfaceHelper.Instance.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("FAMILYRAID_SUCCESS"), grp?.Raid?.Label, grp.Characters.ElementAt(0).Character.Name), 0));

                                    Observable.Timer(TimeSpan.FromSeconds(30)).Subscribe(o =>
                                    {
                                        foreach (ClientSession targetSession in evt.MapInstance.Sessions.ToArray())
                                        {
                                            if (targetSession != null)
                                            {
                                                if (targetSession.Character.Hp <= 0)
                                                {
                                                    targetSession.Character.Hp = 1;
                                                    targetSession.Character.Mp = 1;
                                                }

                                                ServerManager.Instance.ChangeMapInstance(targetSession.Character.CharacterId, fam.Act4Raid.MapInstanceId, destX, destY);
                                            }
                                        }
                                        evt.MapInstance.Dispose();
                                    });
                                }
                            }
                            break;

                        case MapInstanceType.CaligorInstance:

                            FactionType winningFaction = CaligorRaid.AngelDamage > CaligorRaid.DemonDamage ? FactionType.Angel : FactionType.Demon;

                            foreach (ClientSession sess in evt.MapInstance.Sessions)
                            {
                                if (sess?.Character != null)
                                {
                                    if (CaligorRaid.RemainingTime > 2400)
                                    {
                                        if (sess.Character.Faction == winningFaction)
                                        {
                                            sess.Character.GiftAdd(302, 1, 0, 0, 51);
                                        }
                                        else
                                        {
                                            sess.Character.GiftAdd(302, 1, 0, 0, 51);
                                        }
                                    }
                                    else
                                    {
                                        if (sess.Character.Faction == winningFaction)
                                        {
                                            sess.Character.GiftAdd(302, 1, 0, 0, 51);
                                        }
                                        else
                                        {
                                            sess.Character.GiftAdd(302, 1, 0, 0, 51);
                                        }
                                    }
                                    sess.Character.GiftAdd(1244, 50);
                                    sess.Character.GiftAdd(1134, 1);
                                    sess.Character.GenerateFamilyXp(500);
                                }
                            }
                            evt.MapInstance.Broadcast(UserInterfaceHelper.GenerateCHDM(ServerManager.GetNpc(2305).MaxHP, CaligorRaid.AngelDamage, CaligorRaid.DemonDamage, CaligorRaid.RemainingTime));
                            break;
                        }
                        break;

                    case EventActionType.MAPCLOCK:
                        evt.MapInstance.Clock.TotalSecondsAmount = Convert.ToInt32(evt.Parameter);
                        evt.MapInstance.Clock.SecondsRemaining   = Convert.ToInt32(evt.Parameter);
                        break;

                    case EventActionType.STARTCLOCK:
                        Tuple <List <EventContainer>, List <EventContainer> > eve = (Tuple <List <EventContainer>, List <EventContainer> >)evt.Parameter;
                        evt.MapInstance.InstanceBag.Clock.StopEvents    = eve.Item1;
                        evt.MapInstance.InstanceBag.Clock.TimeoutEvents = eve.Item2;
                        evt.MapInstance.InstanceBag.Clock.StartClock();
                        evt.MapInstance.Broadcast(evt.MapInstance.InstanceBag.Clock.GetClock());
                        break;

                    case EventActionType.TELEPORT:
                        Tuple <short, short, short, short> tp = (Tuple <short, short, short, short>)evt.Parameter;
                        List <Character> characters           = evt.MapInstance.GetCharactersInRange(tp.Item1, tp.Item2, 5).ToList();
                        characters.ForEach(s =>
                        {
                            s.PositionX = tp.Item3;
                            s.PositionY = tp.Item4;
                            evt.MapInstance?.Broadcast(s.Session, s.GenerateTp(), ReceiverType.Group);
                        });
                        break;

                    case EventActionType.STOPCLOCK:
                        evt.MapInstance.InstanceBag.Clock.StopClock();
                        evt.MapInstance.Broadcast(evt.MapInstance.InstanceBag.Clock.GetClock());
                        break;

                    case EventActionType.STARTMAPCLOCK:
                        eve = (Tuple <List <EventContainer>, List <EventContainer> >)evt.Parameter;
                        evt.MapInstance.Clock.StopEvents    = eve.Item1;
                        evt.MapInstance.Clock.TimeoutEvents = eve.Item2;
                        evt.MapInstance.Clock.StartClock();
                        evt.MapInstance.Broadcast(evt.MapInstance.Clock.GetClock());
                        break;

                    case EventActionType.STOPMAPCLOCK:
                        evt.MapInstance.Clock.StopClock();
                        evt.MapInstance.Broadcast(evt.MapInstance.Clock.GetClock());
                        break;

                    case EventActionType.SPAWNPORTAL:
                        evt.MapInstance.CreatePortal((Portal)evt.Parameter);
                        break;

                    case EventActionType.REFRESHMAPITEMS:
                        evt.MapInstance.MapClear();
                        break;

                    case EventActionType.NPCSEFFECTCHANGESTATE:
                        evt.MapInstance.Npcs.ForEach(s => s.EffectActivated = (bool)evt.Parameter);
                        break;

                    case EventActionType.CHANGEPORTALTYPE:
                        Tuple <int, PortalType> param = (Tuple <int, PortalType>)evt.Parameter;
                        Portal portal = evt.MapInstance.Portals.Find(s => s.PortalId == param.Item1);
                        if (portal != null)
                        {
                            portal.Type = (short)param.Item2;
                        }
                        break;

                    case EventActionType.CHANGEDROPRATE:
                        evt.MapInstance.DropRate = (int)evt.Parameter;
                        break;

                    case EventActionType.CHANGEXPRATE:
                        evt.MapInstance.XpRate = (int)evt.Parameter;
                        break;

                    case EventActionType.DISPOSEMAP:
                        evt.MapInstance.Dispose();
                        break;

                    case EventActionType.SPAWNBUTTON:
                        evt.MapInstance.SpawnButton((MapButton)evt.Parameter);
                        break;

                    case EventActionType.UNSPAWNMONSTERS:
                        evt.MapInstance.DespawnMonster((int)evt.Parameter);
                        break;

                    case EventActionType.SPAWNMONSTER:
                        evt.MapInstance.SummonMonster((MonsterToSummon)evt.Parameter);
                        break;

                    case EventActionType.SPAWNMONSTERS:
                        evt.MapInstance.SummonMonsters((List <MonsterToSummon>)evt.Parameter);
                        break;

                    case EventActionType.REFRESHRAIDGOAL:
                        ClientSession cl = evt.MapInstance.Sessions.FirstOrDefault();
                        if (cl?.Character != null)
                        {
                            ServerManager.Instance.Broadcast(cl, cl.Character?.Group?.GeneraterRaidmbf(cl), ReceiverType.Group);
                            ServerManager.Instance.Broadcast(cl, UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("NEW_MISSION"), 0), ReceiverType.Group);
                        }
                        break;

                    case EventActionType.SPAWNNPC:
                        evt.MapInstance.SummonNpc((NpcToSummon)evt.Parameter);
                        break;

                    case EventActionType.SPAWNNPCS:
                        evt.MapInstance.SummonNpcs((List <NpcToSummon>)evt.Parameter);
                        break;

                    case EventActionType.DROPITEMS:
                        evt.MapInstance.DropItems((List <Tuple <short, int, short, short> >)evt.Parameter);
                        break;

                    case EventActionType.THROWITEMS:
                        Tuple <int, short, byte, int, int> parameters = (Tuple <int, short, byte, int, int>)evt.Parameter;
                        if (monster != null)
                        {
                            parameters = new Tuple <int, short, byte, int, int>(monster.MapMonsterId, parameters.Item2, parameters.Item3, parameters.Item4, parameters.Item5);
                        }
                        evt.MapInstance.ThrowItems(parameters);
                        break;

                    case EventActionType.SPAWNONLASTENTRY:
                        Character lastincharacter = evt.MapInstance.Sessions.OrderByDescending(s => s.RegisterTime).FirstOrDefault()?.Character;
                        List <MonsterToSummon> summonParameters = new List <MonsterToSummon>();
                        MapCell hornSpawn = new MapCell
                        {
                            X = lastincharacter?.PositionX ?? 154,
                            Y = lastincharacter?.PositionY ?? 140
                        };
                        long hornTarget = lastincharacter?.CharacterId ?? -1;
                        summonParameters.Add(new MonsterToSummon(Convert.ToInt16(evt.Parameter), hornSpawn, hornTarget, true));
                        evt.MapInstance.SummonMonsters(summonParameters);
                        break;

                        #endregion
                    }
                }
            }
        }
示例#24
0
        /// <summary>
        /// Run Event
        /// </summary>
        /// <param name="evt">Event Container</param>
        /// <param name="session">Character Session that run the event</param>
        /// <param name="monster">Monster that run the event</param>
        public void RunEvent(EventContainer evt, ClientSession session = null, MapMonster monster = null)
        {
            if (session != null)
            {
                evt.MapInstance = session.CurrentMapInstance;
                switch (evt.EventActionType)
                {
                    #region EventForUser

                case EventActionType.NPCDIALOG:
                    session.SendPacket(session.Character.GenerateNpcDialog((int)evt.Parameter));
                    break;

                case EventActionType.SENDPACKET:
                    session.SendPacket((string)evt.Parameter);
                    break;

                    #endregion
                }
            }
            if (evt.MapInstance == null)
            {
                return;
            }
            switch (evt.EventActionType)
            {
                #region EventForUser

            case EventActionType.NPCDIALOG:
            case EventActionType.SENDPACKET:
                if (session == null)
                {
                    evt.MapInstance.Sessions.ToList().ForEach(e =>
                    {
                        RunEvent(evt, e);
                    });
                }
                break;

                #endregion

                #region MapInstanceEvent

            case EventActionType.REGISTEREVENT:
                Tuple <string, ConcurrentBag <EventContainer> > even = (Tuple <string, ConcurrentBag <EventContainer> >)evt.Parameter;
                switch (even.Item1)
                {
                case "OnCharacterDiscoveringMap":
                    even.Item2.ToList().ForEach(s => evt.MapInstance.OnCharacterDiscoveringMapEvents.Add(new Tuple <EventContainer, List <long> >(s, new List <long>())));
                    break;

                case "OnMoveOnMap":
                    evt.MapInstance.OnMoveOnMapEvents.AddRange(even.Item2);
                    break;

                case "OnMapClean":
                    evt.MapInstance.OnMapClean.AddRange(even.Item2);
                    break;

                case "OnLockerOpen":
                    even.Item2.ToList().ForEach(s => evt.MapInstance.InstanceBag.UnlockEvents.Add(s));
                    break;
                }
                break;

            case EventActionType.REGISTERWAVE:
                evt.MapInstance.WaveEvents.Add((EventWave)evt.Parameter);
                break;

            case EventActionType.SETAREAENTRY:
                ZoneEvent even2 = (ZoneEvent)evt.Parameter;
                evt.MapInstance.OnAreaEntryEvents.Add(even2);

                break;

            case EventActionType.REMOVEMONSTERLOCKER:
                if (evt.MapInstance.InstanceBag.MonsterLocker.Current > 0)
                {
                    evt.MapInstance.InstanceBag.MonsterLocker.Current--;
                }
                if (evt.MapInstance.InstanceBag.MonsterLocker.Current == 0 && evt.MapInstance.InstanceBag.ButtonLocker.Current == 0)
                {
                    evt.MapInstance.InstanceBag.UnlockEvents.ToList().ForEach(s => RunEvent(s));
                    evt.MapInstance.InstanceBag.UnlockEvents.Clear();
                }
                break;

            case EventActionType.REMOVEBUTTONLOCKER:
                if (evt.MapInstance.InstanceBag.ButtonLocker.Current > 0)
                {
                    evt.MapInstance.InstanceBag.ButtonLocker.Current--;
                }
                if (evt.MapInstance.InstanceBag.MonsterLocker.Current == 0 && evt.MapInstance.InstanceBag.ButtonLocker.Current == 0)
                {
                    evt.MapInstance.InstanceBag.UnlockEvents.ToList().ForEach(s => RunEvent(s));
                    evt.MapInstance.InstanceBag.UnlockEvents.Clear();
                }
                break;

            case EventActionType.EFFECT:
                short evt3 = (short)evt.Parameter;
                if (monster != null && (DateTime.Now - monster.LastEffect).TotalSeconds >= 5)
                {
                    evt.MapInstance.Broadcast(monster.GenerateEff(evt3));
                    monster.ShowEffect();
                }
                break;

            case EventActionType.CONTROLEMONSTERINRANGE:
                if (monster != null)
                {
                    Tuple <short, byte, ConcurrentBag <EventContainer> > evnt = (Tuple <short, byte, ConcurrentBag <EventContainer> >)evt.Parameter;
                    List <MapMonster> mapMonsters = evt.MapInstance.GetListMonsterInRange(monster.MapX, monster.MapY, evnt.Item2);
                    if (evnt.Item1 != 0)
                    {
                        mapMonsters.RemoveAll(s => s.MonsterVNum != evnt.Item1);
                    }
                    mapMonsters.ForEach(s => evnt.Item3.ToList().ForEach(e => RunEvent(e, monster: s)));
                }
                break;

            case EventActionType.ONTARGET:
                if (monster?.MoveEvent != null && monster.MoveEvent.InZone(monster.MapX, monster.MapY))
                {
                    ((ConcurrentBag <EventContainer>)evt.Parameter).ToList().ForEach(s => RunEvent(s, monster: monster));
                }
                break;

            case EventActionType.MOVE:
                ZoneEvent evt4 = (ZoneEvent)evt.Parameter;
                if (monster != null)
                {
                    monster.FirstX    = evt4.X;
                    monster.FirstY    = evt4.Y;
                    monster.MoveEvent = evt4;
                    monster.Path      = BestFirstSearch.FindPath(new Node {
                        X = monster.MapX, Y = monster.MapY
                    }, new Node {
                        X = evt4.X, Y = evt4.Y
                    }, evt.MapInstance?.Map.Grid);
                }
                break;

            case EventActionType.CLOCK:
                evt.MapInstance.InstanceBag.Clock.BasesSecondRemaining = Convert.ToInt32(evt.Parameter);
                evt.MapInstance.InstanceBag.Clock.DeciSecondRemaining  = Convert.ToInt32(evt.Parameter);
                break;

            case EventActionType.SETMONSTERLOCKERS:
                evt.MapInstance.InstanceBag.MonsterLocker.Current = Convert.ToByte(evt.Parameter);
                evt.MapInstance.InstanceBag.MonsterLocker.Initial = Convert.ToByte(evt.Parameter);
                break;

            case EventActionType.SETBUTTONLOCKERS:
                evt.MapInstance.InstanceBag.ButtonLocker.Current = Convert.ToByte(evt.Parameter);
                evt.MapInstance.InstanceBag.ButtonLocker.Initial = Convert.ToByte(evt.Parameter);
                break;

            case EventActionType.SCRIPTEND:
                switch (evt.MapInstance.MapInstanceType)
                {
                case MapInstanceType.TimeSpaceInstance:
                    evt.MapInstance.InstanceBag.EndState = (byte)evt.Parameter;
                    ClientSession client = evt.MapInstance.Sessions.FirstOrDefault();
                    if (client != null)
                    {
                        Guid             mapInstanceId = ServerManager.Instance.GetBaseMapInstanceIdByMapId(client.Character.MapId);
                        MapInstance      map           = ServerManager.Instance.GetMapInstance(mapInstanceId);
                        ScriptedInstance si            = map.ScriptedInstances.FirstOrDefault(s => s.PositionX == client.Character.MapX && s.PositionY == client.Character.MapY);
                        byte             penalty       = 0;
                        if (si != null && penalty > (client.Character.Level - si.LevelMinimum) * 2)
                        {
                            penalty = penalty > 100 ? (byte)100 : penalty;
                            client.SendPacket(client.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("TS_PENALTY"), penalty), 10));
                        }
                        int    point      = evt.MapInstance.InstanceBag.Point * (100 - penalty) / 100;
                        string perfection = string.Empty;
                        perfection += si != null && evt.MapInstance.InstanceBag.MonstersKilled >= si.MonsterAmount ? 1 : 0;
                        perfection += evt.MapInstance.InstanceBag.NpcsKilled == 0 ? 1 : 0;
                        perfection += si != null && evt.MapInstance.InstanceBag.RoomsVisited >= si.RoomAmount ? 1 : 0;

                        if (si != null)
                        {
                            evt.MapInstance.Broadcast(
                                $"score  {evt.MapInstance.InstanceBag.EndState} {point} 27 47 18 {si.DrawItems.Count()} {evt.MapInstance.InstanceBag.MonstersKilled} {si.NpcAmount - evt.MapInstance.InstanceBag.NpcsKilled} {evt.MapInstance.InstanceBag.RoomsVisited} {perfection} 1 1");
                        }
                    }
                    break;

                case MapInstanceType.RaidInstance:
                    evt.MapInstance.InstanceBag.EndState = (byte)evt.Parameter;
                    client = evt.MapInstance.Sessions.FirstOrDefault();
                    List <ClientSession> toBan = new List <ClientSession>();
                    if (client != null)
                    {
                        Group grp = client.Character?.Group;
                        if (grp == null)
                        {
                            return;
                        }
                        if (evt.MapInstance.InstanceBag.EndState == 1 && evt.MapInstance.Monsters.Any(s => s.IsBoss && !s.IsAlive))
                        {
                            foreach (ClientSession sess in grp.Characters.Replace(s => s.CurrentMapInstance.Monsters.Any(e => e.IsBoss)))
                            {
                                // TODO REMOTE THAT FOR PUBLIC RELEASE
                                if (grp.Characters.Count(s => s.IpAddress.Equals(sess.IpAddress)) > 2)
                                {
                                    toBan.Add(sess);
                                    continue;
                                }
                                if (grp.Raid?.GiftItems == null)
                                {
                                    continue;
                                }
                                if (grp.Raid.Reputation > 0)
                                {
                                    sess.Character.GetReput(grp.Raid.Reputation);
                                }
                                if (sess.Character.Dignity < 0)
                                {
                                    sess.Character.Dignity += 100;
                                }
                                else
                                {
                                    sess.Character.Dignity = 100;
                                }
                                if (sess.Character.Level > grp.Raid.LevelMaximum)
                                {
                                    // RAID CERTIFICATE
                                    sess.Character.GiftAdd(2320, 1);
                                }
                                else
                                {
                                    foreach (Gift gift in grp.Raid?.GiftItems)
                                    {
                                        sbyte rare = 0;
                                        if (gift.IsRandomRare)
                                        {
                                            rare = (sbyte)ServerManager.Instance.RandomNumber(-2, 7);
                                        }
                                        //TODO add random rarity for some object
                                        sess.Character.GiftAdd(gift.VNum, gift.Amount, gift.Design, rare: rare);
                                    }
                                }
                            }
                            // Remove monster when raid is over
                            foreach (MapMonster e in evt.MapInstance.Monsters.Where(s => !s.IsBoss))
                            {
                                evt.MapInstance.DespawnMonster(e.MonsterVNum);
                            }
                            evt.MapInstance.WaveEvents.Clear();

                            ServerManager.Instance.Broadcast(UserInterfaceHelper.Instance.GenerateMsg(
                                                                 string.Format(Language.Instance.GetMessageFromKey("RAID_SUCCEED"), grp.Raid?.Label, grp.Characters.ElementAt(0).Character.Name), 0));

                            Observable.Timer(TimeSpan.FromSeconds(evt.MapInstance.InstanceBag.EndState == 1 ? 30 : 0)).Subscribe(obj =>
                            {
                                ClientSession[] grpmembers = new ClientSession[40];
                                grp.Characters.ToList().CopyTo(grpmembers);
                                List <MapInstance> mapinstances = new List <MapInstance>();
                                foreach (ClientSession targetSession in grpmembers)
                                {
                                    if (targetSession == null)
                                    {
                                        continue;
                                    }
                                    if (targetSession.Character.Hp <= 0)
                                    {
                                        targetSession.Character.Hp = 1;
                                        targetSession.Character.Mp = 1;
                                    }
                                    targetSession.SendPacket(targetSession.Character.GenerateRaidBf(evt.MapInstance.InstanceBag.EndState));
                                    targetSession.SendPacket(targetSession.Character.GenerateRaid(1, true));
                                    targetSession.SendPacket(targetSession.Character.GenerateRaid(2, true));
                                    if (!mapinstances.Any(s => s.MapInstanceId == targetSession?.CurrentMapInstance.MapInstanceId && s.MapInstanceType == MapInstanceType.RaidInstance))
                                    {
                                        mapinstances.Add(targetSession.CurrentMapInstance);
                                    }
                                    grp.LeaveGroup(targetSession);
                                }
                                ServerManager.Instance.GroupList.RemoveAll(s => s.GroupId == grp.GroupId);
                                ServerManager.Instance.GroupsThreadSafe.TryRemove(grp.GroupId, out Group _);
                                mapinstances.ForEach(s => s.Dispose());
                            });
                        }
                    }
                    break;
                }
                break;

            case EventActionType.MAPCLOCK:
                evt.MapInstance.Clock.BasesSecondRemaining = Convert.ToInt32(evt.Parameter);
                evt.MapInstance.Clock.DeciSecondRemaining  = Convert.ToInt32(evt.Parameter);
                break;

            case EventActionType.STARTCLOCK:
                Tuple <List <EventContainer>, List <EventContainer> > eve = (Tuple <List <EventContainer>, List <EventContainer> >)evt.Parameter;
                if (eve != null)
                {
                    evt.MapInstance.InstanceBag.Clock.StopEvents    = eve.Item2;
                    evt.MapInstance.InstanceBag.Clock.TimeoutEvents = eve.Item1;
                    evt.MapInstance.InstanceBag.Clock.StartClock();
                    evt.MapInstance.Broadcast(evt.MapInstance.InstanceBag.Clock.GetClock());
                }
                break;

            case EventActionType.TELEPORT:
                Tuple <short, short, short, short> tp = (Tuple <short, short, short, short>)evt.Parameter;
                List <Character> characters           = evt.MapInstance.GetCharactersInRange(tp.Item1, tp.Item2, 5).ToList();
                characters.ForEach(s =>
                {
                    s.PositionX = tp.Item3;
                    s.PositionY = tp.Item4;
                    evt.MapInstance?.Broadcast(s.Session, s.GenerateTp(), ReceiverType.Group);
                });
                break;

            case EventActionType.STOPCLOCK:
                evt.MapInstance.InstanceBag.Clock.StopClock();
                evt.MapInstance.Broadcast(evt.MapInstance.InstanceBag.Clock.GetClock());
                break;

            case EventActionType.STARTMAPCLOCK:
                eve = (Tuple <List <EventContainer>, List <EventContainer> >)evt.Parameter;
                if (eve != null)
                {
                    evt.MapInstance.Clock.StopEvents    = eve.Item2;
                    evt.MapInstance.Clock.TimeoutEvents = eve.Item1;
                    evt.MapInstance.Clock.StartClock();
                    evt.MapInstance.Broadcast(evt.MapInstance.Clock.GetClock());
                }
                break;

            case EventActionType.STOPMAPCLOCK:
                evt.MapInstance.Clock.StopClock();
                evt.MapInstance.Broadcast(evt.MapInstance.Clock.GetClock());
                break;

            case EventActionType.SPAWNPORTAL:
                evt.MapInstance.CreatePortal((Portal)evt.Parameter);
                break;

            case EventActionType.REFRESHMAPITEMS:
                evt.MapInstance.MapClear();
                break;

            case EventActionType.NPCSEFFECTCHANGESTATE:
                evt.MapInstance.Npcs.ForEach(s => s.EffectActivated = (bool)evt.Parameter);
                break;

            case EventActionType.CHANGEPORTALTYPE:
                Tuple <int, PortalType> param = (Tuple <int, PortalType>)evt.Parameter;
                Portal portal = evt.MapInstance.Portals.FirstOrDefault(s => s.PortalId == param.Item1);
                if (portal != null)
                {
                    portal.Type = (short)param.Item2;
                }
                break;

            case EventActionType.CHANGEDROPRATE:
                evt.MapInstance.DropRate = (int)evt.Parameter;
                break;

            case EventActionType.CHANGEXPRATE:
                evt.MapInstance.XpRate = (int)evt.Parameter;
                break;

            case EventActionType.DISPOSEMAP:
                evt.MapInstance.Dispose();
                break;

            case EventActionType.SPAWNBUTTON:
                evt.MapInstance.SpawnButton((MapButton)evt.Parameter);
                break;

            case EventActionType.UNSPAWNMONSTERS:
                evt.MapInstance.DespawnMonster((int)evt.Parameter);
                break;

            case EventActionType.SPAWNMONSTERS:
                evt.MapInstance.SummonMonsters(((ConcurrentBag <MonsterToSummon>)evt.Parameter).ToList());
                break;

            case EventActionType.REFRESHRAIDGOAL:
                ClientSession cl = evt.MapInstance.Sessions.FirstOrDefault();
                if (cl?.Character != null)
                {
                    ServerManager.Instance.Broadcast(cl, cl.Character?.Group?.GeneraterRaidmbf(), ReceiverType.Group);
                    ServerManager.Instance.Broadcast(cl, UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("NEW_MISSION"), 0), ReceiverType.Group);
                }
                break;

            case EventActionType.SPAWNNPCS:
                evt.MapInstance.SummonNpcs((List <NpcToSummon>)evt.Parameter);
                break;

            case EventActionType.DROPITEMS:
                evt.MapInstance.DropItems((List <Tuple <short, int, short, short> >)evt.Parameter);
                break;

            case EventActionType.THROWITEMS:
                Tuple <int, short, byte, int, int> parameters = (Tuple <int, short, byte, int, int>)evt.Parameter;
                if (monster != null)
                {
                    parameters = new Tuple <int, short, byte, int, int>(monster.MapMonsterId, parameters.Item2, parameters.Item3, parameters.Item4, parameters.Item5);
                }
                evt.MapInstance.ThrowItems(parameters);
                break;

            case EventActionType.SPAWNONLASTENTRY:
                Character lastincharacter = evt.MapInstance.Sessions.OrderByDescending(s => s.RegisterTime).FirstOrDefault()?.Character;
                List <MonsterToSummon> summonParameters = new List <MonsterToSummon>();
                MapCell hornSpawn = new MapCell
                {
                    X = lastincharacter?.PositionX ?? 154,
                    Y = lastincharacter?.PositionY ?? 140
                };
                long hornTarget = lastincharacter?.CharacterId ?? -1;
                summonParameters.Add(new MonsterToSummon(Convert.ToInt16(evt.Parameter), hornSpawn, hornTarget, true));
                evt.MapInstance.SummonMonsters(summonParameters);
                break;

                #endregion
            }
        }
示例#25
0
        private void npcLife()
        {
            // Respawn
            if (CurrentHp <= 0 && ShouldRespawn != null && !ShouldRespawn.Value)
            {
                MapInstance.RemoveNpc(this);
                MapInstance.Broadcast(GenerateOut());
            }

            if (!IsAlive && ShouldRespawn != null && ShouldRespawn.Value)
            {
                double timeDeath = (DateTime.Now - Death).TotalSeconds;
                if (timeDeath >= Npc.RespawnTime / 10d)
                {
                    Respawn();
                }
            }

            if (LastProtectedEffect.AddMilliseconds(6000) <= DateTime.Now)
            {
                LastProtectedEffect = DateTime.Now;
                if (IsMate || IsProtected)
                {
                    MapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, MapNpcId, 825), MapX, MapY);
                }
            }

            double time = (DateTime.Now - LastEffect).TotalMilliseconds;

            if (EffectDelay > 0)
            {
                if (time > EffectDelay)
                {
                    if (Effect > 0 && EffectActivated)
                    {
                        MapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, MapNpcId, Effect), MapX, MapY);
                    }

                    LastEffect = DateTime.Now;
                }
            }

            time = (DateTime.Now - LastMove).TotalMilliseconds;
            if (Target == -1 && IsMoving && Npc.Speed > 0 && time > _movetime && !HasBuff(CardType.Move, (byte)AdditionalTypes.Move.MovementImpossible))
            {
                _movetime = ServerManager.RandomNumber(500, 3000);
                int maxindex = Path.Count > Npc.Speed / 2 && Npc.Speed > 1 ? Npc.Speed / 2 : Path.Count;
                if (maxindex < 1)
                {
                    maxindex = 1;
                }
                if (Path.Count == 0 || Path.Count >= maxindex && maxindex > 0 && Path[maxindex - 1] == null)
                {
                    short xoffset = (short)ServerManager.RandomNumber(-1, 1);
                    short yoffset = (short)ServerManager.RandomNumber(-1, 1);

                    MapCell moveToPosition = new MapCell {
                        X = FirstX, Y = FirstY
                    };
                    if (RunToX != 0 || RunToY != 0)
                    {
                        moveToPosition = new MapCell {
                            X = RunToX, Y = RunToY
                        };
                        _movetime = ServerManager.RandomNumber(300, 1200);
                    }
                    Path = BestFirstSearch.FindPathJagged(new GridPos {
                        X = MapX, Y = MapY
                    }, new GridPos {
                        X = (short)ServerManager.RandomNumber(moveToPosition.X - 3, moveToPosition.X + 3), Y = (short)ServerManager.RandomNumber(moveToPosition.Y - 3, moveToPosition.Y + 3)
                    }, MapInstance.Map.JaggedGrid);
                    maxindex = Path.Count > Npc.Speed / 2 && Npc.Speed > 1 ? Npc.Speed / 2 : Path.Count;
                }
                if (DateTime.Now > LastMove && Npc.Speed > 0 && Path.Count > 0)
                {
                    byte speedIndex = (byte)(Npc.Speed / 2.5 < 1 ? 1 : Npc.Speed / 2.5);
                    maxindex = Path.Count > speedIndex ? speedIndex : Path.Count;
                    short mapX = (short)ServerManager.RandomNumber(Path[maxindex - 1].X - 1, Path[maxindex - 1].X + 1);
                    short mapY = (short)_random.Next(Path[maxindex - 1].Y - 1, Path[maxindex - 1].Y + 1);

                    //short mapX = Path[maxindex - 1].X;
                    //short mapY = Path[maxindex - 1].Y;
                    double waitingtime = Map.GetDistance(new MapCell {
                        X = mapX, Y = mapY
                    }, new MapCell {
                        X = MapX, Y = MapY
                    }) / (double)Npc.Speed;
                    MapInstance.Broadcast(new BroadcastPacket(null, PacketFactory.Serialize(StaticPacketHelper.Move(UserType.Npc, MapNpcId, mapX, mapY, Npc.Speed)), ReceiverType.All, xCoordinate: mapX, yCoordinate: mapY));
                    LastMove = DateTime.Now.AddSeconds(waitingtime > 1 ? 1 : waitingtime);

                    Observable.Timer(TimeSpan.FromMilliseconds((int)((waitingtime > 1 ? 1 : waitingtime) * 1000))).Subscribe(x =>
                    {
                        MapX = mapX;
                        MapY = mapY;
                    });

                    Path.RemoveRange(0, maxindex);
                }
            }
            if (Target == -1)
            {
                if (IsHostile && Shop == null)
                {
                    MapMonster    monster = MapInstance.GetMonsterInRangeList(MapX, MapY, (byte)(Npc.NoticeRange > 5 ? Npc.NoticeRange / 2 : Npc.NoticeRange)).Where(s => BattleEntity.CanAttackEntity(s.BattleEntity)).FirstOrDefault();
                    ClientSession session = MapInstance.Sessions.FirstOrDefault(s => BattleEntity.CanAttackEntity(s.Character.BattleEntity) && MapInstance == s.Character.MapInstance && Map.GetDistance(new MapCell {
                        X = MapX, Y = MapY
                    }, new MapCell {
                        X = s.Character.PositionX, Y = s.Character.PositionY
                    }) < Npc.NoticeRange);

                    if (monster != null)
                    {
                        Target = monster.MapMonsterId;
                    }
                    if (session?.Character != null)
                    {
                        Target = session.Character.CharacterId;
                    }
                }
            }
            else if (Target != -1)
            {
                MapMonster monster = MapInstance.Monsters.Find(s => s.MapMonsterId == Target);
                if (monster == null || monster.CurrentHp < 1)
                {
                    Target = -1;
                    return;
                }
                NpcMonsterSkill npcMonsterSkill = null;
                if (ServerManager.RandomNumber(0, 10) > 8)
                {
                    npcMonsterSkill = Skills.Where(s => (DateTime.Now - s.LastSkillUse).TotalMilliseconds >= 100 * s.Skill.Cooldown).OrderBy(rnd => _random.Next()).FirstOrDefault();
                }
                int  hitmode   = 0;
                bool onyxWings = false;
                int  damage    = DamageHelper.Instance.CalculateDamage(new BattleEntity(this), new BattleEntity(monster), npcMonsterSkill?.Skill, ref hitmode, ref onyxWings);
                if (monster.Monster.BCards.Find(s => s.Type == (byte)CardType.LightAndShadow && s.SubType == (byte)AdditionalTypes.LightAndShadow.InflictDamageToMP) is BCard card)
                {
                    int reduce = damage / 100 * card.FirstData;
                    if (monster.CurrentMp < reduce)
                    {
                        reduce            = (int)monster.CurrentMp;
                        monster.CurrentMp = 0;
                    }
                    else
                    {
                        monster.DecreaseMp(reduce);
                    }
                    damage -= reduce;
                }
                int distance = Map.GetDistance(new MapCell {
                    X = MapX, Y = MapY
                }, new MapCell {
                    X = monster.MapX, Y = monster.MapY
                });
                if (monster.CurrentHp > 0 && ((npcMonsterSkill != null && distance < npcMonsterSkill.Skill.Range) || distance <= Npc.BasicRange) && !HasBuff(CardType.SpecialAttack, (byte)AdditionalTypes.SpecialAttack.NoAttack))
                {
                    if (((DateTime.Now - LastSkill).TotalMilliseconds >= 1000 + (Npc.BasicCooldown * 200) /* && Skills.Count == 0*/) || npcMonsterSkill != null)
                    {
                        if (npcMonsterSkill != null)
                        {
                            npcMonsterSkill.LastSkillUse = DateTime.Now;
                            MapInstance.Broadcast(StaticPacketHelper.CastOnTarget(UserType.Npc, MapNpcId, UserType.Monster, Target, npcMonsterSkill.Skill.CastAnimation, npcMonsterSkill.Skill.CastEffect, npcMonsterSkill.Skill.SkillVNum));
                        }

                        if (npcMonsterSkill != null && npcMonsterSkill.Skill.CastEffect != 0)
                        {
                            MapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, MapNpcId, Effect));
                        }
                        monster.BattleEntity.GetDamage(damage, BattleEntity);
                        lock (monster.DamageList)
                        {
                            if (!monster.DamageList.Any(s => s.Key.MapEntityId == MapNpcId))
                            {
                                monster.AddToAggroList(BattleEntity);
                            }
                        }
                        MapInstance.Broadcast(npcMonsterSkill != null
                            ? StaticPacketHelper.SkillUsed(UserType.Npc, MapNpcId, 3, Target, npcMonsterSkill.SkillVNum, npcMonsterSkill.Skill.Cooldown, npcMonsterSkill.Skill.AttackAnimation, npcMonsterSkill.Skill.Effect, 0, 0, monster.CurrentHp > 0, (int)((float)monster.CurrentHp / (float)monster.MaxHp * 100), damage, hitmode, 0)
                            : StaticPacketHelper.SkillUsed(UserType.Npc, MapNpcId, 3, Target, 0, Npc.BasicCooldown, 11, Npc.BasicSkill, 0, 0, monster.CurrentHp > 0, (int)((float)monster.CurrentHp / (float)monster.MaxHp * 100), damage, hitmode, 0));
                        LastSkill = DateTime.Now;

                        if (npcMonsterSkill?.Skill.TargetType == 1 && npcMonsterSkill?.Skill.HitType == 2)
                        {
                            IEnumerable <ClientSession> clientSessions =
                                MapInstance.Sessions?.Where(s =>
                                                            s.Character.IsInRange(MapX,
                                                                                  MapY, npcMonsterSkill.Skill.TargetRange));
                            IEnumerable <Mate> mates = MapInstance.GetListMateInRange(MapX, MapY, npcMonsterSkill.Skill.TargetRange);

                            foreach (BCard skillBcard in npcMonsterSkill.Skill.BCards)
                            {
                                if (skillBcard.Type == 25 && skillBcard.SubType == 1 && new Buff((short)skillBcard.SecondData, Npc.Level)?.Card?.BuffType == BuffType.Good)
                                {
                                    if (clientSessions != null)
                                    {
                                        foreach (ClientSession clientSession in clientSessions)
                                        {
                                            if (clientSession.Character != null)
                                            {
                                                if (!BattleEntity.CanAttackEntity(clientSession.Character.BattleEntity))
                                                {
                                                    skillBcard.ApplyBCards(clientSession.Character.BattleEntity, BattleEntity);
                                                }
                                            }
                                        }
                                    }
                                    if (mates != null)
                                    {
                                        foreach (Mate mate in mates)
                                        {
                                            if (!BattleEntity.CanAttackEntity(mate.BattleEntity))
                                            {
                                                skillBcard.ApplyBCards(mate.BattleEntity, BattleEntity);
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        if (monster.CurrentHp < 1 && monster.SetDeathStatement())
                        {
                            monster.RunDeathEvent();
                            RemoveTarget();
                        }
                    }
                }
                else
                {
                    int maxdistance = Npc.NoticeRange > 5 ? Npc.NoticeRange / 2 : Npc.NoticeRange;
                    if (IsMoving && !HasBuff(CardType.Move, (byte)AdditionalTypes.Move.MovementImpossible))
                    {
                        const short maxDistance = 5;
                        int         maxindex    = Path.Count > Npc.Speed / 2 && Npc.Speed > 1 ? Npc.Speed / 2 : Path.Count;
                        if (maxindex < 1)
                        {
                            maxindex = 1;
                        }
                        if ((Path.Count == 0 && distance >= 1 && distance < maxDistance) || (Path.Count >= maxindex && maxindex > 0 && Path[maxindex - 1] == null))
                        {
                            short xoffset = (short)ServerManager.RandomNumber(-1, 1);
                            short yoffset = (short)ServerManager.RandomNumber(-1, 1);

                            //go to monster
                            Path = BestFirstSearch.FindPathJagged(new GridPos {
                                X = MapX, Y = MapY
                            }, new GridPos {
                                X = (short)(monster.MapX + xoffset), Y = (short)(monster.MapY + yoffset)
                            }, MapInstance.Map.JaggedGrid);
                            maxindex = Path.Count > Npc.Speed / 2 && Npc.Speed > 1 ? Npc.Speed / 2 : Path.Count;
                        }
                        if (DateTime.Now > LastMove && Npc.Speed > 0 && Path.Count > 0)
                        {
                            byte speedIndex = (byte)(Npc.Speed / 2.5 < 1 ? 1 : Npc.Speed / 2.5);
                            maxindex = Path.Count > speedIndex ? speedIndex : Path.Count;
                            //short mapX = (short)ServerManager.RandomNumber(Path[maxindex - 1].X - 1, Path[maxindex - 1].X + 1);
                            //short mapY = (short)_random.Next(Path[maxindex - 1].Y - 1, Path[maxindex - 1].Y + 1);

                            short  mapX        = Path[maxindex - 1].X;
                            short  mapY        = Path[maxindex - 1].Y;
                            double waitingtime = Map.GetDistance(new MapCell {
                                X = mapX, Y = mapY
                            }, new MapCell {
                                X = MapX, Y = MapY
                            }) / (double)Npc.Speed;
                            MapInstance.Broadcast(new BroadcastPacket(null, PacketFactory.Serialize(StaticPacketHelper.Move(UserType.Npc, MapNpcId, mapX, mapY, Npc.Speed)), ReceiverType.All, xCoordinate: mapX, yCoordinate: mapY));
                            LastMove = DateTime.Now.AddSeconds(waitingtime > 1 ? 1 : waitingtime);

                            Observable.Timer(TimeSpan.FromMilliseconds((int)((waitingtime > 1 ? 1 : waitingtime) * 1000))).Subscribe(x =>
                            {
                                MapX = mapX;
                                MapY = mapY;
                            });

                            Path.RemoveRange(0, maxindex);
                        }
                        if (Target != -1 && (MapId != monster.MapId || distance > maxDistance))
                        {
                            RemoveTarget();
                        }
                    }
                }
            }
        }
示例#26
0
文件: MapNpc.cs 项目: Vorlent/OpenNos
        private void NpcLife()
        {
            double time = (DateTime.Now - LastEffect).TotalMilliseconds;

            if (time > EffectDelay)
            {
                if (IsMate || IsProtected)
                {
                    MapInstance.Broadcast(GenerateEff(825), MapX, MapY);
                }
                if (Effect > 0 && EffectActivated)
                {
                    MapInstance.Broadcast(GenerateEff(Effect), MapX, MapY);
                }
                LastEffect = DateTime.Now;
            }

            time = (DateTime.Now - LastMove).TotalMilliseconds;
            if (IsMoving && Npc.Speed > 0 && time > _movetime)
            {
                _movetime = ServerManager.Instance.RandomNumber(500, 3000);
                byte point  = (byte)ServerManager.Instance.RandomNumber(2, 4);
                byte fpoint = (byte)ServerManager.Instance.RandomNumber(0, 2);

                byte xpoint = (byte)ServerManager.Instance.RandomNumber(fpoint, point);
                byte ypoint = (byte)(point - xpoint);

                short mapX = FirstX;
                short mapY = FirstY;

                if (MapInstance.Map.GetFreePosition(ref mapX, ref mapY, xpoint, ypoint))
                {
                    double value = (xpoint + ypoint) / (double)(2 * Npc.Speed);
                    Observable.Timer(TimeSpan.FromMilliseconds(1000 * value))
                    .Subscribe(
                        x =>
                    {
                        MapX = mapX;
                        MapY = mapY;
                    });

                    LastMove = DateTime.Now.AddSeconds(value);
                    MapInstance.Broadcast(new BroadcastPacket(null, GenerateMv2(), ReceiverType.All, xCoordinate: mapX, yCoordinate: mapY));
                }
            }
            if (Target == -1)
            {
                if (IsHostile && Shop == null)
                {
                    MapMonster monster = MapInstance.Monsters.FirstOrDefault(s => MapInstance == s.MapInstance && Map.GetDistance(new MapCell {
                        X = MapX, Y = MapY
                    }, new MapCell {
                        X = s.MapX, Y = s.MapY
                    }) < (Npc.NoticeRange > 5 ? Npc.NoticeRange / 2 : Npc.NoticeRange));
                    ClientSession session = MapInstance.Sessions.FirstOrDefault(s => MapInstance == s.Character.MapInstance && Map.GetDistance(new MapCell {
                        X = MapX, Y = MapY
                    }, new MapCell {
                        X = s.Character.PositionX, Y = s.Character.PositionY
                    }) < Npc.NoticeRange);

                    if (monster != null && session != null)
                    {
                        Target = monster.MapMonsterId;
                    }
                }
            }
            else if (Target != -1)
            {
                MapMonster monster = MapInstance.Monsters.FirstOrDefault(s => s.MapMonsterId == Target);
                if (monster == null || monster.CurrentHp < 1)
                {
                    Target = -1;
                    return;
                }
                NpcMonsterSkill npcMonsterSkill = null;
                if (ServerManager.Instance.RandomNumber(0, 10) > 8)
                {
                    npcMonsterSkill = Npc.Skills.Where(s => (DateTime.Now - s.LastSkillUse).TotalMilliseconds >= 100 * s.Skill.Cooldown).OrderBy(rnd => _random.Next()).FirstOrDefault();
                }

                const short damage   = 100;
                int         distance = Map.GetDistance(new MapCell {
                    X = MapX, Y = MapY
                }, new MapCell {
                    X = monster.MapX, Y = monster.MapY
                });
                if (monster.CurrentHp > 0 && (npcMonsterSkill != null && distance < npcMonsterSkill.Skill.Range || distance <= Npc.BasicRange))
                {
                    if ((DateTime.Now - LastEffect).TotalMilliseconds >= 1000 + Npc.BasicCooldown * 200 && !Npc.Skills.Any() || npcMonsterSkill != null)
                    {
                        if (npcMonsterSkill != null)
                        {
                            npcMonsterSkill.LastSkillUse = DateTime.Now;
                            MapInstance.Broadcast($"ct 2 {MapNpcId} 3 {Target} {npcMonsterSkill.Skill.CastAnimation} {npcMonsterSkill.Skill.CastEffect} {npcMonsterSkill.Skill.SkillVNum}");
                        }

                        if (npcMonsterSkill != null && npcMonsterSkill.Skill.CastEffect != 0)
                        {
                            MapInstance.Broadcast(GenerateEff(Effect));
                        }

                        monster.CurrentHp -= damage;

                        MapInstance.Broadcast(npcMonsterSkill != null
                            ? $"su 2 {MapNpcId} 3 {Target} {npcMonsterSkill.SkillVNum} {npcMonsterSkill.Skill.Cooldown} {npcMonsterSkill.Skill.AttackAnimation} {npcMonsterSkill.Skill.Effect} 0 0 {(monster.CurrentHp > 0 ? 1 : 0)} {(int)((double)monster.CurrentHp / monster.Monster.MaxHP * 100)} {damage} 0 0"
                            : $"su 2 {MapNpcId} 3 {Target} 0 {Npc.BasicCooldown} 11 {Npc.BasicSkill} 0 0 {(monster.CurrentHp > 0 ? 1 : 0)} {(int)((double)monster.CurrentHp / monster.Monster.MaxHP * 100)} {damage} 0 0");

                        LastEffect = DateTime.Now;
                        if (monster.CurrentHp < 1)
                        {
                            RemoveTarget();
                            monster.IsAlive   = false;
                            monster.LastMove  = DateTime.Now;
                            monster.CurrentHp = 0;
                            monster.CurrentMp = 0;
                            monster.Death     = DateTime.Now;
                            Target            = -1;
                        }
                    }
                }
                else
                {
                    int maxdistance = Npc.NoticeRange > 5 ? Npc.NoticeRange / 2 : Npc.NoticeRange;
                    if (IsMoving)
                    {
                        const short maxDistance = 5;
                        if (!Path.Any() && distance > 1 && distance < maxDistance)
                        {
                            short xoffset = (short)ServerManager.Instance.RandomNumber(-1, 1);
                            short yoffset = (short)ServerManager.Instance.RandomNumber(-1, 1);
                            //go to monster
                            Path = BestFirstSearch.FindPath(new GridPos {
                                X = MapX, Y = MapY
                            }, new GridPos {
                                X = (short)(monster.MapX + xoffset), Y = (short)(monster.MapY + yoffset)
                            }, MapInstance.Map.Grid);
                        }
                        if (DateTime.Now > LastMove && Npc.Speed > 0 && Path.Any())
                        {
                            int maxindex = Path.Count > Npc.Speed / 2 && Npc.Speed > 1 ? Npc.Speed / 2 : Path.Count;
                            maxindex = maxindex < 1 ? 1 : maxindex;
                            short  mapX        = (short)Path.ElementAt(maxindex - 1).X;
                            short  mapY        = (short)Path.ElementAt(maxindex - 1).Y;
                            double waitingtime = Map.GetDistance(new MapCell {
                                X = mapX, Y = mapY
                            }, new MapCell {
                                X = MapX, Y = MapY
                            }) / (double)Npc.Speed;
                            MapInstance.Broadcast(new BroadcastPacket(null, $"mv 2 {MapNpcId} {mapX} {mapY} {Npc.Speed}", ReceiverType.All, xCoordinate: mapX, yCoordinate: mapY));
                            LastMove = DateTime.Now.AddSeconds(waitingtime > 1 ? 1 : waitingtime);

                            Observable.Timer(TimeSpan.FromMilliseconds((int)((waitingtime > 1 ? 1 : waitingtime) * 1000)))
                            .Subscribe(
                                x =>
                            {
                                MapX = mapX;
                                MapY = mapY;
                            });

                            Path.RemoveRange(0, maxindex > Path.Count ? Path.Count : maxindex);
                        }
                        if (Target != -1 && (MapId != monster.MapId || distance > maxDistance))
                        {
                            RemoveTarget();
                        }
                    }
                }
            }
        }
示例#27
0
文件: MapNpc.cs 项目: Prosecutor/test
        private void npcLife()
        {
            double time = (DateTime.Now - LastEffect).TotalMilliseconds;

            if (time > EffectDelay)
            {
                if (IsMate || IsProtected)
                {
                    MapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, MapNpcId, 825), MapX, MapY);
                }
                if (Effect > 0 && EffectActivated)
                {
                    MapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, MapNpcId, Effect), MapX, MapY);
                }
                LastEffect = DateTime.Now;
            }

            time = (DateTime.Now - LastMove).TotalMilliseconds;
            if (IsMoving && Npc.Speed > 0 && time > _movetime)
            {
                _movetime = ServerManager.RandomNumber(500, 3000);
                byte point  = (byte)ServerManager.RandomNumber(2, 4);
                byte fpoint = (byte)ServerManager.RandomNumber(0, 2);

                byte xpoint = (byte)ServerManager.RandomNumber(fpoint, point);
                byte ypoint = (byte)(point - xpoint);

                short mapX = FirstX;
                short mapY = FirstY;

                if (MapInstance.Map.GetFreePosition(ref mapX, ref mapY, xpoint, ypoint))
                {
                    double value = (xpoint + ypoint) / (double)(2 * Npc.Speed);
                    Observable.Timer(TimeSpan.FromMilliseconds(1000 * value)).Subscribe(x =>
                    {
                        MapX = mapX;
                        MapY = mapY;
                    });
                    LastMove = DateTime.Now.AddSeconds(value);
                    MapInstance.Broadcast(new BroadcastPacket(null, PacketFactory.Serialize(StaticPacketHelper.Move(UserType.Npc, MapNpcId, MapX, MapY, Npc.Speed)), ReceiverType.All, xCoordinate: mapX, yCoordinate: mapY));
                }
            }
            if (Target == -1)
            {
                if (IsHostile && Shop == null)
                {
                    MapMonster monster = MapInstance.Monsters.Find(s => MapInstance == s.MapInstance && Map.GetDistance(new MapCell {
                        X = MapX, Y = MapY
                    }, new MapCell {
                        X = s.MapX, Y = s.MapY
                    }) < (Npc.NoticeRange > 5 ? Npc.NoticeRange / 2 : Npc.NoticeRange));
                    ClientSession session = MapInstance.Sessions.FirstOrDefault(s => MapInstance == s.Character.MapInstance && Map.GetDistance(new MapCell {
                        X = MapX, Y = MapY
                    }, new MapCell {
                        X = s.Character.PositionX, Y = s.Character.PositionY
                    }) < Npc.NoticeRange);

                    if (monster != null && session != null)
                    {
                        Target = monster.MapMonsterId;
                    }
                }
            }
            else if (Target != -1)
            {
                MapMonster monster = MapInstance.Monsters.Find(s => s.MapMonsterId == Target);
                if (monster == null || monster.CurrentHp < 1)
                {
                    Target = -1;
                    return;
                }
                NpcMonsterSkill npcMonsterSkill = null;
                if (ServerManager.RandomNumber(0, 10) > 8)
                {
                    npcMonsterSkill = Npc.Skills.Where(s => (DateTime.Now - s.LastSkillUse).TotalMilliseconds >= 100 * s.Skill.Cooldown).OrderBy(rnd => _random.Next()).FirstOrDefault();
                }
                int  hitmode   = 0;
                bool onyxWings = false;
                int  damage    = DamageHelper.Instance.CalculateDamage(new BattleEntity(this), new BattleEntity(monster), npcMonsterSkill?.Skill, ref hitmode, ref onyxWings);
                if (monster.Monster.BCards.Find(s => s.Type == (byte)CardType.LightAndShadow && s.SubType == (byte)AdditionalTypes.LightAndShadow.InflictDamageToMP) is BCard card)
                {
                    int reduce = damage / 100 * card.FirstData;
                    if (monster.CurrentMp < reduce)
                    {
                        monster.CurrentMp = 0;
                    }
                    else
                    {
                        monster.CurrentMp -= reduce;
                    }
                }
                int distance = Map.GetDistance(new MapCell {
                    X = MapX, Y = MapY
                }, new MapCell {
                    X = monster.MapX, Y = monster.MapY
                });
                if (monster.CurrentHp > 0 && ((npcMonsterSkill != null && distance < npcMonsterSkill.Skill.Range) || distance <= Npc.BasicRange))
                {
                    if (((DateTime.Now - LastEffect).TotalMilliseconds >= 1000 + (Npc.BasicCooldown * 200) && Npc.Skills.Count == 0) || npcMonsterSkill != null)
                    {
                        if (npcMonsterSkill != null)
                        {
                            npcMonsterSkill.LastSkillUse = DateTime.Now;
                            MapInstance.Broadcast(StaticPacketHelper.CastOnTarget(UserType.Npc, MapNpcId, 3, Target, npcMonsterSkill.Skill.CastAnimation, npcMonsterSkill.Skill.CastEffect, npcMonsterSkill.Skill.SkillVNum));
                        }

                        if (npcMonsterSkill != null && npcMonsterSkill.Skill.CastEffect != 0)
                        {
                            MapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, MapNpcId, Effect));
                        }
                        monster.CurrentHp -= damage;
                        MapInstance.Broadcast(npcMonsterSkill != null
                            ? StaticPacketHelper.SkillUsed(UserType.Npc, MapNpcId, 3, Target, npcMonsterSkill.SkillVNum, npcMonsterSkill.Skill.Cooldown, npcMonsterSkill.Skill.AttackAnimation, npcMonsterSkill.Skill.Effect, 0, 0, monster.CurrentHp > 0, (int)((float)monster.CurrentHp / (float)monster.Monster.MaxHP * 100), damage, hitmode, 0)
                            : StaticPacketHelper.SkillUsed(UserType.Npc, MapNpcId, 3, Target, 0, Npc.BasicCooldown, 11, Npc.BasicSkill, 0, 0, monster.CurrentHp > 0, (int)((float)monster.CurrentHp / (float)monster.Monster.MaxHP * 100), damage, hitmode, 0));
                        LastEffect = DateTime.Now;
                        if (monster.CurrentHp < 1)
                        {
                            RemoveTarget();
                            monster.IsAlive   = false;
                            monster.LastMove  = DateTime.Now;
                            monster.CurrentHp = 0;
                            monster.CurrentMp = 0;
                            monster.Death     = DateTime.Now;
                            Target            = -1;
                        }
                    }
                }
                else
                {
                    int maxdistance = Npc.NoticeRange > 5 ? Npc.NoticeRange / 2 : Npc.NoticeRange;
                    if (IsMoving)
                    {
                        const short maxDistance = 5;
                        int         maxindex    = Path.Count > Npc.Speed / 2 && Npc.Speed > 1 ? Npc.Speed / 2 : Path.Count;
                        if (maxindex < 1)
                        {
                            maxindex = 1;
                        }
                        if ((Path.Count == 0 && distance >= 1 && distance < maxDistance) || (Path.Count >= maxindex && maxindex > 0 && Path[maxindex - 1] == null))
                        {
                            short xoffset = (short)ServerManager.RandomNumber(-1, 1);
                            short yoffset = (short)ServerManager.RandomNumber(-1, 1);

                            //go to monster
                            Path = BestFirstSearch.FindPathJagged(new GridPos {
                                X = MapX, Y = MapY
                            }, new GridPos {
                                X = (short)(monster.MapX + xoffset), Y = (short)(monster.MapY + yoffset)
                            }, MapInstance.Map.JaggedGrid);
                            maxindex = Path.Count > Npc.Speed / 2 && Npc.Speed > 1 ? Npc.Speed / 2 : Path.Count;
                        }
                        if (DateTime.Now > LastMove && Npc.Speed > 0 && Path.Count > 0)
                        {
                            short  mapX        = Path[maxindex - 1].X;
                            short  mapY        = Path[maxindex - 1].Y;
                            double waitingtime = Map.GetDistance(new MapCell {
                                X = mapX, Y = mapY
                            }, new MapCell {
                                X = MapX, Y = MapY
                            }) / (double)Npc.Speed;
                            MapInstance.Broadcast(new BroadcastPacket(null, PacketFactory.Serialize(StaticPacketHelper.Move(UserType.Npc, MapNpcId, MapX, MapY, Npc.Speed)), ReceiverType.All, xCoordinate: mapX, yCoordinate: mapY));
                            LastMove = DateTime.Now.AddSeconds(waitingtime > 1 ? 1 : waitingtime);

                            Observable.Timer(TimeSpan.FromMilliseconds((int)((waitingtime > 1 ? 1 : waitingtime) * 1000))).Subscribe(x =>
                            {
                                MapX = mapX;
                                MapY = mapY;
                            });

                            Path.RemoveRange(0, maxindex);
                        }
                        if (Target != -1 && (MapId != monster.MapId || distance > maxDistance))
                        {
                            RemoveTarget();
                        }
                    }
                }
            }
        }
示例#28
0
文件: Map.cs 项目: LumiereZ/OpenNos-1
 public List <GridPos> PathSearch(GridPos cell1, GridPos cell2)
 {
     return(BestFirstSearch.findPath(cell1, cell2, Grid));
 }
示例#29
0
        /// <summary>
        /// Follow the Monsters target to it's position.
        /// </summary>
        /// <param name="targetSession">The TargetSession to follow</param>
        private void followTarget(ClientSession targetSession)
        {
            if (IsMoving && !_noMove)
            {
                const short maxDistance = 22;
                int         distance    = Map.GetDistance(new MapCell()
                {
                    X = targetSession.Character.PositionX, Y = targetSession.Character.PositionY
                }, new MapCell()
                {
                    X = MapX, Y = MapY
                });
                if (targetSession != null)
                {
                    if (targetSession.Character.LastMonsterAggro.AddSeconds(5) < DateTime.Now || targetSession.Character.BrushFire == null)
                    {
                        targetSession.Character.UpdateBushFire();
                    }
                    targetSession.Character.LastMonsterAggro = DateTime.Now;
                }
                if (Path.Count == 0 && targetSession != null)
                {
                    short xoffset = (short)ServerManager.Instance.RandomNumber(-1, 1);
                    short yoffset = (short)ServerManager.Instance.RandomNumber(-1, 1);
                    try
                    {
                        Path = BestFirstSearch.TracePath(new Node()
                        {
                            X = MapX, Y = MapY
                        }, targetSession.Character.BrushFire, targetSession.Character.MapInstance.Map.Grid);
                    }
                    catch (Exception ex)
                    {
                        Logger.Error($"Pathfinding using Pathfinder failed. Map: {MapId} StartX: {MapX} StartY: {MapY} TargetX: {(short)(targetSession.Character.PositionX + xoffset)} TargetY: {(short)(targetSession.Character.PositionY + yoffset)}", ex);
                        RemoveTarget();
                    }
                }
                if (Monster != null && DateTime.Now > LastMove && Monster.Speed > 0 && Path.Count > 0)
                {
                    int    maxindex    = Path.Count > Monster.Speed / 2 ? Monster.Speed / 2 : Path.Count;
                    short  mapX        = Path[maxindex - 1].X;
                    short  mapY        = Path[maxindex - 1].Y;
                    double waitingtime = Map.GetDistance(new MapCell {
                        X = mapX, Y = mapY
                    }, new MapCell {
                        X = MapX, Y = MapY
                    }) / (double)Monster.Speed;
                    MapInstance.Broadcast(new BroadcastPacket(null, PacketFactory.Serialize(StaticPacketHelper.Move(UserType.Monster, MapMonsterId, mapX, mapY, Monster.Speed)), ReceiverType.All, xCoordinate: mapX, yCoordinate: mapY));
                    LastMove = DateTime.Now.AddSeconds(waitingtime > 1 ? 1 : waitingtime);

                    Observable.Timer(TimeSpan.FromMilliseconds((int)((waitingtime > 1 ? 1 : waitingtime) * 1000))).Subscribe(x =>
                    {
                        MapX = mapX;
                        MapY = mapY;
                    });
                    distance = (int)Path[0].F;
                    Path.RemoveRange(0, maxindex > Path.Count ? Path.Count : maxindex);
                }

                if (targetSession == null || MapId != targetSession.Character.MapInstance.Map.MapId || distance > (maxDistance) + 3)
                {
                    RemoveTarget();
                }
            }
        }
示例#30
0
 public Node[,] GetBrushFire() => BestFirstSearch.LoadBrushFire(new GridPos()
 {
     X = MapX, Y = MapY
 }, MapInstance.Map.Grid);