//String _imgPath;
        public TerrainGridHex(HexBoard<MapGridHex> board, HexCoords coords, String type, String imgSummer, String imgWinter, double stepCost, int elevation, List<Resource> resources)
            : base(board, coords)
        {
            Type = type;
            _specialType = "";
            _stepCost = stepCost;
            _elevation = elevation;
            IsSummer = true;
            Resources = resources;

            //TODO: improve logic
            while (_bmpSummer == null)
            {
                try
                {
                    _bmpSummer = new Bitmap(imgSummer);
                }
                catch (OutOfMemoryException)
                {
                }
            }

            while (_bmpWinter == null)
            {
                try
                {
                    _bmpWinter = new Bitmap(imgWinter);
                }
                catch (OutOfMemoryException)
                {
                }
            }
        }
        public MainForm(String lp = "")
        {
            InitializeComponent();

            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing);
            this.LocationChanged += new System.EventHandler(this.MainForm_LocationChanged);
            this.Resize += new System.EventHandler(this.MainForm_Resize);
            this.StartPosition = FormStartPosition.Manual;
            this.Location = Properties.Settings.Default.Location;
            this.WindowState = Properties.Settings.Default.State;
            if (this.WindowState == FormWindowState.Normal) this.Size = Properties.Settings.Default.Size;

            TerrainMap.DefineBoard(@"Terrain\map.txt");

            tm = new TerrainMap();

            LoadMap();

            //Main panel
            hexgridPanel1.Scales = new List<float>() { 1.000F }.AsReadOnly();
            hexgridPanel1.ScaleIndex = hexgridPanel1.Scales
                              .Select((f, i) => new { value = f, index = i })
                              .Where(s => s.value == 1.0F)
                              .Select(s => s.index).FirstOrDefault();

            hexgridPanel1.Host = tm;
            hexgridPanel1.Size = hexgridPanel1.MapSizePixels;

            //Minimap
            minimapScale = Math.Min((float)pbMinimap.Height / (float)hexgridPanel1.Height, (float)pbMinimap.Width / (float)hexgridPanel1.Width);

            pbMinimap.Width = (int)(hexgridPanel1.Width * minimapScale);
            pbMinimap.Height = (int)(hexgridPanel1.Height * minimapScale);

            clickCoords = HexCoords.NewUserCoords(-1, -1);

            loggedPlayerName = lp;

            isPlayerTurn = (turn.CurrentPlayer.Name == loggedPlayerName || loggedPlayerName == "");

            btnEndTurn.Enabled = isPlayerTurn;

            if (loggedPlayerName != "") btnResolve.Enabled = false;

            btnUndo.Enabled = false;

            UpdateLos();
            UpdateSummary();
            UpdateResources();

            //this.MouseWheel += new MouseEventHandler(hexgridPanel1_MouseWheel);
        }
        public NewBuildingForm(String p, HexCoords c, object[] arr, Race r)
        {
            InitializeComponent();

            cbBuildingType.Items.AddRange(arr);

            playerDoc = XDocument.Load(Player.SavePath);

            player = p;
            coords = c;
            race = r;

            lblCost.Text = "";
        }
 public bool this[HexCoords coords]
 {
     get
     {
         return _isOnboard(coords) && _fovBacking[coords.User.X][coords.User.Y];
     }
     internal set
     {
         lock (_syncLock)
         {
             if (_isOnboard(coords)) { _fovBacking[coords.User.X][coords.User.Y] = value; }
         }
     }
 }
        public NewArmyForm(String pn, HexCoords c, object[] sizeArr)
        {
            InitializeComponent();

            playerName = pn;
            coords = c;

            playerDoc = XDocument.Load(Player.SavePath);
            String race = playerDoc.XPathSelectElement("Players/Player[Name=\"" + playerName + "\"]/Race").Value;
            raceDoc = XDocument.Load(Race.GetConfigDoc(race));

            foreach (var e in raceDoc.XPathSelectElements("Config/ArmyTypes/ArmyType"))
            {
                lbArmyTypes.Items.Add(e.Attribute("Type").Value);
            }

            cbSize.Items.AddRange(sizeArr);
        }
        /// <summary></summary>
        /// <remarks>
        /// Takes a circle in the form of a center point and radius, and a function
        /// that can tell whether a given cell is opaque. Calls the setFoV action on
        /// every cell that is both within the radius and visible from the center. 
        /// </remarks>
        /// <param name="observerCoords">Cordinates of observer;s hex.</param>
        /// <param name="radius">Maximum radius for Field-of-View.</param>
        /// <param name="observerHeight">Height (ASL) of the observer's eyes.</param>
        /// <param name="isOnBoard">Is this hex on the baoard.</param>
        /// <param name="targetHeight">Returns ground level (ASL) of supplied hex.</param>
        /// <param name="terrainHeight">Returns height (ASL) of terrain in supplied hex.</param>
        /// <param name="setFieldOfView">Sets a hex as visible in the Field-of-View.</param>
        public static void ComputeFieldOfView(
          HexCoords observerCoords,
          int radius,
          int observerHeight,
          Func<HexCoords, bool> isOnBoard,
          Func<HexCoords, int> targetHeight,
          Func<HexCoords, int> terrainHeight,
          Action<HexCoords> setFieldOfView
        )
        {
#if TraceFOV
        TraceFlag.FieldOfView.Trace(true, " - Coords = " + observerCoords.User.ToString());
#endif
            var matrixOrigin = new IntMatrix2D(observerCoords.Canon);

            setFieldOfView(observerCoords);    // Always visible to self!
#if TraceFoV
        int dodecant = 0;
        foreach (var matrix in matrices.Select(m => m*matrixOrigin)) {
          TraceFlags.FieldOfView.Trace(true," - Dodecant: {0}", dodecant++);
#else
            Parallel.ForEach(_dodecantMatrices.Select(m => m * matrixOrigin), matrix =>
            {
#endif
                ComputeFieldOfViewInDodecantZero(
                  radius,
                  observerHeight,
                  TranslateDodecant(matrix, isOnBoard),
                  TranslateDodecant(matrix, targetHeight),
                  TranslateDodecant(matrix, terrainHeight),
                  TranslateDodecant(matrix, setFieldOfView));
            }
#if !TraceFoV
);
#endif
        }
Example #7
0
 /// <inheritdoc/>
 public Maybe <THex> Neighbour(HexCoords coords, Hexside hexside)
 => BoardHexes.Neighbour(coords, hexside);
 /// <summary>Returns the scroll position to center a specified hex in viewport.</summary>
 /// <param name="coordsNewCenterHex"><c>HexCoords</c> for the hex to be centered in viewport.</param>
 /// <returns>Pixel coordinates in Client reference frame.</returns>
 protected Point ScrollPositionToCenterOnHex(HexCoords coordsNewCenterHex)
 {
     return Hexgrid.ScrollPositionToCenterOnHex(coordsNewCenterHex);
 }
Example #9
0
 public void ForAllNeighbours(HexCoords coords, Action <Maybe <THex>, Hexside> action)
 => BoardHexes.ForAllNeighbours(coords, action);
 /// <summary>Returns the pixel coordinates of the center of the specified hex.</summary>
 /// <param name="coords"><see cref="HexCoords"/> specification for which pixel center is desired.</param>
 /// <returns>Pixel coordinates of the center of the specified hex.</returns>
 Point HexOrigin(HexCoords coords)
 {
     return new Point(
       (int)(Host.GridSizeF.Width * coords.User.X),
       (int)(Host.GridSizeF.Height * coords.User.Y + Host.GridSizeF.Height / 2 * (coords.User.X + 1) % 2)
     );
 }
Example #11
0
 /// <summary>TODO</summary>
 public int TryEntryCost(HexCoords hexCoords, Hexside hexside) =>
 (from x in _entryCosts[hexCoords] select x[hexside]).ElseDefault() ?? -1;
 /// <summary>Elevation of the hexside Above Sea Level</summary>
 /// <param name="this">The {IFovBoard} to be analyzed.</param>
 /// <param name="coords">The coordinates of the hex being tested.</param>
 /// <param name="hexside"></param>
 public static int ElevationHexsideASL(this IFovBoard @this, HexCoords coords, Hexside hexside)
 => @this[coords].Match(hex => @this.ElevationASL(hex) + hex.HeightHexside(hexside), MaxValue32);
Example #13
0
 public void PlaceUnit(MapUnit unit, HexCoords loc)
 {
     PlaceUnit(unit, CellAt(loc));
 }
 /// <summary>TODO</summary>
 public HexEventArgs(HexCoords coords)
     : this(coords, new MouseEventArgs(MouseButtons.None, 0, 0, 0, 0))
 {
 }
 /// <summary>TODO</summary>
 public HexEventArgs(HexCoords coords, Keys modifierKeys)
     : this(coords, new MouseEventArgs(MouseButtons.None, 0, 0, 0, 0), modifierKeys)
 {
 }
 internal static int Estimate(Func<int,int> heuristic, IntVector2D vectorGoal, HexCoords goal, 
     HexCoords hex, int totalCost)
 {
     var estimate   = (int)heuristic(goal.Range(hex)) + totalCost;
       var preference = Preference(vectorGoal, goal, hex);
       return (estimate << 16) + preference;
 }
 static int Preference(IntVector2D vectorGoal, HexCoords goal, HexCoords hex)
 {
     return (0xFFFF & Math.Abs(vectorGoal ^ (goal.Canon - hex.Canon) ));
 }
        /// <summary>Returns an <c>IPath</c> for the optimal path from coordinates <c>start</c> to <c>goal</c>.</summary>
        /// <param name="start">Coordinates for the <c>last</c> step on the desired path.</param>
        /// <param name="goal">Coordinates for the <c>first</c> step on the desired path.</param>
        /// <param name="stepCost">Cost to extend path by hex at <c>coords</c> from hex at direction <c>hexside</c>.</param>
        /// <param name="heuristic">Returns a cost estimate from a range value.</param>
        /// <param name="isOnboard">Returns whether the coordinates specified are "on board".</param>
        public static IPath FindPath(
      HexCoords   start,
      HexCoords   goal,
      Func<HexCoords, Hexside, int> stepCost,
      Func<int,int>                 heuristic,
      Func<HexCoords,bool>          isOnboard
    )
        {
            if (stepCost==null) throw new ArgumentNullException("stepCost");
              if (heuristic==null) throw new ArgumentNullException("heuristic");
              if (isOnboard==null) throw new ArgumentNullException("isOnboard");

              var vectorGoal = goal.Canon - start.Canon;
              var closed     = new HashSet<HexCoords>();
              var open       = new HashSet<HexCoords>();
              var queue      = DictionaryPriorityQueue<int, Path>.NewQueue();
              TraceFlags.FindPathDetail.Trace(true, "Find path from {0} to {1}; vectorGoal = {0}",
                                          start.Canon, goal.Canon, vectorGoal);

              queue.Enqueue (0, new Path(start));

              HexKeyValuePair<int,Path> item;
              while (queue.TryDequeue(out item)) {
            var path = item.Value;
            if( closed.Contains(path.StepCoords) ) continue;

            open.Add(item.Value.StepCoords);

            TraceFlags.FindPathDetail.Trace(
              "Dequeue Path at {0} w/ cost={1,4} at {2}; estimate={3,4}:{4,4}.",
              item.Value.StepCoords, item.Value.TotalCost, item.Value.HexsideExit,
              item.Key >> 16, item.Key & 0xFFFF);

            if(path.StepCoords.Equals(goal)) return path;

            closed.Add(path.StepCoords);

            foreach (var neighbour in path.StepCoords.GetNeighbours()
                                      .Where(n => isOnboard(n.Coords))
            ) {
            var cost = stepCost(path.StepCoords, neighbour.Hexside);
            if (cost > 0) {
              var newPath  = path.AddStep(neighbour, (ushort)cost);
              var estimate = Estimate(heuristic,vectorGoal,goal, newPath.StepCoords, newPath.TotalCost);
              TraceFlags.FindPathDetail.Trace("   Enqueue {0}: {1,4}:{2,3}",
                      neighbour.Coords, estimate>>16, estimate & 0xFFFF);
              queue.Enqueue(estimate, newPath);
            }
            }
              }
              return null;
        }
     /// <summary>TODO</summary>
     /// <param name="start"></param>
     /// <param name="goal"></param>
     /// <param name="board"></param>
     /// <returns></returns>
     public static IPath FindPath(
   HexCoords     start,
   HexCoords     goal,
   INavigableBoard board
 )
     {
         if (board==null) throw new ArgumentNullException("board");
           return FindPath(start, goal, board.StepCost,
                                board.Heuristic, board.IsOnboard);
     }
        private void hexgridPanel1_RightClick(object sender, HexEventArgs e)
        {
            Army a = tm.GetArmy(e.Coords);
            Town t = tm.GetTown(e.Coords);
            Watchtower wt = tm.GetWatchtower(e.Coords);
            Castle c = tm.GetCastle(e.Coords);
            TerrainGridHex hex = (TerrainGridHex)tm.BoardHexes[e.Coords];

            if (isPlayerTurn && newObject == null)
            {
                if (tm.SelectedArmy == null)
                {
                    clickCoords = e.Coords;
                }

                //Move
                if (tm.SelectedArmy != null && tm.InMovement(e.Coords) && tm.SelectedArmy.Coords != e.Coords)
                {
                    //Can't move, own army in the way
                    if (turn.CurrentPlayer.Armies.Contains(a))
                    {
                        MessageBox.Show("Can't move here, other army in the way");
                    }
                    //Siege
                    else if ((c != null && !turn.CurrentPlayer.Castles.Contains(c)) || (t != null && !turn.CurrentPlayer.Towns.Contains(t)))
                    {

                        SiegeForm sf = new SiegeForm();
                        int result = sf.CustomShowDialog();
                        sf.Dispose();

                        HexCoords coords = tm.Path.ElementAt(tm.Path.TotalSteps - 1).StepCoords;

                        switch(result)
                        {
                            case 0:
                                playerDoc.Save(Player.UndoPath);
                                btnUndo.Enabled = true;

                                tm.SelectedArmy.Move(coords, tm);
                                if (c != null) tm.SelectedArmy.Attack(c);
                                if (t != null) tm.SelectedArmy.Attack(t);

                                playerDoc = XDocument.Load(Player.SavePath);
                                break;

                            case 1:
                                playerDoc.Save(Player.UndoPath);
                                btnUndo.Enabled = true;

                                tm.SelectedArmy.Move(coords, tm);
                                if (c != null) tm.SelectedArmy.Siege(c);
                                if (t != null) tm.SelectedArmy.Siege(t);

                                playerDoc = XDocument.Load(Player.SavePath);
                                break;
                        }

                        tm.SelectedArmy = null;
                    }
                    //Attack army
                    else if (a != null && !turn.CurrentPlayer.Armies.Contains(a))
                    {
                        playerDoc.Save(Player.UndoPath);
                        btnUndo.Enabled = true;

                        if (a.Size > 0)
                        {
                            HexCoords coords = tm.Path.ElementAt(tm.Path.TotalSteps - 1).StepCoords;

                            tm.SelectedArmy.Move(coords, tm);
                            tm.SelectedArmy.Attack(a);

                            tm.SelectedArmy = null;

                            playerDoc = XDocument.Load(Player.SavePath);
                        }
                        else
                        {
                            a.Remove();
                            tm.SelectedArmy.Move(e.Coords, tm);
                            tm.SelectedArmy = null;
                        }

                        playerDoc = XDocument.Load(Player.SavePath);
                    }
                    //Move
                    else //(a == null && t == null && c == null && wt == null)
                    {
                        DialogResult result = System.Windows.Forms.DialogResult.Yes;
                        if (tm.SelectedArmy.IsSieging) { result = MessageBox.Show("About to stop sieging. Are you sure?", "Warning", MessageBoxButtons.YesNo); }

                        if (result == System.Windows.Forms.DialogResult.Yes)
                        {
                            playerDoc.Save(Player.UndoPath);
                            btnUndo.Enabled = true;

                            if (tm.SelectedArmy.IsSieging) tm.SelectedArmy.EndSiege();
                            tm.SelectedArmy.Move(e.Coords, tm);
                            tm.SelectedArmy = null;

                            playerDoc = XDocument.Load(Player.SavePath);
                        }
                    }
                }

                //Show menus
                else //if (tm.SelectedArmy == null)
                {
                    if (turn.CurrentPlayer.Armies.Contains(a) && turn.CurrentPlayer.Towns.Contains(t))
                    {
                        cmsArmyTown_BuildBuilding.Enabled = true;
                        cmsArmyTown_IncreaseArmy.Enabled = true;
                        cmsArmyTown_UpgradeTown.Enabled = true;
                        cmsArmyTown_UpgradeObstacles.Enabled = true;
                        cmsArmyTown_UpgradeWalls.Enabled = true;
                        cmsArmyTown_UpgradeTowers.Enabled = true;

                        cmsArmyTown_BuildBuilding.Enabled = false;
                        cmsArmyTown_BuildRoad.Enabled = false;
                        if (t.Level <= 1 || t.IsUnderSiege || t.IsInBattle) cmsArmyTown_IncreaseArmy.Enabled = false;
                        if (t.Level == 20 || t.LevelChanged || !turn.CurrentPlayer.Race.CanPay("UpgradeTown") || t.IsUnderSiege || t.IsInBattle) cmsArmyTown_UpgradeTown.Enabled = false;
                        if (t.Cover == Town.CoverLevels.Last() || !turn.CurrentPlayer.CanUpgradeCover(t) || t.IsUnderSiege || t.IsInBattle) cmsArmyTown_UpgradeObstacles.Enabled = false;
                        if (t.Walls == Town.WallLevels.Last() || !turn.CurrentPlayer.CanUpgradeWalls(t) || t.IsUnderSiege || t.IsInBattle) cmsArmyTown_UpgradeWalls.Enabled = false;
                        if (t.Towers == Town.TowerLevels.Last() || !turn.CurrentPlayer.CanUpgradeTowers(t) || t.IsUnderSiege || t.IsInBattle) cmsArmyTown_UpgradeTowers.Enabled = false;

                        cmsArmyTown.Show(hexgridPanel1, e.X, e.Y);
                    }
                    else if (turn.CurrentPlayer.Armies.Contains(a) && turn.CurrentPlayer.Castles.Contains(c))
                    {
                        cmsArmyCastle_BuildBuilding.Enabled = true;
                        cmsArmyCastle_IncreaseArmy.Enabled = true;
                        cmsArmyCastle_UpgradeCastle.Enabled = true;
                        cmsArmyCastle_UpgradeWalls.Enabled = true;
                        cmsArmyCastle_UpgradeTowers.Enabled = true;
                        cmsArmyCastle_UpgradeGatehouse.Enabled = true;

                        cmsArmyCastle_BuildBuilding.Enabled = false;
                        cmsArmyCastle_BuildRoad.Enabled = false;
                        if (c.Level <= 1 || a != null || c.IsUnderSiege) cmsArmyCastle_IncreaseArmy.Enabled = false;
                        if (c.Level == 20 || c.LevelChanged || !turn.CurrentPlayer.Race.CanPay("UpgradeCastle") || c.IsUnderSiege || c.IsInBattle) cmsArmyCastle_UpgradeCastle.Enabled = false;
                        if (c.Walls == Castle.WallLevels.Last() || !turn.CurrentPlayer.CanUpgradeWalls(c) || c.IsUnderSiege || c.IsInBattle) cmsArmyCastle_UpgradeWalls.Enabled = false;
                        if (c.Towers == Castle.TowerLevels.Last() || !turn.CurrentPlayer.CanUpgradeTowers(c) || c.IsUnderSiege || c.IsInBattle) cmsArmyCastle_UpgradeTowers.Enabled = false;
                        if (c.Gatehouse == Castle.GatehouseLevels.Last() || !turn.CurrentPlayer.CanUpgradeGatehouse(c) || c.IsUnderSiege || c.IsInBattle) cmsArmyCastle_UpgradeGatehouse.Enabled = false;

                        cmsArmyCastle.Show(hexgridPanel1, e.X, e.Y);
                    }
                    else if (turn.CurrentPlayer.Armies.Contains(a))
                    {
                        cmsArmy_BuildBuilding.Enabled = true;
                        cmsArmy_BuildRoad.Enabled = true;

                        if (tm.GetBuilding(clickCoords) != null || turn.CurrentPlayer.BuildableBuildings.Count == 0 || !a.CanBuild || a.IsInBattle) cmsArmy_BuildBuilding.Enabled = false;
                        if (tm.GetBuilding(clickCoords) != null || !turn.CurrentPlayer.Race.CanPay("Road") || hex.SpecialType == "Road" || !a.CanBuild || a.IsInBattle || !a.CanBuildRoad(tm)) cmsArmy_BuildRoad.Enabled = false;

                        cmsArmy.Show(hexgridPanel1, e.X, e.Y);
                    }
                    else if (turn.CurrentPlayer.Towns.Contains(t))
                    {
                        cmsTown_MusterArmy.Enabled = true;
                        cmsTown_UpgradeTown.Enabled = true;
                        cmsTown_UpgradeObstacles.Enabled = true;
                        cmsTown_UpgradeWalls.Enabled = true;
                        cmsTown_UpgradeTowers.Enabled = true;

                        if (t.Level <= 5 || a != null || t.IsUnderSiege || t.IsInBattle) cmsTown_MusterArmy.Enabled = false;
                        if (t.Level == 20 || t.LevelChanged || !turn.CurrentPlayer.Race.CanPay("UpgradeTown") || t.IsUnderSiege || t.IsInBattle) cmsTown_UpgradeTown.Enabled = false;
                        if (t.Cover == Town.CoverLevels.Last() || !turn.CurrentPlayer.CanUpgradeCover(t) || t.IsUnderSiege || t.IsInBattle) cmsTown_UpgradeObstacles.Enabled = false;
                        if (t.Walls == Town.WallLevels.Last() || !turn.CurrentPlayer.CanUpgradeWalls(t) || t.IsUnderSiege || t.IsInBattle) cmsTown_UpgradeWalls.Enabled = false;
                        if (t.Towers == Town.TowerLevels.Last() || !turn.CurrentPlayer.CanUpgradeTowers(t) || t.IsUnderSiege || t.IsInBattle) cmsTown_UpgradeTowers.Enabled = false;

                        cmsTown.Show(hexgridPanel1, e.X, e.Y);
                    }
                    else if (turn.CurrentPlayer.Castles.Contains(c))
                    {
                        cmsCastle_MusterArmy.Enabled = true;
                        cmsCastle_UpgradeCastle.Enabled = true;
                        cmsCastle_UpgradeWalls.Enabled = true;
                        cmsCastle_UpgradeTowers.Enabled = true;
                        cmsCastle_UpgradeGatehouse.Enabled = true;

                        if (c.Level <= 2 || a != null || c.IsUnderSiege || c.IsInBattle) cmsCastle_MusterArmy.Enabled = false;
                        if (c.Level == 20 || c.LevelChanged || !turn.CurrentPlayer.Race.CanPay("UpgradeCastle") || c.IsUnderSiege || c.IsInBattle) cmsCastle_UpgradeCastle.Enabled = false;
                        if (c.Walls == Castle.WallLevels.Last() || !turn.CurrentPlayer.CanUpgradeWalls(c) || c.IsUnderSiege || c.IsInBattle) cmsCastle_UpgradeWalls.Enabled = false;
                        if (c.Towers == Castle.TowerLevels.Last() || !turn.CurrentPlayer.CanUpgradeTowers(c) || c.IsUnderSiege || c.IsInBattle) cmsCastle_UpgradeTowers.Enabled = false;
                        if (c.Gatehouse == Castle.GatehouseLevels.Last() || !turn.CurrentPlayer.CanUpgradeGatehouse(c) || c.IsUnderSiege || c.IsInBattle) cmsCastle_UpgradeGatehouse.Enabled = false;

                        cmsCastle.Show(hexgridPanel1, e.X, e.Y);
                    }
                }
            }

            UpdateResources();
            LoadMap();
            UpdateSummary();
            UpdateTooltips();
            Refresh();
        }
Example #21
0
    // This method has two main purposes: (1) it marks points inside the
    // portion that are within the radius as in the field of view, and 
    // (2) it computes which portions of the following column are in the 
    // field of view, and puts them on a work queue for later processing. 
    //
    // A more sophisticated algorithm would say that a cell is visible if there is 
    // *any* straight line segment that passes through *any* portion of the origin cell
    // and any portion of the target cell, passing through only transparent cells
    // along the way. This is the "Permissive Field Of View" algorithm, and it
    // is much harder to implement.
    //
    // Search for transitions from opaque to transparent or
    // transparent to opaque and use those to determine what
    // portions of the *next* column are visible from the origin.
    private static FovCone ComputeFoVForRange(
      int                     observerHeight,
      FovCone                 cone,
      Func<ICoordsCanon,bool> isOnBoard,
      Func<ICoordsCanon, int> targetHeight,
      Func<ICoordsCanon, int> terrainHeight,
      Action<ICoordsCanon>    setFieldOfView,
      FovQueue             queue)
    {
      Action<FovCone> enqueue = queue.Enqueue;

      var range         = cone.Range;
      var topVector     = cone.VectorTop;
      var topRiseRun    = cone.RiseRun;
      var bottomVector  = cone.VectorBottom;

      // track the overlap-cone between adjacent hexes as we move down.
      var overlapVector = cone.VectorTop;
      var hexX          = XFromVector(range, topVector, true);
      #if TraceFOV
        TraceFlag.FieldOfView.Trace(false, "DQ:   ({0}) from {1}", cone, hexX);
      #endif

      do {
        while (overlapVector.GT(bottomVector)) {
          var coordsCurrent   = HexCoords.NewCanonCoords(hexX,range);
          var hexVectorBottom = VectorHexBottom(coordsCurrent);
          if (isOnBoard(coordsCurrent)) { 
            #region Set current hex parameters
            var hexVectorTop  = VectorHexTop(coordsCurrent);
            var hexElevation  = targetHeight(coordsCurrent);
            var hexHeight     = terrainHeight(coordsCurrent);
            var hexRiseRun    = new RiseRun(hexHeight-observerHeight, range);
            #endregion

            #region Check visibility of current hex
            var riseRun = new RiseRun(hexElevation-observerHeight, GetRange(coordsCurrent));
            if ( riseRun >= cone.RiseRun  
            && bottomVector.LE(coordsCurrent.Vector) && coordsCurrent.Vector.LE(topVector)  
            ) {
              setFieldOfView(coordsCurrent);
              #if TraceFOV
                TraceFlag.FieldOfView.Trace(false,"    Set visible: {0} / {1}; {2} >= {3}", 
                    MapCoordsDodecant(coordsCurrent), coordsCurrent.ToString(), riseRun, cone.RiseRun);
              #endif
            }
            #endregion

            #region Check hex transition
            if (hexRiseRun > topRiseRun) {
              topVector  = LogAndEnqueue(enqueue, range, topVector, hexVectorTop, topRiseRun, 0);
              topRiseRun = hexRiseRun;
            } else if (hexRiseRun > cone.RiseRun) {
              topVector  = LogAndEnqueue(enqueue, range, topVector, overlapVector, topRiseRun, 1);
              topRiseRun = hexRiseRun;
            } else if (hexRiseRun < cone.RiseRun) {
              topVector  = LogAndEnqueue(enqueue, range, topVector, overlapVector, topRiseRun, 2);
              topRiseRun = cone.RiseRun;
            }
            #endregion
          }

          overlapVector = VectorMax(hexVectorBottom, bottomVector); 
          if (hexVectorBottom.GT(bottomVector))      -- hexX;
        }

        #region Dequeue next cone
        if (queue.Count == 0) {
          topVector   = LogAndEnqueue(enqueue, range, topVector, bottomVector, topRiseRun, 3);
          cone        = queue.Dequeue();
          break;
        } else {
          cone        = queue.Dequeue();
          if(cone.Range != range) {
            topVector = LogAndEnqueue(enqueue, range, topVector, bottomVector, topRiseRun, 4);
            break;
          }
          #if TraceFOV
            TraceFlag.FieldOfView.Trace(false, "DQ:   ({0}) from {1}", cone, hexX);
          #endif
        }
        #endregion

        #region Check cone transition
        if (cone.RiseRun > topRiseRun) {
          topVector   = LogAndEnqueue(enqueue, range, topVector, cone.VectorTop, topRiseRun, 5);
          topRiseRun  = cone.RiseRun;
        } else if (cone.RiseRun < topRiseRun) {
          topVector   = LogAndEnqueue(enqueue, range, topVector, overlapVector, topRiseRun, 6);
          topRiseRun  = cone.RiseRun;  // TODO Why is this commented out?
        }
        #endregion

        overlapVector = topVector;
        bottomVector  = cone.VectorBottom;
      } while(true);

      // Pick-up any cone portion at bottom of range still unprocessed
      if (topVector.GT(bottomVector))
        LogAndEnqueue(enqueue, range, topVector, bottomVector, cone.RiseRun, 7);

      return cone;
    }
 /// <summary>TODO</summary>
 public HexEventArgs(HexCoords coords, MouseEventArgs e)
     : this(coords, e, Keys.None)
 {
 }
 /// <summary>Returns pixel coordinates of centre of specified hex.</summary>
 /// <param name="this">The current {HexBoard}.</param>
 /// <param name="coords">The {HexCoords} of the hex of current interest.</param>
 /// <returns>A Point structure containing pixel coordinates for the (centre of the) specified hex.</returns>
 public static HexPoint CentreOfHex <THex>(this HexBoard <THex> @this, HexCoords coords)
     where THex : IHex
 => @this.UpperLeftOfHex(coords) + @this.HexCentreOffset;
 public HexEventArgs(HexCoords coords, MouseEventArgs e, Keys modifierKeys)
     : base(e.Button, e.Clicks, e.X, e.Y, e.Delta)
 {
     Coords = coords;
     ModifierKeys = modifierKeys;
 }
 /// <summary>Elevation of the terrain Above Sea Level</summary>
 /// <param name="this">The {IFovBoard} to be analyzed.</param>
 /// <param name="coords">The coordinates of the hex being tested.</param>
 public static int ElevationTerrainASL(this IFovBoard @this, HexCoords coords)
 => @this[coords].Match(hex => @this.ElevationASL(hex) + hex.HeightTerrain, MaxValue32);
Example #26
0
        public void Move(HexCoords toCoords, TerrainMap tm)
        {
            Landmark lm = new Landmark(Coords, tm);
            double distance = lm.HexDistance(toCoords);
            Coords = toCoords;
            _moveLeft -= distance;

            Save();
        }
 /// <summary>TODO</summary>
 public EmptyGridHex(HexCoords coords) : base(coords, 0) => TerrainType = default;
 /// <summary>TODO</summary>
 protected MapGridHex(HexBoard<MapGridHex> board, HexCoords coords)
     : base(board, coords)
 {
     ((IMapGridHex)this).Board = board;
 }
 /// <summary>Returns the shortest-path directed-distance to the specified hex <b>from</b> the landmark.</summary>
 public int DistanceTo(HexCoords coords)
 {
     return(backingStore[0][coords]);
 }
 DirectedPath GetPartnerPath(HexCoords coords)
 {
     DirectedPath path;
     _open.TryGetValue(coords, out path);
     return path;
 }
 public HillTerrainGridHex(IBoard <MapGridHex> map, HexCoords coords, Size gridSize) : base(map, coords, gridSize)
 {
 }
 int Heuristic(HexCoords coords)
 {
     return _heuristic(coords);
 }
        private void hexgridPanel1_LeftClick(object sender, HexEventArgs e)
        {
            Army a = tm.GetArmy(e.Coords);
            MapObject b = tm.GetBuilding(e.Coords);
            clickCoords = e.Coords;

            //New object logic
            if (newObject != null)
            {
                if (tm.BoardHexes[clickCoords].StepCost(Hexside.North) == -1)
                {
                    MessageBox.Show("Can't place on immovable terrain");
                }

                else if (newObject.Coords != clickCoords)
                {
                    MessageBox.Show("Other building/enemy unit already on this spot");
                }
                else
                {
                    newObject.Coords = clickCoords;
                    Refresh();
                    newObject.Save();

                    newObjects.Remove(newObject);

                    if (newObjects.Count > 0)
                    {
                        newObject = newObjects.First();
                    }
                    else
                    {
                        newObject = null;
                    }
                }
                clickCoords = HexCoords.NewUserCoords(-1, -1);
            }

            else if (isPlayerTurn)
            {
                if (a != null)
                {
                    if (tm.SelectedArmy == a)
                    {
                        tm.SelectedArmy = null;
                    }
                    else if (turn.CurrentPlayer.Armies.Contains(a))
                    {
                        tm.SelectedArmy = a;
                    }
                }
                else
                {
                    tm.SelectedArmy = null;
                }
            }
            UpdateSummary();
            Refresh();
        }
 /// <summary>IntVector2D for bottom corner of cell Canon(x,y).</summary>
 /// <remarks>
 /// In first dodecant; The bottom corner for hex (x,y) is determined 
 /// (from close visual inspection) as:
 ///       (x,y) + 1/3 * (-2,-1)
 /// which reduces to:
 ///       (x - 2/3, y - 1/3) == 1/3 * (3x - 2, 3y - 1)
 /// </remarks>
 static IntVector2D VectorHexBottom(HexCoords hex)
 {
     return hex.Canon * matrixHexBottom;
 }
Example #35
0
 /// <inheritdoc/>
 public abstract short?Heuristic(HexCoords source, HexCoords target);
 /// <summary>IntVector2D for top corner of cell Canon(x,y).</summary>
 /// <remarks>
 /// In first dodecant; The top corner for hex (x,y) is determined 
 /// (from close visual inspection) as:
 ///       (x,y) + 1/3 * (2,1)
 /// which reduces to:
 ///       (x + 2/3, y + 1/3) == 1/3 * (3x + 2, 3y + 1)
 /// </remarks>
 static IntVector2D VectorHexTop(HexCoords hex)
 {
     return hex.Canon * matrixHexTop;
 }
Example #37
0
 /// <summary>TODO</summary>
 public short?TryEntryCost(HexCoords hexCoords, Hexside hexside)
 => (from x in EntryCosts[hexCoords] from c in x[hexside].ToMaybe() select c).ToNullable();
 private static int GetRange(HexCoords coords)
 {
     return HexCoords.EmptyCanon.Range(coords);
 }
 /// <summary>Returns pixel coordinates of upper-left corner of specified hex.</summary>
 /// <param name="this">The current {HexBoard}.</param>
 /// <param name="coords">The {HexCoords} of the hex of current interest.</param>
 /// <returns>A Point structure containing pixel coordinates for the (upper-left corner of the) specified hex.</returns>
 public static HexPoint UpperLeftOfHex <THex>(this HexBoard <THex> @this, HexCoords coords)
     where THex : IHex
 => new HexPoint(
     coords.User.X * @this.GridSize.Width,
     coords.User.Y * @this.GridSize.Height + (coords.User.X + 1) % 2 * @this.GridSize.Height / 2
     );
        private void btnReset_Click(object sender, EventArgs e)
        {
            tm.Objects = new List<MapObject>();
            newObject = null;
            newObjects = new List<MapObject>();

            playerDoc.XPathSelectElements("Players/Player").Remove();
            playerDoc.Save(Player.SavePath);

            tileDoc.XPathSelectElements("Tiles/Tile").Remove();
            tileDoc.Save(TerrainGridHex.SavePath);

            players = new List<Player>();

            String password = Player.EncryptPassword("a");

            players.Add(new Player("Red Player", 1, "Ogres", password, true, 0, 0));
            players.Add(new Player("Blue Player", 2, "High Elves", password, true, 0, 0));

            List<Resource> res1 = new List<Resource>() { new Resource("Food", 60), new Resource("Magic", 1) };
            List<Resource> res2 = new List<Resource>() { new Resource("Gold", 50), new Resource("Magic", 1) };

            Army a1, a2, a3, a4;

            a1 = new Army(25, 5, "Army 1", "Builder", 4, Pens.Red, 0, "Red Player", true, @"Races\Ogres\builder.png", null);
            tm.AddObject(a1);

            a2 = new Army(8, 8, "Army 2", "Flying", 10, Pens.Blue, 2000, "Blue Player", false, @"Races\HighElves\flying.png", res2);
            tm.AddObject(a2);

            a3 = new Army(14, 3, "Army 3", "Monstrous", 6, Pens.Red, 1500, "Red Player", false, @"Races\Ogres\monstrous.png", res1);
            tm.AddObject(a3);

            a4 = new Army(3, 14, "Army 4", "Builder", 5, Pens.Blue, 0, "Blue Player", true, @"Races\HighElves\builder.png", null);
            tm.AddObject(a4);

            players.ElementAt(0).AddArmy(a1);
            players.ElementAt(1).AddArmy(a2);
            players.ElementAt(0).AddArmy(a3);
            players.ElementAt(1).AddArmy(a4);

            Town t1 = new Town("Town 1", 3, 12, @"Terrain\Possible Buildings or Encampments\human-tile.png", "Red Player");
            t1.Upgrade(10);
            t1.LevelChanged = false;

            tm.AddObject(t1);
            players.ElementAt(0).AddTown(t1);

            Town t2 = new Town("Town 2", 8, 12, @"Terrain\Possible Buildings or Encampments\human-tile.png", "Blue Player");
            t2.Upgrade(5);
            t2.LevelChanged = false;

            tm.AddObject(t2);
            players.ElementAt(1).AddTown(t2);

            Watchtower wt1 = new Watchtower("Tower 1", 5, 7, "Blue Player", @"Terrain\Possible Buildings or Encampments\elven-tile.png");
            tm.AddObject(wt1);
            players.ElementAt(1).AddWatchtower(wt1);

            Castle c1 = new Castle("Castle 1", 20, 13, @"Terrain\Possible Buildings or Encampments\keep-tile.png", "Blue Player");
            c1.Upgrade(6);
            tm.AddObject(c1);
            players.ElementAt(1).AddCastle(c1);

            hexgridPanel1.MapBuffer = null;
            ((TerrainGridHex)tm.BoardHexes[HexCoords.NewUserCoords(5, 7)]).SpecialType = "Road";
            ((TerrainGridHex)tm.BoardHexes[HexCoords.NewUserCoords(6, 6)]).SpecialType = "Road";
            ((TerrainGridHex)tm.BoardHexes[HexCoords.NewUserCoords(7, 6)]).SpecialType = "Road";
            ((TerrainGridHex)tm.BoardHexes[HexCoords.NewUserCoords(8, 5)]).SpecialType = "Road";
            ((TerrainGridHex)tm.BoardHexes[HexCoords.NewUserCoords(9, 5)]).SpecialType = "Road";
            ((TerrainGridHex)tm.BoardHexes[HexCoords.NewUserCoords(10, 4)]).SpecialType = "Road";
            ((TerrainGridHex)tm.BoardHexes[HexCoords.NewUserCoords(11, 4)]).SpecialType = "Road";
            ((TerrainGridHex)tm.BoardHexes[HexCoords.NewUserCoords(12, 3)]).SpecialType = "Road";
            ((TerrainGridHex)tm.BoardHexes[HexCoords.NewUserCoords(13, 3)]).SpecialType = "Road";
            ((TerrainGridHex)tm.BoardHexes[HexCoords.NewUserCoords(14, 3)]).SpecialType = "Road";

            turn = new Turn(players);

            tm.SelectedArmy = null;
            clickCoords = HexCoords.NewUserCoords(-1, -1);

            Refresh();

            playerDoc = XDocument.Load(Player.SavePath);
            playerDoc.Save(Player.UndoPath);

            UpdateResources();
            UpdateSummary();
            UpdateLos();
        }
 /// <summary>Elevation of the ground Above Sea Level</summary>
 /// <param name="this">The {IFovBoard} to be analyzed.</param>
 /// <param name="coords">The coordinates of the hex being tested.</param>
 public static int ElevationGroundASL(this IFovBoard @this, HexCoords coords)
 => @this[coords].Match(hex => @this.ElevationASL(hex), MaxValue32);
Example #42
0
File: Map.cs Project: cruseyd/Filis
 public abstract HexTile TileAt(HexCoords coords);
 /// <summary>Elevation of the observer Above Sea Level</summary>
 /// <param name="this">The {IFovBoard} to be analyzed.</param>
 /// <param name="coords">The coordinates of the hex being tested.</param>
 public static int ElevationObserverASL(this IFovBoard @this, HexCoords coords)
 => @this[coords].Match(hex => @this.ElevationASL(hex) + @this.HeightOfMan, MaxValue32);
Example #44
0
 public override HexTile TileAt(HexCoords coords)
 {
     return(graph.NodeAt(coords)?.tile);
 }
 /// <summary>Returns whether the hex at location <paramref name="coords"/> is passable.</summary>
 /// <param name="this">The {IFovBoard} to be analyzed.</param>
 /// <param name="coords">The coordinates of the hex being tested.</param>
 public static bool IsOverseeable(this IFovBoard @this, HexCoords coords)
 => @this.MapSizeHexes.IsOnboard(coords);
Example #46
0
 public int GetHeight(HexCoords coords)
 {
     return((int)Mathf.Floor(TileAt(coords).node.elevation *numHeightLevels));
 }
Example #47
0
 public override void InitCell(HexCoords loc, MapCell newCell)
 {
     base.InitCell(loc, newCell);
 }
Example #48
0
 /// <summary>Returns ScrollPosition that places given hex in the upper-Left of viewport.</summary>
 /// <param name="coordsNewULHex"><c>HexCoords</c> for new upper-left hex</param>
 /// <returns>Pixel coordinates in Client reference frame.</returns>
 public Point HexCenterPoint(HexCoords coordsNewULHex)
 {
     return(Hexgrid.HexCenterPoint(coordsNewULHex));
 }
Example #49
0
 /// <summary>TODO</summary>
 public CoordsRectangle(HexCoords location, HexCoords size)  : this(new Rectangle(location.User, size.User))
 {
 }
Example #50
0
 /// <summary>Returns the scroll position to center a specified hex in viewport.</summary>
 /// <param name="coordsNewCenterHex"><c>HexCoords</c> for the hex to be centered in viewport.</param>
 /// <returns>Pixel coordinates in Client reference frame.</returns>
 protected Point ScrollPositionToCenterOnHex(HexCoords coordsNewCenterHex)
 {
     return(Hexgrid.ScrollPositionToCenterOnHex(coordsNewCenterHex, VisibleRectangle));
 }
 /// <summary>Populates and returns a new landmark at the specified board coordinates.</summary>
 /// <param name="board">IBoard{IHex} on which the landmark is to be created.</param>
 /// <param name="coords">Coordinates on <c>board</c> where this landmark is to be created.</param>
 public Landmark(HexCoords coords, IHexBoard <IHex> board)
 {
     Board  = board;
     Coords = coords;
     FillLandmark();
 }
 /// <inheritdoc/>
 public virtual Point ScrollPositionToCenterOnHex(HexCoords coordsNewCenterHex)
 {
     return HexCenterPoint(HexCoords.NewUserCoords(
             coordsNewCenterHex.User - (new IntVector2D(Host.VisibleRectangle.Size.User) / 2)
     ));
 }
 /// <summary>Returns the shortest-path directed-distance from the specified hex <b>to</b> the landmark.</summary>
 public int DistanceFrom(HexCoords coords)
 {
     return(backingStore[1][coords]);
 }
 ///<inheritdoc/>
 public override Point HexCenterPoint(HexCoords coordsNewULHex)
 {
     return TransposePoint(base.HexCenterPoint(coordsNewULHex));
 }
Example #55
0
 private string LandmarkText(HexCoords coords)
 => DataContext.Model.Landmarks.DistanceFrom(coords, DataContext.Model.LandmarkToShow - 1);
Example #56
0
 public Maybe <THex> this[HexCoords coords] => BoardHexes[coords];
 /// <summary>Returns ScrollPosition that places given hex in the upper-Left of viewport.</summary>
 /// <param name="coordsNewULHex"><c>HexCoords</c> for new upper-left hex</param>
 /// <returns>Pixel coordinates in Client reference frame.</returns>
 public Point HexCenterPoint(HexCoords coordsNewULHex)
 {
     return Hexgrid.HexCenterPoint(coordsNewULHex);
 }
Example #58
0
 Maybe <IHex> IFovBoard.this[HexCoords coords] => this[coords].Bind(v => new Maybe <IHex>(v));
 /// <inheritdoc/>
 public override bool  IsPassable(HexCoords coords)
 {
     return(base.IsPassable(coords) && this[coords].ElevationLevel == 0);
 }
        private void btnUndo_Click(object sender, EventArgs e)
        {
            playerDoc = XDocument.Load(Player.UndoPath);
            playerDoc.Save(Player.SavePath);

            LoadMap();

            clickCoords = HexCoords.NewUserCoords(-1, -1);
            tm.SelectedArmy = null;
            btnUndo.Enabled = false;

            UpdateSummary();
            Refresh();
        }