예제 #1
0
        string DescribeStrength(ArmyConfiguration Configuration)
        {
            var unitList = Configuration.BuildUnitConfigurationList().ToList();

            return(string.Format(
                       "{0} - {1} Points / {2} Units",
                       ObjectDescriber.Describe(Configuration.Faction),
                       unitList.Sum(i => i.GetPointValue(Configuration.Faction.HalfPriceTrucks)),
                       unitList.Count));
        }
예제 #2
0
 public static string Describe(LineOfFireObjective Objective)
 {
     return(string.Format(
                "{0} {1} {2} {3} hexes wide from {4} to {5}",
                Objective.BreakThrough ? "create a corridor clear of" : "establish an unbroken line of",
                Objective.Friendly ? "friendly" : "enemy",
                Objective.IncludeFieldOfSight ? "fire" : "units",
                Objective.Width,
                ObjectDescriber.Describe(Objective.Vertical ? Direction.NORTH : Direction.EAST),
                ObjectDescriber.Describe(Objective.Vertical ? Direction.SOUTH : Direction.WEST)));
 }
예제 #3
0
 public VictoryConditionRow(ObjectiveSuccessTrigger Trigger)
     : base("scenario-victory-condition-row")
 {
     Add(new Button("scenario-victory-condition-header")
     {
         DisplayedString = ObjectDescriber.Describe(Trigger.SuccessLevel)
     });
     Add(new Button("scenario-victory-condition")
     {
         DisplayedString = ObjectDescriber.Describe(Trigger)
     });
 }
예제 #4
0
 void AddSequence <T>(string SequenceName, Sequence Sequence, T[] Source)
 {
     if (Sequence is StaticSequence)
     {
         AddDetail(
             SequenceName, Sequence.Get(null, 1).Select(i => ObjectDescriber.Describe(Source[i])).ToArray());
     }
     else if (Sequence is RandomSequence)
     {
         AddDetail(SequenceName, "Random");
     }
 }
예제 #5
0
        public ScenarioBuilderArmySection(ArmyBuilder ArmyBuilder, IEnumerable <Faction> Factions)
            : base("scenario-builder-army-section")
        {
            this.ArmyBuilder = ArmyBuilder;

            foreach (Faction faction in Factions)
            {
                _FactionSelect.Add(
                    new SelectionOption <Faction>("scenario-builder-army-section-faction-select-option")
                {
                    DisplayedString = ObjectDescriber.Describe(faction),
                    Value           = faction
                });
            }
            _FactionSelect.SetValue(i => i.Value == ArmyBuilder.Parameters.Faction);

            _PointsInput.Value = ArmyBuilder.Parameters.Points.ToString();

            for (byte i = 1; i <= 3; ++i)
            {
                _TeamSelect.Add(
                    new SelectionOption <byte>("scenario-builder-army-section-team-select-option")
                {
                    DisplayedString = i.ToString(),
                    Value           = i
                });
            }
            _TeamSelect.SetValue(i => i.Value == ArmyBuilder.Parameters.Team);

            var removeButton = new Button("scenario-builder-army-section-remove-button")
            {
                DisplayedString = "X"
            };

            _FactionSelect.OnChange += HandleChange;
            _PointsInput.OnLeave    += HandleChange;
            _TeamSelect.OnChange    += HandleChange;
            removeButton.OnClick    += HandleRemove;

            Add(new GuiContainer <GuiItem>("scenario-builder-army-section-faction-cell")
            {
                _FactionSelect
            });
            Add(new GuiContainer <GuiItem>("scenario-builder-army-section-points-cell")
            {
                _PointsInput
            });
            Add(new GuiContainer <GuiItem>("scenario-builder-army-section-team-cell")
            {
                _TeamSelect
            });
            Add(removeButton);
        }
