Roll V2: les jeux

This commit is contained in:
2025-10-06 01:24:16 +02:00
parent 1bf9e330f4
commit 293af5ab83
15 changed files with 100 additions and 74 deletions

View File

@@ -1,5 +1,9 @@
# 13.0
## 13.0.11 - Le gambit d'Illysis
- Nouvelle fenêtre de jets de dés
- jeux
## 13.0.10 - Les papilles d'Illysis
- Ajout d'un statut "saignement" en cas de blessure grave ou critique sans premiers soins

View File

@@ -1521,12 +1521,7 @@ select,
font-size: 0.8rem;
font-style: italic;
color: rgba(82, 17, 131, 0.9);
overflow: hidden;
}
.system-foundryvtt-reve-de-dragon .poesie-extrait:hover {
max-height: unset;
overflow: visible;
opacity: 1;
overflow-y: scroll;
}
.system-foundryvtt-reve-de-dragon .poesie-reference {
font-size: 0.7rem;

View File

@@ -832,14 +832,14 @@
font-size: 0.8rem;
font-style: italic;
color: rgba(82, 17, 131, 0.9);
overflow: hidden;
overflow-y: scroll;
// overflow: hidden;
}
.poesie-extrait:hover {
max-height: unset;
overflow: visible;
opacity: 1;
}
// .poesie-extrait:hover {
// overflow-y: scroll;
// opacity: 1;
// }
.poesie-reference {
font-size: 0.7rem;

View File

@@ -47,9 +47,10 @@ import { RdDRollResult } from "./rdd-roll-result.js";
import { RdDInitiative } from "./initiative.mjs";
import RollDialog from "./roll/roll-dialog.mjs";
import { OptionsAvancees, ROLL_DIALOG_V2, ROLL_DIALOG_V2_TEST } from "./settings/options-avancees.js";
import { ROLL_TYPE_MEDITATION } from "./roll/roll-constants.mjs";
import { ROLL_TYPE_JEU, ROLL_TYPE_MEDITATION } 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";
export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre']
@@ -1934,8 +1935,8 @@ export class RdDActor extends RdDBaseActorSang {
const rollData = {
ids: { actorId: this.id },
type: { allowed: [PART_COMP], current: PART_COMP },
selected: {
carac: {key: caracName },
selected: {
carac: { key: caracName },
comp: { key: compName, forced: options.forced }
}
}
@@ -1971,7 +1972,7 @@ export class RdDActor extends RdDBaseActorSang {
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
const rollData = {
ids: { actorId: this.id },
selected: { tache: { key: tache.id, forced: options.forced} },
selected: { tache: { key: tache.id, forced: options.forced } },
type: { allowed: [PART_TACHE], current: PART_TACHE }
}
RollDialog.create(rollData, options)
@@ -2026,9 +2027,19 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
async rollJeu(id) {
const oeuvre = this.getJeu(id);
const jeu = this.getJeu(id);
const listCarac = oeuvre.system.caraccomp.toLowerCase().split(/[.,:\/-]/).map(it => it.trim());
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
const rollData = {
ids: { actorId: this.id },
selected: { jeu: { key: jeu.id } },
type: { allowed: [ROLL_TYPE_JEU], current: ROLL_TYPE_JEU }
}
await RollDialog.create(rollData, { onRollDone: RollDialog.onRollDoneClose })
return
}
const listCarac = jeu.system.caraccomp.toLowerCase().split(/[.,:\/-]/).map(it => it.trim());
const carac = listCarac.length > 0 ? listCarac[0] : 'chance'
const artData = {
art: 'jeu', verbe: 'Jeu',
@@ -2038,8 +2049,8 @@ export class RdDActor extends RdDBaseActorSang {
};
listCarac.forEach(c => artData.forceCarac[c] = this.system.carac[c]);
artData.competence.system.niveauReel = artData.competence.system.niveau;
artData.competence.system.niveau = Math.max(artData.competence.system.niveau, oeuvre.system.base);
await this._rollArtV1(artData, carac, oeuvre);
artData.competence.system.niveau = Math.max(artData.competence.system.niveau, jeu.system.base);
await this._rollArtV1(artData, carac, jeu);
}
@@ -3099,17 +3110,9 @@ export class RdDActor extends RdDBaseActorSang {
async _rollArtV2(oeuvreId) {
const oeuvre = this.items.get(oeuvreId)
const rollData = {
title: `Interpretation de ${oeuvre.name} par ${this.name}`,
type: {
allowed: ["oeuvre"],
current: "oeuvre",
},
selected: {
oeuvre: { key: oeuvre.id },
},
ids: {
actorId: this.id
}
ids: { actorId: this.id },
selected: { oeuvre: { key: oeuvre.id } },
type: { allowed: [PART_OEUVRE], current: PART_OEUVRE, },
}
await RollDialog.create(rollData, { onRollDone: RollDialog.onRollDoneClose })
}

View File

@@ -6,6 +6,7 @@ import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs"
import { RdDResolutionTable } from "../rdd-resolution-table.js"
import { RDD_CONFIG, renderTemplate } from "../constants.js"
import { EMPOIGNADE } from "../item/arme.js"
import { RdDTextEditor } from "../apps/rdd-text-roll-editor.js"
export default class ChatRollResult {
static init() {

View File

@@ -40,6 +40,7 @@ export class RollBasicParts {
}
static initFrom(rollData) {
const isOpposed = rollData.type.opposed && rollData.opponent
return {
selected: {},
type: rollData.type,
@@ -47,8 +48,8 @@ export class RollBasicParts {
sceneId: rollData.ids.sceneId,
actorId: rollData.active.id,
actorTokenId: rollData.active.tokenId,
opponentId: rollData.type.opposed ? rollData.opponent.id : undefined,
opponentTokenId: rollData.type.opposed ? rollData.opponent.tokenId : undefined,
opponentId: isOpposed ? rollData.opponent.id : undefined,
opponentTokenId: isOpposed ? rollData.opponent.tokenId : undefined,
}
}
}

View File

@@ -8,7 +8,7 @@ import { RdDItemArme } from "../item/arme.js";
import { RdDBonus } from "../rdd-bonus.js";
import { ITEM_TYPES, RDD_CONFIG } from "../constants.js";
import { CARACS } from "../rdd-carac.js";
import { ROLL_TYPE_ATTAQUE } from "./roll-constants.mjs";
import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_OEUVRE } from "./roll-constants.mjs";
import { PART_ATTAQUE } from "./roll-part-attaque.mjs";
/* -------------------------------------------- */
@@ -47,6 +47,10 @@ export class RollDialogAdapter {
rolled.finalLevel = rollData.current.totaldiff
rolled.bonus = rollData.current.bonus ?? 0
rolled.factorHtml = Misc.getFractionOneN(rollData.current.sign.diviseur)
if (ReglesOptionnelles.isUsing("afficher-colonnes-reussite")) {
rolled.niveauNecessaire = RdDResolutionTable.findNiveauNecessaire(rolled.caracValue, rolled.roll)
rolled.ajustementNecessaire = rolled.niveauNecessaire - diff
}
return rolled
}
@@ -74,12 +78,13 @@ export class RollDialogAdapter {
rollData.competence = rollData.refs[PART_COMP].all.find(it => it.key == compKey)?.comp
rollData.jetResistance = rollData.type.jetResistance
}
const oeuvreKey = rollData.current.oeuvre?.key
if (oeuvreKey) {
const oeuvreCurrent = rollData.current[PART_OEUVRE];
rollData.oeuvre = oeuvreCurrent.oeuvre
// rollData.oeuvre = rollData.refs[PART_OEUVRE].oeuvres.find(it => it.key == oeuvreKey)?.oeuvre
rollData.art = oeuvreCurrent.art.type
if (rollData.type.current == ROLL_TYPE_OEUVRE) {
const oeuvreKey = rollData.current.oeuvre?.key
if (rollData.type.current == ROLL_TYPE_OEUVRE && oeuvreKey) {
const oeuvreCurrent = rollData.current[PART_OEUVRE];
rollData.oeuvre = oeuvreCurrent.oeuvre
rollData.art = oeuvreCurrent.art.type
}
}
// pour appel moral
rollData.diviseurSignificative = rollData.current.sign
@@ -87,7 +92,7 @@ export class RollDialogAdapter {
rollData.use.moral = true
}
if (ReglesOptionnelles.isUsing("afficher-colonnes-reussite")) {
rolled.niveauNecessaire = this.findNiveauNecessaire(carac, rolled.roll)
rolled.niveauNecessaire = RdDResolutionTable.findNiveauNecessaire(rollData.selectedCarac.value, rolled.roll)
rolled.ajustementNecessaire = rolled.niveauNecessaire - diff
}
rollData.ajustements = rollData.ajustements.map(aj => {

View File

@@ -436,13 +436,14 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
async roll() {
const roll = RollDialog.saveParts(this.rollData)
this.loadRollData(roll)
const selectedRollType = this.getSelectedType(roll);
RollDialog.loadRollData(roll)
selectedRollType.onSelect(roll)
roll.current.resultat = this.rollData.current[PART_TRICHER]?.resultat ?? -1
roll.choix = {}
roll.rolled = await RollDialogAdapter.rollDice(roll, this.rollTitle(roll))
roll.result = selectedRollType.getResult(roll)
console.info('RollDialog.roll:', roll)
const callbacks = [
...this.rollOptions.callbacks,
@@ -452,8 +453,8 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
await this.chatRollResult.display(roll)
this.rollOptions.onRollDone(this)
}
static loadRollData(roll) {
loadRollData(roll) {
RollDialog.$prepareRollData(roll)
RollDialog.calculAjustements(roll)
roll.v2 = true

View File

@@ -32,7 +32,7 @@ export class RollPartComp extends RollPartSelect {
$getActorComps(rollData) {
const competences = (rollData.active.actor?.getCompetences() ?? [])
.map(RollPartComp.$extractComp)
.map(RollPartComp.extractComp)
.sort(Misc.ascending(it => Grammar.toLowerCaseNoAccentNoSpace(it.label)))
/* TODO: filter competences */
const listCompetences = [
@@ -42,7 +42,7 @@ export class RollPartComp extends RollPartSelect {
return listCompetences
}
static $extractComp(comp) {
static extractComp(comp) {
return {
key: comp.name,
label: comp.name,
@@ -69,7 +69,7 @@ export class RollPartComp extends RollPartSelect {
}
setSpecialComp(rollData, comps) {
this.getRefs(rollData).comps = comps.map(RollPartComp.$extractComp)
this.getRefs(rollData).comps = comps.map(RollPartComp.extractComp)
.sort(Misc.ascending(it => Grammar.toLowerCaseNoAccentNoSpace(it.label)))
}

View File

@@ -1,15 +1,16 @@
import { Grammar } from "../grammar.js"
import { ITEM_TYPES } from "../constants.js"
import { CARACS } from "../rdd-carac.js"
import { ROLL_TYPE_JEU } from "./roll-constants.mjs"
import { PART_CARAC } from "./roll-part-carac.mjs"
import { PART_COMP } from "./roll-part-comp.mjs"
import { PART_COMP, RollPartComp } from "./roll-part-comp.mjs"
import { RollPartSelect } from "./roll-part-select.mjs"
import { ROLLDIALOG_SECTION } from "./roll-part.mjs"
import { RdDItem } from "../item.js"
import { Misc } from "../misc.js"
export const PART_JEU = "jeu"
const COMPETENCE_JEU = 'Jeu'
export const COMPETENCE_JEU = 'Jeu'
export class RollPartJeu extends RollPartSelect {
@@ -21,8 +22,12 @@ export class RollPartJeu extends RollPartSelect {
loadRefs(rollData) {
const refs = this.getRefs(rollData)
refs.jeux = rollData.active.actor.itemTypes[ITEM_TYPES.jeu]
.map(it => RollPartJeu.$extractJeu(it, rollData.active.actor))
const actor = rollData.active.actor
const compJeu = actor.getCompetence(COMPETENCE_JEU)
refs.jeux = actor.itemTypes[ITEM_TYPES.jeu]
.map(it => RollPartJeu.$extractJeu(it, compJeu))
if (refs.jeux.length > 0) {
this.$selectJeu(rollData)
}
@@ -30,18 +35,17 @@ export class RollPartJeu extends RollPartSelect {
choices(refs) { return refs.jeux }
static $extractJeu(jeu, actor) {
const comp = actor.getCompetence(COMPETENCE_JEU)
static $extractJeu(jeu, compJeu) {
const caracs = jeu.system.caraccomp.toLowerCase().split(/[.,:\/-]/).map(it => it.trim())
const base = RollPartJeu.$getJeuBase(jeu, comp, caracs)
const base = RollPartJeu.$getJeuBase(jeu, compJeu, caracs)
return {
key: jeu.id,
label: jeu.name,
caracs: caracs,
jeu: jeu,
value: (base ?? comp).system.niveau,
value: 0,
base: base,
comp: comp
comp: compJeu
}
}
@@ -49,10 +53,10 @@ export class RollPartJeu extends RollPartSelect {
if (jeu.system.base < comp.system.niveau) {
return undefined
}
return {
return new RdDItem({
id: comp.id,
name: `Jeu ${jeu.name}`,
type: comp.type,
name: `Jeu ${Misc.lowerFirst(jeu.name)}`,
type: ITEM_TYPES.competence,
img: comp.img,
system: foundry.utils.mergeObject(
{
@@ -61,9 +65,9 @@ export class RollPartJeu extends RollPartSelect {
default_carac: caracs.length > 0 ? caracs[0] : CARACS.CHANCE
},
comp.system,
{ inplace: true, overwrite: false }
{ overwrite: false }
)
}
})
}
prepareContext(rollData) {
@@ -77,6 +81,13 @@ export class RollPartJeu extends RollPartSelect {
$selectJeu(rollData, key) {
this.selectByKey(rollData, key, 0)
RollPartJeu.forceCompJeu(rollData)
}
static forceCompJeu(rollData) {
const jeu = rollData.current[PART_JEU].base ?? rollData.current[PART_JEU].comp
rollData.refs[PART_COMP].comps = [jeu].map(it => RollPartComp.extractComp(it))
rollData.current[PART_COMP] = rollData.refs[PART_COMP].comps[0]
}
async _onRender(rollDialog, context, options) {
@@ -95,7 +106,7 @@ export class RollPartJeu extends RollPartSelect {
const current = this.getCurrent(rollData)
switch (part.code) {
case PART_CARAC: return part.filterCaracs(rollData, current.caracs)
case PART_COMP: return part.filterComps(rollData,[current.comp?.name])
case PART_COMP: return part.filterComps(rollData, [current.comp?.name])
}
}
return undefined

View File

@@ -122,7 +122,7 @@ export class RollPartSort extends RollPartSelect {
const current = this.getCurrent(rollData)
switch (part.code) {
case PART_CARAC: return part.filterCaracs(rollData, [CARACS.REVE])
case PART_COMP: return part.filterComps(rollData,current.draconics ?? [])
case PART_COMP: return part.filterComps(rollData, current.draconics ?? [])
}
}
return undefined

View File

@@ -1,6 +1,7 @@
import { PART_JEU } from "./roll-part-jeu.mjs"
import { PART_JEU, RollPartJeu } from "./roll-part-jeu.mjs"
import { RollType } from "./roll-type.mjs"
import { ROLL_TYPE_JEU } from "./roll-constants.mjs"
import { DIFF, ROLL_TYPE_JEU } from "./roll-constants.mjs"
export class RollTypeJeu extends RollType {
get code() { return ROLL_TYPE_JEU }
@@ -14,4 +15,9 @@ export class RollTypeJeu extends RollType {
return `joue: ${rollData.current[PART_JEU].label}`
}
onSelect(rollData) {
this.setDiffType(rollData, DIFF.LIBRE)
RollPartJeu.forceCompJeu(rollData)
}
}

View File

@@ -17,6 +17,7 @@ export class RollTypeMeditation extends RollType {
onSelect(rollData) {
this.setDiffType(rollData, DIFF.AUCUN)
}
callbacks(rollOptions) { return [RollTypeMeditation.$onRollMeditation] }
static async $onRollMeditation(rollData) {

View File

@@ -1,10 +1,11 @@
{{log 'jeu' this}}
<div class="roll-chat">
<div class="chat-img">
<img src="{{active.img}}" data-tooltip="{{active.name}}" />
<img src="{{current.comp.img}}" data-tooltip="{{current.comp.name}}" />
</div>
<div class="chat-header">
{{active.name}} {{current.oeuvre.art.action}}: {{current.oeuvre.label}} (de niveau {{current.oeuvre.oeuvre.system.niveau}})
{{active.name}} Joue : {{current.jeu.label}} (niveau de base {{current.jeu.jeu.system.base}})
</div>
<div class="chat-resume">
@@ -15,13 +16,11 @@
<div class="chat-details">
<p>
{{active.name}}
{{#if rolled.isSuccess}}réussit son interprétation avec
{{else}}manque d'inspiration, son interprétation a
{{/if}}
une qualité de {{result.qualite}}.
{{#if rolled.isSuccess}}marque{{else}}perd{{/if}}
des points dans la partie, obtenant {{rolled.ptTache}} points de tâche (si applicable pour le jeu en cours).
</p>
{{> 'partial-info-appel-moral'}}
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-description.hbs" current.oeuvre.oeuvre.system}}
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-description.hbs" current.jeu.jeu.system}}
</div>
<div class="chat-buttons">

View File

@@ -6,7 +6,6 @@
<select name="select-jeu" {{#if rollData.type.retry}}disabled{{/if}}>
{{selectOptions refs.jeux selected=current.key valueAttr="key" labelAttr="label"}}
</select>
<selected-numeric-value>{{plusMoins current.value}}</selected-numeric-value>
</subline>
<subline>
{{> "systems/foundryvtt-reve-de-dragon/templates/partial-description.hbs" current.jeu.system}}