Enchantement des gemmes et potions
This commit is contained in:
112
module/item/gemme.js
Normal file
112
module/item/gemme.js
Normal file
@ -0,0 +1,112 @@
|
||||
import { RdDItem } from "../item.js";
|
||||
import { ACTION_ITEM_ENCHANTER } from "../enchantement/dialog-enchanter.js";
|
||||
|
||||
const tableGemmes = {
|
||||
"almaze": { label: "Almaze", couleur: "Blanc" },
|
||||
"aquafane": { label: "Aquafane", couleur: "Vert Profond" },
|
||||
"asterite": { label: "Astérite", couleur: "Bleu, Violet ou Blanc" },
|
||||
"cyanolithe": { label: "Cyanolithe", couleur: "Bleu Intense" },
|
||||
"larmededragon": { label: "Larme de Dragon", couleur: "Rouge Intense" },
|
||||
"muska": { label: "Muska", couleur: "Violet Profond" },
|
||||
"nebuleuse": { label: "Nébuleuse", couleur: "Brouillard Intense" },
|
||||
"nebuleuse": { label: "Nébuleuse", couleur: "Brouillard Intense, Rose, Vert ou Bleu Pâle" },
|
||||
"oeildetigre": { label: "Oeil de Tigre", couleur: "Jaune" },
|
||||
"scarlatine": { label: "Scarlatine", couleur: "Rouge Clair ou Orangé" },
|
||||
"seliphane": { label: "Séliphane", couleur: "Vert Lumineux" },
|
||||
"tournelune": { label: "Tournelune", couleur: "Violet ou Bleu" },
|
||||
"zebraide": { label: "Zebraïde", couleur: "Bandes Bicolores, toutes couleurs" }
|
||||
}
|
||||
|
||||
/**
|
||||
* un pépin de gemme = 1/10 cm3 = 1/1000 l = 3.5/1000 kg = 7/2000 kg = 7/1000 enc
|
||||
* densité 3.5 (~2.3 à 4, parfois plus) -- https://www.juwelo.fr/guide-des-pierres/faits-et-chiffres/
|
||||
*/
|
||||
const encPepin = 0.0007;
|
||||
|
||||
/**
|
||||
* Item pour gérer les gemmes
|
||||
*/
|
||||
export class RdDItemGemme extends RdDItem {
|
||||
|
||||
static getGemmeTypeOptionList() {
|
||||
// TODO: look how to map object key-value pairs
|
||||
let options = ""
|
||||
for (let gemmeKey in tableGemmes) {
|
||||
options += `<option value="${gemmeKey}">${tableGemmes[gemmeKey].label}</option>`
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
static get defaultIcon() {
|
||||
return "systems/foundryvtt-reve-de-dragon/icons/gemmes/almaze.webp"
|
||||
}
|
||||
|
||||
get isEnchantementPossible() {
|
||||
return this.enchantabilite > 0
|
||||
}
|
||||
|
||||
get inertie() { return 7 - Number(this.system.purete) }
|
||||
get enchantabilite() { return this.system.taille - this.inertie }
|
||||
|
||||
getEnc() {
|
||||
return encPepin * this.system.taille;
|
||||
}
|
||||
|
||||
itemSpecificActions() {
|
||||
return [ACTION_ITEM_ENCHANTER]
|
||||
}
|
||||
|
||||
prepareDerivedData() {
|
||||
super.prepareDerivedData()
|
||||
this.system.cout = (this.system.taille * this.system.purete) + this.system.qualite
|
||||
this.system.inertie = this.inertie
|
||||
this.system.enchantabilite = this.enchantabilite
|
||||
}
|
||||
|
||||
getUtilisation() {
|
||||
switch (this.system.categorie) {
|
||||
case 'Alchimie': case 'Autre': case 'AlchimieAutre':
|
||||
// TODO: distinguer les remèdes alchimiques enchantables/non
|
||||
return 'alchimie'
|
||||
case 'Cuisine':
|
||||
return 'cuisine'
|
||||
case 'Remede': case 'Repos': case 'Soin':
|
||||
return 'soins'
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
getProprietes() {
|
||||
const proprietes = [
|
||||
`<b>Taille</b>: ${this.system.taille}`,
|
||||
`<b>Pureté</b>: ${this.system.purete}`,
|
||||
`<b>Inertie</b>: ${this.system.inertie}`,
|
||||
`<b>Enchantabilité</b>: ${this.system.enchantabilite}`
|
||||
]
|
||||
const proprietesMagiques = this.system.magique ? [
|
||||
`<b>Enchantée</b> <i class="fa-solid fa-sparkles"></i> ${this.system.purifie ? ', purifiée' : ''} ${this.system.prpermanent ? 'permanente' : ''} `,
|
||||
`<b>Points de rêve</b>: ${this.system.pr}`,
|
||||
`<b>Puissance</b>: ${this.system.puissance}`,
|
||||
] : []
|
||||
return proprietes
|
||||
.concat(proprietesMagiques)
|
||||
.concat(this._inventaireTemplateChatData())
|
||||
.filter(it => it != undefined)
|
||||
}
|
||||
|
||||
perteReveChateauDormant() {
|
||||
if (this.system.magique && !this.system.prpermanent && this.system.pr > 0) {
|
||||
const nouveauReve = Math.max(this.system.pr - 1, 0)
|
||||
return {
|
||||
alias: this.parent.getAlias(),
|
||||
item: this,
|
||||
update: {
|
||||
_id: this.id,
|
||||
'system.pr': nouveauReve,
|
||||
'system.magique': nouveauReve > 0
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
}
|
@ -75,7 +75,7 @@ const _BOIRE = {
|
||||
const _DECOCTION = {
|
||||
code: 'item-decoction', label: 'Décoction', icon: it => 'fa-solid fa-flask-vial',
|
||||
optionsFilter: options => options.editable,
|
||||
action: (item, actor) => actor.actionHerbe(item)
|
||||
action: (item, actor) => actor.fabriquerDecoctionHerbe(item)
|
||||
}
|
||||
const _OUVRIR = {
|
||||
code: 'item-edit', label: 'Ouvrir', icon: it => 'fa-solid fa-eye',
|
||||
|
@ -1,32 +1,18 @@
|
||||
import { ITEM_TYPES } from "../constants.js";
|
||||
import { Grammar } from "../grammar.js";
|
||||
import { RdDItem } from "../item.js";
|
||||
import { SystemCompendiums } from "../settings/system-compendiums.js";
|
||||
import { DialogEnchanter } from "./potion/dialog-enchanter.js";
|
||||
|
||||
const POTION_MAGIQUE = ['AlchimieEnchante', 'ReposEnchante', 'SoinEnchante', 'AutreEnchante']
|
||||
const POTION_ENCHANTABLE = ['Alchimie', 'Repos', 'Soin', 'Autre']
|
||||
.concat(POTION_MAGIQUE)
|
||||
|
||||
const MAP_CATEGORIE_ENCHANTEMENT = [
|
||||
{ basique: 'Alchimie', enchante: 'AlchimieEnchante' },
|
||||
{ basique: 'Repos', enchante: 'ReposEnchante' },
|
||||
{ basique: 'Soin', enchante: 'SoinEnchante' },
|
||||
{ basique: 'Autre', enchante: 'AutreEnchante' }]
|
||||
import { ACTION_ITEM_ENCHANTER } from "../enchantement/dialog-enchanter.js";
|
||||
|
||||
// --- Actions sur les "potions"
|
||||
const _CONSOMMER_POTION = {
|
||||
code: 'item-potion-consommer', label: 'Consommer', icon: it => 'fa-solid fa-vial',
|
||||
optionsFilter: options => options.editable,
|
||||
action: (item, actor) => actor.consommerPotion(item)
|
||||
}
|
||||
|
||||
const _ENCHANTER = {
|
||||
code: 'item-enchanter', label: 'Enchanter', icon: it => 'fa-solid fa-sparkles',
|
||||
filter: it => game.user.isGM || it.isEnchantable(),
|
||||
optionsFilter: options => options.editable,
|
||||
action: (item, actor) => item.enchanterPotion()
|
||||
}
|
||||
|
||||
/**
|
||||
* Item pour gérer les potions
|
||||
*/
|
||||
export class RdDItemPotion extends RdDItem {
|
||||
|
||||
static async herbesSoins() {
|
||||
@ -45,114 +31,67 @@ export class RdDItemPotion extends RdDItem {
|
||||
return "systems/foundryvtt-reve-de-dragon/icons/objets/liqueur_de_bagdol.webp"
|
||||
}
|
||||
|
||||
get isEnchantementPossible() {
|
||||
return this.system.etat == 'Liquide'
|
||||
}
|
||||
|
||||
itemSpecificActions() {
|
||||
return [_CONSOMMER_POTION, ACTION_ITEM_ENCHANTER]
|
||||
}
|
||||
|
||||
prepareDerivedData() {
|
||||
super.prepareDerivedData()
|
||||
this.system.puissance = this.system.magique ? this.calculPuissance() : 0
|
||||
}
|
||||
|
||||
isPotion() { return true }
|
||||
isEnchantable() { return POTION_ENCHANTABLE.includes(this.system.categorie) }
|
||||
isMagique() { return POTION_MAGIQUE.includes(this.system.categorie) }
|
||||
|
||||
itemSpecificActions() {
|
||||
return [_CONSOMMER_POTION, _ENCHANTER]
|
||||
}
|
||||
|
||||
getActions(options = { warnIfNot: true }) {
|
||||
const actionConsommer = this.prepareAction('Consommer', options.warnIfNot);
|
||||
if (this.isEnchantable()) {
|
||||
return [
|
||||
actionConsommer,
|
||||
this.prepareAction('Enchanter', options.warnIfNot)
|
||||
]
|
||||
}
|
||||
return [
|
||||
actionConsommer
|
||||
]
|
||||
}
|
||||
// TDOD: purifier?
|
||||
getUtilisation() {
|
||||
switch (this.system.categorie) {
|
||||
case 'Alchimie': case 'AlchimieEnchante':
|
||||
case 'AlchimieAutre':
|
||||
case 'Alchimie': case 'Autre': case 'AlchimieAutre':
|
||||
// TODO: distinguer les remèdes alchimiques enchantables/non
|
||||
return 'alchimie'
|
||||
case 'Cuisine': return 'cuisine'
|
||||
case 'Remede': case 'Repos': case 'ReposEnchante': case 'Soin': case 'SoinEnchante':
|
||||
case 'Cuisine':
|
||||
return 'cuisine'
|
||||
case 'Remede': case 'Repos': case 'Soin':
|
||||
return 'soins'
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
_potionChatData() {
|
||||
return [
|
||||
`<b>Rareté</b>: ${this.system.rarete}`,
|
||||
getProprietes() {
|
||||
const proprietes = [
|
||||
`<b>Rareté</b>: ${this.system.rarete} `,
|
||||
`<b>Catégorie</b>: ${this.system.categorie}`,
|
||||
...this._inventaireTemplateChatData()
|
||||
`<b>Etat</b>: ${this.system.etat}`
|
||||
]
|
||||
const proprietesMagiques = this.system.magique ? [
|
||||
`<b>Enchantée</b> <i class="fa-solid fa-sparkles"></i> ${this.system.purifie ? ', purifiée' : ''} ${this.system.prpermanent ? 'permanente' : ''} `,
|
||||
`<b>Points de rêve</b>: ${this.system.pr}`,
|
||||
] : []
|
||||
return proprietes
|
||||
.concat(proprietesMagiques)
|
||||
.concat(this._inventaireTemplateChatData())
|
||||
.filter(it => it != undefined)
|
||||
}
|
||||
|
||||
async enchanterPotion() {
|
||||
const actor = this.parent;
|
||||
if (actor && (!actor.isPersonnage() || !actor.isHautRevant())) {
|
||||
ui.notifications.info('Seul un haut rêvant peut enchanter une potion')
|
||||
return
|
||||
}
|
||||
const dailog = await DialogEnchanter.create(this, actor, (updates) => this.$onEnchanterPotion(updates));
|
||||
dailog.render(true)
|
||||
}
|
||||
|
||||
perteRevePotion() {
|
||||
perteReveChateauDormant() {
|
||||
if (this.system.magique && !this.system.prpermanent && this.system.pr > 0) {
|
||||
const nouveauReve = Math.max(this.system.pr - 1, 0)
|
||||
const nouveaupr = Math.max(this.system.pr - 1, 0)
|
||||
return {
|
||||
_id: this.id,
|
||||
'system.pr': nouveauReve,
|
||||
'system.quantite': nouveauReve > 0 ? this.system.quantite : 0,
|
||||
'system.magique': nouveauReve > 0
|
||||
alias: this.parent.getAlias(),
|
||||
item: this,
|
||||
nouveaupr: nouveaupr,
|
||||
update: {
|
||||
_id: this.id,
|
||||
'system.pr': nouveaupr,
|
||||
'system.magique': nouveaupr > 0
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
async $onEnchanterPotion(enchanter) {
|
||||
if (enchanter.nouveaupr == 0) {
|
||||
await this.update({
|
||||
name: this.name, // TODO: enlever "enchantée" ?
|
||||
'system.pr': 0,
|
||||
'system.purifie': false,
|
||||
'system.magique': false,
|
||||
'system.categorie': this.categorieEnchantement().basique,
|
||||
'system.prpermanent': false,
|
||||
'system.prdate': 0,
|
||||
'system.quantite': this.parent ? 0 : this.system.quantite
|
||||
})
|
||||
}
|
||||
else {
|
||||
await this.update({
|
||||
name: this.name, // TODO: ajout "enchantée" ?
|
||||
'system.pr': enchanter.nouveaupr,
|
||||
'system.purifie': enchanter.purifier,
|
||||
'system.magique': true,
|
||||
'system.categorie': this.categorieEnchantement().enchante,
|
||||
'system.prpermanent': enchanter.prpermanent,
|
||||
'system.prdate': RdDItemPotion.dateEnchantement()
|
||||
})
|
||||
}
|
||||
this.sheet?.render(true)
|
||||
}
|
||||
|
||||
calculPuissance() { return this.system.herbebonus * this.system.pr }
|
||||
|
||||
categorieEnchantement() {
|
||||
const categorie = this.system.categorie
|
||||
const categorieEnchantement = MAP_CATEGORIE_ENCHANTEMENT.find(it => [it.basique, it.enchante].includes(categorie))
|
||||
return categorieEnchantement ?? { basique: categorie, enchante: categorie }
|
||||
}
|
||||
|
||||
static dateEnchantement() {
|
||||
return game.system.rdd.calendrier.getTimestamp().debutJournee().indexDate
|
||||
}
|
||||
|
||||
static buildHerbesList(listeHerbes, max) {
|
||||
let list = {}
|
||||
for (let herbe of listeHerbes) {
|
||||
|
@ -1,46 +0,0 @@
|
||||
|
||||
export class DialogEnchanter extends Dialog {
|
||||
|
||||
static async create(item, actor, callback) {
|
||||
const enchanter = {
|
||||
actor: actor,
|
||||
item: item,
|
||||
nouveaupr: item.system.pr,
|
||||
prpermanent: item.system.prpermanent,
|
||||
purifier: false
|
||||
}
|
||||
const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/item/potion/dialog-enchanter.hbs`, enchanter)
|
||||
return new DialogEnchanter(enchanter, html, callback)
|
||||
}
|
||||
|
||||
constructor(enchanter, html, callback) {
|
||||
let options = { classes: ["dialog-enchanter"], width: 400, height: 'fit-content', 'z-index': 99999 }
|
||||
let conf = {
|
||||
title: "Enchanter une potion",
|
||||
content: html,
|
||||
default: "enchanter",
|
||||
buttons: {
|
||||
"enchanter": { label: "Enchanter", callback: it => this.onEnchanter() }
|
||||
}
|
||||
};
|
||||
super(conf, options)
|
||||
|
||||
this.callback = callback
|
||||
this.enchanter = enchanter
|
||||
}
|
||||
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html)
|
||||
this.html = html
|
||||
this.html.find("input.nouveaupr").change(event => this.enchanter.nouveaupr = Number(event.currentTarget.value))
|
||||
this.html.find("input.purifier").change(event => this.enchanter.purifier = event.currentTarget.checked)
|
||||
this.html.find("input.prpermanent").change(event => this.enchanter.prpermanent = event.currentTarget.checked)
|
||||
}
|
||||
|
||||
|
||||
async onEnchanter() {
|
||||
await this.html.find(".nouveaupr").change()
|
||||
this.callback(this.enchanter);
|
||||
}
|
||||
|
||||
}
|
38
module/item/sheet-gemme.js
Normal file
38
module/item/sheet-gemme.js
Normal file
@ -0,0 +1,38 @@
|
||||
import { ITEM_TYPES } from "../constants.js";
|
||||
import { DialogEnchanter } from "../enchantement/dialog-enchanter.js";
|
||||
import { RdDTimestamp } from "../time/rdd-timestamp.js";
|
||||
import { RdDItemGemme } from "./gemme.js";
|
||||
import { RdDItemInventaireSheet } from "./sheet-base-inventaire.js";
|
||||
|
||||
export class RdDGemmeItemSheet extends RdDItemInventaireSheet {
|
||||
|
||||
static get ITEM_TYPE() { return ITEM_TYPES.gemme };
|
||||
|
||||
async getData() {
|
||||
const formData = foundry.utils.mergeObject(await super.getData(),
|
||||
{
|
||||
inertie: this.item.inertie,
|
||||
enchantabilite: this.item.enchantabilite,
|
||||
isEnchantementPossible: this.item.isEnchantementPossible,
|
||||
gemmeTypeList: RdDItemGemme.getGemmeTypeOptionList(),
|
||||
dateActuelle: game.system.rdd.calendrier.dateCourante(),
|
||||
enchantement: RdDTimestamp.splitIndexDate(this.item.system.prdate)
|
||||
})
|
||||
return formData
|
||||
}
|
||||
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
this.html.find('.item-enchanter').click((event) => DialogEnchanter.enchanter(this.item))
|
||||
|
||||
this.html.find('.date-enchantement').change((event) => {
|
||||
const jour = Number(this.html.find('input.date-enchantement[name="enchantement.jour"]').val())
|
||||
const mois = RdDTimestamp.definition(this.html.find('select.date-enchantement[name="enchantement.mois"]').val())
|
||||
const indexDate = game.system.rdd.calendrier.getIndexFromDate(jour, mois.heure)
|
||||
this.item.update({ 'system.prdate': indexDate })
|
||||
console.warn(`Date d'enchantement modifiée ${jour}/${mois.heure}: ${indexDate}`)
|
||||
});
|
||||
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import { ITEM_TYPES } from "../constants.js";
|
||||
import { DialogEnchanter } from "../enchantement/dialog-enchanter.js";
|
||||
import { RdDTimestamp } from "../time/rdd-timestamp.js";
|
||||
import { RdDItemPotion } from "./potion.js";
|
||||
import { RdDItemInventaireSheet } from "./sheet-base-inventaire.js";
|
||||
@ -18,14 +19,12 @@ export class RdDPotionItemSheet extends RdDItemInventaireSheet {
|
||||
}
|
||||
}
|
||||
}
|
||||
get potion(){ return this.item }
|
||||
|
||||
async getData() {
|
||||
const formData = await super.getData()
|
||||
formData.enchantable = this.potion.isEnchantable()
|
||||
const enchantement = this.potion.categorieEnchantement()
|
||||
formData.isSoins = enchantement.basique == 'Soin'
|
||||
formData.isRepos = enchantement.basique == 'Repos'
|
||||
formData.isEnchantementPossible = this.item.isEnchantementPossible
|
||||
formData.isSoins = this.item.categorie == 'Soin'
|
||||
formData.isRepos = this.item.categorie == 'Repos'
|
||||
if (formData.isSoins) {
|
||||
const herbesSoins = await RdDItemPotion.herbesSoins()
|
||||
RdDPotionItemSheet.$calculBonusHerbe(formData, herbesSoins, 12);
|
||||
@ -37,20 +36,20 @@ export class RdDPotionItemSheet extends RdDItemInventaireSheet {
|
||||
formData.herbesRepos = RdDItemPotion.buildHerbesList(herbesRepos, 7)
|
||||
}
|
||||
formData.dateActuelle = game.system.rdd.calendrier.dateCourante()
|
||||
formData.enchantement = RdDTimestamp.splitIndexDate(this.potion.system.prdate)
|
||||
formData.enchantement = RdDTimestamp.splitIndexDate(this.item.system.prdate)
|
||||
return formData
|
||||
}
|
||||
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
this.html.find('.item-enchanter').click((event) => this.potion.enchanterPotion())
|
||||
this.html.find('.item-enchanter').click((event) => DialogEnchanter.enchanter(this.item))
|
||||
|
||||
this.html.find('.date-enchantement').change((event) => {
|
||||
const jour = Number(this.html.find('input.date-enchantement[name="enchantement.jour"]').val())
|
||||
const mois = RdDTimestamp.definition(this.html.find('select.date-enchantement[name="enchantement.mois"]').val())
|
||||
const indexDate = game.system.rdd.calendrier.getIndexFromDate(jour, mois.heure)
|
||||
this.potion.update({ 'system.prdate': indexDate })
|
||||
this.item.update({ 'system.prdate': indexDate })
|
||||
console.warn(`Date d'enchantement modifiée ${jour}/${mois.heure}: ${indexDate}`)
|
||||
});
|
||||
|
||||
|
Reference in New Issue
Block a user