예제 #6
0
        void DescribeOddsCalculation(OddsCalculation OddsCalculation)
        {
            _Description.Add(new Button("attack-odds-box")
            {
                DisplayedString = OddsString(OddsCalculation)
            });

            var p = Attack.CombatResultsTable.GetCombatResultProbabilities(OddsCalculation);

            for (int i = 0; i < p.Length; ++i)
            {
                if (p[i] > 0)
                {
                    _Description.Add(new Button("attack-factor-box")
                    {
                        DisplayedString = string.Format(
                            "{0} - {1}%", ObjectDescriber.Describe((CombatResult)i), Math.Round(p[i] * 100))
                    });
                }
            }

            _Description.Add(new Button("attack-odds-section")
            {
                DisplayedString = string.Format("{0} Total Attack Factor", OddsCalculation.TotalAttack)
            });
            foreach (var a in OddsCalculation.AttackFactorCalculations)
            {
                DescribeAttackFactorCalculation(a.Item1, a.Item2);
            }
            _Description.Add(new Button("attack-odds-section")
            {
                DisplayedString = string.Format("{0} Total Defense Factor", OddsCalculation.TotalDefense)
            });
            foreach (Unit d in OddsCalculation.Defenders)
            {
                _Description.Add(new Button("attack-part-box")
                {
                    DisplayedString = string.Format("+{0} {1}", d.Configuration.Defense, d.Configuration.Name)
                });
            }
            _Description.Add(new Button("odds-factor-box")
            {
                DisplayedString = OddsCalculation.StackArmored ? "Armored Target" : "Unarmored Target"
            });
            foreach (OddsCalculationFactor o in OddsCalculation.OddsCalculationFactors)
            {
                _Description.Add(new Button("odds-factor-box")
                {
                    DisplayedString = ObjectDescriber.Describe(o)
                });
            }
        }
예제 #7
0
 public void SetTurn(Turn Turn)
 {
     _InfoDisplay.Clear();
     _InfoDisplay.Add(
         new Button("info-display-header")
     {
         DisplayedString = ObjectDescriber.Describe(Turn.TurnInfo.Army)
     });
     _InfoDisplay.Add(
         new Button("info-display-info")
     {
         DisplayedString = ObjectDescriber.Describe(Turn.TurnInfo.TurnComponent)
     });
 }
예제 #8
0
 protected void AddMountedInfantryAttributes()
 {
     if (_UnitConfiguration.DismountAs != null || _UnitConfiguration.CanRemount)
     {
         AddSection("Mounted Infantry");
     }
     if (_UnitConfiguration.DismountAs != null)
     {
         AddAttribute(ObjectDescriber.Describe(_UnitConfiguration.DismountAs));
     }
     if (_UnitConfiguration.CanRemount)
     {
         AddAttribute("Can Re-mount");
     }
 }
예제 #9
0
        public UnitInfoPane(Unit Unit, UnitConfigurationRenderer Renderer)
            : base(Unit.Configuration, Unit.Army.Configuration.Faction, Renderer)
        {
            _Info.Add(new Button("unit-info-header")
            {
                DisplayedString = ObjectDescriber.Describe(Unit)
            });

            AddBasicAttributes();
            AddComposition();
            AddCombatCapabilities();
            AddSightCapabilities();
            AddTransportCapabilities();
            AddMovementAttributes();
            AddMountedInfantryAttributes();
        }
예제 #10
0
 string PackName(Faction Faction, UnitClass UnitClass)
 {
     if (Faction == null && UnitClass == UnitClass.NONE)
     {
         return("Random Pack");
     }
     if (Faction == null)
     {
         return(string.Format("{0} Pack", ObjectDescriber.Describe(UnitClass)));
     }
     if (UnitClass == UnitClass.NONE)
     {
         return(string.Format("{0} Pack", Faction.Name));
     }
     return(string.Format("{0} {1} Pack", Faction.Name, ObjectDescriber.Describe(UnitClass)));
 }
예제 #11
0
 public MatchEndArmyRow(Army Army, FactionRenderer FactionRenderer)
     : base("match-end-army-row")
 {
     _FactionView = new FactionView(Army.Configuration.Faction, FactionRenderer, 128)
     {
         Position = LeftPadding
     };
     Add(new Button("match-end-army-header")
     {
         DisplayedString = ObjectDescriber.Describe(Army.Configuration.Faction)
     });
     Add(new Button("match-end-army-success")
     {
         DisplayedString = ObjectDescriber.Describe(Army.GetObjectiveSuccessLevel())
     });
 }
