//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 }
/// <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); }
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) ); }
/// <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);
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(); }
// 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);
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; }
/// <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; }
/// <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);
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);
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);
public int GetHeight(HexCoords coords) { return((int)Mathf.Floor(TileAt(coords).node.elevation *numHeightLevels)); }
public override void InitCell(HexCoords loc, MapCell newCell) { base.InitCell(loc, newCell); }
/// <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)); }
/// <summary>TODO</summary> public CoordsRectangle(HexCoords location, HexCoords size) : this(new Rectangle(location.User, size.User)) { }
/// <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)); }
private string LandmarkText(HexCoords coords) => DataContext.Model.Landmarks.DistanceFrom(coords, DataContext.Model.LandmarkToShow - 1);
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); }
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(); }