public override AttackLog DealDamage(IAttackable target) { if (!this.CanAttack()) { return(AttackLog.AttackFailed); } if (target.IsAlive) { SkillDamage attackPower; AttackLog result; if (RandomGenerator.GetRandomValue(0, 100) % 2 == 0) { var specialSkills = this.AvailableSkills.Where(x => !(x is BasicAttack) && !(x is CriticalStrike)).ToList(); var skillToUse = specialSkills[RandomGenerator.GetRandomValue(0, specialSkills.Count)]; var appliesStatusEffect = skillToUse as IAppliesStatusEffect; if (appliesStatusEffect != null) { target.AddStatusEffect(appliesStatusEffect.ApplyEffect()); } attackPower = skillToUse.DealDamage(this.AttackDamage); result = target.TakeDamage(attackPower); result.AttackDetails = string.Format("{0} applies {1} on {2}", this.Name, skillToUse.Name, result.AttackDetails); } else { if (RandomGenerator.GetRandomValue(0, 101) <= this.CriticalStrikeChance) { attackPower = this.AvailableSkills["critical strike"].DealDamage(this.AttackDamage); result = target.TakeDamage(attackPower); result.AttackDetails = String.Format("{0} scores a critical strike on {1}", this.Name, result.AttackDetails); } else { attackPower = this.AvailableSkills["basic attack"].DealDamage(this.AttackDamage); result = target.TakeDamage(attackPower); result.AttackDetails = String.Format("{0} attacks {1}", this.Name, result.AttackDetails); } } return(result); } else { return(AttackLog.AttackFailed); } }