예제 #12
0
        public NewMapPane()
            : base("new-map-pane")
        {
            _CreateButton.Position = Size - new Vector2f(_CreateButton.Size.X + 32, _CreateButton.Size.Y + 32);
            _CancelButton.Position = _CreateButton.Position - new Vector2f(_CancelButton.Size.X + 4, 0);

            _CancelButton.OnClick += HandleCancelClicked;
            _CreateButton.OnClick += HandleCreateClicked;

            foreach (var matchSetting in GameData.MatchSettings.Values)
            {
                _MatchSettingsSelect.Add(
                    new SelectionOption <MatchSetting>("new-map-parameters-section-select-option")
                {
                    Value           = matchSetting,
                    DisplayedString = ObjectDescriber.Describe(matchSetting)
                });
            }

            _Display.Add(new Button("new-map-header-1")
            {
                DisplayedString = "New Map"
            });
            _Display.Add(new Button("new-map-header-2")
            {
                DisplayedString = "Height"
            });
            _Display.Add(_HeightInput);
            _Display.Add(new Button("new-map-header-2")
            {
                DisplayedString = "Width"
            });
            _Display.Add(_WidthInput);
            _Display.Add(new Button("new-map-header-2")
            {
                DisplayedString = "Random Map Generation"
            });
            _Display.Add(_GenerateRandomCheckbox);
            _Display.Add(new GuiContainer <Pod>("new-map-parameters-section")
            {
                _MatchSettingsSelect
            });

            Add(_CancelButton);
            Add(_CreateButton);
            Add(_Display);
        }
예제 #13
0
 protected void AddComposition()
 {
     AddSection("Composition");
     AddAttribute(string.Format("Weight - {0}", _UnitConfiguration.UnitWeight));
     if (_UnitConfiguration.IsVehicle)
     {
         AddAttribute("Vehicular");
     }
     if (_UnitConfiguration.IsArmored)
     {
         AddAttribute("Armored");
     }
     if (_UnitConfiguration.WrecksAs != null)
     {
         AddAttribute(string.Format("Wrecks As - {0}", ObjectDescriber.Describe(_UnitConfiguration.WrecksAs)));
     }
 }
예제 #14
0
 protected void AddBasicAttributes()
 {
     AddSection("Basic Attributes");
     AddAttribute(string.Format(
                      "Unit Class - {0}", ObjectDescriber.Describe(_UnitConfiguration.UnitClass)));
     AddAttribute(
         string.Format(
             "Weapon Class - {0}", ObjectDescriber.Describe(_UnitConfiguration.PrimaryWeapon.WeaponClass)));
     AddAttribute(string.Format("Attack - {0}", _UnitConfiguration.PrimaryWeapon.Attack));
     AddAttribute(string.Format("Range - {0}", _UnitConfiguration.PrimaryWeapon.Range));
     AddAttribute(string.Format("Defense - {0}", _UnitConfiguration.Defense));
     AddAttribute(
         string.Format(
             "Movement - {0}",
             _UnitConfiguration.HasUnlimitedMovement() ? "Unlimited" : _UnitConfiguration.Movement.ToString()));
     AddAttribute(
         string.Format("Point Value - {0}", _UnitConfiguration.GetPointValue(_Faction.HalfPriceTrucks)));
 }
예제 #15
0
 void DescribeAttackFactorCalculation(
     SingleAttackOrder Attacker, AttackFactorCalculation AttackFactorCalculation)
 {
     _Description.Add(new Button("attack-part-box")
     {
         DisplayedString = string.Format(
             "+{0} {1}", AttackFactorCalculation.Attack, ObjectDescriber.Describe(Attacker.Attacker))
     });
     _Description.Add(new Button("attack-factor-box")
     {
         DisplayedString = string.Format(
             "{0} Base Attack Factor",
             Attacker.Attacker.Configuration.GetWeapon(Attacker.UseSecondaryWeapon).Attack)
     });
     foreach (AttackFactorCalculationFactor a in AttackFactorCalculation.Factors)
     {
         _Description.Add(new Button("attack-factor-box")
         {
             DisplayedString = ObjectDescriber.Describe(a)
         });
     }
 }
