Initial import
This commit is contained in:
8
module/models/_module.mjs
Normal file
8
module/models/_module.mjs
Normal file
@@ -0,0 +1,8 @@
|
||||
export { default as LethalFantasyCharacter } from "./character.mjs"
|
||||
export { default as LethalFantasyOpponent } from "./opponent.mjs"
|
||||
export { default as LethalFantasyPath } from "./path.mjs"
|
||||
export { default as LethalFantasyTalent } from "./talent.mjs"
|
||||
export { default as LethalFantasyArmor } from "./armor.mjs"
|
||||
export { default as LethalFantasyWeapon } from "./weapon.mjs"
|
||||
export { default as LethalFantasySpell } from "./spell.mjs"
|
||||
export { default as LethalFantasyAttack } from "./attack.mjs"
|
||||
34
module/models/armor.mjs
Normal file
34
module/models/armor.mjs
Normal file
@@ -0,0 +1,34 @@
|
||||
import { SYSTEM } from "../config/system.mjs"
|
||||
import { CATEGORY } from "../config/armor.mjs"
|
||||
|
||||
export default class LethalFantasyArmor extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
const requiredInteger = { required: true, nullable: false, integer: true }
|
||||
const schema = {}
|
||||
|
||||
schema.description = new fields.HTMLField({ required: true, textSearch: true })
|
||||
|
||||
schema.categorie = new fields.StringField({ required: true, initial: "sommaire", choices: SYSTEM.ARMOR_CATEGORY })
|
||||
|
||||
schema.valeur = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||||
|
||||
schema.malus = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||||
|
||||
return schema
|
||||
}
|
||||
|
||||
/** @override */
|
||||
static LOCALIZATION_PREFIXES = ["TENEBRIS.Armor"]
|
||||
|
||||
get armorCategory() {
|
||||
return game.i18n.localize(CATEGORY[this.categorie].label)
|
||||
}
|
||||
|
||||
get details() {
|
||||
return game.i18n.format("TENEBRIS.Armor.details", {
|
||||
valeur: this.valeur,
|
||||
malus: this.malus,
|
||||
})
|
||||
}
|
||||
}
|
||||
18
module/models/attack.mjs
Normal file
18
module/models/attack.mjs
Normal file
@@ -0,0 +1,18 @@
|
||||
export default class LethalFantasy extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
const schema = {}
|
||||
|
||||
schema.description = new fields.HTMLField({ required: true, textSearch: true })
|
||||
schema.degats = new fields.StringField({ required: false, nullable: true, blank: true })
|
||||
|
||||
return schema
|
||||
}
|
||||
|
||||
/** @override */
|
||||
static LOCALIZATION_PREFIXES = ["TENEBRIS.Attack"]
|
||||
|
||||
get toolTip() {
|
||||
return this.description || ""
|
||||
}
|
||||
}
|
||||
176
module/models/character.mjs
Normal file
176
module/models/character.mjs
Normal file
@@ -0,0 +1,176 @@
|
||||
import { ROLL_TYPE, SYSTEM } from "../config/system.mjs"
|
||||
import LethalFantasyRoll from "../documents/roll.mjs"
|
||||
import LethalFantasyUtils from "../utils.mjs"
|
||||
|
||||
export default class LethalFantasyCharacter extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
const requiredInteger = { required: true, nullable: false, integer: true }
|
||||
const schema = {}
|
||||
|
||||
schema.description = new fields.HTMLField({ required: true, textSearch: true })
|
||||
schema.langues = new fields.HTMLField({ required: true, textSearch: true })
|
||||
schema.notes = new fields.HTMLField({ required: true, textSearch: true })
|
||||
schema.biens = new fields.HTMLField({ required: true, textSearch: true })
|
||||
|
||||
// Caractéristiques
|
||||
const characteristicField = (label) => {
|
||||
const schema = {
|
||||
valeur: new fields.NumberField({ ...requiredInteger, initial: 10, min: 0 }),
|
||||
progression: new fields.SchemaField({
|
||||
experience: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
|
||||
progres: new fields.BooleanField(),
|
||||
}),
|
||||
}
|
||||
return new fields.SchemaField(schema, { label })
|
||||
}
|
||||
|
||||
schema.caracteristiques = new fields.SchemaField(
|
||||
Object.values(SYSTEM.CHARACTERISTICS).reduce((obj, characteristic) => {
|
||||
obj[characteristic.id] = characteristicField(characteristic.label)
|
||||
return obj
|
||||
}, {}),
|
||||
)
|
||||
|
||||
// Ressources
|
||||
const resourceField = (label) => {
|
||||
const schema = {
|
||||
valeur: new fields.StringField({
|
||||
required: true,
|
||||
nullable: false,
|
||||
initial: SYSTEM.RESOURCE_VALUE.ZERO,
|
||||
choices: Object.fromEntries(Object.entries(SYSTEM.RESOURCE_VALUE).map(([key, value]) => [value, { label: `${value}` }])),
|
||||
blank: true,
|
||||
}),
|
||||
max: new fields.StringField({
|
||||
required: true,
|
||||
nullable: false,
|
||||
initial: SYSTEM.RESOURCE_VALUE.ZERO,
|
||||
choices: Object.fromEntries(Object.entries(SYSTEM.RESOURCE_VALUE).map(([key, value]) => [value, { label: `${value}` }])),
|
||||
blank: true,
|
||||
}),
|
||||
experience: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
|
||||
}
|
||||
return new fields.SchemaField(schema, { label })
|
||||
}
|
||||
|
||||
schema.ressources = new fields.SchemaField(
|
||||
Object.values(SYSTEM.RESOURCES).reduce((obj, resource) => {
|
||||
obj[resource.id] = resourceField(resource.label)
|
||||
return obj
|
||||
}, {}),
|
||||
)
|
||||
|
||||
schema.commanditaire = new fields.StringField({})
|
||||
|
||||
schema.dv = new fields.StringField({
|
||||
required: true,
|
||||
nullable: false,
|
||||
initial: SYSTEM.RESOURCE_VALUE.ZERO,
|
||||
choices: Object.fromEntries(Object.entries(SYSTEM.RESOURCE_VALUE).map(([key, value]) => [value, { label: `${value}` }])),
|
||||
})
|
||||
|
||||
schema.pv = new fields.SchemaField({
|
||||
value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
|
||||
max: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
|
||||
})
|
||||
|
||||
schema.dmax = new fields.SchemaField({
|
||||
valeur: new fields.StringField({
|
||||
required: true,
|
||||
nullable: false,
|
||||
initial: SYSTEM.RESOURCE_VALUE.ZERO,
|
||||
choices: Object.fromEntries(Object.entries(SYSTEM.RESOURCE_VALUE).map(([key, value]) => [value, { label: `${value}` }])),
|
||||
}),
|
||||
experience: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
|
||||
})
|
||||
|
||||
schema.voies = new fields.SchemaField({
|
||||
majeure: new fields.SchemaField({
|
||||
id: new fields.DocumentIdField(),
|
||||
key: new fields.StringField({ required: true }),
|
||||
nom: new fields.StringField({ required: true }),
|
||||
}),
|
||||
mineure: new fields.SchemaField({
|
||||
id: new fields.DocumentIdField(),
|
||||
key: new fields.StringField({ required: true }),
|
||||
nom: new fields.StringField({ required: true }),
|
||||
}),
|
||||
})
|
||||
|
||||
return schema
|
||||
}
|
||||
|
||||
/** @override */
|
||||
static LOCALIZATION_PREFIXES = ["TENEBRIS.Character"]
|
||||
|
||||
get hasVoieMajeure() {
|
||||
return !!this.voies.majeure.id
|
||||
}
|
||||
|
||||
get hasVoieMineure() {
|
||||
return !!this.voies.mineure.id
|
||||
}
|
||||
|
||||
/**
|
||||
* Rolls a dice for a character.
|
||||
* @param {("save"|"resource|damage")} rollType The type of the roll.
|
||||
* @param {number} rollTarget The target value for the roll. Which caracteristic or resource. If the roll is a damage roll, this is the id of the item.
|
||||
* @param {"="|"+"|"++"|"-"|"--"} rollAdvantage If there is an avantage (+), a disadvantage (-), a double advantage (++), a double disadvantage (--) or a normal roll (=).
|
||||
* @returns {Promise<null>} - A promise that resolves to null if the roll is cancelled.
|
||||
*/
|
||||
async roll(rollType, rollTarget, rollAdvantage = "=") {
|
||||
let rollValue
|
||||
let opponentTarget
|
||||
switch (rollType) {
|
||||
case ROLL_TYPE.SAVE:
|
||||
rollValue = this.caracteristiques[rollTarget].valeur
|
||||
opponentTarget = game.user.targets.first()
|
||||
break
|
||||
case ROLL_TYPE.RESOURCE:
|
||||
rollValue = this.ressources[rollTarget].valeur
|
||||
break
|
||||
case ROLL_TYPE.DAMAGE:
|
||||
rollValue = this.parent.items.get(rollTarget).system.degats
|
||||
opponentTarget = game.user.targets.first()
|
||||
break
|
||||
default:
|
||||
// Handle other cases or do nothing
|
||||
break
|
||||
}
|
||||
await this._roll(rollType, rollTarget, rollValue, opponentTarget, rollAdvantage)
|
||||
}
|
||||
|
||||
/**
|
||||
* Rolls a dice for a character.
|
||||
* @param {("save"|"resource|damage")} rollType The type of the roll.
|
||||
* @param {number} rollTarget The target value for the roll. Which caracteristic or resource. If the roll is a damage roll, this is the id of the item.
|
||||
* @param {number} rollValue The value of the roll. If the roll is a damage roll, this is the dice to roll.
|
||||
* @param {Token} opponentTarget The target of the roll : used for save rolls to get the oppponent's malus.
|
||||
* @param {"="|"+"|"++"|"-"|"--"} rollAdvantage If there is an avantage (+), a disadvantage (-), a double advantage (++), a double disadvantage (--) or a normal roll (=).
|
||||
* @returns {Promise<null>} - A promise that resolves to null if the roll is cancelled.
|
||||
*/
|
||||
async _roll(rollType, rollTarget, rollValue, opponentTarget = undefined, rollAdvantage = "=") {
|
||||
const hasTarget = opponentTarget !== undefined
|
||||
let roll = await LethalFantasyRoll.prompt({
|
||||
rollType,
|
||||
rollTarget,
|
||||
rollValue,
|
||||
actorId: this.parent.id,
|
||||
actorName: this.parent.name,
|
||||
actorImage: this.parent.img,
|
||||
hasTarget,
|
||||
target: opponentTarget,
|
||||
rollAdvantage,
|
||||
})
|
||||
if (!roll) return null
|
||||
|
||||
// Perte de ressouces
|
||||
if (rollType === ROLL_TYPE.RESOURCE && roll.resultType === "failure") {
|
||||
const value = this.ressources[rollTarget].valeur
|
||||
const newValue = LethalFantasyUtils.findLowerDice(value)
|
||||
await this.parent.update({ [`system.ressources.${rollTarget}.valeur`]: newValue })
|
||||
}
|
||||
await roll.toMessage({}, { rollMode: roll.options.rollMode })
|
||||
}
|
||||
}
|
||||
49
module/models/opponent.mjs
Normal file
49
module/models/opponent.mjs
Normal file
@@ -0,0 +1,49 @@
|
||||
import LethalFantasyRoll from "../documents/roll.mjs"
|
||||
import { ROLL_TYPE } from "../config/system.mjs"
|
||||
|
||||
export default class LethalFantasyOpponent extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
const requiredInteger = { required: true, nullable: false, integer: true }
|
||||
const schema = {}
|
||||
|
||||
schema.dv = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||||
schema.pv = new fields.SchemaField({
|
||||
value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
|
||||
max: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
|
||||
})
|
||||
schema.armure = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||||
schema.malus = new fields.NumberField({ ...requiredInteger, initial: 0, max: 0 })
|
||||
schema.actions = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||||
schema.description = new fields.HTMLField({ required: true, textSearch: true })
|
||||
// Attaques : embedded items of type Attack
|
||||
|
||||
return schema
|
||||
}
|
||||
|
||||
/** @override */
|
||||
static LOCALIZATION_PREFIXES = ["TENEBRIS.Opponent"]
|
||||
|
||||
/**
|
||||
* Rolls a dice attack for an opponent.
|
||||
* @param {number} rollValue The dice to roll.
|
||||
* @param {number} rollTarget The name of the attack
|
||||
* @returns {Promise<null>} - A promise that resolves to null if the roll is cancelled.
|
||||
*/
|
||||
async roll(rollValue, rollTarget) {
|
||||
let roll = await LethalFantasyRoll.prompt({
|
||||
rollType: ROLL_TYPE.ATTACK,
|
||||
rollValue,
|
||||
rollTarget,
|
||||
actorId: this.parent.id,
|
||||
actorName: this.parent.name,
|
||||
actorImage: this.parent.img,
|
||||
})
|
||||
if (!roll) return null
|
||||
await roll.toMessage({}, { rollMode: roll.options.rollMode })
|
||||
}
|
||||
|
||||
get toolTip() {
|
||||
return this.description || ""
|
||||
}
|
||||
}
|
||||
83
module/models/path.mjs
Normal file
83
module/models/path.mjs
Normal file
@@ -0,0 +1,83 @@
|
||||
import { SYSTEM } from "../config/system.mjs"
|
||||
export default class LethalFantasyPath extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
const schema = {}
|
||||
|
||||
schema.key = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
|
||||
// Caractéristiques
|
||||
const characteristicField = (label) => {
|
||||
const schema = {
|
||||
valeur: new fields.NumberField({
|
||||
required: true,
|
||||
nullable: false,
|
||||
integer: true,
|
||||
initial: 10,
|
||||
min: 0,
|
||||
}),
|
||||
}
|
||||
return new fields.SchemaField(schema, { label })
|
||||
}
|
||||
|
||||
schema.caracteristiques = new fields.SchemaField(
|
||||
Object.values(SYSTEM.CHARACTERISTICS).reduce((obj, characteristic) => {
|
||||
obj[characteristic.id] = characteristicField(characteristic.label)
|
||||
return obj
|
||||
}, {}),
|
||||
)
|
||||
|
||||
// Ressources
|
||||
const resourceField = (label) => {
|
||||
const schema = {
|
||||
valeur: new fields.StringField({
|
||||
required: true,
|
||||
initial: SYSTEM.RESOURCE_VALUE.ZERO,
|
||||
choices: Object.fromEntries(Object.entries(SYSTEM.RESOURCE_VALUE).map(([key, value]) => [value, { label: `${value}` }])),
|
||||
}),
|
||||
}
|
||||
return new fields.SchemaField(schema, { label })
|
||||
}
|
||||
|
||||
schema.ressources = new fields.SchemaField(
|
||||
Object.values(SYSTEM.RESOURCES).reduce((obj, resource) => {
|
||||
obj[resource.id] = resourceField(resource.label)
|
||||
return obj
|
||||
}, {}),
|
||||
)
|
||||
|
||||
schema.dv = new fields.StringField({
|
||||
required: true,
|
||||
initial: SYSTEM.RESOURCE_VALUE.ZERO,
|
||||
choices: Object.fromEntries(Object.entries(SYSTEM.RESOURCE_VALUE).map(([key, value]) => [value, { label: `${value}` }])),
|
||||
})
|
||||
|
||||
schema.dmax = new fields.StringField({
|
||||
required: true,
|
||||
initial: SYSTEM.RESOURCE_VALUE.ZERO,
|
||||
choices: Object.fromEntries(Object.entries(SYSTEM.RESOURCE_VALUE).map(([key, value]) => [value, { label: `${value}` }])),
|
||||
})
|
||||
|
||||
schema.description = new fields.HTMLField({ required: true, textSearch: true })
|
||||
|
||||
schema.biens = new fields.HTMLField({ required: true, textSearch: true })
|
||||
|
||||
schema.langues = new fields.HTMLField({ required: true, textSearch: true })
|
||||
|
||||
schema.talents = new fields.ArrayField(new fields.DocumentUUIDField())
|
||||
|
||||
return schema
|
||||
}
|
||||
|
||||
/** @override */
|
||||
static LOCALIZATION_PREFIXES = ["TENEBRIS.Path"]
|
||||
|
||||
async getAllTalents() {
|
||||
const talents = []
|
||||
this.talents.forEach(async (element) => {
|
||||
const talent = await fromUuid(element)
|
||||
if (talent) talents.push(talent)
|
||||
})
|
||||
return talents
|
||||
}
|
||||
}
|
||||
27
module/models/spell.mjs
Normal file
27
module/models/spell.mjs
Normal file
@@ -0,0 +1,27 @@
|
||||
import { SYSTEM } from "../config/system.mjs"
|
||||
export default class LethalFantasySpell extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
const requiredInteger = { required: true, nullable: false, integer: true }
|
||||
const schema = {}
|
||||
|
||||
schema.description = new fields.HTMLField({
|
||||
required: false,
|
||||
blank: true,
|
||||
initial: "",
|
||||
textSearch: true,
|
||||
})
|
||||
|
||||
schema.preparation = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||||
schema.cible = new fields.StringField({ required: true })
|
||||
schema.portee = new fields.StringField({ required: true, initial: "contact", choices: SYSTEM.SPELL_RANGE })
|
||||
schema.duree = new fields.StringField({ required: true })
|
||||
schema.consequenceA = new fields.StringField({ required: true })
|
||||
schema.consequenceB = new fields.StringField({ required: true })
|
||||
|
||||
return schema
|
||||
}
|
||||
|
||||
/** @override */
|
||||
static LOCALIZATION_PREFIXES = ["TENEBRIS.Spell"]
|
||||
}
|
||||
44
module/models/talent.mjs
Normal file
44
module/models/talent.mjs
Normal file
@@ -0,0 +1,44 @@
|
||||
export default class LethalFantasyTalent extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
const requiredInteger = { required: true, nullable: false, integer: true }
|
||||
const schema = {}
|
||||
|
||||
schema.description = new fields.HTMLField({ required: true, textSearch: true })
|
||||
|
||||
schema.appris = new fields.BooleanField()
|
||||
schema.progression = new fields.BooleanField()
|
||||
schema.niveau = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 3 })
|
||||
schema.path = new fields.DocumentUUIDField()
|
||||
|
||||
return schema
|
||||
}
|
||||
|
||||
/** @override */
|
||||
static LOCALIZATION_PREFIXES = ["TENEBRIS.Talent"]
|
||||
|
||||
get canProgress() {
|
||||
return this.progression
|
||||
}
|
||||
|
||||
get isLearned() {
|
||||
return this.appris
|
||||
}
|
||||
|
||||
get improvedDescription() {
|
||||
return this.description.replace(/#niveau\b/g, this.niveau)
|
||||
}
|
||||
|
||||
get details() {
|
||||
if (this.progression)
|
||||
return game.i18n.format("TENEBRIS.Talent.details", {
|
||||
niveau: this.niveau,
|
||||
})
|
||||
return ""
|
||||
}
|
||||
|
||||
async getPathName() {
|
||||
const path = await fromUuid(this.path)
|
||||
return path ? path.name : ""
|
||||
}
|
||||
}
|
||||
24
module/models/weapon.mjs
Normal file
24
module/models/weapon.mjs
Normal file
@@ -0,0 +1,24 @@
|
||||
import { SYSTEM } from "../config/system.mjs"
|
||||
import { CATEGORY } from "../config/weapon.mjs"
|
||||
export default class LethalFantasyWeapon extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
const schema = {}
|
||||
|
||||
schema.description = new fields.HTMLField({ required: true, textSearch: true })
|
||||
schema.categorie = new fields.StringField({ required: true, initial: "mains", choices: SYSTEM.WEAPON_CATEGORY })
|
||||
schema.degats = new fields.StringField({
|
||||
required: true,
|
||||
initial: SYSTEM.WEAPON_DAMAGE.UN,
|
||||
choices: Object.fromEntries(Object.entries(SYSTEM.WEAPON_DAMAGE).map(([key, value]) => [value, { label: `${value}` }])),
|
||||
})
|
||||
return schema
|
||||
}
|
||||
|
||||
/** @override */
|
||||
static LOCALIZATION_PREFIXES = ["TENEBRIS.Weapon"]
|
||||
|
||||
get weaponCategory() {
|
||||
return game.i18n.localize(CATEGORY[this.categorie].label)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user