Exemplo n.º 1
0
        /// <summary>
        /// If the user clicks a battle square when it's a Character's turn, call the battle engine to
        /// perform an action on that square
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public bool CharacterManualTurn(MapModelLocation data)
        {
            if (!IsCharacterTurn)
            {
                return(false);
            }

            // no one is taking a turn - do nothing
            if (EngineViewModel.Engine.CurrentEntity == null)
            {
                return(false);
            }

            // only take a turn if we're waiting on a character
            if (EngineViewModel.Engine.CurrentEntity.EntityType != EntityTypeEnum.Character)
            {
                return(false);
            }

            // toggle flag to prevent this character from performing multiple actions if user keeps clicking
            IsCharacterTurn = false;

            var result = EngineViewModel.Engine.CharacterManualTurn(EngineViewModel.Engine.CurrentEntity, data);

            DisplayTurnResult();

            AttackButton.IsVisible         = true;
            CharacterTurnMessage.IsVisible = false;

            return(result);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Make the Game Map Frame
        /// Place the Character or Monster on the frame
        /// If empty, place Empty
        /// </summary>
        /// <param name="mapLocationModel"></param>
        /// <returns></returns>
        public Frame MakeMapGridBox(MapModelLocation mapLocationModel)
        {
            if (mapLocationModel.Player == null)
            {
                mapLocationModel.Player = BattleEngineViewModel.Instance.Engine.EngineSettings.MapModel.EmptySquare;
            }

            var PlayerImageButton = DetermineMapImageButton(mapLocationModel);

            var PlayerStack = new StackLayout
            {
                Padding           = 0,
                Style             = (Style)Application.Current.Resources["BattleMapImageBox"],
                HorizontalOptions = LayoutOptions.Center,
                VerticalOptions   = LayoutOptions.Center,
                BackgroundColor   = DetermineMapBackgroundColor(mapLocationModel),
                Children          =
                {
                    PlayerImageButton
                },
            };

            MapGridObjectAddImage(PlayerImageButton, mapLocationModel);
            MapGridObjectAddStack(PlayerStack, mapLocationModel);

            var MapFrame = new Frame
            {
                Style        = (Style)Application.Current.Resources["BattleMapFrame"],
                Content      = PlayerStack,
                AutomationId = GetDictionaryFrameName(mapLocationModel)
            };

            return(MapFrame);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Set the Image onto the map
        /// The Image represents the player
        ///
        /// So a character is the character Image for that character
        ///
        /// The Automation ID equals the guid for the player
        /// This makes it easier to identify when checking the map to update thigns
        ///
        /// The button action is set per the type, so Characters events are differnt than monster events
        /// </summary>
        /// <param name="MapModel"></param>
        /// <returns></returns>
        public ImageButton DetermineMapImageButton(MapModelLocation MapLocationModel)
        {
            ImageButton data;

            if (MapLocationModel.Player.EntityType == EntityTypeEnum.Character)
            {
                data = new ImageButton
                {
                    Style  = (Style)Application.Current.Resources["ImageBattleSmallSpriteStyle"],
                    Source = MapLocationModel.Player.ImageURI,

                    // Store the guid to identify this button
                    AutomationId = MapLocationModel.Player.Guid
                };
            }
            else
            {
                data = new ImageButton
                {
                    Style  = (Style)Application.Current.Resources["ImageBattleSmallIconStyle"],
                    Source = MapLocationModel.Player.ImageURI,

                    // Store the guid to identify this button
                    AutomationId = MapLocationModel.Player.Guid
                };
            }

            // add a click event to handle character manual turn
            data.Clicked += (sender, args) => CharacterManualTurn(MapLocationModel);

            return(data);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Set the Image onto the map
        /// The Image represents the player
        ///
        /// So a charcter is the character Image for that character
        ///
        /// The Automation ID equals the guid for the player
        /// This makes it easier to identify when checking the map to update thigns
        ///
        /// The button action is set per the type, so Characters events are differnt than monster events
        /// </summary>
        /// <param name="MapLocationModel"></param>
        /// <returns></returns>
        public ImageButton DetermineMapImageButton(MapModelLocation MapLocationModel)
        {
            var data = new ImageButton
            {
                Style  = (Style)Application.Current.Resources["BattleMapPlayerSmallStyle"],
                Source = MapLocationModel.Player.ImageURI,

                // Store the guid to identify this button
                AutomationId = MapLocationModel.Player.Guid
            };

            switch (MapLocationModel.Player.PlayerType)
            {
            case PlayerTypeEnum.Character:
                data.Clicked += (sender, args) => SetSelectedCharacter(MapLocationModel);
                break;

            case PlayerTypeEnum.Monster:
                data.Clicked += (sender, args) => SetSelectedMonster(MapLocationModel);
                break;

            case PlayerTypeEnum.Unknown:
            default:
                data.Clicked += (sender, args) => SetSelectedEmpty(MapLocationModel);

                // Use the blank cell
                data.Source = BattleEngineViewModel.Instance.Engine.EngineSettings.MapModel.EmptySquare.ImageURI;
                break;
            }

            return(data);
        }
        /// <summary>
        /// Event when a Monster is clicked on
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>

        public bool SetSelectedMonster(MapModelLocation data)
        {
            // Click on a monster if within range
            if (data.Player.PlayerType == PlayerTypeEnum.Monster)
            {
                // the ImageButton serves to disable Monsters out of reach
                object MapObject = GetMapGridObject(GetDictionaryImageButtonName(data));
                if (MapObject != null)
                {
                    var imageObject = (ImageButton)MapObject;
                    imageObject.IsEnabled = false;
                    // check range
                    if (Math.Abs(selectedCharacterLocation.Row - data.Row) + Math.Abs(selectedCharacterLocation.Column - data.Column) <= selectedCharacterRange)
                    {
                        // Choose the attack action and choose this monster as current defender
                        selectedMonster = data.Player;
                        BattleEngineViewModel.Instance.Engine.EngineSettings.CurrentAction = ActionEnum.Attack;
                        BattleEngineViewModel.Instance.Engine.Round.SetCurrentDefender(selectedMonster);

                        data.IsSelectedTarget = true;

                        // setting the current action to move if a monster is selected
                        monsterIsSelected     = true;
                        imageObject.IsEnabled = true;
                        return(true);
                    }
                }
            }
            return(false);
        }
 /// <summary>
 /// Event when a Character is clicked on
 /// </summary>
 /// <param name="data"></param>
 /// <returns></returns>
 public bool SetSelectedCharacter(MapModelLocation data)
 {
     // Only for characters
     if (data.Player.PlayerType == PlayerTypeEnum.Character)
     {
         // flags that help with turns in the SetAttackerAndDefender method
         selectedCharacter         = data.Player;
         selectedCharacterRange    = data.Player.Range;
         selectedCharacterLocation = data;
         characterIsSelected       = true;
         foreach (var cell in BattleEngineViewModel.Instance.Engine.EngineSettings.MapModel.MapGridLocation)
         {
             // disable out-of-reach cells
             object MapObject = GetMapGridObject(GetDictionaryImageButtonName(cell));
             if (MapObject != null & cell.Player.PlayerType != PlayerTypeEnum.Character)
             {
                 var imageObject = (ImageButton)MapObject;
                 imageObject.IsEnabled = true;
                 // check range
                 if (Math.Abs(selectedCharacterLocation.Row - cell.Row) + Math.Abs(selectedCharacterLocation.Column - cell.Column) > selectedCharacterRange)
                 {
                     imageObject.IsEnabled = false;
                 }
             }
         }
         return(true);
     }
     return(false);
 }
Exemplo n.º 7
0
        /// <summary>
        /// Event when a Character is clicked on
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public bool SetSelectedCharacter(MapModelLocation data)
        {
            // TODO: Info

            /*
             * This gets called when the characters is clicked on
             * Usefull if you want to select the character and then set state or do something
             *
             * For Mike's simple battle grammar there is no selection of action so I just return true
             */

            return(true);
        }
Exemplo n.º 8
0
        /// <summary>
        /// Event when an empty location is clicked on
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public bool SetSelectedEmpty(MapModelLocation data)
        {
            // TODO: Info

            /*
             * This gets called when the characters is clicked on
             * Usefull if you want to select the location to move to etc.
             *
             * For Mike's simple battle grammar there is no selection of action so I just return true
             */

            return(true);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Event when a Monster is clicked on
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public bool SetSelectedMonster(MapModelLocation data)
        {
            // TODO: Info

            /*
             * This gets called when the Monster is clicked on
             * Usefull if you want to select the monster to attack etc.
             *
             * For Mike's simple battle grammar there is no selection of action so I just return true
             */

            data.IsSelectedTarget = true;
            return(true);
        }
Exemplo n.º 10
0
        public void BattleSettingsPage_MakeMapGridBox_InValid_Should_Fail()
        {
            // Arrange
            var data = new MapModelLocation {
                Player = null, Column = 0, Row = 0
            };

            // Act
            var result = page.MakeMapGridBox(data);

            // Reset

            // Assert
            Assert.AreEqual(HitStatusEnum.Default, BattleEngineViewModel.Instance.Engine.EngineSettings.BattleSettingsModel.CharacterHitEnum);
        }
Exemplo n.º 11
0
        /// <summary>
        /// This adds the Stack into the Dictionary to keep track of
        /// </summary>
        /// <param name="data"></param>
        /// <param name="MapModel"></param>
        /// <returns></returns>
        public bool MapGridObjectAddStack(StackLayout data, MapModelLocation MapModel)
        {
            var name = GetDictionaryStackName(MapModel);

            // First check to see if it has data, if so update rather than add
            if (MapLocationObject.ContainsKey(name))
            {
                // Update it
                MapLocationObject[name] = data;
                return(true);
            }

            MapLocationObject.Add(name, data);
            return(true);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Set the Background color for the tile.
        /// Monsters and Characters have different colors
        /// Empty cells are transparent
        /// </summary>
        /// <param name="MapModel"></param>
        /// <returns></returns>
        public Color DetermineMapBackgroundColor(MapModelLocation MapModel)
        {
            if (EngineViewModel.Engine.CurrentAttacker == MapModel.Player)
            {
                return((Color)Application.Current.Resources["BattleMapCurrentAttacker"]);
            }

            if (EngineViewModel.Engine.CurrentEntity == MapModel.Player)
            {
                return((Color)Application.Current.Resources["BattleMapCurrentEntity"]);
            }

            if (EngineViewModel.Engine.CurrentDefender == MapModel.Player)
            {
                return((Color)Application.Current.Resources["BattleMapCurrentDefender"]);
            }

            return(Color.Transparent);
        }
        /// <summary>
        /// Event when an empty location is clicked on
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public bool SetSelectedEmpty(MapModelLocation data)
        {
            // pick empty sells and move if within range
            if (BattleEngineViewModel.Instance.Engine.EngineSettings.CurrentAttacker.PlayerType == PlayerTypeEnum.Character
                & data.Player.PlayerType == PlayerTypeEnum.Unknown)
            {
                BattleEngineViewModel.Instance.Engine.EngineSettings.CurrentAction = ActionEnum.Move;

                // if within range, pick empty cell and move the character on map
                if (Math.Abs(selectedCharacterLocation.Row - data.Row) + Math.Abs(selectedCharacterLocation.Column - data.Column) <= selectedCharacterRange)
                {
                    emptyIsSelected = true;
                    BattleEngineViewModel.Instance.Engine.EngineSettings.MapModel.MovePlayerOnMap(selectedCharacterLocation, data);
                }

                UpdateMapGrid();
                // If the player moves, then ability cannot be applied
                AbilityButton.IsEnabled = false;
            }
            return(true);
        }
        /// <summary>
        /// Event when player is clicked. To swap position.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void OnPlayerClicked(object sender, EventArgs e)
        {
            var imgButton = (ImageButton)sender;

            var player_clicked = (EntityInfoModel)imgButton.BindingContext;

            if (player_clicked.PlayerType != PlayerTypeEnum.Character)
            {
                return; // validate the player is a character
            }

            if (From == null)
            {
                From = EngineViewModel.Engine.MapModel.GetLocationForPlayer(player_clicked);

                Selected = imgButton;

                Selected.IsEnabled = false;
            }
            else
            {
                if (player_clicked != From.Player)
                {
                    var to = EngineViewModel.Engine.MapModel.GetLocationForPlayer(player_clicked);

                    var temp = From.Player;

                    From.Player = to.Player;

                    to.Player = temp;
                }

                From = null;

                Selected.IsEnabled = true;

                // redraw game board
                DrawBattleBoard();
            }
        }
Exemplo n.º 15
0
        /// <summary>
        /// Set the Background color for the tile.
        /// Monsters and Characters have different colors
        /// Empty cells are transparent
        /// </summary>
        /// <param name="MapModel"></param>
        /// <returns></returns>
        public Color DetermineMapBackgroundColor(MapModelLocation MapModel)
        {
            string BattleMapBackgroundColor;

            switch (MapModel.Player.PlayerType)
            {
            case PlayerTypeEnum.Character:
                BattleMapBackgroundColor = "BattleMapCharacterColor";
                break;

            case PlayerTypeEnum.Monster:
                BattleMapBackgroundColor = "BattleMapMonsterColor";
                break;

            case PlayerTypeEnum.Unknown:
            default:
                BattleMapBackgroundColor = "BattleMapTransparentColor";
                break;
            }

            var result = (Color)Application.Current.Resources[BattleMapBackgroundColor];

            return(result);
        }
Exemplo n.º 16
0
        /// <summary>
        /// Character takes a turn by performing an action on the specified MapModelLocation.
        /// Possible actions are:
        ///     Attack: if location has a monster in range
        ///     Move: if location has a monster out of range, or location is empty
        ///     Swap: if location has a character, the characters swap places
        ///     Wait: if character's own square was clicked, do nothing
        /// </summary>
        /// <param name="Attacker"></param>
        /// <param name="location"></param>
        /// <returns></returns>
        public bool CharacterManualTurn(BattleEntityModel Attacker, MapModelLocation Location)
        {
            Score.TurnCount++;
            CurrentAttacker = Attacker;

            // only characters are allowed to do manual attacks
            if (Attacker.EntityType == EntityTypeEnum.Monster)
            {
                return(false);
            }

            // is there a monster at the location?
            if (Location.Player.EntityType == EntityTypeEnum.Monster)
            {
                CurrentDefender = Location.Player;

                // is it in range? attack...
                if (MapModel.IsTargetInRange(Attacker, Location.Player))
                {
                    return(TurnAsAttack(Attacker, Location.Player));
                }

                // otherwise move to the closest found space
                var openSquare = MapModel.ReturnClosestEmptyLocation(Location);
                var current    = MapModel.GetLocationForPlayer(Attacker);

                Debug.WriteLine(string.Format("{0} moves from {1},{2} to {3},{4}", Attacker.Name,
                                              current.Column, current.Row, openSquare.Column, openSquare.Row));

                BattleMessages.TurnMessage = Attacker.Name + " moves closer to " + CurrentDefender.Name;

                return(MapModel.MovePlayerOnMap(current, openSquare));
            }

            // is the location empty?
            if (Location.Player.EntityType == EntityTypeEnum.Unknown)
            {
                CurrentDefender = null;

                // move to empty space
                var current = MapModel.GetLocationForPlayer(Attacker);

                Debug.WriteLine(string.Format("{0} moves from {1},{2} to {3},{4}", Attacker.Name,
                                              current.Column, current.Row, Location.Column, Location.Row));

                BattleMessages.TurnMessage = Attacker.Name + " moves to an empty space";

                return(MapModel.MovePlayerOnMap(current, Location));
            }

            // is there a character at the location?
            if (Location.Player.EntityType == EntityTypeEnum.Character)
            {
                CurrentDefender = null;

                // is this my own space?
                if (Location.Player.Id.Equals(Attacker.Id))
                {
                    Debug.WriteLine(string.Format("{0} hums a song and does nothing", Attacker.Name));

                    BattleMessages.TurnMessage = Attacker.Name + " hums a song and does nothing";

                    return(true);
                }

                // characters swap locations
                var current = MapModel.GetLocationForPlayer(Attacker);

                Debug.WriteLine(string.Format("{0} moves and swaps places with {1} ", Attacker.Name,
                                              Location.Player.Name));

                BattleMessages.TurnMessage = Attacker.Name + " moves and swaps places with " + Location.Player.Name;

                return(MapModel.SwapPlayersOnMap(current, Location));
            }

            // did not perform action
            return(false);
        }
Exemplo n.º 17
0
        /// <summary>
        /// Find a Desired Target
        /// Move close to them
        /// Get to move the number of Speed
        /// </summary>
        /// <param name="Attacker"></param>
        /// <returns></returns>
        public bool MoveAsTurn(EntityInfoModel Attacker, MapModelLocation targetLocation = null)
        {
            /*
             * TODO: TEAMS Work out your own move logic if you are implementing move
             *
             * Mike's Logic
             * The monster or charcter will move to a different square if one is open
             * Find the Desired Target
             * Jump to the closest space near the target that is open
             *
             * If no open spaces, return false
             *
             */

            if (Attacker.PlayerType == PlayerTypeEnum.Monster)
            {
                // For Attack, Choose Who
                CurrentDefender = AttackChoice(Attacker);

                if (CurrentDefender == null)
                {
                    return(false);
                }

                // Get X, Y for Defender
                var locationDefender = MapModel.GetLocationForPlayer(CurrentDefender);
                if (locationDefender == null)
                {
                    return(false);
                }

                var locationAttacker = MapModel.GetLocationForPlayer(Attacker);
                if (locationAttacker == null)
                {
                    return(false);
                }

                // Find Location Nearest to Defender that is Open.

                // Get the Open Locations
                var openSquare = MapModel.ReturnClosestEmptyLocation(locationDefender);

                Debug.WriteLine(string.Format("{0} moves from {1},{2} to {3},{4}", locationAttacker.Player.Name, locationAttacker.Column, locationAttacker.Row, openSquare.Column, openSquare.Row));

                BattleMessageModel.TurnMessage = Attacker.Name + " moves closer to " + CurrentDefender.Name;

                return(MapModel.MovePlayerOnMap(locationAttacker, openSquare));
            }
            else if (Attacker.PlayerType == PlayerTypeEnum.Character)
            {
                var locationAttacker = MapModel.GetLocationForPlayer(Attacker);
                if (locationAttacker == null)
                {
                    return(false);
                }

                var openSquare = TargetLocation;

                Debug.WriteLine(string.Format("{0} moves from {1},{2} to {3},{4}", locationAttacker.Player.Name, locationAttacker.Column, locationAttacker.Row, openSquare.Column, openSquare.Row));

                BattleMessageModel.TurnMessage = Attacker.Name + " moves to row: " + openSquare.Row + 1 + " column: " + openSquare.Column;

                return(MapModel.MovePlayerOnMap(locationAttacker, openSquare));
            }

            return(true);
        }
Exemplo n.º 18
0
 /// <summary>
 /// Covert the player map location to a name for the dictionary to lookup
 /// </summary>
 /// <param name="data"></param>
 /// <returns></returns>
 public string GetDictionaryImageButtonName(MapModelLocation data)
 {
     // Look up the Frame in the Dictionary
     return(string.Format("MapR{0}C{1}ImageButton", data.Row, data.Column));
 }
Exemplo n.º 19
0
 /// <summary>
 /// Convert the Stack to a name for the dictionary to lookup
 /// </summary>
 /// <param name="data"></param>
 /// <returns></returns>
 public string GetDictionaryStackName(MapModelLocation data)
 {
     return(string.Format("MapR{0}C{1}Stack", data.Row, data.Column));
 }