예제 #16
0
        public SelectPane(string Title, IEnumerable <T> Items)
            : base("select-pane")
        {
            var header = new Button("select-pane-header")
            {
                DisplayedString = Title
            };

            Add(header);

            _UnitSelect.Position = new Vector2f(0, header.Size.Y + 6);
            foreach (T item in Items)
            {
                var option = new SelectionOption <T>("select-option")
                {
                    Value           = item,
                    DisplayedString = ObjectDescriber.Describe(item)
                };
                _UnitSelect.Add(option);
            }
            _UnitSelect.OnChange += HandleChange;
            Add(_UnitSelect);
        }
예제 #17
0
 public void SetVictoryCondition(VictoryCondition Condition, Army ForArmy, Match Match)
 {
     _Display.Clear();
     foreach (var objective in Condition.Scorers)
     {
         _Display.Add(
             new Button("objective-header")
         {
             DisplayedString =
                 string.Format(
                     "{0}/{1}",
                     objective.CalculateScore(ForArmy, Match, new Dictionary <Objective, int>()),
                     Condition.GetMaximumScore(objective, ForArmy, Match))
         });
         _Display.Add(
             new Button("objective-regular")
         {
             DisplayedString =
                 ObjectDescriber.Sentencify(
                     ObjectiveDescriber.RemoveScore(ObjectiveDescriber.Describe(objective)))
         });
     }
 }
예제 #18
0
 public static string Describe(TileHasBase Matcher)
 {
     return(string.Format("in {0}", ObjectDescriber.Describe(Matcher.TileBase)));
 }
예제 #19
0
 public static string Describe(TileHasCoordinate Matcher)
 {
     return(string.Format("at {0}", ObjectDescriber.Describe(Matcher.Coordinate)));
 }
예제 #20
0
 public static string Describe(UnitHasStatus Matcher)
 {
     return(ObjectDescriber.Describe(Matcher.Status));
 }
예제 #21
0
 public static string Describe(UnitHasReconned Matcher)
 {
     return(string.Format("reconned {0}", ObjectDescriber.Describe(Matcher.Direction)));
 }
예제 #22
0
 public static string Describe(UnitHasConfiguration Matcher)
 {
     return(string.Format("of type {0}", ObjectDescriber.Describe(Matcher.UnitConfiguration)));
 }
예제 #23
0
 public static string Describe(UnitHasClass Matcher)
 {
     return(string.Format("of class {0}", ObjectDescriber.Describe(Matcher.UnitClass)));
 }
예제 #24
0
 public static string Describe(TileOnEdge Matcher)
 {
     return(string.Format("on {0} edge of the board", ObjectDescriber.Describe(Matcher.Edge)));
 }
예제 #25
0
 public static string Describe(TileInRegion Matcher)
 {
     return(string.Format("within {0}", ObjectDescriber.Describe(Matcher.NormalizedRegionName, '-')));
 }
예제 #26
0
 public static string Describe(TileHasEdge Matcher)
 {
     return(string.Format("next to {0}", ObjectDescriber.Describe(Matcher.Edge)));
 }
