public void TestBasicFight() { var attackerCharacter = new CharacterBuilder() .Attributes(new AttributesBuilder() .Health(15) .Skill(12) .Defense(2) .Special(0) .Speed(13) .Strength(7) .Build()) .Weapons("Shortsword") .Build(); var defenderCharacter = new CharacterBuilder() .Attributes(new AttributesBuilder() .Health(15) .Skill(12) .Defense(2) .Special(0) .Speed(13) .Strength(3) .Build()) .Weapons("Shortsword") .Build(); var attacker = new BaseCombatant(attackerCharacter, ArmyType.Friendly); var defender = new BaseCombatant(defenderCharacter, ArmyType.Friendly); attacker.Position = new Vector2(0, 1); defender.Position = new Vector2(0, 0); var map = new Map(); map.AddCombatant(attacker); map.AddCombatant(defender); var skillDatabase = new SkillDatabase(map); var forecaster = new FightForecaster(map, skillDatabase); var forecast = forecaster.Forecast(attacker, defender, SkillType.Melee); var finalizer = new FightFinalizer(skillDatabase); var final = finalizer.Finalize(forecast, new ConstantRandomizer(100)); var initialPhase = final.InitialPhase; Assert.NotNull(initialPhase); var initialDamage = initialPhase.Effects.GetDefenderDamage(); Assert.AreEqual(5, initialDamage); var counterPhase = final.CounterPhase; Assert.NotNull(counterPhase); var counterDamage = counterPhase.Effects.GetDefenderDamage(); Assert.AreEqual(1, counterDamage); }
public void TestAttackerKillsOnDouble() { var attackerCharacter = new CharacterBuilder() .Attributes(new AttributesBuilder() .Health(15) .Skill(12) .Defense(2) .Special(0) .Speed(33) .Strength(10) .Build()) .Weapons("Shortsword") .Build(); var defenderCharacter = new CharacterBuilder() .Attributes(new AttributesBuilder() .Health(15) .Skill(12) .Defense(0) .Special(0) .Speed(13) .Strength(7) .Build()) .Stats(new StatsBuilder() .ParryChance(0) .Build()) .Weapons("Shortsword") .Build(); var attacker = new BaseCombatant(attackerCharacter, ArmyType.Friendly); var defender = new BaseCombatant(defenderCharacter, ArmyType.Friendly); attacker.Position = new Vector2(0, 0); defender.Position = new Vector2(0, 1); var map = new Map(); var skillDatabase = new SkillDatabase(map); var forecaster = new FightForecaster(map, skillDatabase); var forecast = forecaster.Forecast(attacker, defender, SkillType.Melee); var finalizer = new FightFinalizer(skillDatabase); var final = finalizer.Finalize(forecast, new ConstantRandomizer(100)); Assert.NotNull(final.InitialPhase); Assert.NotNull(final.CounterPhase); Assert.NotNull(final.DoubleAttackPhase); Assert.Null(final.FlankerPhase); }
public override void Execute() { var state = BattleViewModel.State; if (state == BattleUIState.Uninitialized || state == BattleUIState.PhaseChanging || state == BattleUIState.Preparations || state == BattleUIState.Surveying) { return; } var combatant = BattleViewModel.Map.GetAtPosition(Position); if (state == BattleUIState.SelectingUnit) { if (combatant != null && combatant.Army == ArmyType.Friendly) { var actions = AvailableActions.GetAvailableActionTypes(combatant); if (actions.Count <= 0) { return; } // Mark the unit at Position as selected, change the battle state. BattleViewModel.SelectedCombatant = combatant; BattleViewModel.State = BattleUIState.SelectingAction; BattleViewModel.AvailableActions = actions; var dimensions = BattleViewModel.Dimensions; var worldPosition = dimensions.GetWorldPositionForGridPosition(combatant.Position); UnitSelectedSignal.Dispatch(worldPosition); } } else if (state == BattleUIState.SelectingMoveLocation) { var map = BattleViewModel.Map; var path = BattleViewModel.CurrentMovementPath; if (path != null) { // Don't allow movement to the terminal points of a path if they are blocked. var terminus = path.Terminus; if (!map.IsBlocked(terminus)) { var positions = path.Positions.GetRange(1, path.Positions.Count - 1); var action = new MoveAction(map, path.Combatant, positions.Last(), positions); AnimateActionSignal.Dispatch(action); BattleViewModel.State = BattleUIState.CombatantMoving; } } } else if (state == BattleUIState.SelectingInteractTarget) { var map = BattleViewModel.Map; var tile = map.GetEventTile(Position); // Only if the player clicks on a tile that is actually interactible by clicks if (tile != null && tile.InteractionMode == InteractionMode.Use) { EventTileInteractedSignal.Dispatch(tile); } } else if (state == BattleUIState.SelectingAttackTarget) { if (combatant != null && combatant.Army == ArmyType.Enemy) { // Forecast the fight against this unit var attacker = BattleViewModel.SelectedCombatant; var battle = BattleViewModel.Battle; var selectedUnitPosition = attacker.Position; var distanceToTarget = MathUtils.ManhattanDistance(selectedUnitPosition, Position); var map = BattleViewModel.Map; SkillType skill; if (BattleViewModel.SpecialAttack) { if (!attacker.SpecialSkill.HasValue) { throw new ArgumentException("Combatant " + attacker.Id + " has no special skill configured."); } skill = attacker.SpecialSkill.Value; } else { skill = battle.GetWeaponSkillForRange(attacker, distanceToTarget); } var skillDatabase = new SkillDatabase(map); var forecaster = new FightForecaster(map, skillDatabase); var fight = forecaster.Forecast(BattleViewModel.SelectedCombatant, combatant, skill); FightForecastSignal.Dispatch(fight); BattleViewModel.FightForecast = fight; BattleViewModel.State = BattleUIState.ForecastingCombat; } } }
public void TestRangedCounter() { var attackerCharacter = new CharacterBuilder() .Attributes(new AttributesBuilder() .Health(15) .Skill(12) .Defense(2) .Special(0) .Speed(13) .Strength(7) .Build()) .Stats(new StatsBuilder() .ParryChance(0) .Build()) .Weapons("Slim Recurve") .Build(); var defenderCharacter = new CharacterBuilder() .Attributes(new AttributesBuilder() .Health(15) .Skill(12) .Defense(2) .Special(0) .Speed(13) .Strength(7) .Build()) .Stats(new StatsBuilder() .ParryChance(0) .Build()) .Weapons("Slim Recurve") .Build(); var attacker = new BaseCombatant(attackerCharacter, ArmyType.Friendly); var defender = new BaseCombatant(defenderCharacter, ArmyType.Friendly); attacker.Position = new Vector2(0, 0); defender.Position = new Vector2(0, 2); var map = new Map(); map.AddCombatant(attacker); map.AddCombatant(defender); var skillDatabase = new SkillDatabase(map); var forecaster = new FightForecaster(map, skillDatabase); var forecast = forecaster.Forecast(attacker, defender, SkillType.Ranged); var finalizer = new FightFinalizer(skillDatabase); var final = finalizer.Finalize(forecast, new ConstantRandomizer(100)); var initialPhase = final.InitialPhase; Assert.NotNull(initialPhase); var initialEffects = initialPhase.Effects; Assert.AreEqual(5, initialEffects.GetDefenderDamage()); var counterPhase = final.CounterPhase; Assert.NotNull(counterPhase); var counterEffects = counterPhase.Effects; Assert.AreEqual(5, counterEffects.GetDefenderDamage()); Assert.Null(final.DoubleAttackPhase); Assert.Null(final.FlankerPhase); }
public FightForecast ForecastFight(ICombatant attacker, ICombatant defender, SkillType type) { return(_forecaster.Forecast(attacker, defender, type)); }