From d6f2f6651e804e2696153b58efe6723497b9e338 Mon Sep 17 00:00:00 2001 From: Zachary Love Date: Wed, 11 May 2022 15:37:45 -0400 Subject: [PATCH] Moved spell info to spell.ts, moved shared references and utilities to util.ts, added more spell info & comments, added tsconfig --- .gitignore | 3 +- interfaces/index.ts | 202 ++++++-------------------------------------- interfaces/spell.ts | 120 ++++++++++++++++++++++++++ interfaces/util.ts | 128 ++++++++++++++++++++++++++++ tsconfig.json | 27 ++++++ 5 files changed, 304 insertions(+), 176 deletions(-) create mode 100644 interfaces/spell.ts create mode 100644 interfaces/util.ts create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore index 40b878d..1faaeab 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -node_modules/ \ No newline at end of file +node_modules/ +.vscode/settings.json diff --git a/interfaces/index.ts b/interfaces/index.ts index f22aed3..3e2145b 100644 --- a/interfaces/index.ts +++ b/interfaces/index.ts @@ -1,90 +1,8 @@ -const ABILITIES = ["str", "dex", "con", "int", "wis", "cha"] as const; +import * as util from './util'; +import * as spell from './spell'; -const SKILLS = [ - "acrobatics", - "animal handling", - "arcana", - "athletics", - "deception", - "history", - "insight", - "intimidation", - "investigation", - "medicine", - "nature", - "perception", - "performance", - "persuasion", - "religion", - "sleight of Hand", - "stealth", - "survival", -] as const; -const SIZES = [ - "tiny", - "small", - "medium", - "large", - "huge", - "gargantuan", -] as const; -const ALIGNMENTS = [ - "lawful good", - "neutral good", - "chaotic good", - "lawful neutral", - "true neutral", - "chaotic neutral", - "lawful evil", - "neutral evil", - "chaotic evil", -] as const; - -const DAMAGE_TYPES = [ - "piercing", - "slashing", - "bludgeoning", - "acid", - "cold", - "fire", - "force", - "lightning", - "necrotic", - "posion", - "psychic", - "radiant", - "thunder", -] as const; - -const CONDITIONS = [ - "blinded", - "charmed", - "deafened", - "exhaustion", - "frightened", - "grappled", - "incapacitated", - "invisible", - "necrotic", - "paralyzed", - "petrified", - "poisoned", - "prone", - "restrained", - "stunned", - "unconscious", -] as const; - -const SENSES = [ - "blindsight", - "darkvision", - "tremorsense", - "truesight", -] as const; - -const SPELL_COMPONENTS = ["v", "s", "m"] as const; export interface FirestoreDoc { ref: any; @@ -131,7 +49,7 @@ export interface Creature { /** The name of the creature */ name: string; /** The creature's current size */ - size: typeof SIZES[number]; + size: typeof util.SIZES[number]; /** The creature's current speeds */ speed: { /** The basic speed show on the character sheet */ @@ -143,7 +61,7 @@ export interface Creature { }; /** The creature's ability scores */ abilityScores: { - [ability in typeof ABILITIES[number]]: number; + [ability in typeof util.ABILITIES[number]]: number; }; /** The creature's hitpoint info */ hitPoints: { @@ -158,34 +76,34 @@ export interface Creature { passivePerception: number; /** The creature's skill values (taking into consideration proficiencies, expertises, etc.) */ skills: { - [skill in typeof SKILLS[number]]: number; + [skill in typeof util.SKILLS[number]]: number; }; /** List of skills the creature is proficient in */ - skillProficiencies: typeof SKILLS[number][]; + skillProficiencies: typeof util.SKILLS[number][]; /** List of skills the creature has expertise in */ - skillExpertises: typeof SKILLS[number][]; + skillExpertises: typeof util.SKILLS[number][]; /** The creature's saving throw modifiers (taking into consideration proficiencies, etc.) */ savingThrows: { - [ability in typeof ABILITIES[number]]: number; + [ability in typeof util.ABILITIES[number]]: number; }; /** The saving throws the creature is proficient in */ - savingThrowProficiencies: typeof ABILITIES[number][]; + savingThrowProficiencies: typeof util.ABILITIES[number][]; /** The creature's understood languages */ languages: string[]; /** The special senses the creature has and their ranges in feet (https://www.dndbeyond.com/sources/basic-rules/monsters#Senses) */ senses: { - [sense in typeof SENSES[number]]: number; + [sense in typeof util.SENSES[number]]: number; }; /** The creature's current conditions */ - conditions: typeof CONDITIONS[number][]; + conditions: typeof util.CONDITIONS[number][]; /** List of conditions the creature is immune to */ - conditionImmunities: typeof CONDITIONS[number][]; + conditionImmunities: typeof util.CONDITIONS[number][]; /** List of damage types the creature is immune to */ - damageImmunities: typeof DAMAGE_TYPES[number][]; + damageImmunities: typeof util.DAMAGE_TYPES[number][]; /** List of damage types the creature has resistance to */ - damageResistances: typeof DAMAGE_TYPES[number][]; + damageResistances: typeof util.DAMAGE_TYPES[number][]; /** List of damage types the creature is vulnerable to */ - damageVulnerabilities: typeof DAMAGE_TYPES[number][]; + damageVulnerabilities: typeof util.DAMAGE_TYPES[number][]; /** The creature's tags (https://www.dndbeyond.com/sources/basic-rules/monsters#Tags) */ tags: string[]; } @@ -200,7 +118,7 @@ export interface Character extends Creature { /** The character's class(es) */ classes: Class[]; /** The character's moral alignment */ - alignment: typeof ALIGNMENTS[number]; + alignment: typeof util.ALIGNMENTS[number]; /** The character's current proficiency bonus */ proficiencyBonus: number; /** Whether the character is currently inspired */ @@ -234,12 +152,12 @@ export interface Character extends Creature { backstory: string; }; /** The character's feats */ - feats: Feat[]; + feats: spell.Feat[]; weaponProficiencies: string[]; armorProficiencies: string[]; toolProficiencies: string[]; /** The character's current spells */ - spells?: Spell[]; + spells?: spell.Spell[]; /** The character's weapons (equipped and not) */ weapons: Weapon[]; /** The character's currently equipped items */ @@ -254,6 +172,12 @@ export interface Character extends Creature { }; } + +export interface Source { + name: string; + pages: number[]; +} + export interface Race { name: string; subtype?: string; @@ -262,7 +186,7 @@ export interface Race { export interface Class { name: string; - spellcastingAbility?: typeof ABILITIES[number]; + spellcastingAbility?: typeof util.ABILITIES[number]; /** The classes current level */ level: number; source?: Source; @@ -280,7 +204,7 @@ export interface Weapon extends Item { category: string; damage: { diceRoll: DiceRoll; - type: typeof DAMAGE_TYPES[number]; + type: typeof util.DAMAGE_TYPES[number]; }; range: Range; throwRange: Range; @@ -296,80 +220,8 @@ export interface DiceRoll { modifier: number; } -export interface Range { - normal: number; - long: number; -} + export interface Equipment extends Item { quantity: number; } - -export interface Feat { - name: string; - description: string; - source?: Source; -} - -export interface SpellDuration { - type: "timed" | "instant"; - duration?: { - type: "round" | "hour" | "day"; - amount: number; - }; - /** When the spell ends */ - ends?: string[]; - concentration?: boolean; -} - -export interface SpellRange { - type: "point" | "cone" | "cube" | "cylinder" | "line" | "sphere"; - distance: { - type: "self" | "feet" | "touch"; - amount?: number; - }; -} - -export interface Spell { - name: string; - /** Description of spell and effects */ - entries: string[]; - /** Spell level where 0 means cantrip */ - level: number; - /** How long it takes to cast the spell */ - time: { - number: number; - unit: "action" | "bonus" | "reaction" | "minute"; - }[]; - /** How far you can cast the spell */ - range: SpellRange; - /** Required components to cast the spell */ - components: { - [component in typeof SPELL_COMPONENTS[number]]: - | boolean - | { - text: string; - cost: number; - }; - }; - /** Duration of spell effect */ - duration: SpellDuration[]; - meta?: { - ritual?: boolean; - }; - school: string; // TODO: list out schools - /** The possible damage types the spell inflicts */ - damageInflict: typeof DAMAGE_TYPES[number][]; - /** The possible conditions the spell inflicts */ - conditionInflict: typeof CONDITIONS[number][]; - /** The possible saving throws the target has to roll */ - savingThrow: typeof ABILITIES[number][]; - spellAttack: string[]; - tags: string[]; - source?: Source; -} - -export interface Source { - name: string; - pages: number[]; -} diff --git a/interfaces/spell.ts b/interfaces/spell.ts new file mode 100644 index 0000000..9364e41 --- /dev/null +++ b/interfaces/spell.ts @@ -0,0 +1,120 @@ +import * as util from './util'; + + +export interface Feat { + name: string; + description: string; + source?: Source; +} +/* Components required to cast spell +Verbal (V): Chanting of words, any non-silenced characters can cast +Somatic (S): Gestures, must have a free hand to cast +Material (M): Required objects. Can use Component Pouch or + Spellcasting focus as replacement. Must have free hand + to access materials. +*/ +const SPELL_COMPONENTS = ["v", "s", "m"] as const; + + +/* Spell Duration + - The length of time that the spell persists. + - The effects of some spells persist until dispelled or destroyed. +*/ +export interface SpellDuration { + type: "timed" | "instant"; + duration?: { + type: "round" | "hour" | "day"; + amount: number; + }; + /** When the spell ends */ + ends?: string[]; + concentration?: boolean; +} + +/* Spell Range + - Some spells have an effective range, and cannot be cast + too far away or too close to the target. +*/ +export interface SpellRange { + type: "point" | "cone" | "cube" | "cylinder" | "line" | "sphere"; + distance: { + type: "self" | "feet" | "touch"; + amount?: number; + }; +} +/* Magic Schools + - Spells are grouped into eight schools, which help describe their function +*/ +const MAGIC_SCHOOL = [ + "abjuration", + "conjuration", + "divination", + "enchantment", + "evocation", + "illusion", + "necromancy", + "transmutation" +] + + +/* Spell */ +export interface Spell { + name: string; + /** Description of spell and effects */ + entries: string[]; + /* How powerful a spell is, from 0 (cantrip) to 9 */ + level: number; + /* How many spell slots the spell requires + - Dictionary of form {slot level, # slots required} + - Spells have a minimum slot requirement + - Some spells can be cast at higher levels for bonus effect(s) + */ + spellSlots: { + 1: number; + 2: number, + 3: number, + 4: number, + 5: number, + 6: number, + 7: number, + 8: number, + 9: number, + } + /** How long it takes to cast the spell */ + time: { + number: number; + unit: "action" | "bonus" | "reaction" | "minute"; + }[]; + /** How far you can cast the spell */ + range: SpellRange; + /** Required components to cast the spell */ + components: { + [component in typeof SPELL_COMPONENTS[number]]: + | boolean + | { + text: string; + cost: number; + }; + }; + /** Duration of spell effect */ + duration: SpellDuration[]; + meta?: { + ritual?: boolean; + }; + /* The school of magic the spell belongs to */ + school: typeof MAGIC_SCHOOL; + /** The possible damage types the spell inflicts */ + damageInflict: typeof util.DAMAGE_TYPES[number][]; + /** The possible conditions the spell inflicts */ + conditionInflict: typeof util.CONDITIONS[number][]; + /** The possible saving throws the target has to roll */ + savingThrow: typeof util.ABILITIES[number][]; + spellAttack: string[]; + tags: string[]; + source?: Source; +} + +export interface Source { + name: string; + pages: number[]; +} diff --git a/interfaces/util.ts b/interfaces/util.ts new file mode 100644 index 0000000..67bfcbd --- /dev/null +++ b/interfaces/util.ts @@ -0,0 +1,128 @@ + +/* The basic stats for characters/creatures */ +export const ABILITIES = ["str", "dex", "con", "int", "wis", "cha"] as const; + +/* Skills + - Each associated ability is marked as a comment next to its corresponding skill +*/ +export const SKILLS = [ + "acrobatics", // DEX + "animal handling", // WIS + "arcana", // INT + "athletics", // STR + "deception", // CHR + "history", // INT + "insight", // WIS + "intimidation", // CHR + "investigation", // INT + "medicine", // WIS + "nature", // INT + "perception", // WIS + "performance", // CHR + "persuasion", // CHR + "religion", // INT + "sleight of Hand", // DEX + "stealth", // DEX + "survival", // WIS +] as const; + + +/* Types of damage that can be inflicted */ +export const DAMAGE_TYPES = [ + "piercing", // Sharp object (e.g, spear or arrow) + "slashing", // Cut or gash (e.g, blades) + "bludgeoning", // Blunt damage (e.g, club or mace) + "acid", // Corrosive damage, causes burning and stinging, sometimes burns through materials + "cold", // Frigid pain/numbness caused by subzero temperatures + "fire", // Heat damage from exposure to high temperatures + "force", // Magic energy, moves at high velocity, pushes targets away + "lightning", // Damage from high voltage of electricity + "necrotic", // Damage to life force, involves death/decay/corruption + "poison", // Toxic damage from poisonous/venomous substances entering the body + "psychic", // Damage dealt to mind through telepathic abilities + "radiant", // Holy damage, usually related to a god or celestial object + "thunder", // Percussive noise, loud enough to cause damage +] as const; + +/* Status effects that can be inflicted */ +export const CONDITIONS = [ + "blinded", + "charmed", + "deafened", + "exhaustion", + "frightened", + "grappled", + "incapacitated", + "invisible", + "necrotic", + "paralyzed", + "petrified", + "poisoned", + "prone", + "restrained", + "stunned", + "unconscious", +] as const; + +/* Types of sights that a creature may have */ +export const SENSES = [ + "blindsight", + "darkvision", + "tremorsense", + "truesight", +] as const; + +/* +Resistance, Vulnerability, and Immunity for the target of an attack + - Dictionary of the form {interaction, modifier} + - The damage of the attack is multiplied by the modifier +*/ +export const DAMAGE_INTERACTIONS = { + "resistance": 0.5, + "vulnerability": 2, + "immunity": 0 +} + +/* Alignments for characters and creatures + - Determines behavior and moral compass +*/ +export const ALIGNMENTS = [ + "lawful good", + "neutral good", + "chaotic good", + "lawful neutral", + "true neutral", + "chaotic neutral", + "lawful evil", + "neutral evil", + "chaotic evil", +] as const; + + +/* Sizes for characters and creatures +Tiny: 2.5 x 2.5ft approx. space, 1d4 hit die, 2.5 avg HP/die +Small: 5 x 5ft approx. space, 1d6 hit die, 3.5 avg HP/die +Medium: 5 x 5ft approx. space, 1d8 hit die, 4.5 avg HP/die +Large: 10 x 10ft approx. space, 1d10 hit die, 5.5 avg HP/die +Huge: 15 x 15ft approx. space, 1d12 hit die, 6.5 avg HP/die +Gargantuan: 20 x 20ft approx. space, 1d20 hit die, 10.5 avg HP/die +*/ +export const SIZES = [ + "tiny", + "small", + "medium", + "large", + "huge", + "gargantuan", +] as const; + + +/* The effective range of an action + - 0 to normal range: standard attack + - normal range to long range: attack with disadvantage + - Cannot attack beyond long range +*/ +export interface Range { + normal: number; + long: number; + } \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..281416e --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx" + }, + "include": [ + "interfaces" + ] + } + \ No newline at end of file