예제 #27
0
        public ArmyBuilderScreen(
            Vector2f WindowSize,
            IEnumerable <UnitConfigurationLink> UnitConfigurations,
            ArmyParameters Parameters,
            UnitConfigurationRenderer Renderer)
            : base(WindowSize)
        {
            _Parameters = Parameters;
            _Links      = UnitConfigurations;

            _Pane.Position = .5f * (WindowSize - _Pane.Size);

            var header = new Button("army-builder-header")
            {
                DisplayedString =
                    string.Format(
                        "{0} - {1} - {2}",
                        ObjectDescriber.Describe(Parameters.Faction),
                        ObjectDescriber.Describe(Parameters.Parameters.Setting.Front),
                        Parameters.Parameters.Year)
            };

            _UnitClassSelect.Position = new Vector2f(0, header.Size.Y);

            _AvailableUnits = new UnitConfigurationTable(
                "army-builder-table",
                "army-builder-table-row",
                "army-builder-table-cell",
                _Parameters.Faction,
                Renderer,
                false);
            _AvailableUnits.Position            = new Vector2f(0, _UnitClassSelect.Position.Y + _UnitClassSelect.Size.Y + 16);
            _AvailableUnits.OnUnitClicked      += HandleAddUnit;
            _AvailableUnits.OnUnitRightClicked += HandleUnitInfoRequested;

            _PointTotalButton          = new Button("army-builder-point-total");
            _PointTotalButton.Position = new Vector2f(_AvailableUnits.Size.X + 16, header.Size.Y);
            SetPointTotal(0);

            _SelectedUnits = new UnitConfigurationTable(
                "army-builder-table",
                "army-builder-table-row",
                "army-builder-table-cell",
                _Parameters.Faction,
                Renderer,
                true);
            _SelectedUnits.Position =
                new Vector2f(_AvailableUnits.Size.X + 16, _PointTotalButton.Position.Y + _PointTotalButton.Size.Y + 16);
            _SelectedUnits.OnUnitRightClicked += HandleRemoveUnit;

            foreach (UnitClass c in Enum.GetValues(typeof(UnitClass)))
            {
                _UnitClassSelect.Add(
                    new SelectionOption <UnitClass>("army-builder-select-option")
                {
                    DisplayedString = ObjectDescriber.Describe(c),
                    Value           = c
                });
            }

            _UnitClassSelect.OnChange += FilterUnits;
            FilterUnits();

            var finishedButton = new Button("army-builder-large-button")
            {
                DisplayedString = "Finished"
            };

            finishedButton.Position = _Pane.Size - finishedButton.Size - new Vector2f(32, 32);
            finishedButton.OnClick += HandleFinished;

            _Pane.Add(header);
            _Pane.Add(_AvailableUnits);
            _Pane.Add(_SelectedUnits);
            _Pane.Add(_PointTotalButton);
            _Pane.Add(_UnitClassSelect);
            _Pane.Add(finishedButton);
            _Items.Add(_Pane);
        }
예제 #28
0
 public static string Describe(TileWithin Matcher)
 {
     return(string.Format("within the bounds {0}", ObjectDescriber.Describe(Matcher.Zone)));
 }
