コード例 #1
0
        public void BurningHands()
        {
            // Let's create a smart sorcerer first:
            var sorcerer = new Character {
                Int = 16, BurningHandsSpellLevel = 1
            };
            // Then let's create a provider for a modifier derived from the sorcerer's Intelligence:
            var intMod = new IntModProvider {
                Character = sorcerer
            };
            // Create a provider for a spell damage dice count, which depends on the sorcerer's current spell level.
            var spellDiceCount = new BurningHandsDiceCountProvider {
                Character = sorcerer
            };

            // Merge these into a chain:
            DiceChain damageDice = Dice.Take(spellDiceCount).D(8).EachPlus(intMod);
            // Let's burn some poor fella:
            double damage = damageDice.Roll();

            // Let's say we want to display the spell damage, so check the dice chain stats:
            Trace.WriteLine("Damage: " + damageDice.Minimum + " to " + damageDice.Maximum);
            // Outputs 'Damage: 4 to 11', which is equal to '1d8+3', looks good.

            // What if sorcerer gains two levels of proficiency in the spell?
            sorcerer.BurningHandsSpellLevel += 2;
            Console.WriteLine("Damage: " + damageDice.Minimum + " to " + damageDice.Maximum);
            // Outputs 'Damage: 8 to 22', which is equal to '2d8(+3)', once again looks good.
            // Parens mean that 3 is apllied to each die separately instead of affecting dice sum.


            // Now let's say when you miss an enemy with burning hands, you still can deal some damage.
            // In this case damage dealt to the target equals to sum of each damage die that rolled its maximum result.
            // Normally you don't want to deal with individual roll values when using dice chain,
            // but there is a method just in case:

            List <DiceChainRollStep> rollParts;

            // Normal hit damage is returned by dice chain as usual:
            damage = damageDice.RollStepByStep(out rollParts);
            // Damage on a miss is calculated as a sum of each damage die that rolled its maximum result.
            // Looking at dice chain 'Xd8+Y' we can see that damage dice are rolled in the first (leftmost) step.
            double missedDamage = rollParts[0].Rolls.Where(roll => roll == Dice.D8.Maximum).Sum();


            // For the sake of completeness, there is a way of achieving the same thing without a dice chain.
            // That way we have to do all calculations manually.
            // Let's bundle D8 with spell damage dice count:
            var rawSpellDamage = new SeveralDice(Dice.D8, spellDiceCount);
            // Make a damage roll, rolling each die separately:
            var rawRolls = rawSpellDamage.RollSeparately().ToArray();

            // .ToArray() is important here. Otherwise different roll values would be generated on each enumeration.
            // Damage on a miss:
            missedDamage = rawRolls.Where(roll => roll == Dice.D8.Maximum).Sum();
            // Damage on a hit:
            damage = rawRolls.Select(roll => roll + intMod.Roll()).Sum();
        }
コード例 #2
0
ファイル: DiceChainLink.cs プロジェクト: EnoughTea/natural20
        /// <summary> Initializes a new instance of the <see cref="DiceChainLink" /> class. </summary>
        /// <param name="operation">The dice operation which will be used with a dice chain node.</param>
        /// <param name="node">This dice chain node.</param>
        /// <param name="previous">The link to previous node in the dice chain.</param>
        internal DiceChainLink(DiceOperation operation, SeveralDice node, DiceChainLink previous)
        {
            Contract.Requires(operation != DiceOperation.None);
            Contract.Requires(node != null);

            Operation = operation;
            Node      = node;
            Previous  = previous;
        }
コード例 #3
0
ファイル: DiceChainLink.cs プロジェクト: EnoughTea/natural20
        /// <summary> Initializes a new instance of the <see cref="DiceChainLink" /> class. </summary>
        /// <param name="operation">The dice operation which will be used with a dice chain node.</param>
        /// <param name="node">This dice chain node.</param>
        /// <param name="previous">The link to previous node in the dice chain.</param>
        internal DiceChainLink(DiceOperation operation, SeveralDice node, DiceChainLink previous)
        {
            Contract.Requires(operation != DiceOperation.None);
            Contract.Requires(node != null);

            Operation = operation;
            Node = node;
            Previous = previous;
        }
コード例 #4
0
        public void EntryLevel()
        {
            // Roll a standard cubic die one time:
            var d6   = new Die(6);
            var roll = d6.Roll();

            // Roll an interval die from 10 to 20 four times:
            var interval10t20 = new Die(10, 20);

            roll = interval10t20.Roll(4).Sum();

            // There is also a fixed die, which always returns the same value.
            // It's useful when something expects IDie as value provider and you want to pass a constant value:
            var fixed50 = new FixedDie(50);

            // Roll two d10's:
            var d2d10 = new SeveralDice(Dice.D10, 2);

            roll = d2d10.Roll(); // Compared to simple Dice.D10.Roll(2), SeveralDice provides statistics and serialization
            Console.WriteLine("Possible roll value range: " + d2d10.Minimum + " to " + d2d10.Maximum);

            // Roll a d4d10 / d2 * 3:
            var d4d10divD2mul3 = Dice.Take(Dice.D4).D(10).Divide(Dice.D2).Multiply(3);  // This is a dice chain.

            // Math operations in dice chains are always executed from left to right, so this chain translates to:
            // take a 1-4 of d10 dice and divide their roll value by 2 with 50 % chance, then multiply resulting roll value by 3.
            roll = d4d10divD2mul3.Roll();
            // Dice chains also provide statistics and serialization.

            // This chain was created via fluent interface, but it is also possible to create such chain in a more explicit way:
            d4d10divD2mul3 = new DiceChain(
                new SeveralDice(new Die(10), new Die(4)))                         // d4d10
                             .Append(DiceOperation.Divide, new SeveralDice(2))    // / 2
                             .Append(DiceOperation.Multiply, new SeveralDice(3)); // * 3

            // Oh, and where is a random number generator? Built-in dice get it from thread-local `Dice.Random`.
        }
コード例 #5
0
ファイル: DiceChainLink.cs プロジェクト: EnoughTea/natural20
 /// <summary> Initializes a new instance of the <see cref="DiceChainLink" /> class. </summary>
 /// <param name="operation">The dice operation which will be used with a dice chain node.</param>
 /// <param name="node">This dice chain node.</param>
 internal DiceChainLink(DiceOperation operation, SeveralDice node)
     : this(operation, node, null)
 {
     Contract.Requires(operation != DiceOperation.None);
     Contract.Requires(node != null);
 }
コード例 #6
0
ファイル: DiceChainLink.cs プロジェクト: EnoughTea/natural20
 /// <summary> Initializes a new instance of the <see cref="DiceChainLink" /> class. </summary>
 /// <param name="operation">The dice operation which will be used with a dice chain node.</param>
 /// <param name="node">This dice chain node.</param>
 internal DiceChainLink(DiceOperation operation, SeveralDice node)
     : this(operation, node, null)
 {
     Contract.Requires(operation != DiceOperation.None);
     Contract.Requires(node != null);
 }