Import initial
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
export { default as LesOubliesPersonnageSheet } from "./personnage-sheet.mjs"
|
||||
export { default as LesOubliesCompagnieSheet } from "./compagnie-sheet.mjs"
|
||||
export { default as LesOubliesCreatureSheet } from "./creature-sheet.mjs"
|
||||
export { default as LesOubliesReferenceItemSheet } from "./reference-item-sheet.mjs"
|
||||
export { default as LesOubliesCompetenceSheet } from "./competence-sheet.mjs"
|
||||
export { default as LesOubliesSortilegeSheet } from "./sortilege-sheet.mjs"
|
||||
export { default as LesOubliesArmeSheet } from "./arme-sheet.mjs"
|
||||
export { default as LesOubliesArmureSheet } from "./armure-sheet.mjs"
|
||||
export { default as LesOubliesEquipementSheet } from "./equipement-sheet.mjs"
|
||||
export { default as LesOubliesPouvoirCompagnieSheet } from "./pouvoir-compagnie-sheet.mjs"
|
||||
@@ -0,0 +1,9 @@
|
||||
import LesOubliesItemSheet from "./base-item-sheet.mjs"
|
||||
|
||||
export default class LesOubliesArmeSheet extends LesOubliesItemSheet {
|
||||
static PARTS = {
|
||||
sheet: {
|
||||
template: "systems/fvtt-les-oublies/templates/item-arme-sheet.hbs",
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import LesOubliesItemSheet from "./base-item-sheet.mjs"
|
||||
|
||||
export default class LesOubliesArmureSheet extends LesOubliesItemSheet {
|
||||
static PARTS = {
|
||||
sheet: {
|
||||
template: "systems/fvtt-les-oublies/templates/item-armure-sheet.hbs",
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
const { HandlebarsApplicationMixin } = foundry.applications.api
|
||||
|
||||
import { LesOubliesUtility } from "../../les-oublies-utility.js"
|
||||
|
||||
export default class LesOubliesActorSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ActorSheetV2) {
|
||||
static SHEET_MODES = { EDIT: 0, PLAY: 1 }
|
||||
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ["fvtt-les-oublies", "sheet", "actor"],
|
||||
position: {
|
||||
width: 980,
|
||||
height: 860,
|
||||
},
|
||||
window: {
|
||||
resizable: true,
|
||||
},
|
||||
form: {
|
||||
submitOnChange: true,
|
||||
closeOnSubmit: false,
|
||||
},
|
||||
dragDrop: [{ dragSelector: ".item-card", dropSelector: "form" }],
|
||||
actions: {
|
||||
toggleSheet: LesOubliesActorSheet.#onToggleSheet,
|
||||
editImage: LesOubliesActorSheet.#onEditImage,
|
||||
createItem: LesOubliesActorSheet.#onCreateItem,
|
||||
editItem: LesOubliesActorSheet.#onEditItem,
|
||||
deleteItem: LesOubliesActorSheet.#onDeleteItem,
|
||||
openRoll: LesOubliesActorSheet.#onOpenRoll,
|
||||
openConfrontation: LesOubliesActorSheet.#onOpenConfrontation,
|
||||
openInitiative: LesOubliesActorSheet.#onOpenInitiative,
|
||||
rollProfile: LesOubliesActorSheet.#onRollProfile,
|
||||
rollSkill: LesOubliesActorSheet.#onRollSkill,
|
||||
useWeapon: LesOubliesActorSheet.#onUseWeapon,
|
||||
resolveWeaponDamage: LesOubliesActorSheet.#onResolveWeaponDamage,
|
||||
useSpell: LesOubliesActorSheet.#onUseSpell,
|
||||
openCombatPreset: LesOubliesActorSheet.#onOpenCombatPreset,
|
||||
openThreadHarvest: LesOubliesActorSheet.#onOpenThreadHarvest,
|
||||
},
|
||||
}
|
||||
|
||||
_sheetMode = this.constructor.SHEET_MODES.EDIT
|
||||
|
||||
get isEditMode() {
|
||||
return this._sheetMode === this.constructor.SHEET_MODES.EDIT
|
||||
}
|
||||
|
||||
get isPlayMode() {
|
||||
return this._sheetMode === this.constructor.SHEET_MODES.PLAY
|
||||
}
|
||||
|
||||
async _prepareContext() {
|
||||
return {
|
||||
actor: this.document,
|
||||
system: this.document.system,
|
||||
source: this.document.toObject(),
|
||||
fields: this.document.schema.fields,
|
||||
systemFields: this.document.system.schema.fields,
|
||||
isEditable: this.isEditable,
|
||||
isEditMode: this.isEditMode,
|
||||
isPlayMode: this.isPlayMode,
|
||||
isGM: game.user.isGM,
|
||||
config: CONFIG.LESOUBLIES,
|
||||
enrichedDescription: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.biodata?.description ?? this.document.system.description ?? "", { async: true }),
|
||||
}
|
||||
}
|
||||
|
||||
_onRender(context, options) {
|
||||
super._onRender(context, options)
|
||||
}
|
||||
|
||||
_canDragStart() {
|
||||
return this.isEditable
|
||||
}
|
||||
|
||||
_canDragDrop() {
|
||||
return this.isEditable
|
||||
}
|
||||
|
||||
async _onDrop(event) {
|
||||
const data = TextEditor.getDragEventData(event)
|
||||
if (data.type !== "Item" || !data.uuid) return
|
||||
const item = await fromUuid(data.uuid)
|
||||
if (!item) return
|
||||
return this._onDropItem(item)
|
||||
}
|
||||
|
||||
async _onDropItem(item) {
|
||||
const itemData = item.toObject()
|
||||
delete itemData._id
|
||||
return this.document.createEmbeddedDocuments("Item", [itemData], { renderSheet: false })
|
||||
}
|
||||
|
||||
static #onToggleSheet() {
|
||||
const modes = this.constructor.SHEET_MODES
|
||||
this._sheetMode = this.isEditMode ? modes.PLAY : modes.EDIT
|
||||
this.render()
|
||||
}
|
||||
|
||||
static async #onEditImage(event, target) {
|
||||
const attr = target.dataset.edit
|
||||
const current = foundry.utils.getProperty(this.document, attr)
|
||||
const fp = new FilePicker({
|
||||
current,
|
||||
type: "image",
|
||||
callback: (path) => this.document.update({ [attr]: path }),
|
||||
top: this.position.top + 40,
|
||||
left: this.position.left + 10,
|
||||
})
|
||||
return fp.browse()
|
||||
}
|
||||
|
||||
static async #onCreateItem(event, target) {
|
||||
const type = target.dataset.type
|
||||
if (!type) return
|
||||
const label = game.i18n.localize(`TYPES.Item.${type}`)
|
||||
return this.document.createEmbeddedDocuments("Item", [{
|
||||
name: label,
|
||||
type,
|
||||
img: LesOubliesUtility.getDefaultItemImage(type),
|
||||
}])
|
||||
}
|
||||
|
||||
static async #onEditItem(event, target) {
|
||||
const itemId = target.dataset.itemId
|
||||
const item = this.document.items.get(itemId)
|
||||
if (item) item.sheet.render(true)
|
||||
}
|
||||
|
||||
static async #onDeleteItem(event, target) {
|
||||
const itemId = target.dataset.itemId
|
||||
const item = this.document.items.get(itemId)
|
||||
if (item) await item.delete()
|
||||
}
|
||||
|
||||
static async #onOpenRoll() {
|
||||
await this.document.openTestRollDialog()
|
||||
}
|
||||
|
||||
static async #onOpenConfrontation() {
|
||||
await this.document.openConfrontationRollDialog()
|
||||
}
|
||||
|
||||
static async #onOpenInitiative() {
|
||||
await this.document.openInitiativeRollDialog()
|
||||
}
|
||||
|
||||
static async #onRollProfile(event, target) {
|
||||
const profileKey = target.dataset.profileKey
|
||||
if (!profileKey) return
|
||||
await this.document.rollProfile(profileKey)
|
||||
}
|
||||
|
||||
static async #onRollSkill(event, target) {
|
||||
const itemId = target.dataset.itemId
|
||||
if (!itemId) return
|
||||
await this.document.rollCompetence(itemId)
|
||||
}
|
||||
|
||||
static async #onUseWeapon(event, target) {
|
||||
const itemId = target.dataset.itemId
|
||||
if (!itemId) return
|
||||
await this.document.openAttackRollDialog({ itemId })
|
||||
}
|
||||
|
||||
static async #onResolveWeaponDamage(event, target) {
|
||||
const itemId = target.dataset.itemId
|
||||
if (!itemId) return
|
||||
await this.document.openDamageDialog({ itemId })
|
||||
}
|
||||
|
||||
static async #onUseSpell(event, target) {
|
||||
const itemId = target.dataset.itemId
|
||||
if (!itemId) return
|
||||
await this.document.openSpellActivationDialog(itemId)
|
||||
}
|
||||
|
||||
static async #onOpenCombatPreset(event, target) {
|
||||
const actionKey = target.dataset.preset
|
||||
if (!actionKey) return
|
||||
await this.document.openCombatPresetDialog(actionKey)
|
||||
}
|
||||
|
||||
static async #onOpenThreadHarvest() {
|
||||
await this.document.openThreadHarvestDialog()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
const { HandlebarsApplicationMixin } = foundry.applications.api
|
||||
|
||||
export default class LesOubliesItemSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ItemSheetV2) {
|
||||
static SHEET_MODES = { EDIT: 0, PLAY: 1 }
|
||||
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ["fvtt-les-oublies", "sheet", "item"],
|
||||
position: {
|
||||
width: 760,
|
||||
height: 720,
|
||||
},
|
||||
window: {
|
||||
resizable: true,
|
||||
},
|
||||
form: {
|
||||
submitOnChange: true,
|
||||
closeOnSubmit: false,
|
||||
},
|
||||
actions: {
|
||||
toggleSheet: LesOubliesItemSheet.#onToggleSheet,
|
||||
editImage: LesOubliesItemSheet.#onEditImage,
|
||||
},
|
||||
}
|
||||
|
||||
_sheetMode = this.constructor.SHEET_MODES.EDIT
|
||||
|
||||
get isEditMode() {
|
||||
return this._sheetMode === this.constructor.SHEET_MODES.EDIT
|
||||
}
|
||||
|
||||
get isPlayMode() {
|
||||
return this._sheetMode === this.constructor.SHEET_MODES.PLAY
|
||||
}
|
||||
|
||||
async _prepareContext() {
|
||||
return {
|
||||
item: this.document,
|
||||
system: this.document.system,
|
||||
source: this.document.toObject(),
|
||||
fields: this.document.schema.fields,
|
||||
systemFields: this.document.system.schema.fields,
|
||||
isEditable: this.isEditable,
|
||||
isEditMode: this.isEditMode,
|
||||
isPlayMode: this.isPlayMode,
|
||||
isGM: game.user.isGM,
|
||||
config: CONFIG.LESOUBLIES,
|
||||
enrichedDescription: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description ?? "", { async: true }),
|
||||
}
|
||||
}
|
||||
|
||||
static #onToggleSheet() {
|
||||
const modes = this.constructor.SHEET_MODES
|
||||
this._sheetMode = this.isEditMode ? modes.PLAY : modes.EDIT
|
||||
this.render()
|
||||
}
|
||||
|
||||
static async #onEditImage(event, target) {
|
||||
const attr = target.dataset.edit
|
||||
const current = foundry.utils.getProperty(this.document, attr)
|
||||
const fp = new FilePicker({
|
||||
current,
|
||||
type: "image",
|
||||
callback: (path) => this.document.update({ [attr]: path }),
|
||||
top: this.position.top + 40,
|
||||
left: this.position.left + 10,
|
||||
})
|
||||
return fp.browse()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import LesOubliesActorSheet from "./base-actor-sheet.mjs"
|
||||
|
||||
export default class LesOubliesCompagnieSheet extends LesOubliesActorSheet {
|
||||
static DEFAULT_OPTIONS = {
|
||||
...super.DEFAULT_OPTIONS,
|
||||
classes: [...super.DEFAULT_OPTIONS.classes, "compagnie"],
|
||||
window: {
|
||||
...super.DEFAULT_OPTIONS.window,
|
||||
title: "TYPES.Actor.compagnie",
|
||||
},
|
||||
}
|
||||
|
||||
static PARTS = {
|
||||
sheet: {
|
||||
template: "systems/fvtt-les-oublies/templates/actor-compagnie-sheet.hbs",
|
||||
},
|
||||
}
|
||||
|
||||
async _prepareContext() {
|
||||
const context = await super._prepareContext()
|
||||
context.members = (this.document.system.memberIds ?? []).map((id) => game.actors.get(id)).filter(Boolean)
|
||||
context.captain = this.document.system.captainId ? game.actors.get(this.document.system.captainId) : null
|
||||
context.shadow = this.document.system.ombreDuTourmentId ? game.actors.get(this.document.system.ombreDuTourmentId) : null
|
||||
context.powers = this.document.getEmbeddedItems("pouvoircompagnie")
|
||||
context.primaryPower = context.powers[0] ?? null
|
||||
context.links = (this.document.system.links ?? []).map((link) => ({
|
||||
...link,
|
||||
sourceLabel: game.actors.get(link.sourceId)?.name ?? link.sourceId,
|
||||
targetLabel: game.actors.get(link.targetId)?.name ?? link.targetId,
|
||||
}))
|
||||
return context
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import LesOubliesItemSheet from "./base-item-sheet.mjs"
|
||||
|
||||
export default class LesOubliesCompetenceSheet extends LesOubliesItemSheet {
|
||||
static PARTS = {
|
||||
sheet: {
|
||||
template: "systems/fvtt-les-oublies/templates/item-competence-sheet.hbs",
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import LesOubliesActorSheet from "./base-actor-sheet.mjs"
|
||||
|
||||
export default class LesOubliesCreatureSheet extends LesOubliesActorSheet {
|
||||
static DEFAULT_OPTIONS = {
|
||||
...super.DEFAULT_OPTIONS,
|
||||
classes: [...super.DEFAULT_OPTIONS.classes, "creature"],
|
||||
window: {
|
||||
...super.DEFAULT_OPTIONS.window,
|
||||
title: "TYPES.Actor.creature",
|
||||
},
|
||||
}
|
||||
|
||||
static PARTS = {
|
||||
sheet: {
|
||||
template: "systems/fvtt-les-oublies/templates/actor-creature-sheet.hbs",
|
||||
},
|
||||
}
|
||||
|
||||
async _prepareContext() {
|
||||
const context = await super._prepareContext()
|
||||
context.derived = this.document.getDerivedOverview()
|
||||
context.skillGroups = this.document.getGroupedCompetences()
|
||||
context.spells = this.document.getEmbeddedItems("sortilege")
|
||||
context.weapons = this.document.getEmbeddedItems("arme")
|
||||
context.armors = this.document.getEmbeddedItems("armure")
|
||||
context.equipment = this.document.getEmbeddedItems("equipement")
|
||||
return context
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import LesOubliesItemSheet from "./base-item-sheet.mjs"
|
||||
|
||||
export default class LesOubliesEquipementSheet extends LesOubliesItemSheet {
|
||||
static PARTS = {
|
||||
sheet: {
|
||||
template: "systems/fvtt-les-oublies/templates/item-equipement-sheet.hbs",
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import LesOubliesActorSheet from "./base-actor-sheet.mjs"
|
||||
|
||||
export default class LesOubliesPersonnageSheet extends LesOubliesActorSheet {
|
||||
static DEFAULT_OPTIONS = {
|
||||
...super.DEFAULT_OPTIONS,
|
||||
classes: [...super.DEFAULT_OPTIONS.classes, "personnage"],
|
||||
window: {
|
||||
...super.DEFAULT_OPTIONS.window,
|
||||
title: "TYPES.Actor.personnage",
|
||||
},
|
||||
}
|
||||
|
||||
static PARTS = {
|
||||
sheet: {
|
||||
template: "systems/fvtt-les-oublies/templates/actor-personnage-sheet.hbs",
|
||||
},
|
||||
}
|
||||
|
||||
async _prepareContext() {
|
||||
const context = await super._prepareContext()
|
||||
context.derived = this.document.getDerivedOverview()
|
||||
context.creation = {
|
||||
race: this.document.getCreationItem("race"),
|
||||
tribu: this.document.getCreationItem("tribu"),
|
||||
metier: this.document.getCreationItem("metier"),
|
||||
}
|
||||
context.profileEntries = this.document.system.profils
|
||||
context.skillGroups = this.document.getGroupedCompetences()
|
||||
context.spells = this.document.getEmbeddedItems("sortilege")
|
||||
context.weapons = this.document.getEmbeddedItems("arme")
|
||||
context.armors = this.document.getEmbeddedItems("armure")
|
||||
context.equipment = this.document.getEmbeddedItems("equipement")
|
||||
context.companyPowers = this.document.getEmbeddedItems("pouvoircompagnie")
|
||||
context.activeCompanyPower = context.derived.compagnie?.getEmbeddedItems?.("pouvoircompagnie")?.[0] ?? null
|
||||
return context
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import LesOubliesItemSheet from "./base-item-sheet.mjs"
|
||||
|
||||
export default class LesOubliesPouvoirCompagnieSheet extends LesOubliesItemSheet {
|
||||
static PARTS = {
|
||||
sheet: {
|
||||
template: "systems/fvtt-les-oublies/templates/item-pouvoir-compagnie-sheet.hbs",
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import LesOubliesItemSheet from "./base-item-sheet.mjs"
|
||||
|
||||
export default class LesOubliesReferenceItemSheet extends LesOubliesItemSheet {
|
||||
static PARTS = {
|
||||
sheet: {
|
||||
template: "systems/fvtt-les-oublies/templates/item-reference-sheet.hbs",
|
||||
},
|
||||
}
|
||||
|
||||
async _prepareContext() {
|
||||
const context = await super._prepareContext()
|
||||
context.isRace = this.document.type === "race"
|
||||
context.isTribu = this.document.type === "tribu"
|
||||
context.isMetier = this.document.type === "metier"
|
||||
return context
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import LesOubliesItemSheet from "./base-item-sheet.mjs"
|
||||
|
||||
export default class LesOubliesSortilegeSheet extends LesOubliesItemSheet {
|
||||
static PARTS = {
|
||||
sheet: {
|
||||
template: "systems/fvtt-les-oublies/templates/item-sortilege-sheet.hbs",
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
import { LESOUBLIES_CONFIG } from "./les-oublies-config.js"
|
||||
import { LesOubliesUtility } from "./les-oublies-utility.js"
|
||||
import { LesOubliesRolls } from "./les-oublies-rolls.js"
|
||||
|
||||
export class LesOubliesActor extends Actor {
|
||||
prepareDerivedData() {
|
||||
super.prepareDerivedData()
|
||||
|
||||
if (this.type === "personnage") {
|
||||
const system = this.system
|
||||
const sizeValue = Math.clamp(Number(system.size?.value ?? 1), 1, 4)
|
||||
const hpMax = Math.max(sizeValue * 4 + Number(system.hp?.bonus ?? 0), 0)
|
||||
system.hp.max = hpMax
|
||||
system.hp.value = Math.min(Number(system.hp.value ?? hpMax), hpMax)
|
||||
|
||||
const songesValue = Number(system.songes?.value ?? 0)
|
||||
const cauchemarValue = Number(system.cauchemar?.value ?? 0)
|
||||
const totals = LesOubliesUtility.computeDreamPointTotals(songesValue, cauchemarValue)
|
||||
system.songes.max = totals.songesPoints
|
||||
system.cauchemar.max = totals.cauchemarPoints
|
||||
system.songes.points = Math.clamp(Number(system.songes.points ?? totals.songesPoints), 0, totals.songesPoints)
|
||||
system.cauchemar.points = Math.clamp(Number(system.cauchemar.points ?? totals.cauchemarPoints), 0, totals.cauchemarPoints)
|
||||
return
|
||||
}
|
||||
|
||||
if (this.type !== "creature") return
|
||||
|
||||
const system = this.system
|
||||
const hpValue = Math.max(Number(system.hp?.value ?? 0), 0)
|
||||
const hpMax = Math.max(Number(system.hp?.max ?? hpValue), hpValue, 0)
|
||||
system.hp.max = hpMax
|
||||
system.hp.value = Math.min(hpValue, hpMax)
|
||||
const songesPoints = Math.max(Number(system.songes?.points ?? 0), 0)
|
||||
const cauchemarPoints = Math.max(Number(system.cauchemar?.points ?? 0), 0)
|
||||
system.songes.max = Math.max(Number(system.songes?.max ?? songesPoints), songesPoints)
|
||||
system.cauchemar.max = Math.max(Number(system.cauchemar?.max ?? cauchemarPoints), cauchemarPoints)
|
||||
system.songes.points = Math.min(songesPoints, system.songes.max)
|
||||
system.cauchemar.points = Math.min(cauchemarPoints, system.cauchemar.max)
|
||||
}
|
||||
|
||||
getProfileValue(profileKey) {
|
||||
return Number(this.system.profils?.[profileKey] ?? 0)
|
||||
}
|
||||
|
||||
getCreationItem(type) {
|
||||
return this.items.find((item) => item.type === type) ?? null
|
||||
}
|
||||
|
||||
getEmbeddedItems(type) {
|
||||
const items = this.itemTypes?.[type] ?? this.items.filter((item) => item.type === type)
|
||||
return LesOubliesUtility.sortByName(items)
|
||||
}
|
||||
|
||||
getCompagnie() {
|
||||
const compagnieId = this.system.references?.compagnieId
|
||||
return compagnieId ? game.actors.get(compagnieId) ?? null : null
|
||||
}
|
||||
|
||||
getCompetenceByKey(skillKey) {
|
||||
return this.getEmbeddedItems("competence").find((item) => item.system.key === skillKey) ?? null
|
||||
}
|
||||
|
||||
getSkillScoreByKey(skillKey) {
|
||||
const competence = this.getCompetenceByKey(skillKey)
|
||||
return competence ? this.computeSkillValue(competence) : 0
|
||||
}
|
||||
|
||||
computeSkillValue(item) {
|
||||
const base = Number(item.system.base ?? 0)
|
||||
const profileValue = this.getProfileValue(item.system.profileKey)
|
||||
if (item.system.closed && base === 0) return 0
|
||||
return base + profileValue
|
||||
}
|
||||
|
||||
getCompetences() {
|
||||
return this.getEmbeddedItems("competence").map((item) => ({
|
||||
item,
|
||||
finalValue: this.computeSkillValue(item),
|
||||
profileLabel: LESOUBLIES_CONFIG.profileLabels[item.system.profileKey] ?? item.system.profileKey,
|
||||
}))
|
||||
}
|
||||
|
||||
getGroupedCompetences() {
|
||||
return LESOUBLIES_CONFIG.profiles.map((profile) => ({
|
||||
...profile,
|
||||
items: this.getCompetences().filter((entry) => entry.item.system.profileKey === profile.id),
|
||||
}))
|
||||
}
|
||||
|
||||
getDerivedOverview() {
|
||||
const hpValue = Number(this.system.hp?.value ?? 0)
|
||||
const hpMax = Number(this.system.hp?.max ?? 0)
|
||||
const hpDisplay = this.type === "creature"
|
||||
? (this.system.hp?.display || (hpValue === hpMax ? String(hpValue) : `${hpValue}/${hpMax}`))
|
||||
: `${hpValue}/${hpMax}`
|
||||
|
||||
return {
|
||||
sizeLabel: LESOUBLIES_CONFIG.sizes[this.system.size?.value] ?? this.system.size?.value,
|
||||
hpMax,
|
||||
hpValue,
|
||||
hpDisplay,
|
||||
songesMax: this.system.songes?.max ?? this.system.songes?.points ?? 0,
|
||||
cauchemarMax: this.system.cauchemar?.max ?? this.system.cauchemar?.points ?? 0,
|
||||
songesPoints: this.system.songes?.points ?? 0,
|
||||
cauchemarPoints: this.system.cauchemar?.points ?? 0,
|
||||
race: this.getCreationItem("race"),
|
||||
tribu: this.getCreationItem("tribu"),
|
||||
metier: this.getCreationItem("metier"),
|
||||
compagnie: this.getCompagnie(),
|
||||
}
|
||||
}
|
||||
|
||||
async openTestRollDialog(preset = {}) {
|
||||
return LesOubliesRolls.openTestDialog(this, preset)
|
||||
}
|
||||
|
||||
async openConfrontationRollDialog() {
|
||||
return LesOubliesRolls.openConfrontationDialog(this)
|
||||
}
|
||||
|
||||
async openInitiativeRollDialog() {
|
||||
return LesOubliesRolls.openInitiativeDialog(this)
|
||||
}
|
||||
|
||||
async openAttackRollDialog({ itemId = null, mode = null } = {}) {
|
||||
return LesOubliesRolls.openAttackDialog(this, { itemId, mode })
|
||||
}
|
||||
|
||||
async openDamageDialog({ itemId = null } = {}) {
|
||||
return LesOubliesRolls.openDamageDialog(this, { itemId })
|
||||
}
|
||||
|
||||
async openSpellActivationDialog(itemId) {
|
||||
return LesOubliesRolls.openSpellDialog(this, itemId)
|
||||
}
|
||||
|
||||
async openCombatPresetDialog(actionKey) {
|
||||
return LesOubliesRolls.openCombatPresetDialog(this, actionKey)
|
||||
}
|
||||
|
||||
async openThreadHarvestDialog() {
|
||||
return LesOubliesRolls.openThreadHarvestDialog(this)
|
||||
}
|
||||
|
||||
async rollProfile(profileKey) {
|
||||
return this.openTestRollDialog({
|
||||
label: LESOUBLIES_CONFIG.profileLabels[profileKey] ?? profileKey,
|
||||
score: this.getProfileValue(profileKey),
|
||||
difficulty: 0,
|
||||
rollMode: LesOubliesRolls.getDefaultRollMode(this),
|
||||
})
|
||||
}
|
||||
|
||||
async rollCompetence(itemId) {
|
||||
const item = this.items.get(itemId)
|
||||
if (!item) return null
|
||||
return this.openTestRollDialog({
|
||||
label: item.name,
|
||||
score: this.computeSkillValue(item),
|
||||
difficulty: 0,
|
||||
rollMode: LesOubliesRolls.getDefaultRollMode(this),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
export const PROFILE_KEYS = [
|
||||
"artiste",
|
||||
"athlete",
|
||||
"chasseur",
|
||||
"faiseur",
|
||||
"forceNature",
|
||||
"guerrier",
|
||||
"mystique",
|
||||
"ombre",
|
||||
"savant",
|
||||
]
|
||||
|
||||
export const PROFILE_LABELS = {
|
||||
artiste: "Artiste",
|
||||
athlete: "Athlète",
|
||||
chasseur: "Chasseur",
|
||||
faiseur: "Faiseur",
|
||||
forceNature: "Force de la nature",
|
||||
guerrier: "Guerrier",
|
||||
mystique: "Mystique",
|
||||
ombre: "Ombre",
|
||||
savant: "Savant",
|
||||
}
|
||||
|
||||
export const SKILLS = {
|
||||
arts: { label: "Arts", profileKey: "artiste", closed: false, domainSkill: true },
|
||||
empathie: { label: "Empathie", profileKey: "artiste", closed: false, domainSkill: false },
|
||||
seduction: { label: "Séduction", profileKey: "artiste", closed: false, domainSkill: false },
|
||||
athletisme: { label: "Athlétisme", profileKey: "athlete", closed: false, domainSkill: false },
|
||||
rapidite: { label: "Rapidité", profileKey: "athlete", closed: false, domainSkill: false },
|
||||
volonte: { label: "Volonté", profileKey: "athlete", closed: false, domainSkill: false },
|
||||
sens: { label: "Sens", profileKey: "chasseur", closed: false, domainSkill: false },
|
||||
survie: { label: "Survie", profileKey: "chasseur", closed: false, domainSkill: false },
|
||||
tir: { label: "Tir", profileKey: "chasseur", closed: false, domainSkill: false },
|
||||
artisanat: { label: "Artisanat", profileKey: "faiseur", closed: false, domainSkill: true },
|
||||
intellect: { label: "Intellect", profileKey: "faiseur", closed: false, domainSkill: false },
|
||||
soins: { label: "Soins", profileKey: "faiseur", closed: false, domainSkill: false },
|
||||
commandement: { label: "Commandement", profileKey: "forceNature", closed: false, domainSkill: false },
|
||||
endurance: { label: "Endurance", profileKey: "forceNature", closed: false, domainSkill: false },
|
||||
force: { label: "Force", profileKey: "forceNature", closed: false, domainSkill: false },
|
||||
corpsacorps: { label: "Corps à corps", profileKey: "guerrier", closed: false, domainSkill: false },
|
||||
melee: { label: "Mêlée", profileKey: "guerrier", closed: false, domainSkill: false },
|
||||
montures: { label: "Montures", profileKey: "guerrier", closed: false, domainSkill: false },
|
||||
chimerisme: { label: "Chimérisme", profileKey: "mystique", closed: true, domainSkill: false },
|
||||
magie: { label: "Magie", profileKey: "mystique", closed: true, domainSkill: false },
|
||||
onirologie: { label: "Onirologie", profileKey: "mystique", closed: true, domainSkill: false },
|
||||
discretion: { label: "Discrétion", profileKey: "ombre", closed: false, domainSkill: false },
|
||||
esquive: { label: "Esquive", profileKey: "ombre", closed: false, domainSkill: false },
|
||||
subterfuge: { label: "Subterfuge", profileKey: "ombre", closed: false, domainSkill: false },
|
||||
erudition: { label: "Érudition", profileKey: "savant", closed: true, domainSkill: true },
|
||||
langues: { label: "Langues", profileKey: "savant", closed: true, domainSkill: true },
|
||||
strategie: { label: "Stratégie", profileKey: "savant", closed: false, domainSkill: false },
|
||||
}
|
||||
|
||||
export const SIZE_LABELS = {
|
||||
1: "Minuscule",
|
||||
2: "Petite",
|
||||
3: "Moyenne",
|
||||
4: "Grande",
|
||||
}
|
||||
|
||||
export const ACTOR_IMAGES = {
|
||||
personnage: "icons/svg/mystery-man.svg",
|
||||
compagnie: "icons/svg/book.svg",
|
||||
creature: "icons/svg/eye.svg",
|
||||
}
|
||||
|
||||
export const ITEM_IMAGES = {
|
||||
race: "icons/svg/mystery-man.svg",
|
||||
tribu: "icons/svg/ruins.svg",
|
||||
metier: "icons/svg/upgrade.svg",
|
||||
competence: "icons/svg/book.svg",
|
||||
sortilege: "icons/svg/daze.svg",
|
||||
arme: "icons/svg/sword.svg",
|
||||
armure: "icons/svg/shield.svg",
|
||||
equipement: "icons/svg/chest.svg",
|
||||
pouvoircompagnie: "icons/svg/aura.svg",
|
||||
}
|
||||
|
||||
export const LESOUBLIES_CONFIG = {
|
||||
id: "fvtt-les-oublies",
|
||||
title: "Les Oubliés",
|
||||
profiles: PROFILE_KEYS.map((key) => ({ id: key, label: PROFILE_LABELS[key] })),
|
||||
profileLabels: PROFILE_LABELS,
|
||||
skills: SKILLS,
|
||||
sizes: SIZE_LABELS,
|
||||
actorImages: ACTOR_IMAGES,
|
||||
itemImages: ITEM_IMAGES,
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
export class LesOubliesItem extends Item {
|
||||
getChatData() {
|
||||
const data = super.getChatData()
|
||||
return {
|
||||
...data,
|
||||
description: this.system.description,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import { LESOUBLIES_CONFIG } from "./les-oublies-config.js"
|
||||
import { LesOubliesUtility } from "./les-oublies-utility.js"
|
||||
import { LesOubliesActor } from "./les-oublies-actor.js"
|
||||
import { LesOubliesItem } from "./les-oublies-item.js"
|
||||
import { LesOubliesRolls } from "./les-oublies-rolls.js"
|
||||
import * as models from "./models/index.mjs"
|
||||
import * as sheets from "./applications/sheets/_module.mjs"
|
||||
|
||||
Hooks.once("init", function () {
|
||||
console.info("Les Oubliés | Initialisation du système")
|
||||
|
||||
CONFIG.Actor.documentClass = LesOubliesActor
|
||||
CONFIG.Actor.dataModels = {
|
||||
personnage: models.PersonnageDataModel,
|
||||
compagnie: models.CompagnieDataModel,
|
||||
creature: models.CreatureDataModel,
|
||||
}
|
||||
|
||||
CONFIG.Item.documentClass = LesOubliesItem
|
||||
CONFIG.Item.dataModels = {
|
||||
race: models.RaceDataModel,
|
||||
tribu: models.TribuDataModel,
|
||||
metier: models.MetierDataModel,
|
||||
competence: models.CompetenceDataModel,
|
||||
sortilege: models.SortilegeDataModel,
|
||||
arme: models.ArmeDataModel,
|
||||
armure: models.ArmureDataModel,
|
||||
equipement: models.EquipementDataModel,
|
||||
pouvoircompagnie: models.PouvoirCompagnieDataModel,
|
||||
}
|
||||
|
||||
CONFIG.LESOUBLIES = LESOUBLIES_CONFIG
|
||||
|
||||
game.system.lesOublies = {
|
||||
config: LESOUBLIES_CONFIG,
|
||||
models,
|
||||
sheets,
|
||||
rolls: LesOubliesRolls,
|
||||
utility: LesOubliesUtility,
|
||||
}
|
||||
|
||||
foundry.documents.collections.Actors.registerSheet("fvtt-les-oublies", sheets.LesOubliesPersonnageSheet, { types: ["personnage"], makeDefault: true })
|
||||
foundry.documents.collections.Actors.registerSheet("fvtt-les-oublies", sheets.LesOubliesCompagnieSheet, { types: ["compagnie"], makeDefault: true })
|
||||
foundry.documents.collections.Actors.registerSheet("fvtt-les-oublies", sheets.LesOubliesCreatureSheet, { types: ["creature"], makeDefault: true })
|
||||
|
||||
foundry.documents.collections.Items.registerSheet("fvtt-les-oublies", sheets.LesOubliesReferenceItemSheet, { types: ["race", "tribu", "metier"], makeDefault: true })
|
||||
foundry.documents.collections.Items.registerSheet("fvtt-les-oublies", sheets.LesOubliesCompetenceSheet, { types: ["competence"], makeDefault: true })
|
||||
foundry.documents.collections.Items.registerSheet("fvtt-les-oublies", sheets.LesOubliesSortilegeSheet, { types: ["sortilege"], makeDefault: true })
|
||||
foundry.documents.collections.Items.registerSheet("fvtt-les-oublies", sheets.LesOubliesArmeSheet, { types: ["arme"], makeDefault: true })
|
||||
foundry.documents.collections.Items.registerSheet("fvtt-les-oublies", sheets.LesOubliesArmureSheet, { types: ["armure"], makeDefault: true })
|
||||
foundry.documents.collections.Items.registerSheet("fvtt-les-oublies", sheets.LesOubliesEquipementSheet, { types: ["equipement"], makeDefault: true })
|
||||
foundry.documents.collections.Items.registerSheet("fvtt-les-oublies", sheets.LesOubliesPouvoirCompagnieSheet, { types: ["pouvoircompagnie"], makeDefault: true })
|
||||
|
||||
LesOubliesUtility.registerHandlebarsHelpers()
|
||||
})
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,76 @@
|
||||
import { ACTOR_IMAGES, ITEM_IMAGES, LESOUBLIES_CONFIG, PROFILE_KEYS } from "./les-oublies-config.js"
|
||||
|
||||
export class LesOubliesUtility {
|
||||
static registerHandlebarsHelpers() {
|
||||
Handlebars.registerHelper("eq", (left, right) => left === right)
|
||||
Handlebars.registerHelper("join", (values, separator = ", ") => Array.isArray(values) ? values.filter(Boolean).join(separator) : "")
|
||||
Handlebars.registerHelper("count", (values) => Array.isArray(values) ? values.length : 0)
|
||||
Handlebars.registerHelper("concat", (...parts) => parts.slice(0, -1).join(""))
|
||||
Handlebars.registerHelper("profileLabel", (key) => LESOUBLIES_CONFIG.profileLabels[key] ?? key)
|
||||
Handlebars.registerHelper("skillLabel", (key) => LESOUBLIES_CONFIG.skills[key]?.label ?? key)
|
||||
Handlebars.registerHelper("formatPrice", (value) => Number(value) > 0 ? `${value} e` : "—")
|
||||
Handlebars.registerHelper("formatSkillBonus", (bonus) => {
|
||||
const keys = [bonus.key, ...(bonus.alternativeKeys ?? [])]
|
||||
.filter(Boolean)
|
||||
.map((key) => LESOUBLIES_CONFIG.skills[key]?.label ?? key)
|
||||
const label = keys.join(" ou ")
|
||||
const domains = []
|
||||
if (Array.isArray(bonus.domainsGranted) && bonus.domainsGranted.length) domains.push(bonus.domainsGranted.join(", "))
|
||||
if (Number(bonus.domainsToChoose ?? 0) > 0) {
|
||||
const prefix = bonus.domainsToChoose > 1 ? `${bonus.domainsToChoose} choix` : "1 choix"
|
||||
domains.push(bonus.domainsChoiceText ? `${prefix} : ${bonus.domainsChoiceText}` : prefix)
|
||||
}
|
||||
return domains.length ? `${label} +${bonus.base} — ${domains.join(" ; ")}` : `${label} +${bonus.base}`
|
||||
})
|
||||
Handlebars.registerHelper("formatEquipmentEntry", (entry) => {
|
||||
const baseLabel = entry.choiceText || entry.name || ""
|
||||
const quantity = Number(entry.quantity ?? 0) > 1 ? ` x${entry.quantity}` : ""
|
||||
const extras = []
|
||||
if (entry.details) extras.push(entry.details)
|
||||
if (Number(entry.ecorces ?? 0) > 0) extras.push(`${entry.ecorces} écorces`)
|
||||
return extras.length ? `${baseLabel}${quantity} — ${extras.join(", ")}` : `${baseLabel}${quantity}`
|
||||
})
|
||||
Handlebars.registerHelper("formatSpellGrant", (grant) => {
|
||||
const discipline = LESOUBLIES_CONFIG.skills[grant.skillKey]?.label ?? grant.skillKey ?? grant.tradition
|
||||
return `${grant.tradition} (${discipline}) / ${grant.polarity} : ${grant.amount}`
|
||||
})
|
||||
}
|
||||
|
||||
static getDefaultActorImage(type) {
|
||||
return ACTOR_IMAGES[type] ?? "icons/svg/mystery-man.svg"
|
||||
}
|
||||
|
||||
static getDefaultItemImage(type) {
|
||||
return ITEM_IMAGES[type] ?? "icons/svg/item-bag.svg"
|
||||
}
|
||||
|
||||
static createEmptyProfiles() {
|
||||
return PROFILE_KEYS.reduce((profiles, key) => {
|
||||
profiles[key] = 0
|
||||
return profiles
|
||||
}, {})
|
||||
}
|
||||
|
||||
static computeDreamPointTotals(songesValue, cauchemarValue) {
|
||||
if (songesValue > cauchemarValue) {
|
||||
return {
|
||||
songesPoints: songesValue * 2 - cauchemarValue,
|
||||
cauchemarPoints: cauchemarValue,
|
||||
}
|
||||
}
|
||||
if (songesValue === cauchemarValue) {
|
||||
return {
|
||||
songesPoints: songesValue,
|
||||
cauchemarPoints: cauchemarValue,
|
||||
}
|
||||
}
|
||||
return {
|
||||
songesPoints: songesValue,
|
||||
cauchemarPoints: cauchemarValue * 3 - songesValue * 2,
|
||||
}
|
||||
}
|
||||
|
||||
static sortByName(documents = []) {
|
||||
return [...documents].sort((left, right) => left.name.localeCompare(right.name, "fr"))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { BaseItemDataModel } from "./base-item.mjs"
|
||||
|
||||
export default class ArmeDataModel extends BaseItemDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
return {
|
||||
...this.defineBaseSchema(),
|
||||
category: new fields.StringField({ initial: "melee" }),
|
||||
origin: new fields.StringField({ initial: "petitPeuple" }),
|
||||
sizeMode: new fields.StringField({ initial: "variable" }),
|
||||
sizeValue: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
sizeModifier: new fields.NumberField({ initial: 0, integer: true }),
|
||||
damage: new fields.StringField({ initial: "" }),
|
||||
range: new fields.StringField({ initial: "" }),
|
||||
properties: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||
restrictedRace: new fields.StringField({ initial: "" }),
|
||||
quantity: new fields.NumberField({ initial: 1, integer: true, min: 0 }),
|
||||
price: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
equipped: new fields.BooleanField({ initial: false }),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { BaseItemDataModel } from "./base-item.mjs"
|
||||
|
||||
export default class ArmureDataModel extends BaseItemDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
return {
|
||||
...this.defineBaseSchema(),
|
||||
state: new fields.StringField({ initial: "protege" }),
|
||||
protection: new fields.NumberField({ initial: 1, integer: true, min: 0 }),
|
||||
physicalPenalty: new fields.NumberField({ initial: 1, integer: true, min: 0 }),
|
||||
initiativePenalty: new fields.NumberField({ initial: 1, integer: true, min: 0 }),
|
||||
quantity: new fields.NumberField({ initial: 1, integer: true, min: 0 }),
|
||||
price: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
equipped: new fields.BooleanField({ initial: false }),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
export class BaseItemDataModel extends foundry.abstract.TypeDataModel {
|
||||
static defineBaseSchema() {
|
||||
const fields = foundry.data.fields
|
||||
return {
|
||||
description: new fields.HTMLField({ initial: "" }),
|
||||
notes: new fields.HTMLField({ initial: "" }),
|
||||
source: new fields.StringField({ initial: "Livre de règles Les Oubliés" }),
|
||||
tags: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
export default class CompagnieDataModel extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
return {
|
||||
description: new fields.HTMLField({ initial: "" }),
|
||||
notes: new fields.HTMLField({ initial: "" }),
|
||||
captainId: new fields.StringField({ initial: "" }),
|
||||
memberIds: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||
ombreDuTourmentId: new fields.StringField({ initial: "" }),
|
||||
power: new fields.SchemaField({
|
||||
name: new fields.StringField({ initial: "" }),
|
||||
description: new fields.HTMLField({ initial: "" }),
|
||||
sharedDreamPoints: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
activationCondition: new fields.StringField({ initial: "À portée de vue du capitaine" }),
|
||||
captainVisible: new fields.BooleanField({ initial: true }),
|
||||
captainNeedsWitness: new fields.BooleanField({ initial: true }),
|
||||
}),
|
||||
links: new fields.ArrayField(new fields.SchemaField({
|
||||
sourceId: new fields.StringField({ initial: "" }),
|
||||
targetId: new fields.StringField({ initial: "" }),
|
||||
label: new fields.StringField({ initial: "" }),
|
||||
details: new fields.StringField({ initial: "" }),
|
||||
}), { initial: [] }),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { BaseItemDataModel } from "./base-item.mjs"
|
||||
|
||||
export default class CompetenceDataModel extends BaseItemDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
return {
|
||||
...this.defineBaseSchema(),
|
||||
key: new fields.StringField({ initial: "" }),
|
||||
profileKey: new fields.StringField({ initial: "" }),
|
||||
base: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
closed: new fields.BooleanField({ initial: false }),
|
||||
domainSkill: new fields.BooleanField({ initial: false }),
|
||||
domains: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||
fixedDomains: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||
exampleDomains: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
export default class CreatureDataModel extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
return {
|
||||
biodata: new fields.SchemaField({
|
||||
categorie: new fields.StringField({ initial: "autre" }),
|
||||
habitat: new fields.HTMLField({ initial: "" }),
|
||||
motscles: new fields.StringField({ initial: "" }),
|
||||
description: new fields.HTMLField({ initial: "" }),
|
||||
notes: new fields.HTMLField({ initial: "" }),
|
||||
gmnotes: new fields.HTMLField({ initial: "" }),
|
||||
}),
|
||||
size: new fields.SchemaField({
|
||||
value: new fields.NumberField({ initial: 2, integer: true, min: 1, max: 8 }),
|
||||
label: new fields.StringField({ initial: "" }),
|
||||
}),
|
||||
profils: new fields.SchemaField({
|
||||
artiste: new fields.NumberField({ initial: 0, integer: true }),
|
||||
athlete: new fields.NumberField({ initial: 0, integer: true }),
|
||||
chasseur: new fields.NumberField({ initial: 0, integer: true }),
|
||||
faiseur: new fields.NumberField({ initial: 0, integer: true }),
|
||||
forceNature: new fields.NumberField({ initial: 0, integer: true }),
|
||||
guerrier: new fields.NumberField({ initial: 0, integer: true }),
|
||||
mystique: new fields.NumberField({ initial: 0, integer: true }),
|
||||
ombre: new fields.NumberField({ initial: 0, integer: true }),
|
||||
savant: new fields.NumberField({ initial: 0, integer: true }),
|
||||
}),
|
||||
songes: new fields.SchemaField({
|
||||
value: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
points: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
max: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
}),
|
||||
cauchemar: new fields.SchemaField({
|
||||
value: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
points: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
max: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
}),
|
||||
hp: new fields.SchemaField({
|
||||
value: new fields.NumberField({ initial: 8, integer: true, min: 0 }),
|
||||
max: new fields.NumberField({ initial: 8, integer: true, min: 0 }),
|
||||
display: new fields.StringField({ initial: "" }),
|
||||
}),
|
||||
protection: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
statblock: new fields.SchemaField({
|
||||
damage: new fields.HTMLField({ initial: "" }),
|
||||
special: new fields.HTMLField({ initial: "" }),
|
||||
spellSonges: new fields.HTMLField({ initial: "" }),
|
||||
spellCauchemar: new fields.HTMLField({ initial: "" }),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { BaseItemDataModel } from "./base-item.mjs"
|
||||
|
||||
export default class EquipementDataModel extends BaseItemDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
return {
|
||||
...this.defineBaseSchema(),
|
||||
category: new fields.StringField({ initial: "survie" }),
|
||||
quantity: new fields.NumberField({ initial: 1, integer: true, min: 0 }),
|
||||
price: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
bonus: new fields.StringField({ initial: "" }),
|
||||
usage: new fields.StringField({ initial: "" }),
|
||||
lifespan: new fields.StringField({ initial: "" }),
|
||||
equipped: new fields.BooleanField({ initial: false }),
|
||||
consumable: new fields.BooleanField({ initial: false }),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
export { BaseItemDataModel } from "./base-item.mjs"
|
||||
export { default as PersonnageDataModel } from "./personnage.mjs"
|
||||
export { default as CompagnieDataModel } from "./compagnie.mjs"
|
||||
export { default as CreatureDataModel } from "./creature.mjs"
|
||||
export { default as RaceDataModel } from "./race.mjs"
|
||||
export { default as TribuDataModel } from "./tribu.mjs"
|
||||
export { default as MetierDataModel } from "./metier.mjs"
|
||||
export { default as CompetenceDataModel } from "./competence.mjs"
|
||||
export { default as SortilegeDataModel } from "./sortilege.mjs"
|
||||
export { default as ArmeDataModel } from "./arme.mjs"
|
||||
export { default as ArmureDataModel } from "./armure.mjs"
|
||||
export { default as EquipementDataModel } from "./equipement.mjs"
|
||||
export { default as PouvoirCompagnieDataModel } from "./pouvoir-compagnie.mjs"
|
||||
@@ -0,0 +1,39 @@
|
||||
import { BaseItemDataModel } from "./base-item.mjs"
|
||||
|
||||
export default class MetierDataModel extends BaseItemDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
return {
|
||||
...this.defineBaseSchema(),
|
||||
specialRules: new fields.HTMLField({ initial: "" }),
|
||||
roleplayNotes: new fields.HTMLField({ initial: "" }),
|
||||
skillBonuses: new fields.ArrayField(new fields.SchemaField({
|
||||
key: new fields.StringField({ initial: "" }),
|
||||
alternativeKeys: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||
base: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
domainsGranted: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||
domainsToChoose: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
domainsChoiceText: new fields.StringField({ initial: "" }),
|
||||
}), { initial: [] }),
|
||||
startingEquipment: new fields.ArrayField(new fields.SchemaField({
|
||||
name: new fields.StringField({ initial: "" }),
|
||||
type: new fields.StringField({ initial: "equipement" }),
|
||||
quantity: new fields.NumberField({ initial: 1, integer: true, min: 0 }),
|
||||
details: new fields.StringField({ initial: "" }),
|
||||
choiceText: new fields.StringField({ initial: "" }),
|
||||
ecorces: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
}), { initial: [] }),
|
||||
spellGrants: new fields.ArrayField(new fields.SchemaField({
|
||||
tradition: new fields.StringField({ initial: "" }),
|
||||
skillKey: new fields.StringField({ initial: "" }),
|
||||
polarity: new fields.StringField({ initial: "" }),
|
||||
amount: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
}), { initial: [] }),
|
||||
revenues: new fields.SchemaField({
|
||||
beginner: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
intermediate: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
expert: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
export default class PersonnageDataModel extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
return {
|
||||
biodata: new fields.SchemaField({
|
||||
age: new fields.NumberField({ initial: 20, integer: true, min: 0 }),
|
||||
sexe: new fields.StringField({ initial: "" }),
|
||||
motscles: new fields.StringField({ initial: "" }),
|
||||
description: new fields.HTMLField({ initial: "" }),
|
||||
notes: new fields.HTMLField({ initial: "" }),
|
||||
gmnotes: new fields.HTMLField({ initial: "" }),
|
||||
}),
|
||||
references: new fields.SchemaField({
|
||||
raceId: new fields.StringField({ initial: "" }),
|
||||
tribuId: new fields.StringField({ initial: "" }),
|
||||
metierId: new fields.StringField({ initial: "" }),
|
||||
compagnieId: new fields.StringField({ initial: "" }),
|
||||
}),
|
||||
size: new fields.SchemaField({
|
||||
value: new fields.NumberField({ initial: 2, integer: true, min: 1, max: 4 }),
|
||||
label: new fields.StringField({ initial: "" }),
|
||||
}),
|
||||
profils: new fields.SchemaField({
|
||||
artiste: new fields.NumberField({ initial: 0, integer: true }),
|
||||
athlete: new fields.NumberField({ initial: 0, integer: true }),
|
||||
chasseur: new fields.NumberField({ initial: 0, integer: true }),
|
||||
faiseur: new fields.NumberField({ initial: 0, integer: true }),
|
||||
forceNature: new fields.NumberField({ initial: 0, integer: true }),
|
||||
guerrier: new fields.NumberField({ initial: 0, integer: true }),
|
||||
mystique: new fields.NumberField({ initial: 0, integer: true }),
|
||||
ombre: new fields.NumberField({ initial: 0, integer: true }),
|
||||
savant: new fields.NumberField({ initial: 0, integer: true }),
|
||||
}),
|
||||
songes: new fields.SchemaField({
|
||||
value: new fields.NumberField({ initial: 1, integer: true, min: 0 }),
|
||||
points: new fields.NumberField({ initial: 2, integer: true, min: 0 }),
|
||||
max: new fields.NumberField({ initial: 2, integer: true, min: 0 }),
|
||||
debt: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
xpCredit: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
}),
|
||||
cauchemar: new fields.SchemaField({
|
||||
value: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
points: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
max: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
debt: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
xpCredit: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
}),
|
||||
hp: new fields.SchemaField({
|
||||
value: new fields.NumberField({ initial: 8, integer: true, min: 0 }),
|
||||
max: new fields.NumberField({ initial: 8, integer: true, min: 0 }),
|
||||
bonus: new fields.NumberField({ initial: 0, integer: true }),
|
||||
}),
|
||||
experience: new fields.SchemaField({
|
||||
value: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
}),
|
||||
money: new fields.SchemaField({
|
||||
ecorces: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
}),
|
||||
flagsNarratifs: new fields.SchemaField({
|
||||
ombreDuTourment: new fields.BooleanField({ initial: false }),
|
||||
isCaptain: new fields.BooleanField({ initial: false }),
|
||||
}),
|
||||
visions: new fields.HTMLField({ initial: "" }),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { BaseItemDataModel } from "./base-item.mjs"
|
||||
|
||||
export default class PouvoirCompagnieDataModel extends BaseItemDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
return {
|
||||
...this.defineBaseSchema(),
|
||||
scope: new fields.StringField({ initial: "compagnie" }),
|
||||
effectMode: new fields.StringField({ initial: "" }),
|
||||
ruleText: new fields.HTMLField({ initial: "" }),
|
||||
limitedUses: new fields.StringField({ initial: "" }),
|
||||
resourceImpact: new fields.StringField({ initial: "" }),
|
||||
activationCondition: new fields.StringField({ initial: "À portée de vue du capitaine" }),
|
||||
captainVisible: new fields.BooleanField({ initial: true }),
|
||||
captainNeedsWitness: new fields.BooleanField({ initial: true }),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { BaseItemDataModel } from "./base-item.mjs"
|
||||
|
||||
export default class RaceDataModel extends BaseItemDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
return {
|
||||
...this.defineBaseSchema(),
|
||||
size: new fields.NumberField({ initial: 2, integer: true, min: 1, max: 4 }),
|
||||
lifeExpectancy: new fields.NumberField({ initial: 50, integer: true, min: 0 }),
|
||||
keywords: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||
mainTribes: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||
language: new fields.StringField({ initial: "" }),
|
||||
languageDomains: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||
specialRules: new fields.HTMLField({ initial: "" }),
|
||||
appearance: new fields.HTMLField({ initial: "" }),
|
||||
roleplayHints: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||
profiles: new fields.SchemaField({
|
||||
artiste: new fields.NumberField({ initial: 0, integer: true }),
|
||||
athlete: new fields.NumberField({ initial: 0, integer: true }),
|
||||
chasseur: new fields.NumberField({ initial: 0, integer: true }),
|
||||
faiseur: new fields.NumberField({ initial: 0, integer: true }),
|
||||
forceNature: new fields.NumberField({ initial: 0, integer: true }),
|
||||
guerrier: new fields.NumberField({ initial: 0, integer: true }),
|
||||
mystique: new fields.NumberField({ initial: 0, integer: true }),
|
||||
ombre: new fields.NumberField({ initial: 0, integer: true }),
|
||||
savant: new fields.NumberField({ initial: 0, integer: true }),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { BaseItemDataModel } from "./base-item.mjs"
|
||||
|
||||
export default class SortilegeDataModel extends BaseItemDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
return {
|
||||
...this.defineBaseSchema(),
|
||||
tradition: new fields.StringField({ initial: "" }),
|
||||
skillKey: new fields.StringField({ initial: "" }),
|
||||
polarity: new fields.StringField({ initial: "songes" }),
|
||||
cost: new fields.NumberField({ initial: 1, integer: true, min: 0 }),
|
||||
costFormula: new fields.StringField({ initial: "" }),
|
||||
variableCost: new fields.BooleanField({ initial: false }),
|
||||
preparation: new fields.StringField({ initial: "" }),
|
||||
duration: new fields.StringField({ initial: "" }),
|
||||
range: new fields.StringField({ initial: "" }),
|
||||
area: new fields.StringField({ initial: "" }),
|
||||
stacking: new fields.StringField({ initial: "" }),
|
||||
requiredDomains: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||
artsDomains: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||
effectsText: new fields.HTMLField({ initial: "" }),
|
||||
ruleTags: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { BaseItemDataModel } from "./base-item.mjs"
|
||||
|
||||
export default class TribuDataModel extends BaseItemDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
return {
|
||||
...this.defineBaseSchema(),
|
||||
keywords: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||
mainRace: new fields.StringField({ initial: "" }),
|
||||
spokenLanguage: new fields.StringField({ initial: "" }),
|
||||
philosophy: new fields.StringField({ initial: "" }),
|
||||
pride: new fields.StringField({ initial: "" }),
|
||||
mythNature: new fields.StringField({ initial: "" }),
|
||||
mythEdenia: new fields.StringField({ initial: "" }),
|
||||
territory: new fields.StringField({ initial: "" }),
|
||||
specialRules: new fields.HTMLField({ initial: "" }),
|
||||
roleplayNotes: new fields.HTMLField({ initial: "" }),
|
||||
restrictedJobs: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||
allowedJobs: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||
skillBonuses: new fields.ArrayField(new fields.SchemaField({
|
||||
key: new fields.StringField({ initial: "" }),
|
||||
alternativeKeys: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||
base: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
domainsGranted: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||
domainsToChoose: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||
domainsChoiceText: new fields.StringField({ initial: "" }),
|
||||
}), { initial: [] }),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user