예제 #29
0
        public Map GenerateMap(Random Random, Environment Environment, IdGenerator IdGenerator)
        {
            var map = new Map(Width, Height, Environment, IdGenerator);

            var cache = new Dictionary <FunctionFactory, Func <double, double, double> >();
            var elevationGenerator =
                Setting.MapGenerator.TerrainGenerator.ElevationGenerator.GetFeatureGenerator(Random, cache);
            var waterGenerator =
                Setting.MapGenerator.TerrainGenerator.WaterGenerator.GetFeatureGenerator(Random, cache);
            var swampGenerator =
                Setting.MapGenerator.TerrainGenerator.SwampGenerator.GetFeatureGenerator(Random, cache);
            var forestGenerator =
                Setting.MapGenerator.TerrainGenerator.ForestGenerator.GetFeatureGenerator(Random, cache);
            var townGenerator =
                Setting.MapGenerator.TerrainGenerator.TownGenerator.GetFeatureGenerator(Random, cache);

            foreach (Tile t in map.TilesEnumerable)
            {
                if (elevationGenerator(t.Center.X, t.Center.Y) && t.OnEdge(Direction.NONE))
                {
                    t.Configuration.SetElevation(1);
                }
                else if (waterGenerator(t.Center.X, t.Center.Y))
                {
                    for (int i = 0; i < 6; ++i)
                    {
                        t.SetEdge(i, TileEdge.WATER);
                    }
                }
                if (t.Configuration.Elevation == 0 && swampGenerator(t.Center.X, t.Center.Y))
                {
                    t.Configuration.SetTileBase(TileBase.SWAMP);
                }
            }
            foreach (Tile t in map.TilesEnumerable)
            {
                if (t.NeighborTiles.Any(i => i != null && i.Configuration.Elevation > t.Configuration.Elevation))
                {
                    t.Configuration.SetTileBase(TileBase.SLOPE);
                    for (int i = 0; i < 6; ++i)
                    {
                        t.SetEdge(i, TileEdge.NONE);
                    }
                }
            }
            foreach (Tile t in map.TilesEnumerable)
            {
                if (t.Configuration.TileBase == TileBase.SWAMP)
                {
                    continue;
                }

                var slopes = GetSlopeDirections(t).ToArray();
                for (int i = 0; i < 6; ++i)
                {
                    if (t.Configuration.GetEdge(i) == TileEdge.WATER)
                    {
                        continue;
                    }

                    Tile neighbor = t.NeighborTiles[i];
                    if (neighbor == null)
                    {
                        continue;
                    }

                    if (t.Configuration.TileBase == TileBase.SLOPE)
                    {
                        if (neighbor.Configuration.TileBase == TileBase.SLOPE)
                        {
                            var nSlopes = GetSlopeDirections(neighbor).ToArray();
                            if (!slopes.All(v => nSlopes.Any(w => DoublesEqual(v, w))))
                            {
                                t.SetEdge(i, TileEdge.SLOPE);
                            }
                        }
                        continue;
                    }

                    if (neighbor.Configuration.TileBase != TileBase.SLOPE &&
                        neighbor.Configuration.TileBase != TileBase.SWAMP)
                    {
                        Vector2f v = .5f * (t.Bounds[i].Point + t.Bounds[i].End);
                        if (forestGenerator(v.X, v.Y))
                        {
                            t.SetEdge(i, TileEdge.FOREST);
                        }
                        if (townGenerator(t.Bounds[i].Point.X, t.Bounds[i].Point.Y) ||
                            townGenerator(t.Bounds[i].End.X, t.Bounds[i].End.Y))
                        {
                            t.SetEdge(i, TileEdge.TOWN);
                        }
                    }
                }
            }

            // Rivers
            var riverNodes = new HashSet <Tile>();

            for (int i = 0; i < Math.Max(1, Width * Height / 160); ++i)
            {
                var t = GetRandomTile(Random, map);
                if (!IsElevated(t))
                {
                    riverNodes.Add(t);
                }
            }
            for (int i = 0; i < Math.Max(2, (Width + Height - 2) / 8); ++i)
            {
                var t = GetRandomEdgeTile(Random, map);
                if (!IsElevated(t))
                {
                    EdgePathOverlay(t, TilePathOverlay.STREAM);
                    riverNodes.Add(t);
                }
            }
            var mst   = new MinimalSpanning <Tile>(riverNodes, i => riverNodes, (i, j) => i.HeuristicDistanceTo(j));
            var edges = mst.GetEdges().ToList();

            for (int i = 0; i < edges.Count / 4; ++i)
            {
                edges.RemoveAt(Random.Next(0, edges.Count));
            }
            foreach (Tuple <Tile, Tile> edge in edges)
            {
                MakePath(edge.Item1, edge.Item2, TilePathOverlay.STREAM, RiverDistanceFunction(Random));
            }

            // Roads and Towns
            var towns     = new Partitioning <Tile>(map.TilesEnumerable, (i, j) => i.GetEdge(j) == TileEdge.TOWN);
            var roadNodes = new HashSet <Tile>();

            foreach (ISet <Tile> town in towns.GetPartitions())
            {
                var name =
                    new string(Setting.MapGenerator.NameGenerator.Generate(Random).ToArray());
                name = ObjectDescriber.Namify(name);
                map.Regions.Add(new MapRegion(name, town));
                var tiles = town.ToList();
                for (int i = 0; i < Math.Max(1, tiles.Count / 4); ++i)
                {
                    roadNodes.Add(tiles[Random.Next(0, tiles.Count)]);
                }
            }
            for (int i = 0; i < Math.Max(1, Width * Height / 160); ++i)
            {
                roadNodes.Add(GetRandomTile(Random, map));
            }
            for (int i = 0; i < Math.Max(2, (Width + Height - 2) / 8); ++i)
            {
                var t = GetRandomEdgeTile(Random, map);
                EdgePathOverlay(t, TilePathOverlay.ROAD);
                roadNodes.Add(t);
            }

            mst   = new MinimalSpanning <Tile>(roadNodes, i => roadNodes, (i, j) => i.HeuristicDistanceTo(j));
            edges = mst.GetEdges().ToList();
            var nodes = roadNodes.ToList();

            for (int i = 0; i < edges.Count / 4; ++i)
            {
                edges.Add(
                    new Tuple <Tile, Tile>(nodes[Random.Next(0, nodes.Count)], nodes[Random.Next(0, nodes.Count)]));
            }
            foreach (Tuple <Tile, Tile> edge in edges)
            {
                MakePath(edge.Item1, edge.Item2, TilePathOverlay.ROAD, (i, j) => RoadDistanceFunction(Random, i, j, 6));
            }

            map.Ready();
            return(map);
        }
