foundryvtt / dnd5e

An implementation of the 5th Edition game system for Foundry Virtual Tabletop (http://foundryvtt.com).
MIT License
288 stars 195 forks source link

Add a Race item type which functions similarly to the Class item #342

Closed aaclayton closed 8 months ago

aaclayton commented 4 years ago

Basic Goals

Status

This is not a priority in the short term - but something that should be added to the system eventually to provide for better automation in character creation.

Progress

aaclayton commented 3 years ago

Shifting by group decision to %"D&D5E 1.3.1 - Continued Work on Level-Up" or later

aaclayton commented 3 years ago

Originally in GitLab by @iaguastalli

I'm working with other folk on a module mimicking Roll20's Charactermancer and we have a Race class model that would be nice to align with whatever the Race item on foundry ends up been, as it would ease mapping and there could be some bidirectional feedback. This is the current structure (pardon the Typescript)

Values were mostly geared towards first-level automation, but I've been pondering options for races that get features later on (like the many races with 3rd level spells) and variant features.

class Race {
    name: string;
    item: any = null; // we are keeping a reference to the Compendium item here, for adding it to Actors
    parentRace?: Race; // if this is a subclass, this holds the main e.g High Elf has an Elf reference here

    abilityScoreImprovements: {
        str?: { bonus: number },
        dex?: { bonus: number },
        con?: { bonus: number },
        int?: { bonus: number },
        wis?: { bonus: number },
        cha?: { bonus: number },
        any?: { bonus: number[] } // array for things like Half Elf with their two +1's
    } = {};

    type?: CreatureType = CreatureType.Humanoid;
    size?: Size = Size.Medium;
    hp?: { bonus: number } // this might go, but was added geared towards Hill Dwarves and Draconic Sorcerers (we expect to have a similar class for Classes)
    darkvision: number = 0;

    movement: {
        walk?: number,
        burrow?: number,
        climb?: number,
        fly?: number,
        swim?: number,
        hover?: boolean
    } = { walk: 30 };

    proficiencies: {
        skills?: {
            fixed?: Skill[], // any proficiencies that the race always has
            any?: number, // any number of free skill proficiencies (e.g. pick any three skills..)
            choose?: { // number and options when you can pick some number of skills between a subset
                quantity: number,
                options: Skill[]
            }
        },
        weapons?: { // weapon and armor might need some love to make more sense
            fixed?: WeaponType[] | string[],
            any?: number,
            choose?: string[] // free input
        },
        armor?: {
            fixed?: ArmorType[] | string[],
            any?: number,
            choose?: string[]
        },
        languages?: {
            fixed?: Language[],
            any?: number,
            choose?: {
                quantity: number,
                options: Language[]
            }
        },
        tools?: {
            fixed?: Tool[] | string[],
            any?: number,
            choose?: {
                quantity: number,
                options: Tool[] | string[]
            }
        }
    } = { languages: { fixed: [Language.common] } }

    damage: {
        immunities?: {
            fixed?: DamageType[],
            any?: number,
            choose?: {
                quantity: number,
                options: DamageType[]
            }
        },
        resistances?: {
            fixed?: DamageType[],
            any?: number,
            choose?: {
                quantity: number,
                options: DamageType[]
            }
        },
        vulnerabilities?: {
            fixed?: DamageType[],
            any?: number,
            choose?: {
                quantity: number,
                options: DamageType[]
            }
        }
    } = {}

    condition: {
        immunities?: {
            fixed?: Condition[],
            any?: number,
            choose?: {
                quantity: number,
                options: Condition[]
            }
        },
        advantage?: {
            fixed?: Condition[],
            any?: number,
            choose?: {
                quantity: number,
                options: Condition[]
            }
        }
    } = {}

    constructor(raceName: string, subraceOf: Race, compendium: Entity<Entity.Data>[]) {
        this.name = raceName;
        this.parentRace = subraceOf;
        this.item = Utils.getItemFromCompendiumByName(compendium, raceName);
    }
}

this would have somewhere to be added a set of Items with the features to be added into the Actor.

aaclayton commented 3 years ago

Originally in GitLab by @arbron

I've added the work I've done so far to !257 for @aaclayton and everyone else to check out and see if that is the direction we want to go with this item.

aaclayton commented 3 years ago

Originally in GitLab by @akrigline

Little confused about the assignment here @aaclayton, looks like @arbron is working on this but also looks like you've taken it too.

aaclayton commented 3 years ago

Originally in GitLab by @arbron

I've been working on this one.

aaclayton commented 3 years ago

Originally in GitLab by @akrigline

Marked Breaking because it involves changing some things about Actors.

aaclayton commented 3 years ago

Originally in GitLab by @arbron

I've written up some of my thoughts on the design of the Race Item here: raceDataModel.md. The basic template structure is here:

"race": {
  "templates": ["itemDescription"],
  "speed": 30,
  "size": "med",
  "type": "humanoid",
  "abilityScores": {
    "default": {},
    "additional": 0,
    "selected": []
  },
  "languages": {
    "default": [],
    "additional": 0,
    "selected": []
  }
}

The abilityScores default object would be formatted like: {"str": 2, "dex": 1} to indicate the which scores are improved by what amount.

aaclayton commented 3 years ago

Comment from @iaguastalli

Right now Races being "simple" items makes it hard to work with them programmatically, for example, there's no clear way of distinguishing High Elf from Fey Ancestry.

Something I mentioned on another issue that could also be part of this feature request is that other things defined by the race (languages, some tool/weapon/armor proficiencies, condition and damage resistances/immunities/vulnerabilities, etc) could also be part of that extra metadata.

MaxPat931 commented 2 years ago

Just want to mention that in addition to Item Grant, Races should also allow for Scale Value advancements, this could be used for Dragonborn Breath Weapons, or as a workaround for any homebrew a DM wants to scale off of total character level instead of class level

krbz999 commented 1 year ago

Characters should be prevented from adding a 2nd race-type item to enforce that only one is chosen.

I don't see any reason to enforce this. If a table wants to have multi-race characters for some reason, it'd be much better to be able to drag an additional Race item to the sheet rather than having to create a new race which is a mix of the two. Characters can already add multiple Background items, this would be identical.