private void SubActionOne() { IEnumerable <int> availableNodeIds; if (ActionNumber == 1 || ActionNumber == 2) { var enemyNodes = GuestMonsters.Select(monster => monster.CurrentNode).ToList(); availableNodeIds = GameGraph.Nodes.Where(n => HostMonsters.Select(m => m.CurrentNode.Id).Contains(n.Id)) .OrderByDescending(t => MoveCalculator.FindAttackMoves(t, enemyNodes).Count()) // 1. one with the most attack moves .ThenBy(m => m.Id > 12 ? 0 : 1) // 2. Monsters on the outer circle .ThenByDescending(r => HostMonsters.First(w => w.CurrentNode.Id == r.Id).AttackRating) // 3. the attack level of the monster .Select(n => n.Id); } else { var enemyNodes = HostMonsters.Select(monster => monster.CurrentNode).ToList(); availableNodeIds = GameGraph.Nodes.Where(n => GuestMonsters.Select(m => m.CurrentNode.Id).Contains(n.Id)) .OrderByDescending(t => MoveCalculator.FindAttackMoves(t, enemyNodes).Count()) // 1. one with the most attack moves .ThenBy(m => m.Id > 12 ? 0 : 1) // 2. Monsters on the outer circle .ThenByDescending(r => GuestMonsters.First(w => w.CurrentNode.Id == r.Id).AttackRating) // 3. the attack level of the monster .Select(n => n.Id); } SubActionNumber = 2; _hostServer.SendToAll(CustomMessageTypes.AvailableMonstersResponse, new AvailableMonstersResponseMessage { ActionNumber = ActionNumber, SubActionNumber = SubActionNumber, AvailableMonsterNodeIds = availableNodeIds.ToArray(), Message = "Monsters available for selection" }); }
private void IncrementActionNumber() { SubActionNumber = 1; SelectedAttackNode = null; SelectedMovementPath = null; if (ActionNumber == 4) { ActionNumber = 1; SelectedMonster = null; } else if (ActionNumber == 3) { ActionNumber++; SubActionNumber = SelectedMonster != null ? 3 : 1; } else if (ActionNumber == 2) { ActionNumber++; SelectedMonster = null; } else if (ActionNumber == 1) { ActionNumber++; SubActionNumber = SelectedMonster != null ? 3 : 1; } _hostServer.SendToAll(CustomMessageTypes.GameState, new GameStateMessage { ActionNumber = ActionNumber, SubActionNumber = SubActionNumber, Message = "New action started", HostMonsterState = JsonConvert.SerializeObject(HostMonsters.Select(m => new { m.MonsterTypeId, m.CurrentNode.Id }).ToDictionary(k => k.MonsterTypeId, v => v.Id)), GuestMonsterState = JsonConvert.SerializeObject(GuestMonsters.Select(m => new { m.MonsterTypeId, m.CurrentNode.Id }).ToDictionary(k => k.MonsterTypeId, v => v.Id)) }); }
private void SubActionThree() { if (SelectedMonster != null) { IEnumerable <Node> friendlyOccupiedNodes; IEnumerable <Node> enemyOccupiedNodes; if (ActionNumber == 1 || ActionNumber == 2) { friendlyOccupiedNodes = HostMonsters.Select(monster => monster.CurrentNode).ToList(); enemyOccupiedNodes = GuestMonsters.OrderBy(t => t.DefenseRating).Select(monster => monster.CurrentNode).ToList(); // order enemies defense rating } else { friendlyOccupiedNodes = GuestMonsters.Select(monster => monster.CurrentNode).ToList(); enemyOccupiedNodes = HostMonsters.OrderBy(t => t.DefenseRating).Select(monster => monster.CurrentNode).ToList(); // order enemies defense rating } IEnumerable <int> availableMoveActionNodeIds = MoveCalculator.FindMoves(SelectedMonster.CurrentNode, SelectedMonster.MovementRating, friendlyOccupiedNodes.Union(enemyOccupiedNodes)) .Select(a => a.DestinationNode.Id) .OrderBy(a => a); // order nodes by id so center nodes are prioritized IEnumerable <int> availableAttackActionNodeIds = MoveCalculator.FindAttackMoves(SelectedMonster.CurrentNode, enemyOccupiedNodes).Select(a => a.Id); SubActionNumber = 4; if (friendlyOccupiedNodes.Count() <= 1 && !availableAttackActionNodeIds.Any() && !availableMoveActionNodeIds.Any()) { SubActionNumber = 0; _hostServer.SendToAll(CustomMessageTypes.GameState, new PassActionMessage { ActionNumber = ActionNumber, SubActionNumber = SubActionNumber, Message = "No available moves.", HostMonsterState = JsonConvert.SerializeObject(HostMonsters.Select(m => new { m.MonsterTypeId, m.CurrentNode.Id }).ToDictionary(k => k.MonsterTypeId, v => v.Id)), GuestMonsterState = JsonConvert.SerializeObject(GuestMonsters.Select(m => new { m.MonsterTypeId, m.CurrentNode.Id }).ToDictionary(k => k.MonsterTypeId, v => v.Id)) }); } else { if (friendlyOccupiedNodes.Count() == 1 && availableAttackActionNodeIds.Any()) { availableMoveActionNodeIds = new List <int>(); } _hostServer.SendToAll(CustomMessageTypes.AvailableMovesResponse, new AvailableMovesResponseMessage { ActionNumber = ActionNumber, SubActionNumber = SubActionNumber, AvailableAttackNodeIds = availableAttackActionNodeIds.ToArray(), AvailableMoveNodeIds = availableMoveActionNodeIds.ToArray(), Message = "Available actions", SelectedMonsterTypeId = SelectedMonster.MonsterTypeId }); } } }
public void ProcessAttackAction(int attackingMonsterTypeId, int defendingMonsterTypeId) { Monster attacker; Monster defender; bool isHostAttacker = ActionNumber == 1 || ActionNumber == 2; if (isHostAttacker) { attacker = HostMonsters.Single(m => m.MonsterTypeId == attackingMonsterTypeId); defender = GuestMonsters.Single(m => m.MonsterTypeId == defendingMonsterTypeId); } else { attacker = GuestMonsters.Single(m => m.MonsterTypeId == attackingMonsterTypeId); defender = HostMonsters.Single(m => m.MonsterTypeId == defendingMonsterTypeId); } AttackResult attackResult = AttackCalculator.Calculate(attacker.AttackRating, defender.DefenseRating); IEnumerable <Node> friendlyOccupiedNodes = HostMonsters.Select(monster => monster.CurrentNode).ToList(); IEnumerable <Node> enemyOccupiedNodes = GuestMonsters.Select(monster => monster.CurrentNode).ToList(); switch (attackResult) { case AttackResult.Kill: if (isHostAttacker) { GuestMonsters.Remove(defender); } else { HostMonsters.Remove(defender); } SubActionNumber = 0; _hostServer.SendToAll(CustomMessageTypes.AttackKillResponse, new AttackKillResponseMessage { ActionNumber = ActionNumber, SubActionNumber = SubActionNumber, AttackingMonsterTypeId = attackingMonsterTypeId, DefendingMonsterTypeId = defendingMonsterTypeId, AttackResultId = (int)AttackResult.Kill, Message = "Kill" }); break; case AttackResult.CounterKill: if (isHostAttacker) { HostMonsters.Remove(attacker); } else { GuestMonsters.Remove(attacker); } SelectedMonster = null; SubActionNumber = 0; _hostServer.SendToAll(CustomMessageTypes.AttackKillResponse, new AttackKillResponseMessage { ActionNumber = ActionNumber, SubActionNumber = SubActionNumber, AttackingMonsterTypeId = attackingMonsterTypeId, DefendingMonsterTypeId = defendingMonsterTypeId, AttackResultId = (int)AttackResult.CounterKill, Message = "Counter Kill" }); break; case AttackResult.Push: AvailablePushDestinations = MoveCalculator.FindMoves(defender.CurrentNode, 1, friendlyOccupiedNodes.Union(enemyOccupiedNodes)).Select(m => m.DestinationNode); if (!AvailablePushDestinations.Any()) { SubActionNumber = 0; _hostServer.SendToAll(CustomMessageTypes.GameState, new GameStateMessage { ActionNumber = ActionNumber, SubActionNumber = SubActionNumber, Message = "No available push destinations.", HostMonsterState = JsonConvert.SerializeObject(HostMonsters.Select(m => new { m.MonsterTypeId, m.CurrentNode.Id }).ToDictionary(k => k.MonsterTypeId, v => v.Id)), GuestMonsterState = JsonConvert.SerializeObject(GuestMonsters.Select(m => new { m.MonsterTypeId, m.CurrentNode.Id }).ToDictionary(k => k.MonsterTypeId, v => v.Id)) }); } else { SubActionNumber = 6; _hostServer.SendToAll(CustomMessageTypes.AttackPushResponse, new AttackPushResponseMessage { ActionNumber = ActionNumber, SubActionNumber = SubActionNumber, AttackingMonsterTypeId = attackingMonsterTypeId, DefendingMonsterTypeId = defendingMonsterTypeId, AvailablePushDestinationIds = AvailablePushDestinations.Select(d => d.Id).ToArray(), AttackResultId = (int)AttackResult.Push, Message = "Push" }); } break; case AttackResult.CounterPush: AvailablePushDestinations = MoveCalculator.FindMoves(attacker.CurrentNode, 1, friendlyOccupiedNodes.Union(enemyOccupiedNodes)).Select(m => m.DestinationNode); if (!AvailablePushDestinations.Any()) { SubActionNumber = 0; _hostServer.SendToAll(CustomMessageTypes.GameState, new GameStateMessage { ActionNumber = ActionNumber, SubActionNumber = SubActionNumber, Message = "No available push destinations.", HostMonsterState = JsonConvert.SerializeObject(HostMonsters.Select(m => new { m.MonsterTypeId, m.CurrentNode.Id }).ToDictionary(k => k.MonsterTypeId, v => v.Id)), GuestMonsterState = JsonConvert.SerializeObject(GuestMonsters.Select(m => new { m.MonsterTypeId, m.CurrentNode.Id }).ToDictionary(k => k.MonsterTypeId, v => v.Id)) }); } else { SubActionNumber = 7; _hostServer.SendToAll(CustomMessageTypes.AttackPushResponse, new AttackPushResponseMessage { ActionNumber = ActionNumber, SubActionNumber = SubActionNumber, AttackingMonsterTypeId = attackingMonsterTypeId, DefendingMonsterTypeId = defendingMonsterTypeId, AvailablePushDestinationIds = AvailablePushDestinations.Select(d => d.Id).ToArray(), AttackResultId = (int)AttackResult.CounterPush, Message = "Counter Push" }); } break; default: throw new ArgumentOutOfRangeException(); } }
public void SelectAction(int selectedNodeId) { if (selectedNodeId < 0) { SubActionNumber = 0; _hostServer.SendToAll(CustomMessageTypes.GameState, new PassActionMessage { ActionNumber = ActionNumber, SubActionNumber = SubActionNumber, Message = "No available moves.", HostMonsterState = JsonConvert.SerializeObject(HostMonsters.Select(m => new { m.MonsterTypeId, m.CurrentNode.Id }).ToDictionary(k => k.MonsterTypeId, v => v.Id)), GuestMonsterState = JsonConvert.SerializeObject(GuestMonsters.Select(m => new { m.MonsterTypeId, m.CurrentNode.Id }).ToDictionary(k => k.MonsterTypeId, v => v.Id)) }); } IEnumerable <Node> friendlyOccupiedNodes; IEnumerable <Node> enemyOccupiedNodes; List <Monster> friendlyMonsters = ActionNumber == 1 || ActionNumber == 2 ? HostMonsters : GuestMonsters; List <Monster> enemyMonsters = ActionNumber == 1 || ActionNumber == 2 ? GuestMonsters : HostMonsters; friendlyOccupiedNodes = friendlyMonsters.Select(monster => monster.CurrentNode).ToList(); enemyOccupiedNodes = enemyMonsters.Select(monster => monster.CurrentNode).ToList(); IEnumerable <NodePath> movementPaths = MoveCalculator.FindMoves(SelectedMonster.CurrentNode, SelectedMonster.MovementRating, friendlyOccupiedNodes.Union(enemyOccupiedNodes)); IEnumerable <Node> availableMoveActions = movementPaths.Select(p => p.DestinationNode); IEnumerable <Node> availableAttackActions = MoveCalculator.FindAttackMoves(SelectedMonster.CurrentNode, enemyOccupiedNodes); if (friendlyOccupiedNodes.Select(n => n.Id).Contains(selectedNodeId)) { SelectedMonster = friendlyMonsters.Single(m => m.CurrentNode.Id == selectedNodeId); SelectedAttackNode = null; SubActionNumber = 3; _hostServer.SendToAll(CustomMessageTypes.SelectMonsterResponse, new SelectMonsterResponseMessage { ActionNumber = ActionNumber, SubActionNumber = SubActionNumber, SelectedMonsterTypeId = SelectedMonster.MonsterTypeId, Message = SelectedMonster.Name, }); } else if (availableAttackActions.Select(a => a.Id).Contains(selectedNodeId)) { SelectedAttackNode = availableAttackActions.Single(a => a.Id == selectedNodeId); SelectedMovementPath = null; SubActionNumber = 5; _hostServer.SendToAll(CustomMessageTypes.SelectAttackActionResponse, new SelectAttackResponseMessage { ActionNumber = ActionNumber, SubActionNumber = SubActionNumber, Message = "Attack selected", AttackNodeId = SelectedAttackNode.Id }); } else if (availableMoveActions.Select(m => m.Id).Contains(selectedNodeId)) { SelectedMovementPath = movementPaths.Single(m => m.DestinationNode.Id == selectedNodeId); SelectedAttackNode = null; SubActionNumber = 5; _hostServer.SendToAll(CustomMessageTypes.SelectMoveActionResponse, new SelectMoveResponseMessage { ActionNumber = ActionNumber, SubActionNumber = SubActionNumber, Message = SelectedMovementPath.ToString(), MovementPathIds = SelectedMovementPath.PathToDestination.Select(n => n.Id).ToArray(), DestinationNodeId = SelectedMovementPath.DestinationNode.Id }); } }