/// <summary> /// Точка перехода между районами /// </summary> /// <param name="From">Откуда</param> /// <param name="To">Куда</param> /// <param name="Position">Координаты левой верхней точки</param> /// <param name="Size">Размер (в клетках)</param> public MapAreaTransitionPoint(MapArea From, MapArea To, MapPoint Position, MapSize Size) { this.From = From; this.To = To; this.Position = Position; this.Size = Size; }
/// <summary> /// Точка находится на заданной площади /// </summary> /// <param name="LeftTopPoint">Левая верхняя точка площади</param> /// <param name="Size">Размер</param> /// <returns>Находиться ли точка на заданной площади</returns> public bool InArea(MapPoint LeftTopPoint, MapSize Size) { return this.X >= LeftTopPoint.X && this.X <= LeftTopPoint.X + Size.Width && this.Y >= LeftTopPoint.Y && this.Y <= LeftTopPoint.Y + Size.Height; }
public void Render(MapObject mapObject) { MapPoint cellPoint = new MapPoint(0, 0, 0); Map map = new Map(1, MapSize.One); map[cellPoint] = new MapCell(new MapPlace(), null); if (mapObject is MapPlace) { map[cellPoint].Place = mapObject as MapPlace; } if (mapObject is MapWall) { map[cellPoint].SetWall(MapDirection.North, mapObject as MapWall); map[cellPoint].SetWall(MapDirection.East, mapObject as MapWall); map[cellPoint].SetWall(MapDirection.West, mapObject as MapWall); map[cellPoint].SetWall(MapDirection.South, mapObject as MapWall); } MapState mapState = new MapState(map); if (mapObject is MapActiveObject) { mapState.AddActiveObject(mapObject as MapActiveObject, cellPoint); } GameMap gameMap = new GameMap(mapState); Renderer.SetMap(gameMap, new MapCellRange(cellPoint, cellPoint)); Renderer.Render(); }
/// <summary> /// Определить район, которому принадлежит клетка карты /// </summary> /// <param name="Cell">Клетка карты</param> /// <returns>Район</returns> public MapAreaState GetAreaByCell(MapPoint Cell) { foreach (MapAreaState MapAreaState in Areas) { if (Cell.InArea(MapAreaState.Area.Position, MapAreaState.Area.Size)) return MapAreaState; } return null; }
public NpcState(Npc Npc, MapState MapState, Script AI, Fraction Fraction, MapPoint Position) : base(Npc) { this.MapState = MapState; //this.MapActiveObjectGuid = this.MapState.AddActiveObject(this.Npc.MapActiveObject, Position); this.AI = AI; this.Fraction = Fraction; }
/// <summary> /// Состояние активного объекта карты /// </summary> /// <param name="ActiveObject">Активный объект</param> /// <param name="Position">Координаты левой верхней точки</param> public MapActiveObjectState(MapActiveObject ActiveObject, MapPoint Position) : base(ActiveObject) { this.Position = Position; this.ArmorType = ActiveObject.ArmorType; this._Health = ActiveObject.Health; this._Direction = Direction; this.ActualSize = this.Size; }
/// <summary> /// Состояние клетки карты /// </summary> /// <param name="Cell">Клетка</param> /// <param name="Point">Координаты</param> public MapCellState(MapCell Cell, MapPoint Point) { if (Cell == null) throw new ArgumentNullException("Cell", "Cell of MapCellState cannot be null"); this.Point = Point; this.Cell = Cell; this.Place = (Cell.Place != null) ? new MapPlaceState(Cell.Place) : null; if (Cell.Walls != null) { foreach (KeyValuePair<MapDirection, MapWall> wall in Cell.Walls) { if (wall.Value == null) continue; MapWallState wallState = new MapWallState(wall.Value, wall.Key); wallState.Destroying += (sender, args) => { OnWallDestroying(args.Wall); }; wallState.Destroyed += (sender, args) => { OnWallDestroyed(args.Wall); }; this.SetWall(wall.Key, wallState); } } }
/// <summary> /// Добавить новый объект на карту /// </summary> /// <param name="ActiveObject">Активный объект</param> /// <param name="Position">Координаты левой верхней точки</param> /// <param name="Id">Идентификатор (для десериализации)</param> /// <returns>Идентификатор</returns> public Guid AddActiveObject(MapActiveObject ActiveObject, MapPoint Position) { if (ActiveObject == null) throw new ArgumentNullException("ActiveObject", "ActiveObject cannot be null"); if (Position.Level >= this.LevelsCount) throw new ArgumentOutOfRangeException("Position.Level", "Level cannot be out of map"); if ((Position.X + ActiveObject.Tile.Size.Width > this.Size.Width) || (Position.Y + ActiveObject.Tile.Size.Height > this.Size.Height)) throw new ArgumentOutOfRangeException("Position", "Position cannot be out of map"); if (!CheckPlaceForActiveObject(ActiveObject, Position)) throw new ArgumentException("ActiveObject", "ActiveObject cannot be located to this Position"); Guid Id = Guid.NewGuid(); MapActiveObjectState state = new MapActiveObjectState(ActiveObject, Position); state.Destroying += (sender, args) => { OnActiveObjectDestroying(args.ActiveObject); }; state.Destroyed += (sender, args) => { OnActiveObjectDestroyed(args.ActiveObject); }; this.ActiveObjects.Add(Id, state); AttachActiveObject(state, Position); return Id; }
/// <summary> /// Клетка /// </summary> /// <param name="Point">Точка</param> /// <returns>Клетка</returns> public MapCellState this[MapPoint Point] { get { if (Point.Level >= LevelsCount) throw new ArgumentOutOfRangeException("Point.Level", "Point.Level cannot out of Map"); return this.Levels[Point.Level].Cells[Point]; } set { if (Point.Level >= LevelsCount) throw new ArgumentOutOfRangeException("Point.Level", "Point.Level cannot out of Map"); this.Levels[Point.Level].Cells[Point] = value; } }
/// <summary> /// Район карты /// </summary> /// <param name="Position">Координаты левой верхней точки</param> /// <param name="Size">Размер (в клетках)</param> /// <param name="TransitionPoints">Точки перехода</param> public MapArea(MapPoint Position, MapSize Size) { this.Position = Position; this.Size = Size; this.TransitionPoints = new List <MapAreaTransitionPoint>(); }
/// <summary> /// Клетка /// </summary> /// <param name="Point">Точка</param> /// <returns>Клетка</returns> public MapCellState this[MapPoint Point] { get { return this.Cells[Point]; } set { this.Cells[Point] = value; } }
/// <summary> /// Обработка волны в конкретной клетке /// </summary> /// <param name="Point">Клетка</param> /// <param name="WaveValue">Значение волны</param> private void Wave(MapPoint Point, UInt16 WaveValue) { if (endflag) return; if (Waves[Point.X - Area.Area.Position.X, Point.Y - Area.Area.Position.Y] != UInt16.MaxValue) return; if (Point.Equals(To.Point)) { endflag = true; return; } Waves[Point.X - Area.Area.Position.X, Point.Y - Area.Area.Position.Y] = WaveValue; MapCellState left = GetMapCell(Point, -1, 0); MapCellState right = GetMapCell(Point, +1, 0); MapCellState up = GetMapCell(Point, 0, -1); MapCellState down = GetMapCell(Point, 0, +1); if ((left != null) && Area.CheckCellInArea(left) && (left.Place.Passability > 0)) Wave(left.Point, WaveValue++); if ((right != null) && Area.CheckCellInArea(right) && (right.Place.Passability > 0)) Wave(right.Point, WaveValue++); if ((up != null) && Area.CheckCellInArea(up) && (up.Place.Passability > 0)) Wave(up.Point, WaveValue++); if ((down != null) && Area.CheckCellInArea(down) && (down.Place.Passability > 0)) Wave(down.Point, WaveValue++); }
/// <summary> /// Район карты /// </summary> /// <param name="Position">Координаты левой верхней точки</param> /// <param name="Size">Размер (в клетках)</param> /// <param name="TransitionPoints">Точки перехода</param> public MapArea(MapPoint Position, MapSize Size) { this.Position = Position; this.Size = Size; this.TransitionPoints = new List<MapAreaTransitionPoint>(); }
/// <summary> /// Переместить объект в другое место карты /// </summary> /// <param name="Id">Идентификатор объекта</param> /// <param name="Position">Координаты левой верхней точки</param> public void RelocateActiveObject(Guid Id, MapPoint Position) { MapActiveObjectState ActiveObject = GetActiveObjectById(Id); if (Position.Level >= this.LevelsCount) throw new ArgumentOutOfRangeException("Position.Level", "Position.Level cannot be out of map"); if ((Position.X + ActiveObject.Size.Width >= this.Size.Width) || (Position.Y + ActiveObject.Size.Height >= this.Size.Height)) throw new ArgumentOutOfRangeException("Position", "Position cannot be out of map"); if (!CheckPlaceForActiveObject(ActiveObject.ActiveObject, Position)) throw new ArgumentException("ActiveObject", "ActiveObject cannot be located to this Position"); DeAttachActiveObject(ActiveObject); AttachActiveObject(ActiveObject, Position); }
public MapPoint(MapPoint Point, Int16 DeltaX, Int16 DeltaY) { this.Level = Point.Level; this.X = (UInt16)(Point.X + DeltaX); this.Y = (UInt16)(Point.Y + DeltaY); }
/// <summary> /// "Приклеить" объект к карте /// </summary> /// <param name="ActiveObject">Активный объект</param> /// <param name="Position">Координаты левой верхней точки</param> private void AttachActiveObject(MapActiveObjectState ActiveObject, MapPoint Position) { ActiveObject.Locate(Position); for (UInt16 x = ActiveObject.Position.X; x < ActiveObject.Position.X + ActiveObject.Size.Width; x++) for (UInt16 y = ActiveObject.Position.Y; y < ActiveObject.Position.Y + ActiveObject.Size.Height; y++) Levels[Position.Level].Cells[x, y].AddActiveObject(ActiveObject); }
/// <summary> /// Расположить активный объект /// </summary> /// <param name="Position">Левая верхняя точка</param> public void Locate(MapPoint Position) { this.Position = Position; }
/// <summary> /// Определить принадлежит ли району точка карты /// </summary> /// <param name="Point">Точка карты</param> /// <returns>Принадлежит ли району</returns> public bool CheckCellInArea(MapPoint Point) { return Point.InArea(Area.Position, Area.Size); }
public MoveAction(MapPoint target) { this.Target = target; }
/// <summary> /// Проверить возможность размещения объекта на карт /// </summary> /// <param name="ActiveObject">Активный объект</param> /// <param name="Position">Координаты левой верхней точки</param> public bool CheckPlaceForActiveObject(MapActiveObject ActiveObject, MapPoint Position) { if (ActiveObject == null) throw new ArgumentNullException("ActiveObject", "ActiveObject cannot be null"); if (Position.Level >= this.LevelsCount) throw new ArgumentOutOfRangeException("Position.Level", "Position.Level cannot be out of map"); if ((Position.X + ActiveObject.Tile.Size.Width > this.Size.Width) || (Position.Y + ActiveObject.Tile.Size.Height > this.Size.Height)) throw new ArgumentOutOfRangeException("Position", "Position cannot be out of map"); for (UInt16 x = Position.X; x < Position.X + ActiveObject.Tile.Size.Width; x++) for (UInt16 y = Position.Y; y < Position.Y + ActiveObject.Tile.Size.Height; y++) { bool North = (y == Position.Y); bool South = (y == (Position.Y + ActiveObject.Tile.Size.Height - 1)); bool West = (x == Position.X); bool East = (x == (Position.Y + ActiveObject.Tile.Size.Width - 1)); if (!CheckCell(ActiveObject, Position, North, South, West, East)) return false; } return true; }
public MapCellState CreateCell(MapPlace place, Dictionary<MapDirection, MapWall> walls, MapPoint point) { MapCellState currentCell = this[point]; if (currentCell != null) { if (currentCell.ActiveObjects != null) { foreach (var activeObject in currentCell.ActiveObjects) this.RemoveActiveObject(GetIdOfActiveObject(activeObject)); } } MapCell cell = Map[point] = new MapCell(place, walls); return (this[point] = new MapCellState(cell, point)); }
/// <summary> /// Построить путь из одной клетки в другую /// </summary> /// <param name="From">Откуда</param> /// <param name="To">Куда</param> /// <returns>Путь</returns> public MapPoint[] CalcPath(MapPoint From, MapPoint To) { if (!Area.CheckCellInArea(From)) throw new ArgumentOutOfRangeException("From", "From cannot be out of Area"); if (!Area.CheckCellInArea(To)) throw new ArgumentOutOfRangeException("To", "To cannot be out of Area"); lock (locker) { UInt16 level = From.Level; // пересчитываем волны Waves = new UInt16[Height, Width]; for (int i = 0; i < Height; i++) for (int j = 0; j < Width; j++) Waves[i, j] = UInt16.MaxValue; endflag = false; Wave(From, 0); MapPoint current = To; List<MapPoint> path = new List<MapPoint>(); while (!current.Equals(From)) { int X = current.X - Area.Area.Position.X; int Y = current.Y - Area.Area.Position.Y; if (X + 1 < Width && Waves[X, Y] > Waves[X + 1, Y]) current = new MapPoint(current, 1, 0); else if (Y + 1 < Height && Waves[X, Y] > Waves[X, Y + 1]) current = new MapPoint(current, 0, 1); else if (Y - 1 >= 0 && Waves[X, Y] > Waves[X, Y - 1]) current = new MapPoint(current, 0, -1); else if (X - 1 >= 0 && Waves[X, Y] > Waves[X - 1, Y]) current = new MapPoint(current, -1, 0); path.Add(current); } path.Reverse(); return path.ToArray(); } }
public MapCellState SetPlace(MapPlace place, MapPoint point) { MapCellState cell = this[point]; if (cell == null) { return (cell = CreateCell(place, null, point)); } else { return (cell = CreateCell(place, cell.Cell.Walls, point)); } }
/// <summary> /// Взять клетку карты со смещением относительно определённой точки /// </summary> /// <param name="Point">Базовая точка</param> /// <param name="DeltaX">Смещение по оси X</param> /// <param name="DeltaY">Смещение по оси Y</param> /// <returns>Клетка карты</returns> protected MapCellState GetMapCell(MapPoint Point, int DeltaX, int DeltaY) { int newX = Point.X + DeltaX; int newY = Point.Y + DeltaY; if ((newX < 0) || (newY < 0)) return null; if ((newX >= Map.Levels[Point.Level].Size.Width) || (newY >= Map.Levels[Point.Level].Size.Height)) return null; return Map.Levels[Point.Level].Cells[newX, newY]; }
/// <summary> /// Проверка возможности размещения в данной клетке объекта /// </summary> /// <param name="ActiveObject">Объект</param> /// <param name="Position">Координаты</param> /// <param name="IgnoreNorth">Игнорируется ли северная стена</param> /// <param name="IgnoreSouth">Мгнорируется ли южная стена</param> /// <param name="IgnoreWest">Игнорируется ли западная стена</param> /// <param name="IgnoreEast">Игнорируется ли восточная стена</param> /// <returns>Возможно ли разместить объект в данной клетке</returns> private bool CheckCell(MapActiveObject ActiveObject, MapPoint Position, bool IgnoreNorth, bool IgnoreSouth, bool IgnoreWest, bool IgnoreEast) { MapCellState cell = Levels[Position.Level].Cells[Position]; if ((cell.Place != null) && (cell.Place.Passability < ActiveObject.Passability)) return false; if (!IgnoreNorth && (cell.GetPassbilityByDirection(MapDirection.North) < ActiveObject.Passability)) return false; if (!IgnoreSouth && (cell.GetPassbilityByDirection(MapDirection.South) < ActiveObject.Passability)) return false; if (!IgnoreWest && (cell.GetPassbilityByDirection(MapDirection.West) < ActiveObject.Passability)) return false; if (!IgnoreEast && (cell.GetPassbilityByDirection(MapDirection.East) < ActiveObject.Passability)) return false; return true; }
/// <summary> /// Диапазон на карте /// </summary> /// <param name="from"></param> /// <param name="to"></param> public MapCellRange(MapPoint from, MapPoint to) { Begin = from; End = to; }