RollV2, tchat et appel chance
gestion des appels à la chance pour tout jet V2 correction de soucis forçage du jet continuation des messages de défense
This commit is contained in:
@@ -1,8 +1,16 @@
|
||||
import { ChatUtility } from "../chat-utility.js"
|
||||
import RollDialog from "./roll-dialog.mjs"
|
||||
import { RdDCarac } from "../rdd-carac.js";
|
||||
import { RdDCarac } from "../rdd-carac.js"
|
||||
import { RdDCombat } from "../rdd-combat.js"
|
||||
import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs"
|
||||
import { RdDResolutionTable } from "../rdd-resolution-table.js"
|
||||
|
||||
export class ChatRollResult {
|
||||
export default class ChatRollResult {
|
||||
static init() {
|
||||
ChatRollResult.instance = new ChatRollResult()
|
||||
|
||||
Hooks.on('renderChatLog', (log, html, chatLog) => ChatRollResult.instance.chatListeners(html))
|
||||
}
|
||||
|
||||
static onReady() {
|
||||
foundry.applications.handlebars.loadTemplates({
|
||||
@@ -14,10 +22,7 @@ export class ChatRollResult {
|
||||
}
|
||||
|
||||
async display(roll) {
|
||||
roll.show = roll.show || {};
|
||||
roll.show.chance = this.isAppelChancePossible(roll)
|
||||
roll.show.encaissement = this.isShowEncaissement(roll)
|
||||
roll.show.recul = this.isShowReculChoc(roll)
|
||||
this.prepareDisplay(roll)
|
||||
|
||||
const chatMessage = await ChatUtility.createChatWithRollMode(
|
||||
{
|
||||
@@ -26,14 +31,18 @@ export class ChatRollResult {
|
||||
roll.active.actor,
|
||||
roll.current?.rollmode?.key
|
||||
)
|
||||
if (roll.show.chance) {
|
||||
const save = RollDialog.saveParts(roll)
|
||||
console.log("Store message roll", save)
|
||||
ChatUtility.setMessageData(chatMessage, 'rollData', save)
|
||||
}
|
||||
const save = RollDialog.saveParts(roll)
|
||||
ChatUtility.setMessageData(chatMessage, 'rollData', save)
|
||||
return chatMessage
|
||||
}
|
||||
|
||||
prepareDisplay(roll) {
|
||||
roll.show = roll.show || {}
|
||||
roll.show.chance = this.isAppelChancePossible(roll)
|
||||
roll.show.encaissement = this.isShowEncaissement(roll)
|
||||
roll.show.recul = this.isShowReculChoc(roll)
|
||||
}
|
||||
|
||||
isAppelChancePossible(roll) {
|
||||
return roll.active.actor.isPersonnage() &&
|
||||
roll.rolled.isEchec &&
|
||||
@@ -46,14 +55,87 @@ export class ChatRollResult {
|
||||
}
|
||||
|
||||
isShowReculChoc(roll) {
|
||||
return roll.rolled.isEchec &&
|
||||
roll.attackerRoll &&
|
||||
!roll.current.defense.isEsquive &&
|
||||
(roll.attackerRoll.particuliere == 'force' || 'charge' == attackerRoll.tactique?.key)
|
||||
const attaque = roll.attackerRoll
|
||||
return attaque &&
|
||||
(roll.rolled.isEchec || !roll.current.defense.isEsquive) &&
|
||||
(attaque.particuliere == 'force' || 'charge' == attaque.tactique?.key)
|
||||
}
|
||||
|
||||
async buildRollHtml(roll) {
|
||||
const template = `systems/foundryvtt-reve-de-dragon/templates/roll/result/chat-${roll.type.current}.hbs`
|
||||
return await foundry.applications.handlebars.renderTemplate(template, roll)
|
||||
}
|
||||
|
||||
async chatListeners(html) {
|
||||
$(html).on("click", '.appel-chance', event => this.onClickAppelChance(event))
|
||||
$(html).on("click", '.appel-destinee', event => this.onClickAppelDestinee(event))
|
||||
}
|
||||
|
||||
onClickAppelChance(event) {
|
||||
const chatMessage = ChatUtility.getChatMessage(event)
|
||||
const savedRoll = ChatUtility.getMessageData(chatMessage, 'rollData')
|
||||
const actor = game.actors.get(savedRoll.ids.actorId)
|
||||
actor.rollAppelChance(
|
||||
() => this.onAppelChanceSuccess(savedRoll, chatMessage),
|
||||
() => this.onAppelChanceEchec(savedRoll, chatMessage))
|
||||
event.preventDefault()
|
||||
}
|
||||
|
||||
getCombat(roll) {
|
||||
switch (roll.type.current) {
|
||||
case ROLL_TYPE_DEFENSE:
|
||||
return RdDCombat.rddCombatForAttackerAndDefender(roll.ids.opponentId, roll.ids.opponentTokenId, roll.ids.actorId)
|
||||
case ROLL_TYPE_ATTAQUE:
|
||||
return RdDCombat.rddCombatForAttackerAndDefender(roll.ids.actorId, roll.ids.actorTokenId, roll.ids.opponentId)
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
onAppelChanceSuccess(savedRoll, chatMessage) {
|
||||
const reRoll = foundry.utils.duplicate(savedRoll)
|
||||
reRoll.type.retry = true
|
||||
// TODO: annuler les effets
|
||||
switch (reRoll.type.current) {
|
||||
case ROLL_TYPE_DEFENSE:
|
||||
this.getCombat(reRoll)?.doRollDefense(reRoll)
|
||||
break
|
||||
case ROLL_TYPE_ATTAQUE:
|
||||
this.getCombat(reRoll)?.doRollAttaque(reRoll)
|
||||
break
|
||||
default: {
|
||||
RollDialog.create(reRoll)
|
||||
}
|
||||
}
|
||||
ChatUtility.removeChatMessageId(chatMessage.id)
|
||||
}
|
||||
|
||||
async onAppelChanceEchec(savedRoll, chatMessage) {
|
||||
savedRoll.type.retry = true
|
||||
await this.updateChatMessage(chatMessage, savedRoll)
|
||||
}
|
||||
|
||||
async updateChatMessage(chatMessage, savedRoll) {
|
||||
ChatUtility.setMessageData(chatMessage, 'rollData', savedRoll)
|
||||
const copy = foundry.utils.duplicate(savedRoll)
|
||||
RollDialog.loadRollData(copy)
|
||||
this.prepareDisplay(copy)
|
||||
chatMessage.update({ content: await this.buildRollHtml(copy) })
|
||||
chatMessage.render(true)
|
||||
}
|
||||
|
||||
onClickAppelDestinee(event) {
|
||||
const chatMessage = ChatUtility.getChatMessage(event)
|
||||
const savedRoll = ChatUtility.getMessageData(chatMessage, 'rollData')
|
||||
const actor = game.actors.get(savedRoll.ids.actorId)
|
||||
|
||||
actor.appelDestinee(async () => {
|
||||
const reRoll = foundry.utils.duplicate(savedRoll)
|
||||
reRoll.type.retry = true
|
||||
RdDResolutionTable.significativeRequise(reRoll.rolled)
|
||||
await this.updateChatMessage(chatMessage, savedRoll)
|
||||
})
|
||||
event.preventDefault()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -41,9 +41,7 @@ export class RollBasicParts {
|
||||
initFrom(rollData) {
|
||||
return {
|
||||
selected: {},
|
||||
type: {
|
||||
current: rollData.type.current
|
||||
},
|
||||
type: rollData.type,
|
||||
ids: {
|
||||
sceneId: rollData.ids.sceneId,
|
||||
actorId: rollData.active.id,
|
||||
|
||||
@@ -25,7 +25,7 @@ import { RollPartMeditation } from "./roll-part-meditation.mjs";
|
||||
import { RollPartMoral } from "./roll-part-moral.mjs";
|
||||
import { RollPartOpponent } from "./roll-part-opponent.mjs";
|
||||
import { RollPartSurEnc } from "./roll-part-surenc.mjs";
|
||||
import { RollPartTricher } from "./roll-part-tricher.mjs";
|
||||
import { PART_TRICHER, RollPartTricher } from "./roll-part-tricher.mjs";
|
||||
import { RollPartTache } from "./roll-part-tache.mjs";
|
||||
import { RollPartOeuvre } from "./roll-part-oeuvre.mjs";
|
||||
import { RollPartSort } from "./roll-part-sort.mjs";
|
||||
@@ -38,7 +38,7 @@ import { RollPartDefense } from "./roll-part-defense.mjs";
|
||||
import { RollDialogAdapter } from "./roll-dialog-adapter.mjs";
|
||||
import { ROLLDIALOG_SECTION } from "./roll-part.mjs";
|
||||
import { ROLL_TYPE_COMP } from "./roll-constants.mjs";
|
||||
import { ChatRollResult } from "./chat-roll-result.mjs";
|
||||
import ChatRollResult from "./chat-roll-result.mjs";
|
||||
|
||||
|
||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api
|
||||
@@ -286,6 +286,8 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
||||
ROLL_PARTS.filter(p => p.isActive(rollData))
|
||||
.forEach(p => p.storeClean(rollData, target))
|
||||
target.attackerRoll = rollData.attackerRoll
|
||||
target.rolled = rollData.rolled
|
||||
target.result = rollData.result
|
||||
return target
|
||||
}
|
||||
|
||||
@@ -317,8 +319,8 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
||||
}
|
||||
|
||||
|
||||
getActiveParts() {
|
||||
return ROLL_PARTS.filter(p => p.isActive(this.rollData))
|
||||
static getActiveParts(rollData) {
|
||||
return ROLL_PARTS.filter(p => p.isActive(rollData))
|
||||
}
|
||||
|
||||
// get title() {
|
||||
@@ -353,12 +355,12 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
||||
))
|
||||
|
||||
Promise.all(
|
||||
this.getActiveParts().map(async p => await p._onRender(this, context, options))
|
||||
RollDialog.getActiveParts(this.rollData).map(async p => await p._onRender(this, context, options))
|
||||
)
|
||||
}
|
||||
|
||||
getAjustements(rollData = this.rollData) {
|
||||
return this.getActiveParts()
|
||||
static getAjustements(rollData) {
|
||||
return RollDialog.getActiveParts(rollData)
|
||||
.map(p => p.getAjustements(rollData))
|
||||
.reduce((a, b) => a.concat(b))
|
||||
.sort((a, b) => a.diff == undefined ? 1 : b.diff == undefined ? -1 : 0)
|
||||
@@ -373,19 +375,19 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
||||
|
||||
const types = ALL_ROLL_TYPES.filter(m => m.isAllowed(rollData) && m.visible(rollData))
|
||||
.map(m => m.toTypeData(rollData))
|
||||
BASIC_PARTS.loadSurprises(this.rollData, this.getSelectedType().code)
|
||||
this.rollData.type.label = this.getSelectedType()?.title(this.rollData)
|
||||
BASIC_PARTS.loadSurprises(rollData, this.getSelectedType().code)
|
||||
rollData.type.label = this.getSelectedType()?.title(rollData)
|
||||
//TOCHECK: set type.label ?
|
||||
const visibleRollParts = this.getActiveParts()
|
||||
const visibleRollParts = RollDialog.getActiveParts(rollData)
|
||||
visibleRollParts.forEach(p => p.applyExternalImpacts(visibleRollParts, rollData))
|
||||
|
||||
this.setSpecialComp(visibleRollParts);
|
||||
|
||||
visibleRollParts.forEach(p => p.prepareContext(rollData))
|
||||
|
||||
this.calculAjustements()
|
||||
RollDialog.calculAjustements(rollData)
|
||||
|
||||
const templates = this.getActiveParts().map(p => p.toTemplateData())
|
||||
const templates = RollDialog.getActiveParts(rollData).map(p => p.toTemplateData())
|
||||
const context = await super._prepareContext()
|
||||
return foundry.utils.mergeObject(
|
||||
{
|
||||
@@ -399,14 +401,14 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
||||
const specialComp = visibleRollParts.map(p => p.getSpecialComp(this.rollData))
|
||||
.reduce((a, b) => a.concat(b))
|
||||
if (specialComp.length > 0) {
|
||||
const rollPartComp = this.getActiveParts()
|
||||
const rollPartComp = RollDialog.getActiveParts(this.rollData)
|
||||
.find(it => it.code == PART_COMP);
|
||||
rollPartComp?.setSpecialComp(this.rollData, specialComp)
|
||||
}
|
||||
}
|
||||
|
||||
calculAjustements(rollData = this.rollData) {
|
||||
rollData.ajustements = this.getAjustements(rollData)
|
||||
static calculAjustements(rollData) {
|
||||
rollData.ajustements = RollDialog.getAjustements(rollData)
|
||||
rollData.ajustements.forEach(it => it.isDiff = it.diff != undefined)
|
||||
rollData.current.totaldiff = rollData.ajustements
|
||||
.map(adj => adj.diff)
|
||||
@@ -419,12 +421,12 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
||||
}
|
||||
|
||||
async roll() {
|
||||
// ROLL_PARTS.filter(p => p.isActive(this.rollData))
|
||||
// .forEach(p => p.validate(this.rollData))
|
||||
|
||||
const roll = RollDialog.saveParts(this.rollData)
|
||||
RollDialog.$prepareRollData(roll)
|
||||
this.calculAjustements(roll)
|
||||
roll.current.resultat = this.rollData.current.resultat
|
||||
roll.v2 = true
|
||||
RollDialog.loadRollData(roll)
|
||||
roll.current.resultat = this.rollData.current[PART_TRICHER]?.resultat ?? -1
|
||||
roll.rolled = await this.$rollDice(roll)
|
||||
roll.result = this.getSelectedType(roll).getResult(roll)
|
||||
console.info('RollDialog.roll:', roll)
|
||||
@@ -434,12 +436,18 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
||||
this.rollOptions.onRollDone(this)
|
||||
}
|
||||
|
||||
static loadRollData(roll) {
|
||||
RollDialog.$prepareRollData(roll)
|
||||
RollDialog.calculAjustements(roll)
|
||||
roll.v2 = true
|
||||
}
|
||||
|
||||
async defaultCallback(rollData, rolled) {
|
||||
await rollData.active.actor.appliquerAjoutExperience(rollData)
|
||||
await rollData.active.actor.appliquerAppelMoral(rollData)
|
||||
}
|
||||
|
||||
async $rollDice(rollData) {
|
||||
return await RollDialogAdapter.rollDice(rollData, this.rollTitle(rollData));
|
||||
return await RollDialogAdapter.rollDice(rollData, this.rollTitle(rollData))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { SYSTEM_RDD } from "../constants.js";
|
||||
import { Misc } from "../misc.js";
|
||||
import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs";
|
||||
|
||||
const CONDITIONS = "conditions"
|
||||
@@ -50,7 +51,7 @@ export class RollPartConditions extends RollPart {
|
||||
const current = this.getCurrent(rollData)
|
||||
current.min = game.settings.get(SYSTEM_RDD, this.settingMin())
|
||||
current.max = game.settings.get(SYSTEM_RDD, this.settingMax())
|
||||
current.value = current.value ?? 0
|
||||
current.value = Misc.inRange(current.value ?? 0, current.min, current.max)
|
||||
}
|
||||
|
||||
getAjustements(rollData) {
|
||||
@@ -63,12 +64,13 @@ export class RollPartConditions extends RollPart {
|
||||
|
||||
async _onRender(rollDialog, context, options) {
|
||||
const input = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="${this.code}"]`)
|
||||
|
||||
input?.addEventListener("change", e => {
|
||||
const current = this.getCurrent(rollDialog.rollData)
|
||||
current.value = parseInt(e.currentTarget.value)
|
||||
rollDialog.render()
|
||||
})
|
||||
|
||||
input?.addEventListener("input", e => this.onInputChange(e, rollDialog))
|
||||
}
|
||||
|
||||
onInputChange(event, rollDialog) {
|
||||
this.getCurrent(rollDialog.rollData).value = parseInt(event.currentTarget.value)
|
||||
rollDialog.render()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { DIFF, DIFFS, ROLL_TYPE_MEDITATION, ROLL_TYPE_OEUVRE, ROLL_TYPE_SORT, ROLL_TYPE_TACHE } from "./roll-constants.mjs";
|
||||
import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs";
|
||||
import { Misc } from "../misc.js";
|
||||
|
||||
export const PART_DIFF = "diff"
|
||||
|
||||
@@ -41,8 +42,8 @@ export class RollPartDiff extends RollPart {
|
||||
{
|
||||
type: diffType.key,
|
||||
label: diffType?.label ?? '',
|
||||
value: current.value ?? 0,
|
||||
disabled: !diffType.libre,
|
||||
value: Misc.inRange(current.value ?? 0, -10, diffType.max),
|
||||
min: -10,
|
||||
max: diffType.max
|
||||
},
|
||||
@@ -67,11 +68,12 @@ export class RollPartDiff extends RollPart {
|
||||
async _onRender(rollDialog, context, options) {
|
||||
const input = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="${this.code}"]`)
|
||||
|
||||
input?.addEventListener("change", e => {
|
||||
this.getCurrent(rollDialog.rollData).value = parseInt(e.currentTarget.value)
|
||||
rollDialog.render()
|
||||
})
|
||||
input?.addEventListener("input", e => this.onInputChange(e, rollDialog))
|
||||
}
|
||||
|
||||
onInputChange(event, rollDialog) {
|
||||
this.getCurrent(rollDialog.rollData).value = parseInt(event.currentTarget.value)
|
||||
rollDialog.render()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Misc } from "../misc.js"
|
||||
import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs"
|
||||
|
||||
export const PART_TRICHER = "tricher"
|
||||
@@ -11,21 +12,20 @@ export class RollPartTricher extends RollPart {
|
||||
|
||||
prepareContext(rollData) {
|
||||
const current = this.getCurrent(rollData)
|
||||
if (current.resultat == undefined) {
|
||||
current.resultat = -1
|
||||
}
|
||||
current.resultat = Misc.inRange(current.resultat == undefined ? -1 : current.resultat, -1, 100)
|
||||
}
|
||||
|
||||
getAjustements(rollData) {
|
||||
rollData.current.resultat = this.getCurrent(rollData).resultat
|
||||
return []
|
||||
}
|
||||
|
||||
async _onRender(rollDialog, context, options) {
|
||||
const input = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="${this.code}"]`)
|
||||
|
||||
input?.addEventListener("change", e => {
|
||||
this.getCurrent(rollDialog.rollData).resultat = parseInt(e.currentTarget.value)
|
||||
})
|
||||
input?.addEventListener("input", e => this.onInputChange(e, rollDialog))
|
||||
}
|
||||
|
||||
onInputChange(event, rollDialog) {
|
||||
this.getCurrent(rollDialog.rollData).resultat = parseInt(event.currentTarget.value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { Misc } from "../misc.js"
|
||||
|
||||
export const ROLLDIALOG_SECTION = {
|
||||
ACTION: 'action',
|
||||
CARAC: 'carac',
|
||||
@@ -86,6 +84,9 @@ export class RollPart {
|
||||
loadRefs(rollData) { }
|
||||
|
||||
prepareContext(rollData) { }
|
||||
|
||||
/** permet de sauvegarder dans rollData les informations (cas des champs edit) */
|
||||
validate(rollData) {}
|
||||
|
||||
/** ---- cross roll-part filtering ---- */
|
||||
applyImpact(rollData, filter) { }
|
||||
@@ -108,14 +109,4 @@ export class RollPart {
|
||||
|
||||
async _onRender(rollDialog, context, options) { }
|
||||
|
||||
addResult(rollData) {
|
||||
const result = this.getResult(rollData)
|
||||
if (result){
|
||||
rollData.result[this.code] = result
|
||||
}
|
||||
}
|
||||
|
||||
getResult(rollData){
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user