Compare commits

...

12 Commits

Author SHA1 Message Date
aec4364889 Type de jet: Jet de résistance 2026-05-09 23:14:28 +02:00
f17996b1c8 Difficultés attaque/défense sur appel à la chance 2026-05-09 22:41:47 +02:00
14a4b34bbd Correction jets de compétence des invocations 2026-05-09 22:41:02 +02:00
1777eced30 Correction des catégories de parades 2026-05-09 21:42:09 +02:00
9bdda32d54 Merge pull request 'Set version changelog 13.0.38' (#805) from feature/v13-corrections into v13
All checks were successful
Release Creation / build (release) Successful in 2m29s
Reviewed-on: https, #805
2026-05-05 23:55:45 +02:00
3fe53d7ff0 Set version changelog 13.0.38 2026-05-05 23:55:16 +02:00
c839d4633d Merge pull request '## 13.0.37 - L'urgence d'Illisys' (#804) from feature/v13-corrections into v13
Reviewed-on: https, #804
2026-05-05 23:54:19 +02:00
24753bfc29 Appel chance RollDialogV2 2026-05-05 23:51:04 +02:00
e7acb0c4f2 Fix v14 Dés dice-so-nice 2026-05-05 21:51:01 +02:00
7535e5f340 Fix v14: /roll dans le tchat 2026-05-05 21:48:24 +02:00
d2326e5a25 Fix: liste des actions disponibles
- ajout du haut-rêve
- possibilité de ne lister que les armes équipées
2026-05-05 02:12:48 +02:00
e2afc24601 Message en cas d'erreur de migration 2026-05-02 16:46:25 +02:00
67 changed files with 322 additions and 146 deletions

View File

@@ -1,5 +1,22 @@
# 13.0
## 13.0.39 - La défense d'Illisys
- mise à jour de version foundry-cli
- correction des catégories de parades des compendiums
- des ne pouvaient pas parer (exemple: le bouclier du guerrier sorde)
- les difficultés des jets d'attaque/défense après appel à la chance sont conservées
- L'absence des compétences cuisine/jeu ne bloque plus l'accès à la fenêtre de jets (cas des invocations)
## 13.0.38 - L'urgence d'Illisys
- Corrections v14
- on peut utiliser les commandes foundry dans le tchat (par exemple, /roll 1d6)
- les dés customisés Dice-So-Nice (heure, rencontres, dé draconique) fonctionnent
- Le Haut-rêve est de nouveau proposé dans les options d'initiative
- Nouvelle règle optionnelle: choisir si seules les armes équipées sont proposées en combat
- L'appel à la chance utilise la nouvelle fenêtre de jet de dés
## 13.0.37 - Le bonheur des zyglutes d'Illisys
- Corrections v14

View File

@@ -216,7 +216,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
// Points de reve actuel
this.html.find('.roll-reve-actuel').click(async event => await this.actor.rollReveActuel({ resistance: false }))
this.html.find('.button-reve-resistance').click(async event => await this.actor.rollReveActuel({ diff: -8, resistance: true }))
this.html.find('.button-reve-resistance').click(async event => await this.actor.rollReveResistance())
this.html.find('.action-empoignade').click(async event => await RdDEmpoignade.onAttaqueEmpoignadeFromItem(RdDSheetUtility.getItem(event, this.actor)))
this.html.find('.roll-arme').click(async event => {

View File

@@ -47,11 +47,7 @@ import { RdDRollResult } from "./rdd-roll-result.js";
import { RdDInitiative } from "./initiative.mjs";
import RollDialog from "./roll/roll-dialog.mjs";
import { OptionsAvancees, ROLL_DIALOG_V2 } from "./settings/options-avancees.js";
import { ROLL_TYPE_JEU, ROLL_TYPE_MEDITATION, ROLL_TYPE_SORT } from "./roll/roll-constants.mjs";
import { PART_TACHE } from "./roll/roll-part-tache.mjs";
import { PART_COMP } from "./roll/roll-part-comp.mjs";
import { PART_OEUVRE } from "./roll/roll-part-oeuvre.mjs";
import { PART_CUISINE } from "./roll/roll-part-cuisine.mjs";
import { ROLL_TYPE_COMP, ROLL_TYPE_CUISINE, ROLL_TYPE_JEU, ROLL_TYPE_MEDITATION, ROLL_TYPE_OEUVRE, ROLL_TYPE_SORT, ROLL_TYPE_APPEL_CHANCE, ROLL_TYPE_TACHE } from "./roll/roll-constants.mjs";
import { RdDPossessionV2 } from "./rdd-possession-v2.mjs";
import { Apprecier, MORAL, SITUATION_MORAL } from "./moral/apprecier.mjs";
import { Distance } from "./combat/distance.mjs";
@@ -140,13 +136,14 @@ export class RdDActor extends RdDBaseActorSang {
.reduce(Misc.sum(), 0);
}
listActions({ isAttaque = false, isEquipe = false }) {
listActions() {
// Recupération des attaques
const actions = this.listActionsAttaque()
.filter(it => !isEquipe || it.arme.system.equipe)
const actions = ReglesOptionnelles.isUsing('armes-equipees')
? this.listActionsAttaque().filter(action => action.equipe)
: this.listActionsAttaque()
if (!isAttaque && this.system.attributs.hautrevant.value) {
actions.push({ label: "Draconic", action: 'haut-reve', initOnly: true })
if (this.system.attributs.hautrevant.value) {
actions.push({ label: "Draconic", action: 'haut-reve', initOnly: true, equipe: true })
}
return actions
}
@@ -1876,7 +1873,7 @@ export class RdDActor extends RdDBaseActorSang {
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
const rollData = {
ids: { actorId: this.id },
type: { allowed: [PART_COMP], current: PART_COMP },
type: { allowed: [ROLL_TYPE_COMP], current: ROLL_TYPE_COMP },
selected: {
carac: { key: caracName },
comp: { key: compName, forced: options.forced },
@@ -1915,7 +1912,7 @@ export class RdDActor extends RdDBaseActorSang {
const rollData = {
ids: { actorId: this.id },
selected: { tache: { key: tache.id, forced: options.forced } },
type: { allowed: [PART_TACHE], current: PART_TACHE }
type: { allowed: [ROLL_TYPE_TACHE], current: ROLL_TYPE_TACHE }
}
return await RollDialog.create(rollData, options)
}
@@ -2128,18 +2125,22 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
async rollAppelChance(onSuccess = () => { }, onEchec = () => { }) {
await this.openRollDialog({
name: 'appelChance',
label: 'Appel à la chance',
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.hbs',
rollData: { selectedCarac: this.getCaracByName('chance-actuelle'), surprise: '' },
callbacks: [{ action: r => this.$appelChanceResult(r, onSuccess, onEchec) }]
});
return await RollDialog.create(
{
ids: { actorId: this.id },
type: { allowed: [ROLL_TYPE_APPEL_CHANCE], current: ROLL_TYPE_APPEL_CHANCE },
},
{
onRollDone: (dialog, roll) => RollDialog.onRollDoneClose(dialog, roll),
callbacks: [
async roll => await this.$onAppelChance(roll, onSuccess, onEchec)
]
})
}
/* -------------------------------------------- */
async $appelChanceResult(rollData, onSuccess, onEchec) {
await RdDRollResult.displayRollData(rollData, this, 'chat-resultat-appelchance.hbs')
async $onAppelChance(rollData, onSuccess, onEchec) {
if (rollData.rolled.isSuccess) {
await this.setFlag(SYSTEM_RDD, 'utilisationChance', true);
await this.chanceActuelleIncDec(-1);
@@ -2474,10 +2475,10 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
async equiperObjet(item) {
if (item?.isEquipable()) {
const isEquipe = !item.system.equipe;
await item.update({ "system.equipe": isEquipe })
const newEquipe = !item.system.equipe;
await item.update({ "system.equipe": newEquipe })
this.computeEncTotal()
if (isEquipe)
if (newEquipe)
await this.verifierForceMin(item)
}
}
@@ -3014,7 +3015,7 @@ export class RdDActor extends RdDBaseActorSang {
const rollData = {
ids: { actorId: this.id },
selected: { oeuvre: { key: oeuvre.id } },
type: { allowed: [PART_OEUVRE], current: PART_OEUVRE, },
type: { allowed: [ROLL_TYPE_OEUVRE], current: ROLL_TYPE_OEUVRE, },
}
return await RollDialog.create(rollData)
}
@@ -3116,7 +3117,7 @@ export class RdDActor extends RdDBaseActorSang {
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
const rollData = {
ids: { actorId: this.id },
type: { allowed: [PART_CUISINE], current: PART_CUISINE },
type: { allowed: [ROLL_TYPE_CUISINE], current: ROLL_TYPE_CUISINE },
selected: {
cuisine: { key: recette.id }
}
@@ -3166,7 +3167,7 @@ export class RdDActor extends RdDBaseActorSang {
if (item.getUtilisationCuisine() == 'brut' && OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
const rollData = {
ids: { actorId: this.id },
type: { allowed: [PART_CUISINE], current: PART_CUISINE },
type: { allowed: [ROLL_TYPE_CUISINE], current: ROLL_TYPE_CUISINE },
selected: {
cuisine: { key: item.id }
}

View File

@@ -26,9 +26,8 @@ import { BASE_CORPS_A_CORPS, BASE_ESQUIVE, CATEGORIES_COMPETENCES_CREATURES } fr
import { RollDataAjustements } from "../rolldata-ajustements-v1.js";
import { MappingCreatureArme } from "../item/mapping-creature-arme.mjs";
import RollDialog from "../roll/roll-dialog.mjs";
import { DEFAULT_ROLL_TYPES, DIFF, ROLL_TYPE_ATTAQUE } from "../roll/roll-constants.mjs";
import { DEFAULT_ROLL_TYPES, DIFF, ROLL_TYPE_ATTAQUE, ROLL_TYPE_COMP, ROLL_TYPE_REVE_RESISTANCE } from "../roll/roll-constants.mjs";
import { OptionsAvancees, ROLL_DIALOG_V2 } from "../settings/options-avancees.js";
import { PART_COMP } from "../roll/roll-part-comp.mjs";
import { RdDInitiative } from "../initiative.mjs";
import { RdDItemCompetenceCreature } from "../item-competencecreature.js";
import { RdDPossessionV2 } from "../rdd-possession-v2.mjs";
@@ -145,7 +144,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
}
}
listActions({ isAttaque = false, isEquipe = false }) {
listActions() {
return this.itemTypes[ITEM_TYPES.competencecreature]
.filter(it => it.isAttaque())
.map(it => it.attaqueCreature())
@@ -156,7 +155,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
async remiseANeuf() { }
async ajoutExperience(rollData, hideChatMessage = 'show') { }
computeResumeBlessure() { return []}
computeResumeBlessure() { return [] }
countBlessures(filter = it => !it.isContusion()) { return 0 }
async santeIncDec(name, inc, isCritique) { }
@@ -317,7 +316,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
const competence = this.getCompetence(compName);
const rollData = {
ids: { actorId: this.id },
type: { allowed: DEFAULT_ROLL_TYPES, current: PART_COMP },
type: { allowed: DEFAULT_ROLL_TYPES, current: ROLL_TYPE_COMP },
selected: {
carac: { key: caracName },
comp: { key: competence.name },
@@ -384,7 +383,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
ids: { actorId: this.id },
type: {
allowed: DEFAULT_ROLL_TYPES,
current: PART_COMP,
current: ROLL_TYPE_COMP,
},
selected: {
diff: { type: DIFF.DEFAUT }
@@ -412,13 +411,33 @@ export class RdDBaseActorReve extends RdDBaseActor {
})
}
/* -------------------------------------------- */
async rollReveResistance(diff = -8) {
return await RollDialog.create(
{
ids: { actorId: this.id },
type: {
allowed: [ROLL_TYPE_REVE_RESISTANCE],
current: ROLL_TYPE_REVE_RESISTANCE,
resistance: true
},
selected: {
carac: { key: CARACS.REVE_ACTUEL, forced: true },
comp: { key: undefined, forced: true },
diff: { type: DIFF.DEFAUT, value: diff }
}
},
{
onRollDone: (dialog, roll) => RollDialog.onRollDoneClose(dialog, roll)
})
}
async rollReveActuel({ diff = 0, resistance = false }) {
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
const rollData = {
ids: { actorId: this.id },
type: {
allowed: [PART_COMP],
current: PART_COMP,
allowed: [ROLL_TYPE_REVE_RESISTANCE],
current: ROLL_TYPE_REVE_RESISTANCE,
resistance: resistance
},
selected: {
@@ -440,8 +459,8 @@ export class RdDBaseActorReve extends RdDBaseActor {
const rollData = {
ids: { actorId: this.id },
type: {
allowed: options.resistance ? [PART_COMP] : DEFAULT_ROLL_TYPES,
current: PART_COMP,
allowed: options.resistance ? [ROLL_TYPE_COMP] : DEFAULT_ROLL_TYPES,
current: options.resistance ? ROLL_TYPE_COMP : ROLL_TYPE_COMP,
resistance: options.resistance
},
selected: {

View File

@@ -914,11 +914,7 @@ export class RdDBaseActor extends Actor {
isActorCombat() { return false }
getCaracInit(competence) { return 0 }
listAttaques() {
return this.listActions({ isAttaque: true, isEquipe: false })
}
listActions({ isAttaque = false, isEquipe = false }) { return [] }
listActions() { return [] }
listActionsPossessions() {
return this.itemTypes[ITEM_TYPES.possession]

View File

@@ -6,7 +6,7 @@ import { RdDInitiative } from "../initiative.mjs";
import { MappingCreatureArme } from "./mapping-creature-arme.mjs";
import { Misc } from "../misc.js";
const nomCategorieParade = {
const categorie_parade = {
"sans-armes": "Sans arme",
"armes-naturelles": "Armes naturelles",
"hast": "Armes d'hast",
@@ -18,6 +18,7 @@ const nomCategorieParade = {
"epees-lourdes": "Epées lourdes",
"haches": "Haches",
"lances": "Lances",
"masses": "Masses",
}
export const ATTAQUE_TYPE = {
UNE_MAIN: '(1 main)',
@@ -122,7 +123,7 @@ export class RdDItemArme extends RdDItem {
/* -------------------------------------------- */
static getNomCategorieParade(arme) {
const categorie = arme?.system ? RdDItemArme.getCategorieParade(arme) : arme;
return nomCategorieParade[categorie];
return categorie_parade[categorie];
}
/* -------------------------------------------- */

View File

@@ -4,9 +4,8 @@ import { SANS_COMPETENCE } from "../item/base-items.js"
import { Misc } from "../misc.js"
import { CARACS } from "../rdd-carac.js"
import { RdDUtility } from "../rdd-utility.js"
import { DIFF } from "../roll/roll-constants.mjs"
import { DIFF, ROLL_TYPE_COMP } from "../roll/roll-constants.mjs"
import RollDialog from "../roll/roll-dialog.mjs"
import { PART_COMP } from "../roll/roll-part-comp.mjs"
export const MORAL = {
MALHEUREUX: "malheureux",
@@ -134,7 +133,7 @@ export class Apprecier {
const competence = (this.appreciation.jetComp && this.appreciation.competence) ? this.appreciation.competence : ""
const rollData = {
ids: { actorId: this.actor.id },
type: { allowed: [PART_COMP], current: PART_COMP, appreciation: true },
type: { allowed: [ROLL_TYPE_COMP], current: ROLL_TYPE_COMP, appreciation: true },
selected: {
carac: { key: this.appreciation.carac, forced: true },
comp: { key: competence, forced: true },

View File

@@ -170,7 +170,7 @@ export class RdDCombatManager extends Combat {
}
static getFirstInitRollFormula(actor) {
const actions = actor.listActions({ isEquipe: true })
const actions = actor.listActions()
if (actions.length > 0) {
const action = actions[0]
const init = RdDCombatManager.getInitData(actor, action)
@@ -307,7 +307,7 @@ export class RdDCombatManager extends Combat {
const possessions = actor.listActionsPossessions()
const actions = possessions.length > 0
? possessions
: actor.listActions({ isEquipe: true })
: actor.listActions()
return Misc.indexed(actions)
}
@@ -644,7 +644,7 @@ export class RdDCombat {
opponentId: this.defender.id,
opponentTokenId: this.defenderTokenId,
},
type: { allowed: ['attaque'], current: 'attaque' },
type: { allowed: [ROLL_TYPE_ATTAQUE], current: ROLL_TYPE_ATTAQUE },
selected: {},
passeArme: foundry.utils.randomID(16),
}

View File

@@ -218,16 +218,16 @@ export class RdDCommands {
/* -------------------------------------------- */
/* Manage chat commands */
processChatCommand(commandLine, content = '', msg = {}) {
// Setup new message's visibility
ChatUtility.applyRollMode(msg)
msg.type = 0;
if (!this.commandsTable) {
this._registerCommands()
}
let command = commandLine[0].toLowerCase();
if (this._isCommandHandled(command)) {
// Setup new message's visibility
ChatUtility.applyRollMode(msg)
msg.type = 0;
let params = commandLine.slice(1);
this._processCommand(this.commandsTable, command, params, content, msg)
return true

View File

@@ -18,7 +18,7 @@ export class DeTMR extends foundry.dice.terms.Die {
static diceSoNiceData(system) {
return {
type: "dt",
type: "d8",
font: "HeuresDraconiques",
fontScale: 0.8,
labels: ['1', '2', '3', '4', '5', '6', 'd', '0'],
@@ -56,7 +56,7 @@ export class DeDraconique extends foundry.dice.terms.Die {
static diceSoNiceData(system) {
return {
type: "dr",
type: "d8",
font: "HeuresDraconiques",
fontScale: 0.8,
labels: ['1', '2', '3', '4', '5', '6', 'd', '0'],
@@ -96,7 +96,7 @@ export class DeHeure extends foundry.dice.terms.Die {
static diceSoNiceData(system) {
return {
type: "dh",
type: "d12",
font: "HeuresDraconiques",
fontScale: 1.2,
labels: ['v', 'i', 'f', 'o', 'd', 'e', 'l', 's', 'p', 'a', 'r', 'c'],

View File

@@ -377,7 +377,17 @@ export class SystemReveDeDragon {
/* -------------------------------------------- */
game.system.rdd.calendrier = new RdDCalendrier()
if (Misc.isFirstConnectedGM()) {
new Migrations().migrate()
try {
new Migrations().migrate()
}
catch (erreur) {
const message = `<p>Erreur lors de la migration du système Rêve de Dragon: ${erreur}</p><p>Plus de détails sont sans doute disponibles dans la console de Foundry/du navigateur.</p><p>Merci de nous signaler cetter erreur qu'on puisse ous aider et réparer le problème.</p>`
ui.notifications.error(message)
await ChatMessage.create({
user: game.user.id,
content: message
})
}
this.messageDeBienvenue()
import("https://www.uberwald.me/fvtt_appcount/count-class-ready.js").then(moduleCounter => {
console.log("ClassCounter loaded", moduleCounter)
@@ -399,7 +409,7 @@ export class SystemReveDeDragon {
if (!game.user.isGM && game.user.character == undefined) {
ui.notifications.info("Attention ! Vous n'êtes connecté à aucun personnage !")
ChatMessage.create({
content: "<b>ATTENTION</b> Le joueur " + game.user.name + " n'est connecté à aucun personnage !",
content: `<b>ATTENTION</b> Le joueur ${game.user.name} n'est connecté à aucun personnage !`,
user: game.user.id
})
}

View File

@@ -49,7 +49,7 @@ export class RdDTokenHud {
static async addExtensionHudCombatV2(html, combatant, actor, token) {
const isPossession = actor.listActionsPossessions().length > 0;
const actionsCombat = isPossession ? [] : actor.listAttaques()
const actionsCombat = isPossession ? [] : actor.listActions()
const ajustements = combatant?.initiative ?
[
{ label: 'Initiative +1', action: 'delta', value: 1 },

View File

@@ -200,6 +200,7 @@ export default class ChatRollResult {
const chatMessage = ChatUtility.getChatMessage(event)
const savedRoll = this.loadChatMessageRoll(chatMessage)
const actor = this.getActiveActor(savedRoll)
Misc.doIfOwner(actor, it => it.rollAppelChance(
() => this.onAppelChanceSuccess(savedRoll, chatMessage),
() => this.onAppelChanceEchec(savedRoll, chatMessage))
@@ -208,6 +209,7 @@ export default class ChatRollResult {
async onAppelChanceSuccess(roll, chatMessage) {
roll.type.retry = true
roll.type.appelChance = true
await this.updateChatMessage(chatMessage, roll)
const callbacks = [ChatUtility.remover(chatMessage)]

View File

@@ -9,6 +9,8 @@ export const ROLL_TYPE_MEDITATION = 'meditation'
export const ROLL_TYPE_OEUVRE = 'oeuvre'
export const ROLL_TYPE_SORT = 'sort'
export const ROLL_TYPE_TACHE = 'tache'
export const ROLL_TYPE_APPEL_CHANCE = 'appel-chance'
export const ROLL_TYPE_REVE_RESISTANCE = 'reve-resistance'
export const ATTAQUE_ROLL_TYPES = [ROLL_TYPE_ATTAQUE]
export const COMBAT_ROLL_TYPES = [ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE]

View File

@@ -50,6 +50,8 @@ import { RollPartResistance } from "./roll-part-resistance.mjs";
import { RollTypePossession } from "./roll-type-possession.mjs";
import { RollPartPossession } from "./roll-part-possession.mjs";
import { RollPartApprecier } from "./roll-part-apprecier.mjs";
import { RollTypeAppelChance } from "./roll-type-appel-chance.mjs";
import { RollTypeReveResistance } from "./roll-type-resistance.mjs";
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api
@@ -65,7 +67,8 @@ export const ALL_ROLL_TYPES = [
new RollTypeCuisine(),
new RollTypeOeuvre(),
new RollTypeJeu(),
// new RollTypeResistance ??
new RollTypeAppelChance(),
new RollTypeReveResistance(),
// new RollTypeFixedCarac ??
]
@@ -290,7 +293,6 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
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 */

View File

@@ -35,7 +35,8 @@ export class RollPartAttaque extends RollPartSelect {
loadRefs(rollData) {
const refs = this.getRefs(rollData)
const attaques = rollData.active.actor.listAttaques()
const attaques = rollData.active.actor.listActions()
.filter(it => !it.initOnly)
.sort(Misc.descending(it => it.comp?.system.niveau ?? -8))
refs.all = attaques.map(it => RollPartAttaque.$extractAttaque(it, rollData))
this.filterAttaquesInitiative(rollData)
@@ -186,7 +187,9 @@ export class RollPartAttaque extends RollPartSelect {
part.setDiff(rollData, { type: DIFF.DEFAUT })
}
else {
part.setDiff(rollData, { type: DIFF.ATTAQUE, diff: current.initialDiff })
if (!rollData.type.appelChance){
part.setDiff(rollData, { type: DIFF.ATTAQUE, diff: current.initialDiff })
}
current.initialDiff = undefined
}
break

View File

@@ -27,7 +27,7 @@ export class RollPartComp extends RollPartSelect {
const selected = this.getSelected(rollData)
const all = this.$getActorComps(rollData)
const selectedComp = selected.key
if (selected.forced && selectedComp) {
if (selected.forced && selectedComp!= undefined ) {
refs.all = all.filter(comp => Grammar.equalsInsensitive(comp.label, selectedComp))
if (refs.all.length == 0) {
if (selected.key && selected.key.length > 0) {
@@ -47,8 +47,11 @@ export class RollPartComp extends RollPartSelect {
const current = this.getCurrent(rollData)
const selectedCarac = RollPart.getSelectedPart(rollData, PART_CARAC)
const selectedDiff = RollPart.getSelectedPart(rollData, PART_DIFF)
this.rollPartCarac.selectByKey(rollData, selectedCarac?.key ?? current.comp.system.defaut_carac)
this.rollPartDiff.setDiff(rollData, selectedDiff?.value ?? current.comp.system.default_diffLibre)
if (!rollData.type.appelChance){
this.rollPartCarac.selectByKey(rollData, selectedCarac?.key ?? current.comp.system.defaut_carac)
this.rollPartDiff.setDiff(rollData, selectedDiff?.value ?? current.comp.system.default_diffLibre)
}
}
}

View File

@@ -10,6 +10,11 @@ export class RollPartConditions extends RollPart {
settingMin() { return RollPart.settingKey(this, 'min') }
settingMax() { return RollPart.settingKey(this, 'max') }
visible(rollData) {
const current = this.getCurrent(rollData)
return !current.hide
}
onReady(rollParts) {
game.settings.register(SYSTEM_RDD, this.settingMin(),
{
@@ -36,6 +41,7 @@ export class RollPartConditions extends RollPart {
restore(rollData) {
const current = this.getCurrent(rollData)
current.value = this.getSaved(rollData)?.value ?? current.value ?? 0
current.hide = this.getSaved(rollData)?.hide
}

View File

@@ -131,7 +131,11 @@ export class RollPartDefense extends RollPartSelect {
switch (part.code) {
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_DIFF: return part.setDiff(rollData, this.getDiffDefense(rollData))
case PART_DIFF:
if (!rollData.type.appelChance) {
return part.setDiff(rollData, this.getDiffDefense(rollData))
}
return
case PART_SIGN: return part.setArme(rollData, this.getArmeDisparate(rollData), current.forceRequise)
}
}

View File

@@ -37,7 +37,7 @@ export class RollPartDiff extends RollPart {
}
const current = this.getCurrent(rollData)
/* TODO: affiner les cas où afficher ou non. devrait s'afficher pour les jets basiques (même si pas d'opposant sélectionné)*/
return Object.values(DIFF).includes(current.type)
return (DIFF.AUCUN !=current.type) && Object.values(DIFF).includes(current.type)
}
prepareContext(rollData) {

View File

@@ -0,0 +1,31 @@
import { CARACS } from "../rdd-carac.js"
import { DIFF, ROLL_TYPE_APPEL_CHANCE } from "./roll-constants.mjs"
import { RollType } from "./roll-type.mjs"
export class RollTypeAppelChance extends RollType {
get code() { return ROLL_TYPE_APPEL_CHANCE }
get name() { return `fait appel à la chance` }
get icon() { return `systems/foundryvtt-reve-de-dragon/assets/ui/chance.svg` }
get chatResultTemplate() { return `systems/foundryvtt-reve-de-dragon/templates/roll/result/chat-appel-chance.hbs` }
title(rollData) {
return this.name
}
setRollDataType(rollData) {
foundry.utils.mergeObject(rollData, {
selected: {
carac: { key: CARACS.CHANCE_ACTUELLE, forced: true },
diff: { value: 0, type: '' },
comp: { key: '', forced: true },
conditions: { hide: true }
}
})
super.setRollDataType(rollData)
}
onSelect(rollData) {
this.setDiffType(rollData, DIFF.AUCUN)
}
}

View File

@@ -9,7 +9,8 @@ export class RollTypeCuisine extends RollType {
get code() { return ROLL_TYPE_CUISINE }
get name() { return `Cuisiner un plat` }
visible(rollData) { return rollData.active.actor.isPersonnage() }
visible(rollData) { return rollData.active.actor.isPersonnage()
&& rollData.active.actor.getCompetence('Cuisine') != undefined }
title(rollData) {
const current = rollData.current[PART_CUISINE]
return current.recette ? `prépare une recette: ${current.label}` : `prépare: ${current.label}`

View File

@@ -8,7 +8,10 @@ export class RollTypeJeu extends RollType {
get code() { return ROLL_TYPE_JEU }
get name() { return `Jouer` }
visible(rollData) { return rollData.active.actor.isPersonnage() }
visible(rollData) {
return rollData.active.actor.isPersonnage()
&& rollData.active.actor.getCompetence('Jeu') != undefined
}
title(rollData) {
if (rollData.opponent) {
return `joue contre`

View File

@@ -0,0 +1,31 @@
import { CARACS } from "../rdd-carac.js"
import { DIFF, ROLL_TYPE_REVE_RESISTANCE } from "./roll-constants.mjs"
import { RollType } from "./roll-type.mjs"
export class RollTypeReveResistance extends RollType {
get code() { return ROLL_TYPE_REVE_RESISTANCE }
get name() { return `fait un jet de résistance` }
get icon() { return `systems/foundryvtt-reve-de-dragon/assets/ui/resistance.svg` }
get chatResultTemplate() { return `systems/foundryvtt-reve-de-dragon/templates/roll/result/chat-reve-resistance.hbs` }
title(rollData) {
return this.name
}
setRollDataType(rollData) {
foundry.utils.mergeObject(rollData, {
selected: {
carac: { key: CARACS.REVE_ACTUEL, forced: true },
diff: { value: -8, type: '' },
comp: { key: '', forced: true },
conditions: { hide: true }
}
})
super.setRollDataType(rollData)
}
onSelect(rollData) {
this.setDiffType(rollData, DIFF.DEFAUT)
}
}

View File

@@ -14,7 +14,7 @@ export class RollType {
return { code: this.code, name: this.name, icon: this.icon, section: 'type', template: this.template, selected: this.isSelected(rollData) }
}
prepare(rollData){}
prepare(rollData) {}
isAllowed(rollData) { return rollData.type.allowed == undefined || rollData.type.allowed.includes(this.code) }
visible(rollData) { return true }
title(rollData) { return this.code }

View File

@@ -10,7 +10,7 @@ const listeReglesOptionnelles = [
{ group: 'Récupération', name: 'recuperation-reve', descr: "Récupérer le rêve pendant la nuit (les jets sont toujours faits pour les Rêves de Dragons)"},
{ group: 'Récupération', name: 'recuperation-moral', descr: "Le moral revient vers 0 durant Château Dormant"},
{ group: 'Règles de combat', name: 'armes-equipees', descr: "Proposer uniquement les armes équipées au combat", default: false},
{ group: 'Règles de combat', name: 'localisation-aleatoire', descr: "Proposer une localisation aléatoire des blessures" },
{ group: 'Règles de combat', name: 'recul', descr: "Appliquer le recul en cas de particulière en force ou de charge" },
{ group: 'Règles de combat', name: 'acrobatie-pour-recul', descr: "L'acrobatie aide à ne pas chuter en cas de recul" , default: false },

View File

@@ -14,7 +14,7 @@
},
"devDependencies": {
"@eslint/js": "^9.8.0",
"@foundryvtt/foundryvtt-cli": "^1.0.3",
"@foundryvtt/foundryvtt-cli": "^3.0.3",
"commander": "^11.1.0",
"eslint": "^9.9.0",
"eslint-config-prettier": "^9.1.0",

View File

@@ -2347,7 +2347,7 @@ items:
milieu: ''
environnement: []
resistance: 8
categorie_parade: ''
categorie_parade: dagues
dommages: 1
mortalite: mortel
penetration: 0
@@ -2395,7 +2395,7 @@ items:
milieu: ''
environnement: []
resistance: 7
categorie_parade: ''
categorie_parade: masses
dommages: 1
mortalite: mortel
penetration: 0
@@ -2443,7 +2443,7 @@ items:
milieu: ''
environnement: []
resistance: 8
categorie_parade: ''
categorie_parade: masses
dommages: 2
mortalite: mortel
penetration: 0
@@ -2611,7 +2611,7 @@ items:
milieu: ''
environnement: []
resistance: 6
categorie_parade: ''
categorie_parade: haches
dommages: 2
mortalite: mortel
penetration: 0

View File

@@ -2418,7 +2418,7 @@ items:
milieu: ''
environnement: []
resistance: 5
categorie_parade: ''
categorie_parade: lances
dommages: 2
mortalite: mortel
penetration: 0
@@ -2466,7 +2466,7 @@ items:
milieu: ''
environnement: []
resistance: 15
categorie_parade: ''
categorie_parade: boucliers
dommages: 0
mortalite: mortel
penetration: 0

View File

@@ -2378,7 +2378,7 @@ items:
milieu: ''
environnement: []
resistance: 15
categorie_parade: ''
categorie_parade: boucliers
dommages: 0
mortalite: mortel
penetration: 0
@@ -2527,7 +2527,7 @@ items:
milieu: ''
environnement: []
resistance: 14
categorie_parade: ''
categorie_parade: epees-lourdes
dommages: 4/5
mortalite: mortel
penetration: 0

View File

@@ -2347,7 +2347,7 @@ items:
milieu: ''
environnement: []
resistance: 8
categorie_parade: ''
categorie_parade: dagues
dommages: 1
mortalite: mortel
penetration: 0
@@ -2735,7 +2735,7 @@ items:
milieu: ''
environnement: []
resistance: 6
categorie_parade: ''
categorie_parade: haches
dommages: 2
mortalite: mortel
penetration: 0

View File

@@ -2378,7 +2378,7 @@ items:
milieu: ''
environnement: []
resistance: 15
categorie_parade: ''
categorie_parade: boucliers
dommages: 0
mortalite: mortel
penetration: 0
@@ -2665,7 +2665,7 @@ items:
milieu: ''
environnement: []
resistance: 10
categorie_parade: ''
categorie_parade: masses
dommages: 3/4
mortalite: mortel
penetration: 0

View File

@@ -2354,7 +2354,7 @@ items:
milieu: ''
environnement: []
resistance: 15
categorie_parade: ''
categorie_parade: epees-lourdes
dommages: 3/4
mortalite: mortel
penetration: 0
@@ -2402,7 +2402,7 @@ items:
milieu: ''
environnement: []
resistance: 8
categorie_parade: ''
categorie_parade: dagues
dommages: 1
mortalite: mortel
penetration: 0
@@ -2548,7 +2548,7 @@ items:
milieu: ''
environnement: []
resistance: 13
categorie_parade: ''
categorie_parade: boucliers
dommages: 0
mortalite: mortel
penetration: 0

View File

@@ -2354,7 +2354,7 @@ items:
milieu: ''
environnement: []
resistance: 15
categorie_parade: ''
categorie_parade: epees-lourdes
dommages: 3/4
mortalite: mortel
penetration: 0
@@ -2402,7 +2402,7 @@ items:
milieu: ''
environnement: []
resistance: 8
categorie_parade: ''
categorie_parade: dagues
dommages: 1
mortalite: mortel
penetration: 0
@@ -2480,7 +2480,7 @@ items:
milieu: ''
environnement: []
resistance: 15
categorie_parade: ''
categorie_parade: boucliers
dommages: 0
mortalite: mortel
penetration: 0

View File

@@ -2390,7 +2390,7 @@ items:
milieu: ''
environnement: []
resistance: 15
categorie_parade: ''
categorie_parade: epees-lourdes
dommages: 3/4
mortalite: mortel
penetration: 0
@@ -2438,7 +2438,7 @@ items:
milieu: ''
environnement: []
resistance: 8
categorie_parade: ''
categorie_parade: dagues
dommages: 1
mortalite: mortel
penetration: 0
@@ -2516,7 +2516,7 @@ items:
milieu: ''
environnement: []
resistance: 13
categorie_parade: ''
categorie_parade: boucliers
dommages: 0
mortalite: mortel
penetration: 0
@@ -2564,7 +2564,7 @@ items:
milieu: ''
environnement: []
resistance: 5
categorie_parade: ''
categorie_parade: lances
dommages: 2
mortalite: mortel
penetration: 0

View File

@@ -2390,7 +2390,7 @@ items:
milieu: ''
environnement: []
resistance: 15
categorie_parade: ''
categorie_parade: epees-lourdes
dommages: 3/4
mortalite: mortel
penetration: 0
@@ -2438,7 +2438,7 @@ items:
milieu: ''
environnement: []
resistance: 8
categorie_parade: ''
categorie_parade: dagues
dommages: 1
mortalite: mortel
penetration: 0
@@ -2516,7 +2516,7 @@ items:
milieu: ''
environnement: []
resistance: 15
categorie_parade: ''
categorie_parade: boucliers
dommages: 0
mortalite: mortel
penetration: 0

View File

@@ -2653,7 +2653,7 @@ items:
milieu: ''
environnement: []
resistance: 8
categorie_parade: ''
categorie_parade: dagues
dommages: 1
mortalite: mortel
penetration: 0
@@ -2706,7 +2706,7 @@ items:
milieu: ''
environnement: []
resistance: 1
categorie_parade: ''
categorie_parade: dagues
dommages: 1
mortalite: mortel
penetration: 0

View File

@@ -2653,7 +2653,7 @@ items:
milieu: ''
environnement: []
resistance: 8
categorie_parade: ''
categorie_parade: dagues
dommages: 1
mortalite: mortel
penetration: 0
@@ -2706,7 +2706,7 @@ items:
milieu: ''
environnement: []
resistance: 1
categorie_parade: ''
categorie_parade: dagues
dommages: 1
mortalite: mortel
penetration: 0

View File

@@ -2711,7 +2711,7 @@ items:
milieu: ''
environnement: []
resistance: 8
categorie_parade: ''
categorie_parade: dagues
dommages: 1
mortalite: mortel
penetration: 0

View File

@@ -2345,7 +2345,7 @@ items:
milieu: ''
environnement: []
resistance: 8
categorie_parade: ''
categorie_parade: dagues
dommages: 1
mortalite: mortel
penetration: 0

View File

@@ -2346,7 +2346,7 @@ items:
milieu: ''
environnement: []
resistance: 8
categorie_parade: ''
categorie_parade: dagues
dommages: 1
mortalite: mortel
penetration: 0

View File

@@ -2313,7 +2313,7 @@ items:
milieu: ''
environnement: []
resistance: 8
categorie_parade: ''
categorie_parade: dagues
dommages: 1
mortalite: mortel
penetration: 0

View File

@@ -2346,7 +2346,7 @@ items:
milieu: ''
environnement: []
resistance: 8
categorie_parade: ''
categorie_parade: dagues
dommages: 1
mortalite: mortel
penetration: 0
@@ -2424,7 +2424,7 @@ items:
milieu: ''
environnement: []
resistance: 8
categorie_parade: ''
categorie_parade: masses
dommages: 2
mortalite: mortel
penetration: 0

View File

@@ -2346,7 +2346,7 @@ items:
milieu: ''
environnement: []
resistance: 8
categorie_parade: ''
categorie_parade: dagues
dommages: 1
mortalite: mortel
penetration: 0
@@ -2424,7 +2424,7 @@ items:
milieu: ''
environnement: []
resistance: 8
categorie_parade: ''
categorie_parade: masses
dommages: 2
mortalite: mortel
penetration: 0

View File

@@ -22,7 +22,7 @@ system:
rarete: Frequente
frequence: 18
resistance: 8
categorie_parade: ''
categorie_parade: batons
dommages: 1
mortalite: mortel
penetration: 0

View File

@@ -27,7 +27,7 @@ system:
rarete: Frequente
frequence: 18
resistance: 8
categorie_parade: ''
categorie_parade: dagues
dommages: 1
mortalite: mortel
penetration: 0

View File

@@ -22,7 +22,7 @@ system:
rarete: Frequente
frequence: 18
resistance: 8
categorie_parade: ''
categorie_parade: batons
dommages: 1
mortalite: mortel
penetration: 0

View File

@@ -22,7 +22,7 @@ system:
rarete: Frequente
frequence: 18
resistance: 7
categorie_parade: ''
categorie_parade: masses
dommages: 1
mortalite: mortel
penetration: 0

View File

@@ -22,7 +22,7 @@ system:
rarete: Frequente
frequence: 18
resistance: 8
categorie_parade: ''
categorie_parade: masses
dommages: 2
mortalite: mortel
penetration: 0

View File

@@ -22,7 +22,7 @@ system:
rarete: Frequente
frequence: 18
resistance: 10
categorie_parade: ''
categorie_parade: masses
dommages: 3/4
mortalite: mortel
penetration: 0

View File

@@ -22,7 +22,7 @@ system:
rarete: Frequente
frequence: 18
resistance: 8
categorie_parade: ''
categorie_parade: masses
dommages: 2
mortalite: mortel
penetration: 0

View File

@@ -2417,7 +2417,7 @@ items:
milieu: ''
environnement: []
resistance: 5
categorie_parade: ''
categorie_parade: lances
dommages: 2
mortalite: mortel
penetration: 0
@@ -2466,7 +2466,7 @@ items:
milieu: ''
environnement: []
resistance: 13
categorie_parade: ''
categorie_parade: boucliers
dommages: 0
mortalite: mortel
penetration: 0
@@ -2569,7 +2569,7 @@ items:
milieu: ''
environnement: []
resistance: 5
categorie_parade: ''
categorie_parade: lances
dommages: 1
mortalite: mortel
penetration: 0

View File

@@ -2382,7 +2382,7 @@ items:
milieu: ''
environnement: []
resistance: 12
categorie_parade: ''
categorie_parade: epees-longues
dommages: 3
mortalite: mortel
penetration: 0

View File

@@ -2441,7 +2441,7 @@ items:
milieu: ''
environnement: []
resistance: 15
categorie_parade: ''
categorie_parade: epees-lourdes
dommages: 3/4
mortalite: mortel
penetration: 0

View File

@@ -2380,7 +2380,7 @@ items:
milieu: ''
environnement: []
resistance: 8
categorie_parade: ''
categorie_parade: haches
dommages: 3/4
mortalite: mortel
penetration: 0
@@ -2429,7 +2429,7 @@ items:
milieu: ''
environnement: []
resistance: 10
categorie_parade: ''
categorie_parade: masses
dommages: 3/4
mortalite: mortel
penetration: 0

View File

@@ -2380,7 +2380,7 @@ items:
milieu: ''
environnement: []
resistance: 10
categorie_parade: ''
categorie_parade: masses
dommages: 3/4
mortalite: mortel
penetration: 0

View File

@@ -2380,7 +2380,7 @@ items:
milieu: ''
environnement: []
resistance: 10
categorie_parade: ''
categorie_parade: masses
dommages: 3/4
mortalite: mortel
penetration: 0
@@ -2434,7 +2434,7 @@ items:
milieu: ''
environnement: []
resistance: 5
categorie_parade: ''
categorie_parade: lances
dommages: 1
mortalite: mortel
penetration: 0

View File

@@ -2420,7 +2420,7 @@ items:
milieu: ''
environnement: []
resistance: 12
categorie_parade: ''
categorie_parade: epees-courtes
dommages: 2
mortalite: mortel
penetration: 0

View File

@@ -2380,7 +2380,7 @@ items:
milieu: ''
environnement: []
resistance: 10
categorie_parade: ''
categorie_parade: masses
dommages: 3/3
mortalite: mortel
penetration: 0
@@ -2464,7 +2464,7 @@ items:
milieu: ''
environnement: []
resistance: 15
categorie_parade: ''
categorie_parade: boucliers
dommages: 0
mortalite: mortel
penetration: 0

View File

@@ -2380,7 +2380,7 @@ items:
milieu: ''
environnement: []
resistance: 5
categorie_parade: ''
categorie_parade: lances
dommages: 2
mortalite: mortel
penetration: 0
@@ -2429,7 +2429,7 @@ items:
milieu: ''
environnement: []
resistance: 15
categorie_parade: ''
categorie_parade: boucliers
dommages: 0
mortalite: mortel
penetration: 0

View File

@@ -2380,7 +2380,7 @@ items:
milieu: ''
environnement: []
resistance: 15
categorie_parade: ''
categorie_parade: boucliers
dommages: 0
mortalite: mortel
penetration: 0

View File

@@ -2434,7 +2434,7 @@ items:
milieu: ''
environnement: []
resistance: 5
categorie_parade: ''
categorie_parade: lances
dommages: 1
mortalite: mortel
penetration: 0
@@ -2483,7 +2483,7 @@ items:
milieu: ''
environnement: []
resistance: 15
categorie_parade: ''
categorie_parade: boucliers
dommages: 0
mortalite: mortel
penetration: 0
@@ -2532,7 +2532,7 @@ items:
milieu: ''
environnement: []
resistance: 5
categorie_parade: ''
categorie_parade: lances
dommages: 2
mortalite: mortel
penetration: 0

View File

@@ -2380,7 +2380,7 @@ items:
milieu: ''
environnement: []
resistance: 5
categorie_parade: ''
categorie_parade: lances
dommages: 1
mortalite: mortel
penetration: 0
@@ -2429,7 +2429,7 @@ items:
milieu: ''
environnement: []
resistance: 13
categorie_parade: ''
categorie_parade: boucliers
dommages: 0
mortalite: mortel
penetration: 0

View File

@@ -2380,7 +2380,7 @@ items:
milieu: ''
environnement: []
resistance: 5
categorie_parade: ''
categorie_parade: lances
dommages: 1
mortalite: mortel
penetration: 0
@@ -2478,7 +2478,7 @@ items:
milieu: ''
environnement: []
resistance: 13
categorie_parade: ''
categorie_parade: boucliers
dommages: 0
mortalite: mortel
penetration: 0

View File

@@ -311,7 +311,7 @@ items:
milieu: ''
environnement: []
resistance: 15
categorie_parade: ''
categorie_parade: epees-lourdes
dommages: 3/4
mortalite: mortel
penetration: 0
@@ -359,7 +359,7 @@ items:
milieu: ''
environnement: []
resistance: 15
categorie_parade: ''
categorie_parade: boucliers
dommages: 0
mortalite: mortel
penetration: 0
@@ -407,7 +407,7 @@ items:
milieu: ''
environnement: []
resistance: 8
categorie_parade: ''
categorie_parade: dagues
dommages: 1
mortalite: mortel
penetration: 0

View File

@@ -0,0 +1,21 @@
<div class="roll-chat">
<div class="chat-img">
<img src="{{active.img}}" data-tooltip="{{active.name}}" />
<img src="{{current.comp.comp.img}}" data-tooltip="{{current.comp.label}}" />
</div>
<div class="chat-header">
{{active.name}} fait appel à la chance
</div>
<div class="chat-resume">
{{> 'partial-infojet'}}
</div>
<div class="chat-details">
{{#if rolled.isSuccess}}
<p>Un point de chance a été dépensé, le jet peut être retenté</p>
{{else}}
<p>Pas de dépense de chance</p>
{{/if}}
</div>
</div>

View File

@@ -0,0 +1,24 @@
<div class="roll-chat">
<div class="chat-img">
<img src="{{active.img}}" data-tooltip="{{active.name}}" />
<img src="{{current.comp.comp.img}}" data-tooltip="{{current.comp.label}}" />
</div>
<div class="chat-header">
{{active.name}} fait un jet de résistance
</div>
<div class="chat-resume">
{{> 'partial-infojet'}}
</div>
<div class="chat-details">
<img class="chat-icon" src="systems/foundryvtt-reve-de-dragon/assets/ui/resistance.svg" />
<span class="rdd-roll-{{rolled.code}} strong-text">
{{#if rolled.isSuccess}}
Jet de résistance réussi
{{else}}
Jet de résistance manqué
{{/if}}
</span>
</div>
</div>