static ProjectedGameState GetNextGameStateFromMove(ScenarioState lastState, EntityData entity, Direction move) { ScenarioState newState = lastState.DeepCopy(); newState.lastGameState = lastState; EntityData entityCopy = newState.GetAllEntities().Find(e => entity.ID == e.ID); Tile currentEntityTile = BoardController.CurrentBoard.GetTileAtPosition(entityCopy.Position); Action stateAction = new Action(GenericMovementCard, entity, move, 1); // If entity can't move that direction, return state as-is. if (!currentEntityTile.ConnectsToNeighbor(move)) { return(new ProjectedGameState(entityCopy, newState, stateAction)); } Tile nextTile = currentEntityTile.GetDirectionalNeighbor(move); // If tile is empty, move entity there and return. if (!newState.IsTileOccupied(nextTile)) { entityCopy.SetPosition(nextTile.Position, newState); return(new ProjectedGameState(entityCopy, newState, stateAction)); } EntityData tileOccupant = newState.GetTileOccupant(nextTile.Position); ResolveBump(entity, tileOccupant, move, newState); Bump bump = new Bump(entityCopy, tileOccupant); return(new ProjectedGameState(entityCopy, newState, stateAction, bump)); }
static void ApplyModifierToAttack_PushPull(EntityData target, ModifierData modifier, EntityData attacker, ScenarioState gameState, ModifierCategory pushOrPull) { if (attacker.Position == target.Position) { return; } // Default to push, check for pull. Direction forceDirection = BoardHelperFunctions.GetDirectionFromPosition(attacker.Position, target.Position); if (pushOrPull == ModifierCategory.Pull) { forceDirection = BoardHelperFunctions.GetDirectionFromPosition(target.Position, attacker.Position); } int pushMagnitude = modifier.value; while (pushMagnitude > 0) { Tile currentTargetTile = BoardController .CurrentBoard .GetTileAtPosition(target.Position); bool canPushTarget = currentTargetTile .ConnectsToNeighbor(forceDirection); if (canPushTarget) { Tile nextTile = currentTargetTile.GetDirectionalNeighbor(forceDirection); bool isNextTileOccupied = nextTile.IsOccupied(gameState); if (isNextTileOccupied) { ResolveBump(target, gameState.GetTileOccupant(nextTile), forceDirection, gameState); break; } else { target.SetPosition(currentTargetTile.GetDirectionalNeighbor(forceDirection).Position, gameState); pushMagnitude--; } } else { target.DealDamage(1, gameState); break; } } }
static void ApplyModifierToAttack_BlowbackFollowUp(ModifierData modifier, EntityData entity, ScenarioState gameState, Direction actionDirection, ModifierCategory blowbackOrFollowUp) { Direction forceDirection = actionDirection; if (blowbackOrFollowUp == ModifierCategory.Blowback) { forceDirection = ScenarioStateHelperFunctions.ReverseDirection(forceDirection); } int pushMagnitude = modifier.value; while (pushMagnitude > 0) { Tile currentEntityTile = BoardController .CurrentBoard .GetTileAtPosition(entity.Position); bool canPushTarget = currentEntityTile .ConnectsToNeighbor(forceDirection); if (canPushTarget) { Tile nextTile = currentEntityTile.GetDirectionalNeighbor(forceDirection); bool isNextTileOccupied = nextTile.IsOccupied(gameState); if (isNextTileOccupied) { ResolveBump(entity, gameState.GetTileOccupant(nextTile), forceDirection, gameState); break; } else { entity.SetPosition(currentEntityTile.GetDirectionalNeighbor(forceDirection).Position, gameState); pushMagnitude--; } } else { entity.DealDamage(1, gameState); break; } } }
public static EntityData GetTileOccupant(this ScenarioState state, Tile tile) { return(state.GetTileOccupant(tile.Position)); }
static ProjectedGameState GetNextStateFromAction_Attack(ScenarioState newState, EntityData entity, Action action) { GameBoard testBoard = BoardController.CurrentBoard; AttackCardData card = action.card as AttackCardData; TargetType attackTargetType = card.targetType; Tile attackOriginTile = BoardController.CurrentBoard.GetTileAtPosition(entity.Position); List <Tile> targetTiles = new List <Tile>(); switch (attackTargetType) { case TargetType.Single: targetTiles.Add(newState.FindFirstOccupiedTileInDirection(attackOriginTile, action.direction, action.distance)); break; case TargetType.AreaOfEffect: Tile impactTile = newState.FindFirstOccupiedTileInDirection(attackOriginTile, action.direction, action.distance); targetTiles.Add(impactTile); targetTiles.AddRange(impactTile.Neighbors); break; case TargetType.Line: targetTiles.AddRange(attackOriginTile.GetAllTilesInDirection(action.direction, action.card.range)); break; default: break; } ProjectedGameState newProjectedState = new ProjectedGameState(entity, newState, action); newProjectedState.AddAttackedPositions(targetTiles.Select(t => t.Position)); List <EntityData> affectedEntities = targetTiles .Select(t => newState.GetTileOccupant(t)) .Where(o => o != null) .ToList(); if (affectedEntities.Count == 0) { List <ModifierData> modifiersToResolve = action.card.modifiers .Where(m => m.modifierCategory == ModifierCategory.Blowback || m.modifierCategory == ModifierCategory.FollowUp) .ToList(); for (int i = 0; i < modifiersToResolve.Count; i++) { ModifierData modifier = modifiersToResolve[i]; ApplyModifierToAttack_BlowbackFollowUp(modifier, entity, newState, action.direction, modifier.modifierCategory); } return(newProjectedState); } for (int i = 0; i < affectedEntities.Count; i++) { EntityData affectedEntity = affectedEntities[i]; int cardDamage = card.damage + entity.GetAttackModifierValue(); affectedEntity.DealDamage(cardDamage, newState); List <ModifierData> attackModifiers = action.card.modifiers; if (attackModifiers != null && attackModifiers.Count > 0) { for (int j = 0; i < attackModifiers.Count; i++) { ApplyModifierToAttack(affectedEntity, attackModifiers[j], entity, newState, action.direction); } } } return(newProjectedState); }