public static int ComputeMeleeDamage(ICombatant attacker, ICombatant defender) { var strength = attacker.GetAttribute(Attribute.AttributeType.Strength); var defense = defender.GetAttribute(Attribute.AttributeType.Defense); return(strength.Value - defense.Value); }
public override SkillEffects ComputeResult(ICombatant attacker, ICombatant defender, IRandomizer randomizer) { var myKinesis = attacker.GetAttribute(Attribute.AttributeType.Special).Value; var hit = new List <IEffect> { new Damage(myKinesis) }; return(new SkillEffects(hit)); }
public override SkillEffects ComputeResult(ICombatant attacker, ICombatant defender, IRandomizer randomizer) { var mySkill = attacker.GetAttribute(Attribute.AttributeType.Skill).Value; return(new SkillEffects( new List <IEffect> { new Damage(-mySkill) } )); }
public override SkillForecast ComputeForecast(ICombatant attacker, ICombatant defender) { var attackCount = 1; var chances = new SkillChances { CritChance = 100, HitChance = 100, GlanceChance = 0 }; var myKinesis = attacker.GetAttribute(Attribute.AttributeType.Special).Value; var hit = new SkillHit { BaseDamage = myKinesis, HitCount = attackCount }; return(new SkillForecast { Type = Type, Hit = hit, Chances = chances, Attacker = attacker, Defender = defender }); }
public void AddNewCombatant(ICombatant combatant) { _movesRemaining[combatant.Id] = combatant.GetAttribute(Attribute.AttributeType.Move).Value; _actionTaken[combatant.Id] = false; }
public IEnumerable <ICombatAction> ComputeActions(IBattle battle) { var map = battle.Map; if (_target != null) { // If the target has died since we last acted, give up on it and // try to find a new thing to do. if (!_target.IsAlive) { _target = null; return(ComputeActions(battle)); } // If the target is in range of one of our weapons, use it var weapon = ChooseWeapon(); if (IsInAttackRange(_self.Position, _target, weapon, map)) { var skill = weapon.Range > 1 ? SkillType.Ranged : SkillType.Melee; var forecast = battle.ForecastFight(_self, _target, skill); var finalized = battle.FinalizeFight(forecast); return(new List <ICombatAction> { new FightAction(finalized) }); } // If there's actually a path to the target, move there var path = map.FindPathToAdjacentTile(_self.Position, _target.Position, PathfindingUtils.GetCombatantTileFilter(_self)); if (path != null) { // Remove the first node because it's exactly where we're standing path.RemoveAt(0); // Move as far as we can toward the target, limited by our move range. var moveRange = _self.GetAttribute(Attribute.AttributeType.Move).Value; var maxPathLength = Math.Min(moveRange, path.Count); path = path.GetRange(0, maxPathLength); var destination = path[path.Count - 1]; var moveAction = new MoveAction(map, _self, destination, path); if (!IsInAttackRange(destination, _target, weapon, map)) { return(new List <ICombatAction> { moveAction }); } var skill = weapon.Range > 1 ? SkillType.Ranged : SkillType.Melee; var forecast = battle.ForecastFight(_self, _target, skill); var finalized = battle.FinalizeFight(forecast); return(new List <ICombatAction> { moveAction, new FightAction(finalized) }); } // There's no path to the target, so do nothing for now. return(new List <ICombatAction>()); } // Find a new target and restart var potentials = map.FindSurroundingPoints(_self.Position, _aggroRadius) .Select(pos => map.GetAtPosition(pos)) .Where(combatant => combatant != null && combatant.Army != _self.Army) .ToList(); // If there's nothing on the field to attack do nothing. if (!potentials.Any()) { return(new List <ICombatAction>()); } _target = potentials.OrderBy(target => { var path = map.FindPathToAdjacentTile(_self.Position, target.Position, PathfindingUtils.GetCombatantTileFilter(_self)); return(path == null ? int.MaxValue : path.Count); }) .First(); return(ComputeActions(battle)); }