static internal AttackResult DeliverAttack(AttackDelivery attackMessage) { // Check for valid message if (attackMessage.DamageDice == null || attackMessage.Target == null || attackMessage.Attacker == null) { throw new ArgumentNullException("AttackDelivery message missing required information"); } ICombatant target = attackMessage.Target; DefenseDelivery defense = target.Defend(); // Compute attack result data // AC = 10 + armor bonus + shield bonus + Dexterity modifier + size modifier // http://www.dandwiki.com/wiki/SRD:Armor_Class int AC = 10 + defense.ArmorBonus + defense.ShieldBonus + defense.DexterityModifier + defense.SizeModifier; AttackResult attackResult = TryToHit(AC, attackMessage.ToHitModifier); DamageResult damageResult; if (attackResult.Hit || attackResult.Critical) { damageResult = RollDamage(attackMessage.DamageDice, attackMessage.DamageModifiers, attackResult.Critical); } else { damageResult = new DamageResult(); damageResult.DamageDealt = new KeyValuePair <DamageType, int> [0]; } damageResult.AttackResult = attackResult; damageResult.Attacker = attackMessage.Attacker; // Determine if blow was strong enough to knock target unconcious (for now, more than half their max HP) if (attackMessage.CombatType == CombatType.Melee) { foreach (var damagePair in damageResult.DamageDealt) { if (damagePair.Key == DamageType.Bludgeoning && damagePair.Value > target.Max_HP / 2) { // For now, you get a 25% chance of being knocked out if damage exceeds half your max. // TODO: Research better calculation for KO savings throw. damageResult.KnockedUnconcious = (Utility.Rand.Next(4) == 0); break; } } } target.TakeDamage(damageResult); return(attackResult); }
//TODO this believes that all attacks are of the same type public void Attack(ICombatant target, Enumerations.DamageType damageType) { var dice = new Enumerations.AttackDie[attackDice]; var set = new int[6] { 0, 0, 1, 1, 2, 3 }; print("Attacking"); for (var i = 0; i < attackDice; i++) { var j = set[Utilities.RollDice(1) - 1]; dice[i] = (Enumerations.AttackDie)j; print("Attack die " + i + ":" + dice[i]); } target.Defend(dice, damageType, this); _attackedThisTurn = true; }