All files / src/oath index.ts

100% Statements 24/24
100% Branches 9/9
100% Functions 4/4
100% Lines 24/24

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 791x 1x   1x     1x                           1x 25x   70x   24x   23x   22x   1x         24x       1x                             1x 26x   51x   12x   13x   13x   12x   1x             1x 1x 1x  
import { Fraction, RandomDevice } from "../math";
import { AttackDieFace } from "./AttackDieFace";
import { AttackResult, DefenseResult } from "./CampaignResult";
import { DefenseDieFace } from "./DefenseDieFace";
 
/** The Oath attack (red) die. */
export const AttackDie = new RandomDevice<AttackDieFace>([
  [AttackDieFace.HOLLOW_SWORD, new Fraction(3, 6)],
  [AttackDieFace.SWORD, new Fraction(2, 6)],
  [AttackDieFace.TWO_SWORDS_AND_SKULL, new Fraction(1, 6)],
]);
 
/**
 * Sums up a set of attack die faces into an attack roll result.
 *
 * @param {DieFace[]} faces
 *   A set of attack die faces.
 * @returns {CampaignResult}
 *   The attack roll result after adding all die faces.
 */
export function toAttackResult(faces: AttackDieFace[]): AttackResult {
  const raw = faces.sort().reduce(
    (acc: AttackResult, face: AttackDieFace) => {
      switch (face) {
        case AttackDieFace.HOLLOW_SWORD:
          return { ...acc, attack: acc.attack + 0.5 };
        case AttackDieFace.SWORD:
          return { ...acc, attack: acc.attack + 1 };
        case AttackDieFace.TWO_SWORDS_AND_SKULL:
          return { ...acc, attack: acc.attack + 2, kill: acc.kill + 1 };
        default:
          throw new Error(`Unknown die face ${face}`);
      }
    },
    { attack: 0, kill: 0 }
  );
  return { ...raw, attack: Math.floor(raw.attack) };
}
 
/** The Oath defense (blue) die. */
export const DefenseDie = new RandomDevice<DefenseDieFace>([
  [DefenseDieFace.BLANK, new Fraction(2, 6)],
  [DefenseDieFace.SHIELD, new Fraction(2, 6)],
  [DefenseDieFace.TWO_SHIELDS, new Fraction(1, 6)],
  [DefenseDieFace.DOUBLE, new Fraction(1, 6)],
]);
 
/**
 * Sums up a set of defense die faces into a defense roll result.
 *
 * @param {DieFace[]} faces
 *   A set of defense die faces.
 * @returns {CampaignResult}
 *   The defense roll result after adding all die faces.
 */
export function toDefenseResult(faces: DefenseDieFace[]): DefenseResult {
  return faces.sort().reduce(
    (acc: DefenseResult, face: DefenseDieFace) => {
      switch (face) {
        case DefenseDieFace.BLANK:
          return acc;
        case DefenseDieFace.SHIELD:
          return { ...acc, defense: acc.defense + 1 };
        case DefenseDieFace.TWO_SHIELDS:
          return { ...acc, defense: acc.defense + 2 };
        case DefenseDieFace.DOUBLE:
          return { ...acc, defense: acc.defense * 2 };
        default:
          throw new Error(`Unknown die face ${face}`);
      }
    },
    { defense: 0 }
  );
}
 
export * from "./AttackDieFace";
export * from "./CampaignResult";
export * from "./DefenseDieFace";