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);
        }
Exemple #2
0
        //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;
        }