예제 #30
0
        public EditPane(Map Map)
            : base("edit-pane")
        {
            _ModeSelect.OnChange += PaneChange;
            _ModeSelect.Add(
                new SelectionOption <Pod>("select-option")
            {
                DisplayedString = "Base",
                Value           = _TileBasePage
            });
            _ModeSelect.Add(
                new SelectionOption <Pod>("select-option")
            {
                DisplayedString = "Overlay",
                Value           = _PathOverlayPage
            });
            _ModeSelect.Add(
                new SelectionOption <Pod>("select-option")
            {
                DisplayedString = "Edge", Value = _EdgePage
            });
            _ModeSelect.Add(
                new SelectionOption <Pod>("select-option")
            {
                DisplayedString = "Elevation",
                Value           = _ElevationPage
            });
            _ModeSelect.Add(
                new SelectionOption <Pod>("select-option")
            {
                DisplayedString = "Map Region",
                Value           = _MapRegionPage
            });

            var header = new Button("edit-header-1")
            {
                DisplayedString = "Edit"
            };

            _ModeSelect.Position        = new Vector2f(0, header.Size.Y);
            _TileBaseSelect.Position    = new Vector2f(0, _ModeSelect.Position.Y + _ModeSelect.Size.Y + 2);
            _PathOverlaySelect.Position = new Vector2f(0, _ModeSelect.Position.Y + _ModeSelect.Size.Y + 2);
            _EdgeSelect.Position        = new Vector2f(0, _ModeSelect.Position.Y + _ModeSelect.Size.Y + 2);
            _Elevation.Position         = new Vector2f(0, _ModeSelect.Position.Y + _ModeSelect.Size.Y + 2);
            _MapRegionSelect.Position   = new Vector2f(0, _ModeSelect.Position.Y + _ModeSelect.Size.Y + 2);

            foreach (TileBase t in Enum.GetValues(typeof(TileBase)).Cast <TileBase>().Where(i => i != TileBase.CLEAR))
            {
                _TileBaseSelect.Add(
                    new SelectionOption <TileBase>("select-option")
                {
                    DisplayedString = ObjectDescriber.Describe(t),
                    Value           = t
                });
            }

            foreach (TileEdge e in Enum.GetValues(typeof(TileEdge)).Cast <TileEdge>().Where(i => i != TileEdge.NONE))
            {
                _EdgeSelect.Add(new SelectionOption <TileEdge>("select-option")
                {
                    DisplayedString = ObjectDescriber.Describe(e),
                    Value           = e
                });
            }

            foreach (TilePathOverlay t in Enum.GetValues(typeof(TilePathOverlay))
                     .Cast <TilePathOverlay>().Where(i => i != TilePathOverlay.NONE))
            {
                _PathOverlaySelect.Add(new SelectionOption <TilePathOverlay>("select-option")
                {
                    DisplayedString = ObjectDescriber.Describe(t),
                    Value           = t
                });
            }

            UpdateFromMap(Map);

            _MapRegionAddButton.Position = new Vector2f(
                Size.X - _MapRegionAddButton.Size.X - 32, Size.Y - _MapRegionAddButton.Size.Y - 32);
            _MapRegionAddButton.OnClick    += HandleAddMapRegion;
            _MapRegionDeleteButton.Position = _MapRegionAddButton.Position
                                              - new Vector2f(_MapRegionDeleteButton.Size.X + 8, 0);
            _MapRegionDeleteButton.OnClick += HandleDeleteMapRegion;
            _MapRegionSelect.OnChange      += HandleSelectMapRegion;

            _ElevationPage.Add(_Elevation);
            _PathOverlayPage.Add(_PathOverlaySelect);
            _EdgePage.Add(_EdgeSelect);
            _TileBasePage.Add(_TileBaseSelect);
            _MapRegionPage.Add(_MapRegionAddButton);
            _MapRegionPage.Add(_MapRegionDeleteButton);
            _MapRegionPage.Add(_MapRegionSelect);

            Add(header);
            Add(_ElevationPage);
            Add(_PathOverlayPage);
            Add(_EdgePage);
            Add(_TileBasePage);
            Add(_MapRegionPage);
            Add(_ModeSelect);
        }