feature/v13-corrections #788
14
changelog.md
14
changelog.md
@@ -1,5 +1,19 @@
|
|||||||
# 13.0
|
# 13.0
|
||||||
|
|
||||||
|
## 13.0.23 - Le marché d'Illysis
|
||||||
|
|
||||||
|
- Améliorations
|
||||||
|
- lors de la consommation suite à un achat, les jets d'appréciation/éthylisme
|
||||||
|
sont faits par l'acheteur. Du coup, c'est lui qui lance le jet d'appréciation
|
||||||
|
(pour un service ou un plat de qualité), et ses dés sont utilisés avec dice-so-nice
|
||||||
|
- les créatures ont le statut Inconscient quand leur endurance est à 0
|
||||||
|
- Fenêtre de jets V2
|
||||||
|
- les soins de blessures sont correctement appliqués
|
||||||
|
- correction d'affichage jet sans compétence/avec compétence
|
||||||
|
- correction de la prise en compte des tactiques
|
||||||
|
- correction du filtrage des défenses selon l'attaque
|
||||||
|
- lorsque le mode de visibilité des jets général est changé, les fenêtres de jets suivent ce changement
|
||||||
|
|
||||||
## 13.0.22 - Les reflets d'Illysis
|
## 13.0.22 - Les reflets d'Illysis
|
||||||
|
|
||||||
- Améliorations
|
- Améliorations
|
||||||
|
|||||||
@@ -40,17 +40,21 @@ export class ChatVente {
|
|||||||
|
|
||||||
static async diminuerQuantiteAchatVente(chatMessageId, quantite) {
|
static async diminuerQuantiteAchatVente(chatMessageId, quantite) {
|
||||||
const chatMessage = game.messages.get(chatMessageId)
|
const chatMessage = game.messages.get(chatMessageId)
|
||||||
const vente = ChatVente.getDetailVente(chatMessageId)
|
|
||||||
vente.nbLots = Math.max(0, vente.nbLots - quantite)
|
|
||||||
await chatMessage.setFlag(SYSTEM_RDD, NB_LOTS, vente.nbLots)
|
|
||||||
|
|
||||||
const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.hbs', vente);
|
const vente = ChatVente.getDetailVente(chatMessageId)
|
||||||
chatMessage.update({ content: html });
|
if (vente.nbLots <= quantite) {
|
||||||
chatMessage.render(true);
|
ChatUtility.removeChatMessageId(chatMessageIdVente);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
vente.nbLots = vente.nbLots - quantite
|
||||||
|
await chatMessage.setFlag(SYSTEM_RDD, NB_LOTS, vente.nbLots)
|
||||||
|
const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.hbs', vente)
|
||||||
|
await chatMessage.update({ content: html }, { render: true })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async displayAchatVente(vente) {
|
static async displayAchatVente(vente) {
|
||||||
const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.hbs', vente);
|
const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.hbs', vente)
|
||||||
const chatMessage = await ChatMessage.create(RdDUtility.chatDataSetup(html))
|
const chatMessage = await ChatMessage.create(RdDUtility.chatDataSetup(html))
|
||||||
await chatMessage.setFlag(SYSTEM_RDD, NB_LOTS, vente.nbLots)
|
await chatMessage.setFlag(SYSTEM_RDD, NB_LOTS, vente.nbLots)
|
||||||
await chatMessage.setFlag(SYSTEM_RDD, DETAIL_VENTE, {
|
await chatMessage.setFlag(SYSTEM_RDD, DETAIL_VENTE, {
|
||||||
|
|||||||
130
module/actor.js
130
module/actor.js
@@ -220,7 +220,7 @@ export class RdDActor extends RdDBaseActorSang {
|
|||||||
initiative: RdDInitiative.getRollInitiative(caracValue, niveau, ajustement)
|
initiative: RdDInitiative.getRollInitiative(caracValue, niveau, ajustement)
|
||||||
};
|
};
|
||||||
attaque.isDistance = Distance.typeAttaqueDistance(attaque),
|
attaque.isDistance = Distance.typeAttaqueDistance(attaque),
|
||||||
actions.push(attaque)
|
actions.push(attaque)
|
||||||
}
|
}
|
||||||
|
|
||||||
addAttaque(RdDItemArme.empoignade(this), ATTAQUE_TYPE.CORPS_A_CORPS)
|
addAttaque(RdDItemArme.empoignade(this), ATTAQUE_TYPE.CORPS_A_CORPS)
|
||||||
@@ -1092,7 +1092,7 @@ export class RdDActor extends RdDBaseActorSang {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$createSortReserve(sort) {
|
$createSortReserve(sort) {
|
||||||
const ptReve = Number.isInteger(sort.system.ptreve) ? Number(sort.system.ptreve) :Number(sort.system.ptreve.match(/\d+/))
|
const ptReve = Number.isInteger(sort.system.ptreve) ? Number(sort.system.ptreve) : Number(sort.system.ptreve.match(/\d+/))
|
||||||
this.createEmbeddedDocuments("Item",
|
this.createEmbeddedDocuments("Item",
|
||||||
[{
|
[{
|
||||||
type: ITEM_TYPES.sortreserve,
|
type: ITEM_TYPES.sortreserve,
|
||||||
@@ -1316,14 +1316,6 @@ export class RdDActor extends RdDBaseActorSang {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async consommerNourritureboisson(itemId, choix = { doses: 1, seForcer: false, supprimerSiZero: false }) {
|
async consommerNourritureboisson(itemId, choix = { doses: 1, seForcer: false, supprimerSiZero: false }) {
|
||||||
if (!this.isOwner) {
|
|
||||||
RdDBaseActor.remoteActorCall({
|
|
||||||
tokenId: this.token?.id,
|
|
||||||
actorId: this.id,
|
|
||||||
method: 'consommerNourritureboisson', args: [itemId, choix]
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const item = this.getItem(itemId)
|
const item = this.getItem(itemId)
|
||||||
if (!item.getUtilisationCuisine()) {
|
if (!item.getUtilisationCuisine()) {
|
||||||
return
|
return
|
||||||
@@ -1333,26 +1325,36 @@ export class RdDActor extends RdDBaseActorSang {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const onManger = [
|
if (!this.isOwner) {
|
||||||
async () => await this.manger(item, choix.doses, { diminuerQuantite: false }),
|
RdDBaseActor.remoteActorCall({
|
||||||
async () => await this.boire(item, choix.doses, { diminuerQuantite: false }),
|
tokenId: this.token?.id,
|
||||||
async () => await item.diminuerQuantite(choix.doses, choix)
|
actorId: this.id,
|
||||||
]
|
method: 'consommerNourritureboisson', args: [itemId, choix]
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (await this._surmonterExotisme(item)) {
|
if (await this._surmonterExotisme(item)) {
|
||||||
const appreciation = item.system.appreciation;
|
if (item.system.qualite > 0) {
|
||||||
new Apprecier(this, appreciation, item.system.qualite)
|
new Apprecier(this, item.system.appreciation, item.system.qualite).apprecier()
|
||||||
.apprecier(onManger)
|
}
|
||||||
|
await this.onConsommerNourritureboisson(item, choix)
|
||||||
}
|
}
|
||||||
else if (choix.seForcer) {
|
else if (choix.seForcer) {
|
||||||
await this.jetDeMoral(MORAL.MALHEUREUX)
|
await this.jetDeMoral(MORAL.MALHEUREUX)
|
||||||
await Promise.all(onManger.map(async callback => await callback()))
|
await this.onConsommerNourritureboisson(item, choix)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ui.notifications.info(`${this.name} ne n'arrive pas à manger de ${item.name}`)
|
ui.notifications.info(`${this.name} ne n'arrive pas à manger de ${item.name}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async onConsommerNourritureboisson(item, choix) {
|
||||||
|
await this.manger(item, choix.doses, { diminuerQuantite: false })
|
||||||
|
await this.boire(item, choix.doses, { diminuerQuantite: false })
|
||||||
|
await item.diminuerQuantite(choix.doses, choix)
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async _surmonterExotisme(item) {
|
async _surmonterExotisme(item) {
|
||||||
const qualite = Math.min(item.system.qualite, 0)
|
const qualite = Math.min(item.system.qualite, 0)
|
||||||
@@ -1363,7 +1365,7 @@ export class RdDActor extends RdDBaseActorSang {
|
|||||||
const rolled = await this.doRollCaracCompetence(CARACS.VOLONTE, competence, difficulte, { title: `tente de surmonter l'exotisme de ${item.name}` })
|
const rolled = await this.doRollCaracCompetence(CARACS.VOLONTE, competence, difficulte, { title: `tente de surmonter l'exotisme de ${item.name}` })
|
||||||
return rolled.isSuccess
|
return rolled.isSuccess
|
||||||
}
|
}
|
||||||
return true;
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -1934,7 +1936,7 @@ export class RdDActor extends RdDBaseActorSang {
|
|||||||
async getTacheBlessure(blesse, blessure) {
|
async getTacheBlessure(blesse, blessure) {
|
||||||
const gravite = blessure?.system.gravite ?? 0;
|
const gravite = blessure?.system.gravite ?? 0;
|
||||||
if (gravite > 0) {
|
if (gravite > 0) {
|
||||||
const tache = this.itemTypes['tache'].find(it => it.system.itemId == blessure.id)
|
const tache = this.itemTypes[ITEM_TYPES.tache].find(it => it.system.itemId == blessure.id)
|
||||||
?? await RdDItemBlessure.createTacheSoinBlessure(this, gravite);
|
?? await RdDItemBlessure.createTacheSoinBlessure(this, gravite);
|
||||||
await blessure?.updateTacheSoinBlessure(tache);
|
await blessure?.updateTacheSoinBlessure(tache);
|
||||||
return tache
|
return tache
|
||||||
@@ -1988,7 +1990,7 @@ export class RdDActor extends RdDBaseActorSang {
|
|||||||
selected: { tache: { key: tache.id, forced: options.forced } },
|
selected: { tache: { key: tache.id, forced: options.forced } },
|
||||||
type: { allowed: [PART_TACHE], current: PART_TACHE }
|
type: { allowed: [PART_TACHE], current: PART_TACHE }
|
||||||
}
|
}
|
||||||
return await RollDialog.create(rollData)
|
return await RollDialog.create(rollData, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
const compData = this.getCompetence(tache.system.competence)
|
const compData = this.getCompetence(tache.system.competence)
|
||||||
@@ -2032,8 +2034,8 @@ export class RdDActor extends RdDBaseActorSang {
|
|||||||
await this.santeIncDec("fatigue", rollData.tache.system.fatigue);
|
await this.santeIncDec("fatigue", rollData.tache.system.fatigue);
|
||||||
|
|
||||||
await RdDRollResult.displayRollData(rollData, this, 'chat-resultat-tache.hbs');
|
await RdDRollResult.displayRollData(rollData, this, 'chat-resultat-tache.hbs');
|
||||||
if (options?.onRollAutomate) {
|
if (options?.callbacks) {
|
||||||
options.onRollAutomate(rollData);
|
await Promise.all(callbacks.map(callback => callback(rollData)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2504,77 +2506,16 @@ export class RdDActor extends RdDBaseActorSang {
|
|||||||
if (!blessure.system.premierssoins.done) {
|
if (!blessure.system.premierssoins.done) {
|
||||||
const tache = await this.getTacheBlessure(blesse, blessure);
|
const tache = await this.getTacheBlessure(blesse, blessure);
|
||||||
return await this.rollTache(tache.id, {
|
return await this.rollTache(tache.id, {
|
||||||
onRollAutomate: async r => blesse.onRollTachePremiersSoins(blessureId, r),
|
callbacks: [async r => await blesse.onRollTachePremiersSoins(blessureId, r, this.id)],
|
||||||
title: 'Premiers soins',
|
title: 'Premiers soins', forced: true
|
||||||
forced: true
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (!blessure.system.soinscomplets.done) {
|
else if (!blessure.system.soinscomplets.done) {
|
||||||
const diff = blessure.system.difficulte + (blessure.system.premierssoins.bonus ?? 0);
|
const diff = blessure.system.difficulte + (blessure.system.premierssoins.bonus ?? 0);
|
||||||
return await this.rollCaracCompetence(CARACS.DEXTERITE, "Chirurgie", diff, {
|
return await this.rollCaracCompetence(CARACS.DEXTERITE, "Chirurgie", diff, {
|
||||||
title: "Soins complets",
|
callbacks: [async r => await blesse.onRollSoinsComplets(blessureId, r, this.id)],
|
||||||
onRollAutomate: r => blesse.onRollSoinsComplets(blessureId, r),
|
onRollDone: RollDialog.onRollDoneClose,
|
||||||
forced: true
|
title: "Soins complets", forced: true
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async onRollTachePremiersSoins(blessureId, rollData) {
|
|
||||||
if (!this.isOwner) {
|
|
||||||
return RdDBaseActor.remoteActorCall({
|
|
||||||
tokenId: this.token?.id,
|
|
||||||
actorId: this.id,
|
|
||||||
method: 'onRollTachePremiersSoins', args: [blessureId, rollData]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const blessure = this.getItem(blessureId, 'blessure')
|
|
||||||
|
|
||||||
if (blessure && !blessure.system.premierssoins.done) {
|
|
||||||
const tache = rollData.tache;
|
|
||||||
if (rollData.rolled.isETotal) {
|
|
||||||
await blessure.update({
|
|
||||||
'system.difficulte': blessure.system.difficulte - 1,
|
|
||||||
'system.premierssoins.tache': Math.max(0, tache.system.points_de_tache_courant)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const bonus = tache.system.points_de_tache_courant - tache.system.points_de_tache
|
|
||||||
await blessure.update({
|
|
||||||
'system.premierssoins': {
|
|
||||||
done: (bonus >= 0),
|
|
||||||
bonus: Math.max(0, bonus),
|
|
||||||
tache: Math.max(0, tache.system.points_de_tache_courant)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
if (bonus >= 0) {
|
|
||||||
await this.deleteEmbeddedDocuments('Item', [tache.id])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async onRollSoinsComplets(blessureId, rollData) {
|
|
||||||
if (!this.isOwner) {
|
|
||||||
return RdDBaseActor.remoteActorCall({
|
|
||||||
tokenId: this.token?.id,
|
|
||||||
actorId: this.id,
|
|
||||||
method: 'onRollSoinsComplets', args: [blessureId, rollData]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const blessure = this.getItem(blessureId, 'blessure')
|
|
||||||
if (blessure && blessure.system.premierssoins.done && !blessure.system.soinscomplets.done) {
|
|
||||||
// TODO: update de la blessure: passer par le MJ!
|
|
||||||
if (rollData.rolled.isETotal) {
|
|
||||||
await blessure.setSoinsBlessure({
|
|
||||||
difficulte: blessure.system.difficulte - 1,
|
|
||||||
premierssoins: { done: false, bonus: 0 }, soinscomplets: { done: false, bonus: 0 },
|
|
||||||
})
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// soins complets finis
|
|
||||||
await blessure.setSoinsBlessure({
|
|
||||||
soinscomplets: { done: true, bonus: Math.max(0, rollData.rolled.ptTache) },
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2990,15 +2931,6 @@ export class RdDActor extends RdDBaseActorSang {
|
|||||||
await this.diminuerQuantiteObjet(potion.id, 1, { supprimerSiZero: potion.supprimer });
|
await this.diminuerQuantiteObjet(potion.id, 1, { supprimerSiZero: potion.supprimer });
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async onUpdateActor(update, options, actorId) {
|
|
||||||
const updatedEndurance = update?.system?.sante?.endurance
|
|
||||||
if (updatedEndurance && options.diff) {
|
|
||||||
await this.setEffect(STATUSES.StatusUnconscious, updatedEndurance.value == 0)
|
|
||||||
}
|
|
||||||
await super.onUpdateActor(update, options, actorId)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async onPreUpdateItem(item, change, options, id) {
|
async onPreUpdateItem(item, change, options, id) {
|
||||||
if (item.isCompetencePersonnage() && item.system.defaut_carac && item.system.xp) {
|
if (item.isCompetencePersonnage() && item.system.defaut_carac && item.system.xp) {
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import { BASE_CORPS_A_CORPS, BASE_ESQUIVE, CATEGORIES_COMPETENCES_CREATURES } fr
|
|||||||
import { RollDataAjustements } from "../rolldata-ajustements-v1.js";
|
import { RollDataAjustements } from "../rolldata-ajustements-v1.js";
|
||||||
import { MappingCreatureArme } from "../item/mapping-creature-arme.mjs";
|
import { MappingCreatureArme } from "../item/mapping-creature-arme.mjs";
|
||||||
import RollDialog from "../roll/roll-dialog.mjs";
|
import RollDialog from "../roll/roll-dialog.mjs";
|
||||||
import { ATTAQUE_ROLL_TYPES, DEFAULT_ROLL_TYPES, DIFF, ROLL_TYPE_ATTAQUE} from "../roll/roll-constants.mjs";
|
import { ATTAQUE_ROLL_TYPES, DEFAULT_ROLL_TYPES, DIFF, ROLL_TYPE_ATTAQUE } from "../roll/roll-constants.mjs";
|
||||||
import { OptionsAvancees, ROLL_DIALOG_V2 } from "../settings/options-avancees.js";
|
import { OptionsAvancees, ROLL_DIALOG_V2 } from "../settings/options-avancees.js";
|
||||||
import { PART_COMP } from "../roll/roll-part-comp.mjs";
|
import { PART_COMP } from "../roll/roll-part-comp.mjs";
|
||||||
import { RdDInitiative } from "../initiative.mjs";
|
import { RdDInitiative } from "../initiative.mjs";
|
||||||
@@ -208,7 +208,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
|||||||
.map(async it => await RdDEmpoignade.onImmobilisation(this, it)))
|
.map(async it => await RdDEmpoignade.onImmobilisation(this, it)))
|
||||||
}
|
}
|
||||||
|
|
||||||
async finDeRoundPossession(){
|
async finDeRoundPossession() {
|
||||||
await Promise.all(this.itemTypes[ITEM_TYPES.possession]
|
await Promise.all(this.itemTypes[ITEM_TYPES.possession]
|
||||||
.map(async it => await RdDPossessionV2.onPossession(this, it)))
|
.map(async it => await RdDPossessionV2.onPossession(this, it)))
|
||||||
}
|
}
|
||||||
@@ -348,7 +348,10 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
|||||||
competence: competence,
|
competence: competence,
|
||||||
show: { title: options?.title ?? '' }
|
show: { title: options?.title ?? '' }
|
||||||
},
|
},
|
||||||
callbacks: [async r => this.$onRollCompetence(r, options)]
|
callbacks: [
|
||||||
|
async r => this.$onRollCompetence(r, options),
|
||||||
|
...(options?.callbacks ?? [])
|
||||||
|
]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { RdDDice } from "../rdd-dice.js";
|
|||||||
import { RdDItemBlessure } from "../item/blessure.js";
|
import { RdDItemBlessure } from "../item/blessure.js";
|
||||||
import { ChatUtility } from "../chat-utility.js";
|
import { ChatUtility } from "../chat-utility.js";
|
||||||
import { Misc } from "../misc.js";
|
import { Misc } from "../misc.js";
|
||||||
|
import { RdDBaseActor } from "./base-actor.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Classe de base pour les acteurs qui peuvent subir des blessures
|
* Classe de base pour les acteurs qui peuvent subir des blessures
|
||||||
@@ -120,16 +121,14 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async santeIncDec(name, inc, isCritique = false) {
|
async santeIncDec(name, inc, isCritique = false) {
|
||||||
if (name == 'fatigue' && !ReglesOptionnelles.isUsing("appliquer-fatigue")) {
|
if (name == 'fatigue' && !ReglesOptionnelles.isUsing("appliquer-fatigue")) {
|
||||||
return;
|
return
|
||||||
|
}
|
||||||
|
if (!this.system.sante[name]) {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
const sante = foundry.utils.duplicate(this.system.sante)
|
const sante = foundry.utils.duplicate(this.system.sante)
|
||||||
let compteur = sante[name];
|
const compteur = sante[name]
|
||||||
if (!compteur) {
|
const result = { sonne: false }
|
||||||
return;
|
|
||||||
}
|
|
||||||
let result = {
|
|
||||||
sonne: false,
|
|
||||||
};
|
|
||||||
let perteEndurance = 0
|
let perteEndurance = 0
|
||||||
let minValue = name == "vie" ? -this.getSConst() - 1 : 0;
|
let minValue = name == "vie" ? -this.getSConst() - 1 : 0;
|
||||||
|
|
||||||
@@ -171,6 +170,67 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async onRollTachePremiersSoins(blessureId, rollData, soigneurId) {
|
||||||
|
if (!this.isOwner) {
|
||||||
|
return RdDBaseActor.remoteActorCall({
|
||||||
|
tokenId: this.token?.id,
|
||||||
|
actorId: this.id,
|
||||||
|
method: 'onRollTachePremiersSoins', args: [blessureId, rollData, soigneurId]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const blessure = this.getItem(blessureId, 'blessure')
|
||||||
|
if (blessure && !blessure.system.premierssoins.done) {
|
||||||
|
const tache = rollData.v2 ? rollData.current.tache.tache : rollData.tache
|
||||||
|
if (rollData.rolled.isETotal) {
|
||||||
|
await blessure.update({
|
||||||
|
'system.difficulte': blessure.system.difficulte - 1,
|
||||||
|
'system.premierssoins.tache': Math.max(0, tache.system.points_de_tache_courant)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const bonus = tache.system.points_de_tache_courant - tache.system.points_de_tache
|
||||||
|
await blessure.update({
|
||||||
|
'system.premierssoins': {
|
||||||
|
done: (bonus >= 0),
|
||||||
|
bonus: Math.max(0, bonus),
|
||||||
|
tache: Math.max(0, tache.system.points_de_tache_courant)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (bonus >= 0 && soigneurId) {
|
||||||
|
const soigneur = game.actors.get(soigneurId)
|
||||||
|
await soigneur.deleteEmbeddedDocuments('Item', [tache.id], { render: true })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async onRollSoinsComplets(blessureId, rollData) {
|
||||||
|
if (!this.isOwner) {
|
||||||
|
return RdDBaseActor.remoteActorCall({
|
||||||
|
tokenId: this.token?.id,
|
||||||
|
actorId: this.id,
|
||||||
|
method: 'onRollSoinsComplets', args: [blessureId, rollData]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const blessure = this.getItem(blessureId, 'blessure')
|
||||||
|
if (blessure && blessure.system.premierssoins.done && !blessure.system.soinscomplets.done) {
|
||||||
|
// TODO: update de la blessure: passer par le MJ!
|
||||||
|
if (rollData.rolled.isETotal) {
|
||||||
|
await blessure.setSoinsBlessure({
|
||||||
|
difficulte: blessure.system.difficulte - 1,
|
||||||
|
premierssoins: { done: false, bonus: 0 }, soinscomplets: { done: false, bonus: 0 },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// soins complets finis
|
||||||
|
await blessure.setSoinsBlessure({
|
||||||
|
soinscomplets: { done: true, bonus: Math.max(0, rollData.rolled.ptTache) },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_computeEnduranceMax() {
|
_computeEnduranceMax() {
|
||||||
const diffVie = this.system.sante.vie.max - this.system.sante.vie.value;
|
const diffVie = this.system.sante.vie.max - this.system.sante.vie.value;
|
||||||
@@ -182,6 +242,14 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
|
|||||||
return Math.max(0, Math.min(maxEndVie, maxEndGraves, maxEndCritiques));
|
return Math.max(0, Math.min(maxEndVie, maxEndGraves, maxEndCritiques));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async onUpdateActor(update, options, actorId) {
|
||||||
|
const updatedEndurance = update?.system?.sante?.endurance
|
||||||
|
if (updatedEndurance && options.diff) {
|
||||||
|
await this.setEffect(STATUSES.StatusUnconscious, updatedEndurance.value == 0)
|
||||||
|
}
|
||||||
|
await super.onUpdateActor(update, options, actorId)
|
||||||
|
}
|
||||||
|
|
||||||
async onCreateItem(item, options, id) {
|
async onCreateItem(item, options, id) {
|
||||||
await this.changeItemEffects(item)
|
await this.changeItemEffects(item)
|
||||||
await super.onCreateItem(item, options, id)
|
await super.onCreateItem(item, options, id)
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export class RdDBaseActor extends Actor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static $findCaracByName(carac, name) {
|
static $findCaracByName(carac, name) {
|
||||||
const caracList = Object.entries(carac);
|
const caracList = Object.entries(carac)
|
||||||
let entry = Misc.findFirstLike(name, caracList, { mapper: it => it[0], description: 'caractéristique', onMessage: m => { } });
|
let entry = Misc.findFirstLike(name, caracList, { mapper: it => it[0], description: 'caractéristique', onMessage: m => { } });
|
||||||
if (!entry || entry.length == 0) {
|
if (!entry || entry.length == 0) {
|
||||||
entry = Misc.findFirstLike(name, caracList, { mapper: it => it[1].label, description: 'caractéristique' });
|
entry = Misc.findFirstLike(name, caracList, { mapper: it => it[1].label, description: 'caractéristique' });
|
||||||
@@ -62,14 +62,14 @@ export class RdDBaseActor extends Actor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static remoteActorCall(callData) {
|
static remoteActorCall(callData, userId = undefined) {
|
||||||
if (game.user.isGM) {
|
if (game.user.isGM) {
|
||||||
RdDBaseActor.onRemoteActorCall(callData, game.user.id)
|
RdDBaseActor.onRemoteActorCall(callData, game.user.id)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const gmUserId = Misc.firstConnectedGMId()
|
const gmUserId = Misc.firstConnectedGMId()
|
||||||
if (gmUserId){
|
if (gmUserId) {
|
||||||
game.socket.emit(SYSTEM_SOCKET_ID, {
|
game.socket.emit(SYSTEM_SOCKET_ID, {
|
||||||
msg: "msg_remote_actor_call",
|
msg: "msg_remote_actor_call",
|
||||||
data: callData,
|
data: callData,
|
||||||
@@ -166,14 +166,22 @@ export class RdDBaseActor extends Actor {
|
|||||||
return this.system.sante.vie
|
return this.system.sante.vie
|
||||||
}
|
}
|
||||||
|
|
||||||
const carac = this.system.carac;
|
const carac = {}
|
||||||
|
foundry.utils.mergeObject(carac, this.system.carac, { overwrite: false })
|
||||||
|
foundry.utils.mergeObject(carac, this.getCaracCompetenceCreature(), { overwrite: false })
|
||||||
return RdDBaseActor.$findCaracByName(carac, name);
|
return RdDBaseActor.$findCaracByName(carac, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getCaracCompetenceCreature() {
|
||||||
|
return this.isCreatureOuEntite()
|
||||||
|
? Object.fromEntries(this.itemTypes[ITEM_TYPES.competencecreature].map(it => [Grammar.toLowerCaseNoAccent(it.name), { label: it.name, value: it.system.carac_value }]))
|
||||||
|
: {}
|
||||||
|
}
|
||||||
|
|
||||||
mapCarac(caracCode) { return caracCode }
|
mapCarac(caracCode) { return caracCode }
|
||||||
|
|
||||||
getCaracByName(name) {
|
getCaracByName(name) {
|
||||||
name = this.mapCarac(Grammar.toLowerCaseNoAccent(name))
|
name = this.mapCarac(Grammar.toLowerCaseNoAccent(name)) ?? name
|
||||||
switch (name) {
|
switch (name) {
|
||||||
case 'reve-actuel': case 'reve actuel':
|
case 'reve-actuel': case 'reve actuel':
|
||||||
return this.getCaracReveActuel();
|
return this.getCaracReveActuel();
|
||||||
@@ -417,6 +425,14 @@ export class RdDBaseActor extends Actor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async depenserSols(sols) {
|
async depenserSols(sols) {
|
||||||
|
if (!this.isOwner) {
|
||||||
|
return RdDBaseActor.remoteActorCall({
|
||||||
|
userId: Misc.connectedGMOrUser(),
|
||||||
|
tokenId: this.token?.id,
|
||||||
|
actorId: this.id,
|
||||||
|
method: 'depenserSols', args: [sols]
|
||||||
|
})
|
||||||
|
}
|
||||||
let reste = this.getFortune() - Number(sols);
|
let reste = this.getFortune() - Number(sols);
|
||||||
if (reste >= 0) {
|
if (reste >= 0) {
|
||||||
await Monnaie.optimiserFortune(this, reste);
|
await Monnaie.optimiserFortune(this, reste);
|
||||||
@@ -425,32 +441,31 @@ export class RdDBaseActor extends Actor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async ajouterSols(sols, fromActorId = undefined) {
|
async ajouterSols(sols, fromActorId = undefined) {
|
||||||
sols = Number(sols);
|
sols = Number(sols)
|
||||||
if (sols == 0) {
|
if (sols == 0) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
if (sols < 0) {
|
if (sols < 0) {
|
||||||
ui.notifications.error(`Impossible d'ajouter un gain de ${sols} <0`);
|
ui.notifications.error(`Impossible d'ajouter un gain de ${sols} <0`)
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
if (fromActorId && !this.isOwner) {
|
if (fromActorId && !this.isOwner) {
|
||||||
RdDBaseActor.remoteActorCall({
|
return RdDBaseActor.remoteActorCall({
|
||||||
userId: Misc.connectedGMOrUser(),
|
userId: Misc.connectedGMOrUser(),
|
||||||
tokenId: this.token?.id,
|
tokenId: this.token?.id,
|
||||||
actorId: this.id,
|
actorId: this.id,
|
||||||
method: 'ajouterSols', args: [sols, fromActorId]
|
method: 'ajouterSols', args: [sols, fromActorId]
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
const fromActor = game.actors.get(fromActorId)
|
|
||||||
await Monnaie.optimiserFortune(this, sols + this.getFortune());
|
|
||||||
|
|
||||||
RdDAudio.PlayContextAudio("argent"); // Petit son
|
const fromActor = game.actors.get(fromActorId)
|
||||||
ChatMessage.create({
|
await Monnaie.optimiserFortune(this, sols + this.getFortune());
|
||||||
whisper: ChatUtility.getOwners(this),
|
|
||||||
content: `Vous avez reçu <strong>${sols} Sols</strong> ${fromActor ? " de " + fromActor.name : ''}, qui ont été ajoutés à votre argent.`
|
RdDAudio.PlayContextAudio("argent"); // Petit son
|
||||||
});
|
ChatMessage.create({
|
||||||
}
|
whisper: ChatUtility.getOwners(this),
|
||||||
|
content: `Vous avez reçu <strong>${sols} Sols</strong> ${fromActor ? " de " + fromActor.name : ''}, qui ont été ajoutés à votre argent.`
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -462,24 +477,28 @@ export class RdDBaseActor extends Actor {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async achatVente(achat) {
|
async achatVente(achat) {
|
||||||
if (achat.vendeurId == achat.acheteurId) {
|
if (achat.vendeurId == achat.acheteurId) {
|
||||||
ui.notifications.info("Inutile de se vendre à soi-même");
|
ui.notifications.info("Inutile de se vendre à soi-même")
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
if (!game.user.isGM) {
|
const cout = Number(achat.prixTotal ?? 0)
|
||||||
|
const acheteur = achat.acheteurId ? game.actors.get(achat.acheteurId) : undefined
|
||||||
|
|
||||||
|
if (acheteur && !acheteur.isOwner) {
|
||||||
|
ui.notifications.warn(`${game.user.id} n'est pas propriétaire de ${this.name} et effectue un achat pour lui!`)
|
||||||
RdDBaseActor.remoteActorCall({
|
RdDBaseActor.remoteActorCall({
|
||||||
actorId: achat.vendeurId ?? achat.acheteurId,
|
actorId: achat.acheteurId,
|
||||||
method: 'achatVente', args: [achat]
|
method: 'achatVente', args: [achat]
|
||||||
});
|
});
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const cout = Number(achat.prixTotal ?? 0);
|
|
||||||
const vendeur = achat.vendeurId ? game.actors.get(achat.vendeurId) : undefined;
|
|
||||||
const acheteur = achat.acheteurId ? game.actors.get(achat.acheteurId) : undefined;
|
const vendeur = achat.vendeurId ? game.actors.get(achat.vendeurId) : undefined
|
||||||
const quantite = (achat.choix.nombreLots ?? 1) * (achat.vente.tailleLot);
|
const quantite = (achat.choix.nombreLots ?? 1) * (achat.vente.tailleLot);
|
||||||
const itemVendu = vendeur?.getItem(achat.vente.item._id) ?? game.items.get(achat.vente.item._id);
|
const itemVendu = vendeur?.getItem(achat.vente.item._id) ?? game.items.get(achat.vente.item._id);
|
||||||
if (!itemVendu) {
|
if (!itemVendu) {
|
||||||
ChatUtility.notifyUser(achat.userId, 'warn', vendeur ? `Le vendeur n'a pas plus de ${achat.vente.item.name} !` : `Impossible de retrouver: ${achat.vente.item.name} !`);
|
ChatUtility.notifyUser(achat.userId, 'warn', vendeur ? `Le vendeur n'a pas plus de ${achat.vente.item.name} !` : `Impossible de retrouver: ${achat.vente.item.name} !`);
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
if (vendeur && !vendeur.verifierQuantite(itemVendu, quantite)) {
|
if (vendeur && !vendeur.verifierQuantite(itemVendu, quantite)) {
|
||||||
ChatUtility.notifyUser(achat.userId, 'warn', `Le vendeur n'a pas assez de ${itemVendu.name} !`);
|
ChatUtility.notifyUser(achat.userId, 'warn', `Le vendeur n'a pas assez de ${itemVendu.name} !`);
|
||||||
@@ -487,10 +506,10 @@ export class RdDBaseActor extends Actor {
|
|||||||
}
|
}
|
||||||
if (acheteur && !acheteur.verifierFortune(cout)) {
|
if (acheteur && !acheteur.verifierFortune(cout)) {
|
||||||
ChatUtility.notifyUser(achat.userId, 'warn', `Vous n'avez pas assez d'argent pour payer ${Math.ceil(cout / 100)} sols !`);
|
ChatUtility.notifyUser(achat.userId, 'warn', `Vous n'avez pas assez d'argent pour payer ${Math.ceil(cout / 100)} sols !`);
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
await vendeur?.vendre(itemVendu, quantite, cout);
|
await vendeur?.vendre(itemVendu, quantite, cout, acheteur);
|
||||||
await acheteur?.acheter(itemVendu, quantite, cout, achat)
|
await acheteur?.acheter(itemVendu, quantite, cout, achat, vendeur)
|
||||||
|
|
||||||
if (cout > 0) {
|
if (cout > 0) {
|
||||||
RdDAudio.PlayContextAudio("argent");
|
RdDAudio.PlayContextAudio("argent");
|
||||||
@@ -505,22 +524,32 @@ export class RdDBaseActor extends Actor {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!achat.vente.quantiteIllimite) {
|
if (!achat.vente.quantiteIllimite) {
|
||||||
if (achat.vente.nbLots <= achat.choix.nombreLots) {
|
await this.updateMessageVente(achat.chatMessageIdVente, achat.choix.nombreLots);
|
||||||
ChatUtility.removeChatMessageId(achat.chatMessageIdVente);
|
|
||||||
}
|
|
||||||
else if (achat.chatMessageIdVente) {
|
|
||||||
await ChatVente.diminuerQuantiteAchatVente(achat.chatMessageIdVente, achat.choix.nombreLots)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async vendre(item, quantite, cout) {
|
async updateMessageVente(chatMessageIdVente, nombreLots) {
|
||||||
await this.ajouterSols(cout);
|
const chatMessage = game.messages.get(chatMessageIdVente)
|
||||||
await this.decrementerQuantiteItem(item, quantite);
|
if (!chatMessage.isOwner) {
|
||||||
|
return RdDBaseActor.remoteActorCall({
|
||||||
|
userId: Misc.firstConnectedGMId(),
|
||||||
|
actorId: this.id,
|
||||||
|
method: 'updateMessageVente', args: [chatMessageIdVente, nombreLots]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
await ChatVente.diminuerQuantiteAchatVente(chatMessageIdVente, nombreLots);
|
||||||
|
}
|
||||||
|
|
||||||
|
async vendre(item, quantite, cout, acheteur) {
|
||||||
|
await this.ajouterSols(cout, acheteur?.id)
|
||||||
|
await this.decrementerQuantiteItem(item.id, quantite)
|
||||||
}
|
}
|
||||||
|
|
||||||
async acheter(item, quantite, cout, achat) {
|
async acheter(item, quantite, cout, achat) {
|
||||||
await this.depenserSols(cout)
|
await this.depenserSols(cout)
|
||||||
|
if (!this.isOwner) {
|
||||||
|
ui.notifications.warn(`${game.user.id} n'est pas propriétaire de ${this.name} et effectue un achat!`)
|
||||||
|
}
|
||||||
const createdItemId = await this.creerQuantiteItem(item, quantite)
|
const createdItemId = await this.creerQuantiteItem(item, quantite)
|
||||||
if (item.type == ITEM_TYPES.nourritureboisson && achat.choix.consommer && createdItemId != undefined) {
|
if (item.type == ITEM_TYPES.nourritureboisson && achat.choix.consommer && createdItemId != undefined) {
|
||||||
achat.choix.doses = achat.choix.nombreLots;
|
achat.choix.doses = achat.choix.nombreLots;
|
||||||
@@ -542,43 +571,46 @@ export class RdDBaseActor extends Actor {
|
|||||||
|
|
||||||
async consommerNourritureboisson(itemId, choix, userId) { }
|
async consommerNourritureboisson(itemId, choix, userId) { }
|
||||||
|
|
||||||
async decrementerQuantiteItem(item, quantite, options = { supprimerSiZero: true }) {
|
async decrementerQuantiteItem(itemId, quantite, options = { supprimerSiZero: true }) {
|
||||||
|
const item = this.items.get(itemId)
|
||||||
if (item.isService()) {
|
if (item.isService()) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
const itemId = item.id;
|
|
||||||
let resteQuantite = (item.system.quantite ?? 1) - quantite;
|
if (!this.isOwner) {
|
||||||
if (resteQuantite <= 0) {
|
return RdDBaseActor.remoteActorCall({
|
||||||
if (options.supprimerSiZero) {
|
userId: Misc.connectedGMOrUser(),
|
||||||
await this.deleteEmbeddedDocuments("Item", [item.id]);
|
tokenId: this.token?.id,
|
||||||
}
|
actorId: this.id,
|
||||||
else {
|
method: 'decrementerQuantiteItem', args: [itemId, quantite, options]
|
||||||
await this.updateEmbeddedDocuments("Item", [{ _id: itemId, 'system.quantite': 0 }]);
|
})
|
||||||
}
|
|
||||||
if (resteQuantite < 0) {
|
|
||||||
ui.notifications.warn(`La quantité de ${item.name} était insuffisante, l'objet a donc été supprimé`)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (resteQuantite > 0) {
|
|
||||||
const realItem = this.getItem(item.id)
|
const resteQuantite = Math.max((item.system.quantite ?? 1) - quantite, 0)
|
||||||
realItem.update({ 'system.quantite': resteQuantite });
|
if (resteQuantite <= 0 && options.supprimerSiZero) {
|
||||||
await this.updateEmbeddedDocuments("Item", [{ _id: item.id, 'system.quantite': resteQuantite }]);
|
await this.deleteEmbeddedDocuments("Item", [itemId]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
await this.updateEmbeddedDocuments("Item", [{ _id: itemId, 'system.quantite': resteQuantite }])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async creerQuantiteItem(item, quantite) {
|
async creerQuantiteItem(item, quantite) {
|
||||||
if (this.canReceive(item)) {
|
if (!this.canReceive(item)) {
|
||||||
const isItemEmpilable = "quantite" in item.system;
|
return
|
||||||
const baseItem = {
|
|
||||||
type: item.type,
|
|
||||||
img: item.img,
|
|
||||||
name: item.name,
|
|
||||||
system: foundry.utils.mergeObject(item.system, { quantite: isItemEmpilable ? quantite : undefined }, { inplace: false })
|
|
||||||
};
|
|
||||||
const newItems = isItemEmpilable ? [baseItem] : Array.from({ length: quantite }, (_, i) => baseItem);
|
|
||||||
const items = await this.createEmbeddedDocuments("Item", newItems);
|
|
||||||
return items.length > 0 ? items[0].id : undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isItemEmpilable = "quantite" in item.system;
|
||||||
|
const baseItem = {
|
||||||
|
type: item.type,
|
||||||
|
img: item.img,
|
||||||
|
name: item.name,
|
||||||
|
system: foundry.utils.mergeObject(item.system, { quantite: isItemEmpilable ? quantite : undefined }, { inplace: false })
|
||||||
|
}
|
||||||
|
|
||||||
|
const newItems = isItemEmpilable ? [baseItem] : Array.from({ length: quantite }, (_, i) => baseItem);
|
||||||
|
const items = await this.createEmbeddedDocuments("Item", newItems);
|
||||||
|
return newItems.length > 0 ? items[0].id : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -866,4 +898,5 @@ export class RdDBaseActor extends Actor {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -28,11 +28,11 @@ export class RdDCommerce extends RdDBaseActor {
|
|||||||
await super.depenserSols(cout)
|
await super.depenserSols(cout)
|
||||||
}
|
}
|
||||||
|
|
||||||
async decrementerQuantiteItem(item, quantite) {
|
async decrementerQuantiteItem(itemId, quantite) {
|
||||||
if (this.system.illimite) {
|
if (this.system.illimite) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await super.decrementerQuantiteItem(item, quantite, { supprimerSiZero: false });
|
await super.decrementerQuantiteItem(itemId, quantite, { supprimerSiZero: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
calculerPrix(item) {
|
calculerPrix(item) {
|
||||||
|
|||||||
@@ -233,4 +233,25 @@ export class ChatUtility {
|
|||||||
static async setTimestamp(chatMessage) {
|
static async setTimestamp(chatMessage) {
|
||||||
await chatMessage.setFlag(SYSTEM_RDD, 'rdd-timestamp', game.system.rdd.calendrier.getTimestamp());
|
await chatMessage.setFlag(SYSTEM_RDD, 'rdd-timestamp', game.system.rdd.calendrier.getTimestamp());
|
||||||
}
|
}
|
||||||
|
// TODO: find ChatLog to change the action for data-action flush
|
||||||
|
|
||||||
|
// async flush() {
|
||||||
|
// const question = game.i18n.localize("AreYouSure");
|
||||||
|
// const warning = game.i18n.localize("CHAT.FlushWarning");
|
||||||
|
// return foundry.applications.api.DialogV2.confirm({
|
||||||
|
// window: {title: "CHAT.FlushTitle"},
|
||||||
|
// content: `<p><strong>${question}</strong> ${warning}</p>`,
|
||||||
|
// position: {
|
||||||
|
// top: window.innerHeight - 150,
|
||||||
|
// left: window.innerWidth - 720
|
||||||
|
// },
|
||||||
|
// yes: {
|
||||||
|
// callback: async () => {
|
||||||
|
// await this.documentClass.deleteDocuments([], {deleteAll: true});
|
||||||
|
// const jumpToBottomElement = document.querySelector(".jump-to-bottom");
|
||||||
|
// jumpToBottomElement.hidden = true;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ export class RdDItemArme extends RdDItem {
|
|||||||
isParade() { return this.system.resistance > 0 && this.system.categorie_parade }
|
isParade() { return this.system.resistance > 0 && this.system.categorie_parade }
|
||||||
isBouclier() { return RdDItemArme.getCategorieParade(this).includes('bouclier') }
|
isBouclier() { return RdDItemArme.getCategorieParade(this).includes('bouclier') }
|
||||||
|
|
||||||
|
|
||||||
getCompetenceAction(main) {
|
getCompetenceAction(main) {
|
||||||
switch (main) {
|
switch (main) {
|
||||||
case ATTAQUE_TYPE.UNE_MAIN: return this.competence1Mains()
|
case ATTAQUE_TYPE.UNE_MAIN: return this.competence1Mains()
|
||||||
@@ -174,24 +174,30 @@ export class RdDItemArme extends RdDItem {
|
|||||||
|
|
||||||
static defenseArmeParade(armeAttaque, armeParade) {
|
static defenseArmeParade(armeAttaque, armeParade) {
|
||||||
const defCategory = RdDItemArme.getCategorieParade(armeParade)
|
const defCategory = RdDItemArme.getCategorieParade(armeParade)
|
||||||
if (defCategory == 'boucliers') {
|
switch (defCategory) {
|
||||||
return 'norm'
|
case 'boucliers':
|
||||||
|
return 'norm'
|
||||||
|
case '':
|
||||||
|
return 'impossible'
|
||||||
}
|
}
|
||||||
if (armeAttaque?.system?.competence?.toLowerCase().match(/(fléau)/)) {
|
if (RdDItemArme.$isFleau(armeAttaque)) {
|
||||||
return ''
|
return 'impossible'
|
||||||
}
|
|
||||||
if (armeParade.system?.tir) {
|
|
||||||
return ''
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const attCategory = RdDItemArme.getCategorieParade(armeAttaque)
|
const attCategory = RdDItemArme.getCategorieParade(armeAttaque)
|
||||||
switch (attCategory) {
|
switch (attCategory) {
|
||||||
case 'armes-naturelles': case 'sans-armes':
|
case 'sans-armes':
|
||||||
return defCategory == 'sans-armes' ? 'norm' : ''
|
case 'armes-naturelles':
|
||||||
|
return defCategory == attCategory ? 'norm' : 'impossible'
|
||||||
default:
|
default:
|
||||||
return RdDItemArme.needParadeSignificative(armeAttaque, armeParade) ? 'sign' : 'norm'
|
return RdDItemArme.needParadeSignificative(armeAttaque, armeParade) ? 'sign' : 'norm'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static $isFleau(armeAttaque) {
|
||||||
|
return armeAttaque?.system?.competence?.toLowerCase().match(/(fléau)/);
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static needParadeSignificative(armeAttaque, armeParade) {
|
static needParadeSignificative(armeAttaque, armeParade) {
|
||||||
if (!armeAttaque || !armeParade) {
|
if (!armeAttaque || !armeParade) {
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ export class Apprecier {
|
|||||||
|
|
||||||
apprecier(callbacks = []) {
|
apprecier(callbacks = []) {
|
||||||
if (this.qualite <= 0) {
|
if (this.qualite <= 0) {
|
||||||
this.raisons.push(`la qualité ${this.qualite} est négative.`)
|
this.raisons.push(`la qualité ${this.qualite} est insuffisante.`)
|
||||||
}
|
}
|
||||||
if (this.qualite <= this.actor.getMoralTotal()) {
|
if (this.qualite <= this.actor.getMoralTotal()) {
|
||||||
this.raisons.push(`la qualité de ${this.qualite} est inférieure au moral de ${this.actor.getMoralTotal()}.`)
|
this.raisons.push(`la qualité de ${this.qualite} est inférieure au moral de ${this.actor.getMoralTotal()}.`)
|
||||||
|
|||||||
@@ -775,7 +775,7 @@ export class RdDCombat {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_prepareAttaque(competence, arme) {
|
_prepareAttaque(competence, arme) {
|
||||||
let rollData = {
|
let rollData = {
|
||||||
mode: ROLL_TYPE_ATTAQUE,
|
mode: 'attaque',
|
||||||
alias: this.attacker?.getAlias(),
|
alias: this.attacker?.getAlias(),
|
||||||
passeArme: foundry.utils.randomID(16),
|
passeArme: foundry.utils.randomID(16),
|
||||||
mortalite: arme?.system.mortalite,
|
mortalite: arme?.system.mortalite,
|
||||||
@@ -1378,6 +1378,7 @@ export class RdDCombat {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
const alias = token?.name ?? actor.getAlias();
|
const alias = token?.name ?? actor.getAlias();
|
||||||
|
const blessuresGraves = actor.countBlessures(it => it.isGrave());
|
||||||
const formData = {
|
const formData = {
|
||||||
combatId: combat._id,
|
combatId: combat._id,
|
||||||
alias: alias,
|
alias: alias,
|
||||||
@@ -1388,7 +1389,7 @@ export class RdDCombat {
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actor: actor,
|
actor: actor,
|
||||||
tokenId: token.id,
|
tokenId: token.id,
|
||||||
isGrave: actor.countBlessures(it => it.isGrave()) > 0,
|
blessuresGraves: blessuresGraves,
|
||||||
isCritique: actor.countBlessures(it => it.isCritique()) > 0
|
isCritique: actor.countBlessures(it => it.isCritique()) > 0
|
||||||
}
|
}
|
||||||
await ChatMessage.create({
|
await ChatMessage.create({
|
||||||
|
|||||||
@@ -49,9 +49,8 @@ export default class ChatRollResult {
|
|||||||
roll.active.actor,
|
roll.active.actor,
|
||||||
roll.current?.rollmode?.key
|
roll.current?.rollmode?.key
|
||||||
)
|
)
|
||||||
const save = RollDialog.saveParts(roll, impacts)
|
|
||||||
|
|
||||||
await this.saveChatMessageRoll(chatMessage, save)
|
await this.saveChatMessageRoll(chatMessage, roll, impacts)
|
||||||
return chatMessage
|
return chatMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,8 +165,20 @@ export default class ChatRollResult {
|
|||||||
return roll.active?.actor ?? (roll.ids?.actorId ? game.actors.get(roll.ids.actorId) : undefined)
|
return roll.active?.actor ?? (roll.ids?.actorId ? game.actors.get(roll.ids.actorId) : undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
async saveChatMessageRoll(chatMessage, savedRoll) {
|
async updateChatMessage(chatMessage, savedRoll) {
|
||||||
await ChatUtility.setMessageData(chatMessage, 'rollData', savedRoll)
|
RollDialog.loadRollData(savedRoll)
|
||||||
|
savedRoll.dmg = savedRoll.current.attaque?.dmg
|
||||||
|
|
||||||
|
await this.saveChatMessageRoll(chatMessage, savedRoll)
|
||||||
|
|
||||||
|
this.prepareDisplay(savedRoll)
|
||||||
|
chatMessage.update({ content: await this.buildRollHtml(savedRoll) })
|
||||||
|
chatMessage.render(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
async saveChatMessageRoll(chatMessage, roll, impacts = undefined) {
|
||||||
|
const save = RollDialog.saveParts(roll, impacts)
|
||||||
|
await ChatUtility.setMessageData(chatMessage, 'rollData', save)
|
||||||
}
|
}
|
||||||
|
|
||||||
loadChatMessageRoll(chatMessage) {
|
loadChatMessageRoll(chatMessage) {
|
||||||
@@ -176,16 +187,6 @@ export default class ChatRollResult {
|
|||||||
return savedRoll
|
return savedRoll
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateChatMessage(chatMessage, savedRoll) {
|
|
||||||
await this.saveChatMessageRoll(chatMessage, savedRoll)
|
|
||||||
const copy = foundry.utils.duplicate(savedRoll)
|
|
||||||
RollDialog.loadRollData(copy)
|
|
||||||
savedRoll.dmg = copy.current.attaque?.dmg
|
|
||||||
this.prepareDisplay(copy)
|
|
||||||
chatMessage.update({ content: await this.buildRollHtml(copy) })
|
|
||||||
chatMessage.render(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
onClickAppelChance(event) {
|
onClickAppelChance(event) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
const chatMessage = ChatUtility.getChatMessage(event)
|
const chatMessage = ChatUtility.getChatMessage(event)
|
||||||
@@ -197,28 +198,28 @@ export default class ChatRollResult {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async onAppelChanceSuccess(reRoll, chatMessage) {
|
async onAppelChanceSuccess(roll, chatMessage) {
|
||||||
reRoll.type.retry = true
|
roll.type.retry = true
|
||||||
await this.updateChatMessage(chatMessage, reRoll)
|
await this.updateChatMessage(chatMessage, roll)
|
||||||
|
|
||||||
const callbacks = [ChatUtility.remover(chatMessage)]
|
const callbacks = [ChatUtility.remover(chatMessage)]
|
||||||
// TODO: annuler les effets...
|
// TODO: annuler les effets...
|
||||||
switch (reRoll.type.current) {
|
switch (roll.type.current) {
|
||||||
case ROLL_TYPE_DEFENSE:
|
case ROLL_TYPE_DEFENSE:
|
||||||
this.getCombat(reRoll)?.doRollDefense(reRoll, callbacks)
|
this.getCombat(roll)?.doRollDefense(roll, callbacks)
|
||||||
break
|
break
|
||||||
case ROLL_TYPE_ATTAQUE:
|
case ROLL_TYPE_ATTAQUE:
|
||||||
this.getCombat(reRoll)?.doRollAttaque(reRoll, callbacks)
|
this.getCombat(roll)?.doRollAttaque(roll, callbacks)
|
||||||
break
|
break
|
||||||
default: {
|
default: {
|
||||||
await RollDialog.create(reRoll, { onRollDone: RollDialog.onRollDoneClose, callbacks })
|
await RollDialog.create(roll, { onRollDone: RollDialog.onRollDoneClose, callbacks })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async onAppelChanceEchec(reRoll, chatMessage) {
|
async onAppelChanceEchec(roll, chatMessage) {
|
||||||
reRoll.type.retry = true
|
roll.type.retry = true
|
||||||
await this.updateChatMessage(chatMessage, reRoll)
|
await this.updateChatMessage(chatMessage, roll)
|
||||||
}
|
}
|
||||||
|
|
||||||
onClickAppelDestinee(event) {
|
onClickAppelDestinee(event) {
|
||||||
@@ -229,10 +230,9 @@ export default class ChatRollResult {
|
|||||||
const actor = this.getActiveActor(savedRoll)
|
const actor = this.getActiveActor(savedRoll)
|
||||||
|
|
||||||
Misc.doIfOwner(actor, it => it.appelDestinee(async () => {
|
Misc.doIfOwner(actor, it => it.appelDestinee(async () => {
|
||||||
const reRoll = foundry.utils.duplicate(savedRoll)
|
savedRoll.type.retry = true
|
||||||
reRoll.type.retry = true
|
RdDResolutionTable.significativeRequise(savedRoll.rolled)
|
||||||
RdDResolutionTable.significativeRequise(reRoll.rolled)
|
await this.updateChatMessage(chatMessage, savedRoll)
|
||||||
await this.updateChatMessage(chatMessage, reRoll)
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ import ChatRollResult from "./chat-roll-result.mjs";
|
|||||||
import { renderTemplate } from "../constants.js";
|
import { renderTemplate } from "../constants.js";
|
||||||
import { RollTypeCuisine } from "./roll-type-cuisine.mjs";
|
import { RollTypeCuisine } from "./roll-type-cuisine.mjs";
|
||||||
import { RollPartCuisine } from "./roll-part-cuisine.mjs";
|
import { RollPartCuisine } from "./roll-part-cuisine.mjs";
|
||||||
import { OptionsAvancees, ROLL_DIALOG_V2_TEST } from "../settings/options-avancees.js";
|
|
||||||
import { ActorImpacts } from "../technical/actor-impacts.mjs";
|
import { ActorImpacts } from "../technical/actor-impacts.mjs";
|
||||||
import { RollPartEmpoignade } from "./roll-part-empoignade.mjs";
|
import { RollPartEmpoignade } from "./roll-part-empoignade.mjs";
|
||||||
import { RollPartEmpoignadeTaille } from "./roll-part-empoignade-taille.mjs";
|
import { RollPartEmpoignadeTaille } from "./roll-part-empoignade-taille.mjs";
|
||||||
@@ -199,9 +198,7 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
|||||||
}
|
}
|
||||||
|
|
||||||
static onRollDoneClose(dialog, roll) {
|
static onRollDoneClose(dialog, roll) {
|
||||||
if (roll.type.retry || !OptionsAvancees.isUsing(ROLL_DIALOG_V2_TEST)) {
|
dialog.close()
|
||||||
dialog.close()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static init() { }
|
static init() { }
|
||||||
@@ -289,6 +286,13 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
|||||||
// rien pour l'instant
|
// rien pour l'instant
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getAllowedParts(rollData) {
|
||||||
|
return rollData.type?.allowed
|
||||||
|
? ROLL_PARTS.filter(p => RollDialog.$isIntersecting(rollData.type.allowed, p.rollTypes))
|
||||||
|
: ROLL_PARTS
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/** pre-configure les paramètres des différentes parties de la fenêtre (par exemple, prépare les listes de caractéristiques/compétences */
|
/** pre-configure les paramètres des différentes parties de la fenêtre (par exemple, prépare les listes de caractéristiques/compétences */
|
||||||
static $prepareRollData(rollData) {
|
static $prepareRollData(rollData) {
|
||||||
rollData.current = rollData.current ?? {}
|
rollData.current = rollData.current ?? {}
|
||||||
@@ -302,17 +306,17 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
|||||||
? [potential]
|
? [potential]
|
||||||
: (rollData.type.allowed ?? ALL_ROLL_TYPES.filter(m => m.isAllowed(rollData) && m.visible(rollData)).map(m => m.code) ?? [ROLL_TYPE_COMP])
|
: (rollData.type.allowed ?? ALL_ROLL_TYPES.filter(m => m.isAllowed(rollData) && m.visible(rollData)).map(m => m.code) ?? [ROLL_TYPE_COMP])
|
||||||
const rollType = allowed.find(c => c == rollData.type.current) ?? allowed[0]
|
const rollType = allowed.find(c => c == rollData.type.current) ?? allowed[0]
|
||||||
|
const allowedRollParts = RollDialog.getAllowedParts(rollData)
|
||||||
|
|
||||||
rollData.type.allowed = allowed
|
rollData.type.allowed = allowed
|
||||||
rollData.type.current = rollType
|
rollData.type.current = rollType
|
||||||
ALL_ROLL_TYPES.find(m => m.code == rollType).setRollDataType(rollData)
|
ALL_ROLL_TYPES.find(m => m.code == rollType).setRollDataType(rollData)
|
||||||
|
|
||||||
rollData.refs = foundry.utils.mergeObject(rollData.refs ?? {}, Object.fromEntries(ROLL_PARTS.map(p => [p.code, {}])));
|
rollData.refs = foundry.utils.mergeObject(rollData.refs ?? {}, Object.fromEntries(allowedRollParts.map(p => [p.code, {}])));
|
||||||
rollData.options = rollData.options ?? { rollMode: game.settings.get("core", "rollMode") }
|
rollData.options = rollData.options ?? { rollMode: game.settings.get("core", "rollMode") }
|
||||||
|
|
||||||
ROLL_PARTS.forEach(p => RollDialog.$initializeRollPart(rollData, p.code))
|
allowedRollParts.forEach(p => RollDialog.$initializeRollPart(rollData, p.code))
|
||||||
ROLL_PARTS
|
allowedRollParts
|
||||||
.filter(p => RollDialog.$isIntersecting(allowed, p.rollTypes))
|
|
||||||
.filter(p => p.isValid(rollData))
|
.filter(p => p.isValid(rollData))
|
||||||
.forEach(p => {
|
.forEach(p => {
|
||||||
p.restore(rollData)
|
p.restore(rollData)
|
||||||
@@ -350,11 +354,13 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
|||||||
}
|
}
|
||||||
if (from.current) {
|
if (from.current) {
|
||||||
// stockage de current
|
// stockage de current
|
||||||
ROLL_PARTS.filter(p => p.isActive(from))
|
RollDialog.getAllowedParts(from)
|
||||||
|
.filter(p => p.isActive(from))
|
||||||
.forEach(p => p.storeClean(from, target))
|
.forEach(p => p.storeClean(from, target))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const target = RollBasicParts.initFrom(rollData)
|
const target = RollBasicParts.initFrom(rollData)
|
||||||
saveBasics(rollData, target)
|
saveBasics(rollData, target)
|
||||||
if (impacts) {
|
if (impacts) {
|
||||||
@@ -382,12 +388,14 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
|||||||
onClose: rollOptions.onClose ?? RollDialog.onCloseDoNothing
|
onClose: rollOptions.onClose ?? RollDialog.onCloseDoNothing
|
||||||
}
|
}
|
||||||
this.chatRollResult = new ChatRollResult()
|
this.chatRollResult = new ChatRollResult()
|
||||||
|
this.rollParts = RollDialog.getAllowedParts(rollData)
|
||||||
|
|
||||||
this.selectType()
|
this.selectType()
|
||||||
this.registerHooks(rollData)
|
this.registerHooks(rollData)
|
||||||
}
|
}
|
||||||
|
|
||||||
registerHooks(rollData) {
|
registerHooks(rollData) {
|
||||||
ROLL_PARTS.filter(p => p.isValid(rollData))
|
this.rollParts.filter(p => p.isValid(rollData))
|
||||||
.forEach(p => p.getHooks(this).forEach(h => {
|
.forEach(p => p.getHooks(this).forEach(h => {
|
||||||
const hook = h.hook;
|
const hook = h.hook;
|
||||||
const id = Hooks.on(hook, h.fn)
|
const id = Hooks.on(hook, h.fn)
|
||||||
@@ -407,13 +415,12 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
|||||||
selectedType.onSelect(this.rollData)
|
selectedType.onSelect(this.rollData)
|
||||||
this.rollData.type.label = selectedType.title(this.rollData)
|
this.rollData.type.label = selectedType.title(this.rollData)
|
||||||
|
|
||||||
ROLL_PARTS.find(it => it.code == PART_CARAC).filterCaracs(this.rollData)
|
this.rollParts.find(it => it.code == PART_CARAC).filterCaracs(this.rollData)
|
||||||
ROLL_PARTS.find(it => it.code == PART_COMP).filterComps(this.rollData)
|
this.rollParts.find(it => it.code == PART_COMP).filterComps(this.rollData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getActiveParts() {
|
||||||
static getActiveParts(rollData) {
|
return this.rollParts.filter(p => p.isActive(this.rollData))
|
||||||
return ROLL_PARTS.filter(p => p.isActive(rollData))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rollTitle(rollData) {
|
rollTitle(rollData) {
|
||||||
@@ -448,12 +455,13 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
|||||||
))
|
))
|
||||||
|
|
||||||
Promise.all(
|
Promise.all(
|
||||||
RollDialog.getActiveParts(this.rollData).map(async p => await p._onRender(this, context, options))
|
this.getActiveParts().map(async p => await p._onRender(this, context, options))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
static getAjustements(rollData) {
|
static getAjustements(rollData) {
|
||||||
return RollDialog.getActiveParts(rollData)
|
return RollDialog.getAllowedParts(rollData)
|
||||||
|
.filter(p => p.isActive(rollData))
|
||||||
.map(p => p.getAjustements(rollData))
|
.map(p => p.getAjustements(rollData))
|
||||||
.reduce((a, b) => a.concat(b))
|
.reduce((a, b) => a.concat(b))
|
||||||
.sort((a, b) => a.value == undefined ? 1 : b.value == undefined ? -1 : 0)
|
.sort((a, b) => a.value == undefined ? 1 : b.value == undefined ? -1 : 0)
|
||||||
@@ -470,8 +478,8 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
|||||||
.map(m => m.toTypeData(rollData))
|
.map(m => m.toTypeData(rollData))
|
||||||
RollBasicParts.loadSurprises(rollData, this.getSelectedType().code)
|
RollBasicParts.loadSurprises(rollData, this.getSelectedType().code)
|
||||||
rollData.type.label = this.getSelectedType()?.title(rollData)
|
rollData.type.label = this.getSelectedType()?.title(rollData)
|
||||||
//TOCHECK: set type.label ?
|
|
||||||
const visibleRollParts = RollDialog.getActiveParts(rollData)
|
const visibleRollParts = this.getActiveParts()
|
||||||
visibleRollParts.forEach(p => p.applyExternalImpacts(visibleRollParts, rollData))
|
visibleRollParts.forEach(p => p.applyExternalImpacts(visibleRollParts, rollData))
|
||||||
|
|
||||||
this.setSpecialComp(visibleRollParts);
|
this.setSpecialComp(visibleRollParts);
|
||||||
@@ -480,7 +488,7 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
|||||||
|
|
||||||
RollDialog.calculAjustement(rollData)
|
RollDialog.calculAjustement(rollData)
|
||||||
|
|
||||||
const templates = RollDialog.getActiveParts(rollData).map(p => p.toTemplateData())
|
const templates = visibleRollParts.map(p => p.toTemplateData())
|
||||||
const context = await super._prepareContext()
|
const context = await super._prepareContext()
|
||||||
return foundry.utils.mergeObject(
|
return foundry.utils.mergeObject(
|
||||||
{
|
{
|
||||||
@@ -494,8 +502,7 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
|||||||
const specialComp = visibleRollParts.map(p => p.getSpecialComp(this.rollData))
|
const specialComp = visibleRollParts.map(p => p.getSpecialComp(this.rollData))
|
||||||
.reduce((a, b) => a.concat(b))
|
.reduce((a, b) => a.concat(b))
|
||||||
if (specialComp.length > 0) {
|
if (specialComp.length > 0) {
|
||||||
const rollPartComp = RollDialog.getActiveParts(this.rollData)
|
const rollPartComp = this.getActiveParts().find(it => it.code == PART_COMP)
|
||||||
.find(it => it.code == PART_COMP);
|
|
||||||
rollPartComp?.setSpecialComp(this.rollData, specialComp)
|
rollPartComp?.setSpecialComp(this.rollData, specialComp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -535,12 +542,15 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
|||||||
roll.result = selectedRollType.getResult(roll, impacts)
|
roll.result = selectedRollType.getResult(roll, impacts)
|
||||||
|
|
||||||
console.info('RollDialog.roll:', roll)
|
console.info('RollDialog.roll:', roll)
|
||||||
|
|
||||||
const callbacks = [
|
const callbacks = [
|
||||||
...this.rollOptions.callbacks,
|
|
||||||
...selectedRollType.callbacks(this.rollOptions),
|
...selectedRollType.callbacks(this.rollOptions),
|
||||||
|
...this.rollOptions.callbacks,
|
||||||
]
|
]
|
||||||
|
|
||||||
await Promise.all(callbacks.map(async callback => await callback(roll)))
|
for (let callback of callbacks) {
|
||||||
|
await callback(roll)
|
||||||
|
}
|
||||||
|
|
||||||
await impacts.applyImpacts()
|
await impacts.applyImpacts()
|
||||||
selectedRollType.onApplyImpacts(roll, impacts)
|
selectedRollType.onApplyImpacts(roll, impacts)
|
||||||
|
|||||||
@@ -46,19 +46,25 @@ export class RollPartAttaque extends RollPartSelect {
|
|||||||
return it.arme.isEmpoignade()
|
return it.arme.isEmpoignade()
|
||||||
}
|
}
|
||||||
|
|
||||||
store(rollData, targetData) {
|
restore(rollData) {
|
||||||
super.store(rollData, targetData)
|
const saved = this.getSaved(rollData) ?? {}
|
||||||
this.getSaved(targetData).dmg = this.getCurrent(rollData).dmg
|
this.setCurrent(rollData, {
|
||||||
|
key: saved.key,
|
||||||
|
tactique: saved.tactique,
|
||||||
|
dmg: saved.dmg
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
restore(rollData) {
|
store(rollData, targetData) {
|
||||||
const saved = this.getSaved(rollData)
|
const current = this.getCurrent(rollData)
|
||||||
super.restore(rollData)
|
this.setSaved(targetData, {
|
||||||
if (saved.dmg != undefined) {
|
key: current.key,
|
||||||
this.getCurrent(rollData).dmg = this.getSaved(rollData).dmg
|
tactique: current.tactique,
|
||||||
}
|
dmg: current.dmg
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
findAttaque(attaques, saved) {
|
findAttaque(attaques, saved) {
|
||||||
return attaques.find(at => at.arme.id == saved?.arme?.id &&
|
return attaques.find(at => at.arme.id == saved?.arme?.id &&
|
||||||
at.comp.id == saved?.comp?.id
|
at.comp.id == saved?.comp?.id
|
||||||
@@ -102,7 +108,11 @@ export class RollPartAttaque extends RollPartSelect {
|
|||||||
|
|
||||||
|
|
||||||
$selectAttaque(rollData, key) {
|
$selectAttaque(rollData, key) {
|
||||||
|
const tactique = this.getCurrent(rollData).tactique
|
||||||
this.selectByKey(rollData, key)
|
this.selectByKey(rollData, key)
|
||||||
|
if (tactique) {
|
||||||
|
this.getCurrent(rollData).tactique = tactique
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onRender(rollDialog, context, options) {
|
async _onRender(rollDialog, context, options) {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export class RollPartDefense extends RollPartSelect {
|
|||||||
: defenseur.getCompetencesEsquive()
|
: defenseur.getCompetencesEsquive()
|
||||||
const parades = isEmpoignade
|
const parades = isEmpoignade
|
||||||
? [RdDItemArme.empoignade(defenseur)]
|
? [RdDItemArme.empoignade(defenseur)]
|
||||||
: defenseur.items.filter(it => it.isParade() && (!refs.distance || it.isBouclier()))
|
: this.$getParades(defenseur, attackerRoll, refs.distance)
|
||||||
|
|
||||||
refs.defenses = [
|
refs.defenses = [
|
||||||
...esquives.map(it => RollPartDefense.$extractEsquive(it, defenseur, attackerRoll)),
|
...esquives.map(it => RollPartDefense.$extractEsquive(it, defenseur, attackerRoll)),
|
||||||
@@ -45,6 +45,14 @@ export class RollPartDefense extends RollPartSelect {
|
|||||||
this.$selectDefense(rollData)
|
this.$selectDefense(rollData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$getParades(defenseur, attackerRoll, distance) {
|
||||||
|
const parades = defenseur.items.filter(it => it.isParade() && (!distance || it.isBouclier()))
|
||||||
|
const armeAttaque = attackerRoll?.current?.attaque?.arme
|
||||||
|
return armeAttaque
|
||||||
|
? parades.filter(armeDefense => RdDItemArme.defenseArmeParade(armeAttaque, armeDefense) != 'impossible')
|
||||||
|
: parades
|
||||||
|
}
|
||||||
|
|
||||||
static $extractEsquive(esquive, defenseur, attackerRoll) {
|
static $extractEsquive(esquive, defenseur, attackerRoll) {
|
||||||
const defense = {
|
const defense = {
|
||||||
key: esquive.id,
|
key: esquive.id,
|
||||||
@@ -124,19 +132,19 @@ export class RollPartDefense extends RollPartSelect {
|
|||||||
case PART_CARAC: return part.filterCaracs(rollData, refs.defenses.length > 0 ? [current.carac] : ['impossible'])
|
case PART_CARAC: return part.filterCaracs(rollData, refs.defenses.length > 0 ? [current.carac] : ['impossible'])
|
||||||
case PART_COMP: return part.filterComps(rollData, refs.defenses.length > 0 ? [current.comp?.name] : ['impossible'])
|
case PART_COMP: return part.filterComps(rollData, refs.defenses.length > 0 ? [current.comp?.name] : ['impossible'])
|
||||||
case PART_DIFF: return part.setDiff(rollData, this.getDiffDefense(rollData))
|
case PART_DIFF: return part.setDiff(rollData, this.getDiffDefense(rollData))
|
||||||
case PART_SIGN: return part.setArme(rollData, this.isArmeDisparate(rollData), current.forceRequise)
|
case PART_SIGN: return part.setArme(rollData, this.getArmeDisparate(rollData), current.forceRequise)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
isArmeDisparate(rollData) {
|
getArmeDisparate(rollData) {
|
||||||
const armeDefense = this.getCurrent(rollData).arme
|
const armeDefense = this.getCurrent(rollData).arme
|
||||||
if (armeDefense) {
|
if (armeDefense) {
|
||||||
const armeAttaque = rollData.attackerRoll?.current.attaque.arme
|
const armeAttaque = rollData.attackerRoll?.current.attaque.arme
|
||||||
return RdDItemArme.defenseArmeParade(armeAttaque, armeDefense) == 'sign'
|
return RdDItemArme.defenseArmeParade(armeAttaque, armeDefense)
|
||||||
}
|
}
|
||||||
return false
|
return 'norm'
|
||||||
}
|
}
|
||||||
|
|
||||||
getDiffDefense(rollData) {
|
getDiffDefense(rollData) {
|
||||||
|
|||||||
@@ -29,4 +29,17 @@ export class RollPartRollMode extends RollPart {
|
|||||||
rollDialog.render()
|
rollDialog.render()
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getHooks(rollDialog) {
|
||||||
|
return [
|
||||||
|
{ hook: "clientSettingChanged", fn: (setting, update, options, id) => this.onUpdateSetting(rollDialog, setting, update, options, id) },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
async onUpdateSetting(rollDialog, setting, update, options, id) {
|
||||||
|
if (setting == 'core.rollMode') {
|
||||||
|
this.setCurrent(rollDialog.rollData, { key: game.settings.get("core", "rollMode") })
|
||||||
|
rollDialog.render()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export class RollPartSign extends RollPart {
|
|||||||
const actor = rollData.active.actor;
|
const actor = rollData.active.actor;
|
||||||
const isCombat = this.isCombat(rollData)
|
const isCombat = this.isCombat(rollData)
|
||||||
const current = this.getCurrent(rollData)
|
const current = this.getCurrent(rollData)
|
||||||
current.armeDisparate = isCombat && current.armeDisparate
|
current.armeDisparate = isCombat ? current.armeDisparate : 'norm'
|
||||||
current.surprise = actor.getSurprise(isCombat, current.forceRequise ?? 0)
|
current.surprise = actor.getSurprise(isCombat, current.forceRequise ?? 0)
|
||||||
current.reasons = actor.getEffects(it => StatusEffects.niveauSurprise(it, isCombat) > 0, current.forceRequise ?? 0)
|
current.reasons = actor.getEffects(it => StatusEffects.niveauSurprise(it, isCombat) > 0, current.forceRequise ?? 0)
|
||||||
.map(it => { return { img: it.img, label: game.i18n.localize(it.name) } })
|
.map(it => { return { img: it.img, label: game.i18n.localize(it.name) } })
|
||||||
@@ -81,7 +81,7 @@ export class RollPartSign extends RollPart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isParadeArmeDisparate(current) {
|
isParadeArmeDisparate(current) {
|
||||||
return current.armeDisparate
|
return current.armeDisparate == 'sign'
|
||||||
}
|
}
|
||||||
|
|
||||||
getAjustements(rollData) {
|
getAjustements(rollData) {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { ITEM_TYPES } from "../constants.js"
|
|
||||||
import { ReglesOptionnelles } from "../settings/regles-optionnelles.js"
|
import { ReglesOptionnelles } from "../settings/regles-optionnelles.js"
|
||||||
import { DIFF, ROLL_TYPE_TACHE } from "./roll-constants.mjs"
|
import { DIFF, ROLL_TYPE_TACHE } from "./roll-constants.mjs"
|
||||||
import { PART_TACHE } from "./roll-part-tache.mjs"
|
import { PART_TACHE } from "./roll-part-tache.mjs"
|
||||||
@@ -19,25 +18,22 @@ export class RollTypeTache extends RollType {
|
|||||||
this.setDiffType(rollData, DIFF.AUCUN)
|
this.setDiffType(rollData, DIFF.AUCUN)
|
||||||
}
|
}
|
||||||
|
|
||||||
callbacks(rollOptions) { return [ async r => await RollTypeTache.$onRollTache(r, rollOptions)] }
|
callbacks(rollOptions) { return [async r => await RollTypeTache.$onRollTache(r)] }
|
||||||
|
|
||||||
static async $onRollTache(rollData, rollOptions) {
|
static async $onRollTache(rollData) {
|
||||||
const actor = rollData.active.actor
|
const actor = rollData.active.actor
|
||||||
const tache = rollData.current[PART_TACHE].tache
|
const tache = rollData.current[PART_TACHE].tache
|
||||||
if (ReglesOptionnelles.isUsing("appliquer-fatigue")) {
|
|
||||||
await actor.santeIncDec("fatigue", tache.system.fatigue)
|
|
||||||
}
|
|
||||||
|
|
||||||
rollData.current[PART_TACHE].tache = await tache.update({
|
rollData.current[PART_TACHE].tache = await tache.update({
|
||||||
'system.points_de_tache_courant': tache.system.points_de_tache_courant + rollData.rolled.ptTache,
|
'system.points_de_tache_courant': tache.system.points_de_tache_courant + rollData.rolled.ptTache,
|
||||||
'system.nb_jet_succes': tache.system.nb_jet_succes + (rollData.rolled.isSuccess ? 1 : 0),
|
'system.nb_jet_succes': tache.system.nb_jet_succes + (rollData.rolled.isSuccess ? 1 : 0),
|
||||||
'system.nb_jet_echec': tache.system.nb_jet_echec + (rollData.rolled.isSuccess ? 0 : 1),
|
'system.nb_jet_echec': tache.system.nb_jet_echec + (rollData.rolled.isSuccess ? 0 : 1),
|
||||||
'system.difficulte': tache.system.difficulte - (rollData.rolled.isETotal ? 1 : 0),
|
'system.difficulte': tache.system.difficulte - (rollData.rolled.isETotal ? 1 : 0),
|
||||||
}, {render:true})
|
}, { render: true })
|
||||||
|
|
||||||
|
if (ReglesOptionnelles.isUsing("appliquer-fatigue")) {
|
||||||
if (rollOptions?.onRollAutomate) {
|
await actor.santeIncDec("fatigue", tache.system.fatigue)
|
||||||
await rollOptions.onRollAutomate(rollData)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -63,5 +63,5 @@ export class RollType {
|
|||||||
* @returns undefined ou une structure contenant les informations requise pour afficher
|
* @returns undefined ou une structure contenant les informations requise pour afficher
|
||||||
*/
|
*/
|
||||||
getResult(rollData, impacts) { return { messages: [] } }
|
getResult(rollData, impacts) { return { messages: [] } }
|
||||||
onApplyImpacts(roll, impacts) { }
|
onApplyImpacts(rollData, impacts) { }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,9 @@ import { Misc } from "../misc.js"
|
|||||||
|
|
||||||
export const EXPORT_CSV_SCRIPTARIUM = 'export-csv-scriptarium'
|
export const EXPORT_CSV_SCRIPTARIUM = 'export-csv-scriptarium'
|
||||||
export const ROLL_DIALOG_V2 = 'roll-dialog-v2'
|
export const ROLL_DIALOG_V2 = 'roll-dialog-v2'
|
||||||
export const ROLL_DIALOG_V2_TEST = 'roll-dialog-v2-test'
|
|
||||||
|
|
||||||
const OPTIONS_AVANCEES = [
|
const OPTIONS_AVANCEES = [
|
||||||
{ group: 'Fenêtres', name: ROLL_DIALOG_V2, descr: "Utiliser les nouvelles fenêtres de jet", default: false },
|
{ group: 'Fenêtres', name: ROLL_DIALOG_V2, descr: "Utiliser les nouvelles fenêtres de jet", default: false },
|
||||||
{ group: 'Fenêtres', name: ROLL_DIALOG_V2_TEST, descr: "Mode de test des nouvelles fenêtres", default: false },
|
|
||||||
{ group: 'Menus', name: EXPORT_CSV_SCRIPTARIUM, descr: "Proposer le menu d'export csv Scriptarium", default: false },
|
{ group: 'Menus', name: EXPORT_CSV_SCRIPTARIUM, descr: "Proposer le menu d'export csv Scriptarium", default: false },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,12 @@
|
|||||||
</h4>
|
</h4>
|
||||||
<p data-combatid="{{combatId}}" data-combatmessage="actor-turn-summary">{{blessuresStatus}}</p>
|
<p data-combatid="{{combatId}}" data-combatmessage="actor-turn-summary">{{blessuresStatus}}</p>
|
||||||
<p>Son état général est de : {{etatGeneral}} {{#if isSonne}} et est <strong>sonné</strong>{{/if}}</p>
|
<p>Son état général est de : {{etatGeneral}} {{#if isSonne}} et est <strong>sonné</strong>{{/if}}</p>
|
||||||
{{#if isGrave}}
|
{{#if blessuresGraves}}
|
||||||
<p>{{alias}} souffre de Blessure(s) Grave(s) : n'oubliez pas de faire un Jet de Vie toutes les SC ({{SConst}}) minutes. Un point d'Endurance a été retiré automatiquement.</p>
|
<p>{{alias}} souffre {{#if (eq blessuresGraves 1)}}d'une <strong>blessure grave</strong>{{else}}
|
||||||
|
de {{blessuresGraves}} <strong>blessures graves</strong>{{/if}} : n'oubliez pas de faire un Jet de Vie toutes les SC ({{SConst}}) minutes. Les pertes d'endurance sont automatiques à la fin du round.</p>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if isCritique}}
|
{{#if isCritique}}
|
||||||
<p>{{alias}} souffre d'une <strong>Blessure Critique</strong> : faites un
|
<p>{{alias}} souffre d'une <strong>blessure critique</strong> : faites un
|
||||||
<a class="chat-card-button chat-jet-vie"
|
<a class="chat-card-button chat-jet-vie"
|
||||||
data-tokenId="{{tokenId}}"
|
data-tokenId="{{tokenId}}"
|
||||||
data-actorId="{{actorId}}">Jet de Vie.<a></p>
|
data-actorId="{{actorId}}">Jet de Vie.<a></p>
|
||||||
|
|||||||
@@ -11,8 +11,13 @@
|
|||||||
{{#if (eq active.surprise.key 'totale')}}
|
{{#if (eq active.surprise.key 'totale')}}
|
||||||
<span><strong>{{active.name}}</strong> est totalement surpris</span>
|
<span><strong>{{active.name}}</strong> est totalement surpris</span>
|
||||||
{{else}}
|
{{else}}
|
||||||
|
{{log 'attackerRoll' attackerRoll}}
|
||||||
<span><strong>{{active.name}}</strong> doit se défendre
|
<span><strong>{{active.name}}</strong> doit se défendre
|
||||||
{{~#if (eq active.surprise.key 'demi')}} avec une significative {{/if}} d'une attaque
|
{{~#if (eq active.surprise.key 'demi')}} avec une significative {{/if}} d'une
|
||||||
|
{{#if (eq attackerRoll.current.attaque.tactique.key 'charge')}}charge
|
||||||
|
{{else if (eq attackerRoll.current.attaque.tactique.key 'feinte')}}feinte
|
||||||
|
{{else}}attaque
|
||||||
|
{{/if}}
|
||||||
{{~#if attackerRoll.particuliere}} <strong>particulière en
|
{{~#if attackerRoll.particuliere}} <strong>particulière en
|
||||||
{{~#if (eq attackerRoll.particuliere 'finesse')}} finesse
|
{{~#if (eq attackerRoll.particuliere 'finesse')}} finesse
|
||||||
{{else if (eq attackerRoll.particuliere 'force')}} force
|
{{else if (eq attackerRoll.particuliere 'force')}} force
|
||||||
|
|||||||
@@ -8,9 +8,9 @@
|
|||||||
<hr>
|
<hr>
|
||||||
<span>
|
<span>
|
||||||
{{#if jetVie.rolled.isSuccess}}
|
{{#if jetVie.rolled.isSuccess}}
|
||||||
{{alias}} a réussi son jet d'éthylisme, il a consommé {{doses}} doses sans effet.
|
{{alias}} a réussi son jet d'éthylisme, {{doses}} doses ont été consommées sans effet.
|
||||||
{{else}}
|
{{else}}
|
||||||
{{alias}} a échoué son jet d'éthylisme, il est maintenant {{nomEthylisme}} ({{ajustementEthylique}}).
|
{{alias}} a échoué son jet d'éthylisme et est maintenant {{nomEthylisme}} ({{ajustementEthylique}}).
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</span>
|
</span>
|
||||||
{{#if jetVie.rolled.isEchec}}
|
{{#if jetVie.rolled.isEchec}}
|
||||||
@@ -19,8 +19,8 @@
|
|||||||
{{alias}} perd {{perteEndurance.perte}} points d'endurance. {{#if perteEndurance.perteVie}}<br/>Il tombe inconscient et perd un point de vie.{{/if}}
|
{{alias}} perd {{perteEndurance.perte}} points d'endurance. {{#if perteEndurance.perteVie}}<br/>Il tombe inconscient et perd un point de vie.{{/if}}
|
||||||
{{#if jetMoral}}
|
{{#if jetMoral}}
|
||||||
<br/>Jet de moral {{#if jetMoral.succes}}réussi{{else}}manqué{{/if}} en situation heureuse ({{jetMoral.jet}}/{{jetMoral.difficulte}}).
|
<br/>Jet de moral {{#if jetMoral.succes}}réussi{{else}}manqué{{/if}} en situation heureuse ({{jetMoral.jet}}/{{jetMoral.difficulte}}).
|
||||||
{{#if (gt jetMoral.ajustement 0)}}L'alcool met {{alias}} en joie. Il gagne un point de moral.
|
{{#if (gt jetMoral.ajustement 0)}}L'alcool met en joie {{alias}} qui gagne un point de moral.
|
||||||
{{else if (lt jetMoral.ajustement 0)}}{{alias}} a l'alcool triste. Il perd un point de moral.
|
{{else if (lt jetMoral.ajustement 0)}}{{alias}} a l'alcool triste et perd un point de moral.
|
||||||
{{else}}{{alias}} garde son moral.{{/if}}
|
{{else}}{{alias}} garde son moral.{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
{{active.name}} fait un jet
|
{{active.name}} fait un jet
|
||||||
{{#if current.comp.key}}de {{current.comp.label}}{{/if}}
|
{{#if current.comp.key}}de {{current.comp.label}}{{/if}}
|
||||||
{{#if type.appreciation}}d'appréciation
|
{{#if type.appreciation}}d'appréciation
|
||||||
{{else if (ne current.comp.key '')}}sans compétence
|
{{else if (eq current.comp.key '')}}sans compétence
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user