Skip to content

Instantly share code, notes, and snippets.

@elyukai
Last active January 29, 2021 13:57
Show Gist options
  • Save elyukai/6321bc6b90ad6b248c0806a7bc287264 to your computer and use it in GitHub Desktop.
Save elyukai/6321bc6b90ad6b248c0806a7bc287264 to your computer and use it in GitHub Desktop.
Unified hero schema proposal with numeric IDs for Optolith
type Hero = {
/**
* The name of the hero.
*/
name: string
/**
* The date of creation.
*/
dateCreated: string
/**
* The date of last modification.
*/
dateModified: string
/**
* The amount of total AP.
*/
ap: {
total: number
// - Verbrauchte AP ins JSON
}
/**
* The selected experience level's ID.
*/
experienceLevelId: number
/**
* The creation phase. `1` is RCP selection, `2` standard hero creation and
* `3` after hero creation.
*/
phaseId: 1 | 2 | 3
/**
* The selected race's (and race variant's) ID.
*/
raceId?: number | [number, number]
/**
* The selected culture's ID.
*/
cultureId?: number
/**
* Has the cultural package been activated?
*/
isCulturalPackageActive: boolean
/**
* The selected profession's (and profession variant's) ID.
*/
professionId?: number | [number, number]
/**
* The changed profession name for a Custom Profession.
*/
professionName?: string
/**
* Rules defined for the hero.
*/
rules: Rules
/**
* Personal data
*/
personalData: PersonalData
/**
* A set of active advantages and their options.
*/
advantages: ActiveAdvantage[]
/**
* A set of active disadvantages and their options.
*/
disadvantages: ActiveDisadvantage[]
/**
* A set of active special abilities and their options.
*/
specialAbilities: ActiveSpecialAbility[]
/**
* A set of attributes with values above `8`.
*/
attributes: EntryWithValue[]
/**
* The attribute you selected for your race modifier.
*/
attributeAdjustmentIdSelected: number
/**
* Additions and permanent loss of LP/AE/KP.
*/
energies: Energies
// - Abgeleitete Werte (LP, AE, KE, INI, GS, ...) ins JSON
/**
* A set of skills and their skill ratings.
*/
skills: EntryWithValue[]
/**
* A set of combat techniques and their combat technique ratings.
*/
combatTechniques: EntryWithValue[]
/**
* A set of active spells/rituals and their skill ratings.
*/
spells: EntryWithValue[]
/**
* A set of active curses and their skill ratings.
*/
curses: EntryWithValue[]
/**
* A set of active Elven magical songs and their skill ratings.
*/
elvenMagicalSongs: EntryWithValue[]
/**
* A set of active domination rituals and their skill ratings.
*/
dominationRituals: EntryWithValue[]
/**
* A set of active magical dances and their skill ratings.
*/
magicalDances: EntryWithValue[]
/**
* A set of active magical melodies and their skill ratings.
*/
magicalMelodies: EntryWithValue[]
// Unclear which translations will be used for the following
// commented magical actions:
// /**
// * A set of active jester spells and their skill ratings.
// */
// jesterSpells: EntryWithValue[]
// /**
// * A set of active animist rituals and their skill ratings.
// */
// animistRituals: EntryWithValue[]
// /**
// * A set of active geode rituals and their skill ratings.
// */
// geodeRituals: EntryWithValue[]
// /**
// * A set of active zibilja rituals and their skill ratings.
// */
// zibiljaRituals: EntryWithValue[]
/**
* A set of active liturgical chants/cemeronies and their skill ratings.
*/
liturgicalChants: EntryWithValue[]
/**
* A set of active cantrips.
*/
cantripIds: number[]
/**
* A set of active blessings.
*/
blessingIds: number[]
/**
* A list of all the items the hero owns, except for hit zone armors.
*/
items: Item[]
hitZoneArmors?: HitZoneArmor[]
purse: {
ducats: number
silverthalers: number
halers: number
kreutzers: number
}
pets?: Pet[]
pact?: Pact
}
type ActiveRule = {
/**
* The ID of the rule.
*/
id: number
/**
* Selected options for the rule.
*/
options?: number[]
}
/**
* Rules defined for the hero.
*/
type Rules = {
/**
* Are all publications without adult content activated? This way they don't
* have to be defined in `activePublications` to be active.
*/
areAllPublicationsActive: boolean
/**
* Explicitly activated publications. Only affects those with adult content
* if `areAllPublicationsActive` is set to `true`.
*/
activePublicationIds: string[]
/**
* Activated focus rules.
*/
activeFocusRules: ActiveRule[]
/**
* Activated optional rules.
*/
activeOptionalRules: ActiveRule[]
}
/**
* Personal data
*/
type PersonalData = {
/**
* The selected sex.
*/
sexId: "m" | "f"
family?: string
placeOfBirth?: string
dateOfBirth?: string
age?: string
hairColorId?: number
eyeColorId?: number
size?: string
weight?: string
title?: string
socialStatusId?: number
characteristics?: string
otherInfo?: string
cultureAreaKnowledge?: string
}
type ActiveAdvantage = {
id: number,
active: {
options?: {
tag: "Generic" | "Skill" | "CombatTechnique"
value: number
}[]
level?: number
customCost?: number
}[]
}
type ActiveDisadvantage = {
id: number,
active: {
options?: {
tag: "Generic" | "Skill" | "CombatTechnique"
value: number
}[]
level?: number
customCost?: number
}[]
}
type ActiveSpecialAbility = {
id: number
active: {
options?: {
tag: "Generic" | "Skill" | "CombatTechnique"
value: number
}[]
level?: number
}[]
}
type EntryWithValue = {
id: number
value: number
}
/**
* Additions and permanent loss of LP/AE/KP.
*/
type Energies = {
/**
* Additionally bought life points.
*/
addedLifePoints: number
/**
* Additionally bought arcane energy.
*/
addedArcaneEnergy: number
/**
* Additionally bought karma points.
*/
addedKarmaPoints: number
/**
* Permanently lost life points.
*/
permanentLP: {
lost: number
}
/**
* Permanently lost arcane energy. Also lists how many of them have been
* bought back.
*/
permanentAE: {
lost: number
boughtBack: number
}
/**
* Permanently lost karma points. Also lists how many of them have been
* bought back.
*/
permanentKP: {
lost: number
boughtBack: number
}
}
type Item = {
/**
* The item's ID.
*/
id: number
/**
* How many of this item are there?
*
* @default 1
*/
amount?: number
/**
* The price in silverthalers.
*/
price?: number
/**
* The weight in kg.
*/
weight?: number
/**
* The template this item is based on, if any.
*/
template?: number
/**
* If the template is locked, values except for `amount`, `where`, `damaged`,
* `wear` and `isHitZoneArmorOnly` are always overwritten with the values from
* the item template from the static data files.
*/
isTemplateLocked: boolean
/**
* Where is the item carried?
*/
carriedWhere?: string
/**
* If the item is a weapon or an armor, place their specific values here. If a
* weapon represents both a melee and a ranged weapon, use an object.
*/
special?: MundaneItem | CombinedWeapon | MeleeWeapon | RangedWeapon | Armor
/**
* The group ID. If this a usual item but it can be used as a normal or
* improvised weapon, use the usual item group, the weapon group can be
* inferred later.
*/
gr: number
}
type MundaneItem = {
/**
* The structure points of the item.
*/
structurePoints?: number | number[]
}
type CombinedWeapon = {
/**
* The melee weapon's stats.
*/
melee: MeleeWeapon
/**
* The ranged weapon's stats.
*/
ranged: RangedWeapon
}
type MeleeWeapon = {
/**
* The combat technique ID.
*/
combatTechniqueId: number
/**
* Number of dice for damage.
*
* @example 2 in "2D6+4"
*/
damageDiceNumber: number
/**
* Number of dice's sides.
*
* @example 6 in "2D6+4"
*/
damageDiceSides: number
/**
* Flat damage, if any. Defaults to 0 if not specified.
*
* @example 4 in "2D6+4"
* @example Undefined in "2D6"
* @example -4 in "2D6-4"
*/
damageFlat?: number
/**
* The primary attribute damage and threshold value. You can either use an
* integer, an object or a pair. Use an integer if you just have to define a
* single threshold value for the default primary attribute of the combat
* technique. Use an object if you need to define the value only or if you
* need to define the value as well as a single different primary attribute
* than which the combat technique uses. Use the pair if you need to set the
* primary attributes to AGI and STR (the combat technique has AGI but this
* item has AGI/STR) and/or if you need to set different thresholds for AGI
* and STR (e.g. AGI 14/STR 15). If the same values are in the pair, they will
* be merged (AGI 14/STR 14 will be AGI/STR 14).
*/
damageThreshold?: {
primaryId?: number | [number, number]
threshold: number | number[]
}
/**
* The AT modifier.
*/
at?: number
/**
* The PA modifier.
*/
pa?: number
/**
* The reach of the weapon. 1 for short, 2 for medium, 3 for long and 4 for
* extra-long.
*/
reachId?: 1 | 2 | 3 | 4
/**
* The length of the weapon in cm.
*/
length?: number
/**
* The structure points of the item.
*/
structurePoints?: number | number[]
/**
* Modifies the breaking point rating of the combat technique for this weapon.
*/
breakingPointRatingMod?: number
/**
* Is the weapon a parrying weapon?
*/
isParryingWeapon: boolean
/**
* Is the weapon a two-handed weapon?
*/
isTwoHandedWeapon: boolean
/**
* Is the weapon an improvised weapon?
*/
isImprovisedWeapon: boolean
/**
* The level of damaged, if any.
*/
damaged?: number
}
type RangedWeapon = {
/**
* The combat technique ID.
*/
combatTechniqueId: number
/**
* Number of dice for damage.
*
* @example 2 in "2D6+4"
*/
damageDiceNumber?: number
/**
* Number of dice's sides.
*
* @example 6 in "2D6+4"
*/
damageDiceSides?: number
/**
* Flat damage, if any. Defaults to 0 if not specified.
*
* @example 4 in "2D6+4"
* @example Undefined in "2D6"
* @example -4 in "2D6-4"
*/
damageFlat?: number
/**
* The length of the weapon in cm.
*/
length?: number
/**
* The close range bracket for the weapon. Distance in m.
*/
closeRange: number
/**
* The medium range bracket for the weapon. Distance in m.
*/
mediumRange: number
/**
* The far range bracket for the weapon. Distance in m.
*/
farRange: number
/**
* The reload time. If you need to provide multiple reload times, use an
* array.
*/
reloadTime: number | number[]
/**
* The needed ammunition. The item template ID.
*/
ammunition?: number
/**
* Is the weapon an improvised weapon?
*/
isImprovisedWeapon: boolean
/**
* The level of damaged, if any.
*/
damaged?: number
}
type Armor = {
/**
* The PRO value
*/
protection: number
/**
* The ENC value.
*/
encumbrance: number
/**
* Does this armor have additional penalties (MOV -1, INI -1)?
*/
hasAdditionalPenalties: boolean
/**
* Modifies the INI modifier of this armor. This adds to the penalty of
* `hasAdditionalPenalties`, which, if `true`, counts as `-1`, otherwise as
* `0`. So if it's `true` and `iniMod` is `1`, the effective mod is `0`.
*/
iniMod?: number
/**
* Modifies the MOV modifier of this armor. This adds to the penalty of
* `hasAdditionalPenalties`, which, if `true`, counts as `-1`, otherwise as
* `0`. So if it's `true` and `movMod` is `1`, the effective mod is `0`.
*/
movMod?: number
/**
* Modifies the sturdiness of this armor.
*/
sturdinessMod?: number
/**
* The armor type ID.
*/
armorTypeId: number
/**
* The level of wear, if any.
*/
wear?: number
/**
* If this armor is only created for hit zone armor and should not be
* displayed as normal armor on character sheet.
*/
isHitZoneArmorOnly?: boolean
}
type HitZoneArmor = {
/**
* The hit zone armor's ID.
*/
id: number
/**
* The name of the hit zone armor.
*/
name: string
/**
* ID of the armor at zone *head*. Can be either a template ID or the ID of an
* armor from `items`.
*/
headId?: HitZoneArmorZoneItemId
/**
* The level of wear at zone *head*, if any. Ignores `wear` if custom armor is
* used, even if `headWear` is not defined.
*/
headWear?: number
/**
* ID of the armor at zone *left arm*. Can be either a template ID or the ID
* of an armor from `items`.
*/
leftArmId?: HitZoneArmorZoneItemId
/**
* The level of wear at zone *left arm*, if any. Ignores `wear` if custom
* armor is used, even if `leftArmWear` is not defined.
*/
leftArmWear?: number
/**
* ID of the armor at zone *right arm*. Can be either a template ID or the ID
* of an item from `items`.
*/
rightArmId?: HitZoneArmorZoneItemId
/**
* The level of wear at zone *right arm*, if any. Ignores `wear` if custom
* armor is used, even if `rightArmWear` is not defined.
*/
rightArmWear?: number
/**
* ID of the armor at zone *torso*. Can be either a template ID or the ID of
* an armor from `items`.
*/
torsoId?: HitZoneArmorZoneItemId
/**
* The level of wear at zone *torso*, if any. Ignores `wear` if custom armor
* is used, even if `torsoWear` is not defined.
*/
torsoWear?: number
/**
* ID of the armor at zone *left leg*. Can be either a template ID or the ID
* of an armor from `items`.
*/
leftLegId?: HitZoneArmorZoneItemId
/**
* The level of wear at zone *left leg*, if any. Ignores `wear` if custom
* armor is used, even if `leftLegWear` is not defined.
*/
leftLegWear?: number
/**
* ID of the armor at zone *right leg*. Can be either a template ID or the ID
* of an armor from `items`.
*/
rightLegId?: HitZoneArmorZoneItemId
/**
* The level of wear at zone *right leg*, if any. Ignores `wear` if custom
* armor is used, even if `rightLegWear` is not defined.
*/
rightLegWear?: number
}
type HitZoneArmorZoneItemId = {
tag: "Template" | "Custom"
value: number
}
type Pet = {
id: number
name: string
avatar?: string
size?: string
type?: string
attack?: string
dp?: string
reach?: string
actions?: string
talents?: string
skills?: string
notes?: string
spentAp?: string
totalAp?: string
cou?: string
sgc?: string
int?: string
cha?: string
dex?: string
agi?: string
con?: string
str?: string
lp?: string
ae?: string
spi?: string
tou?: string
pro?: string
ini?: string
mov?: string
at?: string
pa?: string
}
type Pact = {
categoryId: number
level: number
typeId: number
domainId: { type: "Predefined", value: number }
| { type: "Custom", value: string }
name: string
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment