Compare commits
2 Commits
0f3d1e708d
...
2cbee42180
| Author | SHA1 | Date | |
|---|---|---|---|
| 2cbee42180 | |||
| c47fc4f5b6 |
@@ -2,19 +2,23 @@
|
||||
## 13.0.14 - Le familier d'Illysis
|
||||
|
||||
- Les réussites particulières en demi-surprise sont de simples réussites
|
||||
- Les images des scènes par défaut sont corrigées
|
||||
- Amélioration des entités:
|
||||
- l'attaquant ne sait plus que c'est une entité de cauchemar (surprise!)
|
||||
- l'encaissement indique une blessure dans le tchat... même si ce n'est que de l'endurance
|
||||
- les blurettes suivent les règles des entités de cauchemar (p322)
|
||||
- Nouvelle fenêtre de jets de dés
|
||||
- Attaque/défense des créatures
|
||||
- attaque/défense des créatures
|
||||
- les attaques/parades avec une arme trop lourde se font en demi-surprise
|
||||
- les demandes de défense disparaîssent une fois prises en compte
|
||||
- empoignade
|
||||
- l'empoignade est possible avec une initiative d'empoignade, ou en cours d'empoignade
|
||||
- seule la dague, le pugilat et la dague sont possibles en cours d'empoignade
|
||||
- jet de Dextérité/Dague pour utiliser la dague en cours d'empoignade
|
||||
- attaquer avec une arme un empoigneur donne un +4 si pas d'empoignade
|
||||
- les dommages de l'empoignade ajoutent/enlèvent un point d'empoignade
|
||||
- le statut d'empoignade est affiché sur les tokens
|
||||
- les défenses contre une empoignade sont corrigées
|
||||
|
||||
## 13.0.13 - L'épanouissement d'Illysis
|
||||
|
||||
|
||||
@@ -218,6 +218,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
})
|
||||
}
|
||||
|
||||
addAttaque(RdDItemArme.empoignade(this), ATTAQUE_TYPE.CORPS_A_CORPS)
|
||||
this.itemTypes[ITEM_TYPES.arme]
|
||||
.filter(it => it.isAttaque())
|
||||
.sort(Misc.ascending(it => it.name))
|
||||
@@ -227,9 +228,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
if (arme.system.lancer && arme.system.resistance > 0) { addAttaque(arme, ATTAQUE_TYPE.LANCER) }
|
||||
if (arme.system.tir) { addAttaque(arme, ATTAQUE_TYPE.TIR) }
|
||||
})
|
||||
|
||||
addAttaque(RdDItemArme.pugilat(this), ATTAQUE_TYPE.CORPS_A_CORPS)
|
||||
addAttaque(RdDItemArme.empoignade(this), ATTAQUE_TYPE.CORPS_A_CORPS)
|
||||
addAttaque(RdDItemArme.pugilat(this), ATTAQUE_TYPE.CORPS_A_CORPS)
|
||||
|
||||
return actions
|
||||
}
|
||||
@@ -3040,6 +3039,8 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
await this.onDeleteOwnedCaseTmr(item, options, id)
|
||||
break
|
||||
case ITEM_TYPES.empoignade:
|
||||
await this.setEffect(STATUSES.StatusGrappled, false)
|
||||
await this.setEffect(STATUSES.StatusGrappling, false)
|
||||
await RdDEmpoignade.deleteLinkedEmpoignade(this.id, item)
|
||||
break
|
||||
}
|
||||
|
||||
@@ -126,6 +126,8 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
||||
async remiseANeuf() { }
|
||||
async appliquerAjoutExperience(rollData, hideChatMessage = 'show') { }
|
||||
|
||||
computeResumeBlessure() {}
|
||||
countBlessures(filter = it => !it.isContusion()) { return 0 }
|
||||
async santeIncDec(name, inc, isCritique = false) { }
|
||||
|
||||
async finDeRound(options = { terminer: false }) {
|
||||
@@ -246,7 +248,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
||||
|
||||
async setEffect(statusId, status) {
|
||||
if (this.isEffectAllowed(statusId)) {
|
||||
const effect = this.getEffectByStatus(statusId);
|
||||
const effect = this.getEffectByStatus(statusId)
|
||||
if (!status && effect) {
|
||||
await this.deleteEmbeddedDocuments('ActiveEffect', [effect.id], { render: true })
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ export class RdDBonus {
|
||||
dmgForceInsuffisante: Math.min(0, actor.getForce() - (attaque.forceRequise ?? 0)),
|
||||
dmgDiffLibre: ReglesOptionnelles.isUsing('degat-ajout-malus-libre') ? Math.abs(attaque.diff ?? 0) : 0
|
||||
}
|
||||
dmg.isEmpoignade = dmg.mortalite == RDD_CONFIG.encaissement.empoignade
|
||||
dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere + dmg.dmgForceInsuffisante + dmg.dmgDiffLibre
|
||||
return dmg
|
||||
}
|
||||
|
||||
@@ -408,7 +408,6 @@ export class RdDCombat {
|
||||
/* -------------------------------------------- */
|
||||
static registerChatCallbacks(html) {
|
||||
for (let button of [
|
||||
'.button-defense',
|
||||
'.button-parade',
|
||||
'.button-esquive',
|
||||
'.button-encaisser',
|
||||
@@ -480,8 +479,6 @@ export class RdDCombat {
|
||||
|
||||
switch (button) {
|
||||
case '.particuliere-attaque': return await this.choixParticuliere(attackerRoll, event.currentTarget.attributes['data-mode'].value);
|
||||
case '.button-defense': return this.defenseV2(attackerRoll);
|
||||
|
||||
case '.button-parade': return this.parade(attackerRoll, armeParadeId);
|
||||
case '.button-esquive': return this.esquive(attackerRoll, compId, competence);
|
||||
case '.button-encaisser': return this.encaisser(attackerRoll, defenderRoll);
|
||||
@@ -731,24 +728,24 @@ export class RdDCombat {
|
||||
async _chatMessageDefenseV2(paramDemandeDefense) {
|
||||
const attackerRoll = paramDemandeDefense.attackerRoll;
|
||||
RollBasicParts.loadSurprises(attackerRoll)
|
||||
attackerRoll.passeArme = attackerRoll.passeArme ?? foundry.utils.randomID(16)
|
||||
attackerRoll.dmg = RdDBonus.dmgRollV2(attackerRoll, attackerRoll.current.attaque)
|
||||
const attaque = RollDialog.saveParts(attackerRoll)
|
||||
const defense = {
|
||||
attackerRoll: attaque,
|
||||
ids: RollBasicParts.reverseIds(attaque),
|
||||
passeArme: attaque.passeArme ?? foundry.utils.randomID(16)
|
||||
}
|
||||
|
||||
const defenseData = RollBasicParts.prepareDefense(attackerRoll)
|
||||
|
||||
const choixDefense = await ChatMessage.create({
|
||||
// message privé: du défenseur à lui même (et aux GMs)
|
||||
speaker: ChatMessage.getSpeaker(this.defender, canvas.tokens.get(this.defenderTokenId)),
|
||||
alias: this.attacker?.getAlias(),
|
||||
whisper: ChatUtility.getOwners(this.defender),
|
||||
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.hbs', attackerRoll)
|
||||
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.hbs', defenseData)
|
||||
});
|
||||
// flag pour garder les jets d'attaque/defense
|
||||
ChatUtility.setMessageData(choixDefense, 'rollData', defense)
|
||||
ChatUtility.setMessageData(choixDefense, 'demande-defense', true)
|
||||
ChatUtility.setMessageData(choixDefense, 'rollData', {
|
||||
ids: defenseData.ids,
|
||||
attackerRoll: RollDialog.saveParts(attackerRoll),
|
||||
passeArme: defenseData.passeArme
|
||||
})
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -1058,7 +1055,7 @@ export class RdDCombat {
|
||||
dialog.render(true);
|
||||
}
|
||||
|
||||
async defenseV2(attackerRoll) {
|
||||
async defenseV2(attackerRoll, callbacks = []) {
|
||||
// this._prepareParade(attackerRoll, arme, competence);
|
||||
RollDialog.loadRollData(attackerRoll)
|
||||
await this.doRollDefense({
|
||||
@@ -1071,7 +1068,7 @@ export class RdDCombat {
|
||||
type: { allowed: [ROLL_TYPE_DEFENSE], current: ROLL_TYPE_DEFENSE },
|
||||
attackerRoll: attackerRoll,
|
||||
passeArme: attackerRoll.passeArme,
|
||||
})
|
||||
}, callbacks)
|
||||
}
|
||||
|
||||
async doRollDefense(rollData, callbacks = []) {
|
||||
|
||||
@@ -22,29 +22,38 @@ export class RdDEmpoignade {
|
||||
|
||||
static async ajustementEmpoignade(attacker, defender, adjust = 1) {
|
||||
const empoignade = RdDEmpoignade.getEmpoignade(attacker, defender)
|
||||
const empId = empoignade?.system.empoignadeid ?? foundry.utils.randomID(16)
|
||||
if (empoignade) {
|
||||
if (empoignade.system.empoigneurid == defender.id) {
|
||||
adjust = - adjust
|
||||
}
|
||||
empoignade.system.pointsemp += adjust
|
||||
RdDEmpoignade.$updateEtatEmpoignade(empoignade)
|
||||
await RdDEmpoignade.$updateEtatEmpoignade(empoignade, attacker, defender)
|
||||
}
|
||||
else {
|
||||
RdDEmpoignade.$createEtatEmpoignade( {
|
||||
await RdDEmpoignade.$createEtatEmpoignade({
|
||||
name: `Empoignade de ${attacker.name} sur ${defender.name}`,
|
||||
type: ITEM_TYPES.empoignade,
|
||||
system: {
|
||||
description: "",
|
||||
empoignadeid: foundry.utils.randomID(16),
|
||||
empoignadeid: empId,
|
||||
empoigneurid: attacker.id,
|
||||
empoigneid: defender.id,
|
||||
pointsemp: adjust,
|
||||
empoigneurname: attacker.name,
|
||||
empoignename: defender.name
|
||||
}
|
||||
}
|
||||
)
|
||||
}, attacker, defender)
|
||||
}
|
||||
const result = RdDEmpoignade.getEmpoignadeById(defender, empId);
|
||||
const defGrappled = result.system.pointsemp == (result.system.empoigneid == defender.id ? 2 : -2)
|
||||
const attGrappled = result.system.pointsemp == (result.system.empoigneurid == attacker.id ? -2 : 2)
|
||||
const grappling = Math.abs(result.system.pointsemp) > 0
|
||||
await defender.setEffect(STATUSES.StatusGrappling, grappling && !defGrappled)
|
||||
await attacker.setEffect(STATUSES.StatusGrappling, grappling && !attGrappled)
|
||||
await defender.setEffect(STATUSES.StatusGrappled, defGrappled)
|
||||
await attacker.setEffect(STATUSES.StatusGrappled, attGrappled)
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
@@ -362,18 +371,21 @@ export class RdDEmpoignade {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async $updateEtatEmpoignade(empoignade) {
|
||||
static async $updateEtatEmpoignade(empoignade, attacker, defender) {
|
||||
console.log("UPDATE Empoignade", empoignade)
|
||||
const belligerants = [
|
||||
attacker ?? game.actors.get(empoignade.system.empoigneurid),
|
||||
defender ?? game.actors.get(empoignade.system.empoigneid)]
|
||||
|
||||
let defender = game.actors.get(empoignade.system.empoigneid)
|
||||
let emp = RdDEmpoignade.getEmpoignadeById(defender, empoignade.system.empoignadeid)
|
||||
let update = { _id: emp._id, "system.pointsemp": empoignade.system.pointsemp, "system.ausol": empoignade.system.ausol }
|
||||
await defender.updateEmbeddedDocuments('Item', [update])
|
||||
|
||||
let attacker = game.actors.get(empoignade.system.empoigneurid)
|
||||
emp = RdDEmpoignade.getEmpoignadeById(attacker, empoignade.system.empoignadeid)
|
||||
update = { _id: emp._id, "system.pointsemp": empoignade.system.pointsemp, "system.ausol": empoignade.system.ausol }
|
||||
await attacker.updateEmbeddedDocuments('Item', [update])
|
||||
await Promise.all(
|
||||
belligerants.map(async belligerant => {
|
||||
const emp = RdDEmpoignade.getEmpoignadeById(belligerant, empoignade.system.empoignadeid)
|
||||
return await belligerant.updateEmbeddedDocuments('Item', [{
|
||||
_id: emp._id,
|
||||
"system.pointsemp": empoignade.system.pointsemp,
|
||||
"system.ausol": empoignade.system.ausol
|
||||
}])
|
||||
}))
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
@@ -334,7 +334,7 @@ export class RdDRoll extends Dialog {
|
||||
// Mise à jour valeurs
|
||||
this.html.find(".dialog-roll-title").text(this._getTitle(rollData));
|
||||
this.html.find("input.check-mortalite").prop('checked', rollData.dmg.mortalite == RDD_CONFIG.encaissement.nonmortel);
|
||||
this.html.find("label.dmg-arme-actor").text(rollData.dmg.mortalite == EMPOIGNADE ? EMPOIGNADE : Misc.toSignedString(rollData.dmg.total));
|
||||
this.html.find("label.dmg-arme-actor").text(rollData.dmg.isEmpoignade ? EMPOIGNADE : Misc.toSignedString(rollData.dmg.total));
|
||||
this.html.find("label.arme-mortalite").text(rollData.dmg.mortalite);
|
||||
this.html.find("div.placeholder-ajustements").empty().append(adjustements);
|
||||
this.html.find("div.placeholder-resolution").empty().append(resolutionTable)
|
||||
|
||||
@@ -5,7 +5,6 @@ import { RdDCombat } from "../rdd-combat.js"
|
||||
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"
|
||||
import { RollTypeCuisine } from "./roll-type-cuisine.mjs"
|
||||
import { RollTypeMeditation } from "./roll-type-meditation.mjs"
|
||||
@@ -68,7 +67,7 @@ export default class ChatRollResult {
|
||||
isShowEncaissement(roll) {
|
||||
switch (roll.type.current) {
|
||||
case ROLL_TYPE_DEFENSE:
|
||||
return roll.rolled.isEchec && roll.attackerRoll?.dmg.mortalite != EMPOIGNADE
|
||||
return roll.rolled.isEchec
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -133,8 +132,8 @@ export default class ChatRollResult {
|
||||
async chatListeners(html) {
|
||||
$(html).on("click", '.appel-chance', event => this.onClickAppelChance(event))
|
||||
$(html).on("click", '.appel-destinee', event => this.onClickAppelDestinee(event))
|
||||
$(html).on("click", '.button-defense', event => this.onClickDefense(event))
|
||||
$(html).on("click", '.encaissement', event => this.onClickEncaissement(event))
|
||||
$(html).on("click", '.point-empoignade', event => this.onClickMarquerEmpoignade(event))
|
||||
$(html).on("click", '.resister-recul', event => this.onClickRecul(event))
|
||||
$(html).on("click", '.choix-particuliere', event => this.onClickChoixParticuliere(event))
|
||||
$(html).on("click", '.faire-gouter', event => this.onClickFaireGouter(event))
|
||||
@@ -221,27 +220,41 @@ export default class ChatRollResult {
|
||||
})
|
||||
}
|
||||
|
||||
async onClickEncaissement(event) {
|
||||
async onClickDefense(event) {
|
||||
const chatMessage = ChatUtility.getChatMessage(event)
|
||||
const savedRoll = this.loadChatMessageRoll(chatMessage)
|
||||
const attaque = savedRoll.attackerRoll
|
||||
const defender = game.actors.get(savedRoll.ids.actorId)
|
||||
const attacker = game.actors.get(savedRoll.ids.opponentId)
|
||||
const defenderToken = savedRoll.ids.actorTokenId ? canvas.tokens.get(savedRoll.ids.actorTokenId) : undefined
|
||||
const attackerToken = savedRoll.ids.opponentTokenId ? canvas.tokens.get(savedRoll.ids.opponentTokenId) : undefined
|
||||
await defender?.encaisserDommages(attaque.dmg, attacker, undefined, attackerToken, defenderToken)
|
||||
|
||||
savedRoll.done.encaissement = true
|
||||
await this.updateChatMessage(chatMessage, savedRoll)
|
||||
const attackerRoll = savedRoll.attackerRoll
|
||||
this.getCombat(attackerRoll)?.defenseV2(attackerRoll,
|
||||
[roll => { ChatUtility.removeChatMessageId(chatMessage.id) }]
|
||||
)
|
||||
}
|
||||
|
||||
async onClickMarquerEmpoignade(event) {
|
||||
async onClickEncaissement(event) {
|
||||
const chatMessage = ChatUtility.getChatMessage(event)
|
||||
const isMessageDemande = ChatUtility.getMessageData(chatMessage, 'demande-defense')
|
||||
const savedRoll = this.loadChatMessageRoll(chatMessage)
|
||||
const attaque = savedRoll.attackerRoll
|
||||
const attackerToken = attaque.ids.actorTokenId ? canvas.tokens.get(attaque.ids.actorTokenId) : undefined
|
||||
const defenderToken = attaque.ids.opponentTokenId ? canvas.tokens.get(attaque.ids.opponentTokenId) : undefined
|
||||
RdDEmpoignade.ajustementEmpoignade(attackerToken.actor, defenderToken.actor)
|
||||
const defenderToken = savedRoll.ids.actorTokenId ? canvas.tokens.get(savedRoll.ids.actorTokenId) : undefined
|
||||
const attackerToken = savedRoll.ids.opponentTokenId ? canvas.tokens.get(savedRoll.ids.opponentTokenId) : undefined
|
||||
switch (attaque.dmg.mortalite) {
|
||||
case RDD_CONFIG.encaissement.empoignade:
|
||||
savedRoll.done = savedRoll.done ?? {}
|
||||
savedRoll.done.empoignade = await RdDEmpoignade.ajustementEmpoignade(attackerToken.actor, defenderToken.actor)
|
||||
break
|
||||
case RDD_CONFIG.encaissement.entiteincarnee:
|
||||
case RDD_CONFIG.encaissement.nonmortel:
|
||||
case RDD_CONFIG.encaissement.mortel:
|
||||
const defender = defenderToken?.actor ?? game.actors.get(savedRoll.ids.actorId)
|
||||
const attacker = attackerToken?.actor ?? game.actors.get(savedRoll.ids.opponentId)
|
||||
await defender?.encaisserDommages(attaque.dmg, attacker, undefined, attackerToken, defenderToken)
|
||||
break
|
||||
}
|
||||
if (isMessageDemande) {
|
||||
ChatUtility.removeChatMessageId(chatMessage.id)
|
||||
} else {
|
||||
savedRoll.done.encaissement = true
|
||||
await this.updateChatMessage(chatMessage, savedRoll)
|
||||
}
|
||||
}
|
||||
|
||||
async onClickRecul(event) {
|
||||
|
||||
@@ -54,13 +54,27 @@ export class RollBasicParts {
|
||||
}
|
||||
}
|
||||
|
||||
static prepareDefense(attackerRoll) {
|
||||
if (!attackerRoll.passeArme) {
|
||||
attackerRoll.passeArme = foundry.utils.randomID(16);
|
||||
}
|
||||
return {
|
||||
ids: RollBasicParts.reverseIds(attackerRoll),
|
||||
active: attackerRoll.opponent,
|
||||
opponent: attackerRoll.active,
|
||||
attackerRoll: attackerRoll,
|
||||
passeArme: attackerRoll.passeArme,
|
||||
show: { encaissement: true }
|
||||
}
|
||||
}
|
||||
|
||||
static reverseIds(rollData) {
|
||||
return {
|
||||
sceneId: rollData.ids.sceneId,
|
||||
actorId: rollData.ids.opponentId,
|
||||
actorTokenId: rollData.ids.opponentTokenId,
|
||||
opponentId: rollData.ids.actorId,
|
||||
opponentTokenId: rollData.actorTokenId
|
||||
opponentTokenId: rollData.ids.actorTokenId
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ export class RollDialogAdapter {
|
||||
|
||||
const attaque = rollData.current.attaque;
|
||||
const choix = []
|
||||
const isEmpoignade = attaque.dmg.mortalite == RDD_CONFIG.encaissement.empoignade
|
||||
const isEmpoignade = attaque.dmg.isEmpoignade
|
||||
const isCharge = attaque.tactique == 'charge'
|
||||
/* TODO: cas de créatures faisant des lancers, Glou, Glipzouk */
|
||||
const isMeleeDiffNegative = (attaque.comp.type == ITEM_TYPES.competencecreature || rollData.current.carac.key == CARACS.MELEE)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ITEM_TYPES } from "../constants.js"
|
||||
import { ITEM_TYPES, RDD_CONFIG } from "../constants.js"
|
||||
import { ATTAQUE_TYPE, RdDItemArme } from "../item/arme.js"
|
||||
import { CARACS } from "../rdd-carac.js"
|
||||
import { DIFF, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs"
|
||||
@@ -15,6 +15,8 @@ export class RollPartDefense extends RollPartSelect {
|
||||
|
||||
get code() { return PART_DEFENSE }
|
||||
get section() { return ROLLDIALOG_SECTION.CHOIX }
|
||||
|
||||
isValid(rollData) { return rollData.attackerRoll != undefined }
|
||||
visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_DEFENSE) }
|
||||
|
||||
static getDiffAttaque(attackerRoll) {
|
||||
@@ -27,13 +29,22 @@ export class RollPartDefense extends RollPartSelect {
|
||||
const attackerRoll = rollData.attackerRoll
|
||||
const defenseur = rollData.active.actor
|
||||
refs.isDistance = [ATTAQUE_TYPE.TIR, ATTAQUE_TYPE.LANCER].find(it => it == attackerRoll?.main)
|
||||
const esquives = refs.isDistance == ATTAQUE_TYPE.TIR ? [] : defenseur.getCompetencesEsquive()
|
||||
.map(it => RollPartDefense.$extractEsquive(it, defenseur))
|
||||
const isEmpoignade = attackerRoll.dmg.isEmpoignade
|
||||
const isEmpoignadeEnCours = isEmpoignade && defenseur.itemTypes[ITEM_TYPES.empoignade].find(it =>
|
||||
[it.system.empoigneurid, it.system.empoigneid].includes(rollData.ids.opponentId) &&
|
||||
it.system.pointsemp != 0)
|
||||
|
||||
const parades = defenseur.items.filter(it => it.isParade() && (!refs.isDistance || it.isBouclier()))
|
||||
.map(it => RollPartDefense.$extractParade(it, attackerRoll?.arme, defenseur))
|
||||
const esquives = (refs.isDistance == ATTAQUE_TYPE.TIR || isEmpoignadeEnCours)
|
||||
? []
|
||||
: defenseur.getCompetencesEsquive()
|
||||
const parades = isEmpoignade
|
||||
? [RdDItemArme.empoignade(defenseur)]
|
||||
: defenseur.items.filter(it => it.isParade() && (!refs.isDistance || it.isBouclier()))
|
||||
|
||||
refs.defenses = [...esquives, ...parades].filter(it => it != undefined)
|
||||
refs.defenses = [
|
||||
...esquives.map(it => RollPartDefense.$extractEsquive(it, defenseur)),
|
||||
...parades.map(it => RollPartDefense.$extractParade(it, attackerRoll?.arme, defenseur))
|
||||
]
|
||||
this.$selectDefense(rollData)
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ export const demiReveStatusEffect = {
|
||||
rdd: true, id: STATUSES.StatusDemiReve, name: 'EFFECT.StatusDemiReve', img: RDD_CONFIG.icons.demiReve
|
||||
};
|
||||
const rddStatusEffects = [
|
||||
{ rdd: true, id: STATUSES.StatusGrappling, tint: '#33cc33', name: 'EFFECT.StatusGrappling', img: RDD_CONFIG.icons.empoignade },
|
||||
{ rdd: true, id: STATUSES.StatusGrappled, tint: '#ff9900', name: 'EFFECT.StatusGrappled', img: RDD_CONFIG.icons.empoignade },
|
||||
{ rdd: true, id: STATUSES.StatusGrappling, name: 'EFFECT.StatusGrappling', img: RDD_CONFIG.icons.empoignade },
|
||||
{ rdd: true, id: STATUSES.StatusGrappled, tint: '#d5633d', name: 'EFFECT.StatusGrappled', img: RDD_CONFIG.icons.empoignade },
|
||||
|
||||
{ rdd: true, id: STATUSES.StatusRestrained, name: 'EFFECT.StatusRestrained', img: 'icons/svg/net.svg' },
|
||||
{ rdd: true, id: STATUSES.StatusStunned, name: 'EFFECT.StatusStunned', img: 'icons/svg/stoned.svg', "duration.rounds": 1 },
|
||||
@@ -45,8 +45,9 @@ const statusSurpriseTotale = new Set([STATUSES.StatusUnconscious, STATUSES.Statu
|
||||
export class StatusEffects extends FormApplication {
|
||||
|
||||
static onReady() {
|
||||
const rddEffectIds = rddStatusEffects.map(it => it.id);
|
||||
const rddEffectIds = rddStatusEffects.map(it => it.id)
|
||||
rddStatusEffects.forEach(it => {
|
||||
it.name = game.i18n.localize(it.name)
|
||||
it.statuses = new Set([it.id])
|
||||
})
|
||||
const defaultStatusEffectIds = CONFIG.statusEffects.map(it => it.id);
|
||||
|
||||
@@ -16,7 +16,7 @@ background:
|
||||
alphaThreshold: 0
|
||||
foreground: null
|
||||
foregroundElevation: 4
|
||||
thumb: systems/foundryvtt-reve-de-dragon/assets/scenes/YSpVuLeMCX9tAmgn-thumb.webp
|
||||
thumb: systems/foundryvtt-reve-de-dragon/pic/YSpVuLeMCX9tAmgn-thumb.webp
|
||||
width: 1920
|
||||
height: 1080
|
||||
padding: 0.25
|
||||
|
||||
@@ -7,7 +7,7 @@ initial:
|
||||
x: null
|
||||
'y': null
|
||||
scale: 0.5
|
||||
thumb: systems/foundryvtt-reve-de-dragon/assets/scenes/9fmf9lcb3L9XO3bJ-thumb.png
|
||||
thumb: systems/foundryvtt-reve-de-dragon/pic/9fmf9lcb3L9XO3bJ-thumb.png
|
||||
width: 3521
|
||||
height: 2492
|
||||
padding: 0.25
|
||||
@@ -38,7 +38,7 @@ regions: []
|
||||
ownership:
|
||||
default: 0
|
||||
background:
|
||||
src: systems/foundryvtt-reve-de-dragon/assets/ecran_rdd.webp
|
||||
src: systems/foundryvtt-reve-de-dragon/pic/ecran_rdd.webp
|
||||
offsetX: 0
|
||||
offsetY: 0
|
||||
anchorX: 0
|
||||
|
||||
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 716 KiB After Width: | Height: | Size: 716 KiB |
@@ -1,25 +1,24 @@
|
||||
{{log this}}
|
||||
<div class="roll-chat" data-passearme="{{passeArme}}">
|
||||
<div class="chat-img">
|
||||
<img src="{{opponent.img}}" data-tooltip="{{opponent.name}}" />
|
||||
<img src="{{active.img}}" data-tooltip="{{active.name}}" />
|
||||
</div>
|
||||
|
||||
<div class="chat-header">
|
||||
<h4>Défense de {{opponent.name}}</h4>
|
||||
<h4>Défense de {{active.name}}</h4>
|
||||
</div>
|
||||
|
||||
<div class="chat-resume">
|
||||
{{#if (eq opponent.surprise.key 'totale')}}
|
||||
<span><strong>{{opponent.name}}</strong> est totalement surpris</span>
|
||||
{{#if (eq active.surprise.key 'totale')}}
|
||||
<span><strong>{{active.name}}</strong> est totalement surpris</span>
|
||||
{{else}}
|
||||
<span><strong>{{opponent.name}}</strong> doit se défendre
|
||||
{{~#if (eq opponent.surprise.key 'demi')}} avec une significative {{/if}} d'une attaque
|
||||
{{~#if particuliere}} <strong>particulière en
|
||||
{{~#if (eq particuliere 'finesse')}} finesse
|
||||
<span><strong>{{active.name}}</strong> doit se défendre
|
||||
{{~#if (eq active.surprise.key 'demi')}} avec une significative {{/if}} d'une attaque
|
||||
{{~#if attackerRoll.particuliere}} <strong>particulière en
|
||||
{{~#if (eq attackerRoll.particuliere 'finesse')}} finesse
|
||||
{{else if (eq particuliere 'force')}} force
|
||||
{{else if (eq particuliere 'rapidite')}} rapidité
|
||||
{{/if~}}</strong>
|
||||
{{/if}} de {{active.name}} ({{current.attaque.label}}):
|
||||
{{/if}} de {{opponent.name}} ({{attackerRoll.current.attaque.label}}):
|
||||
</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
@@ -28,35 +27,23 @@
|
||||
</div>
|
||||
|
||||
<div class="chat-actions">
|
||||
{{#unless (eq opponent.surprise.key 'totale')}}
|
||||
{{#unless (eq active.surprise.key 'totale')}}
|
||||
<a class='chat-card-button button-defense'
|
||||
data-attackerId='{{ids.actorId}}'
|
||||
data-attackerTokenId='{{ids.actorTokenId}}'
|
||||
data-defenderTokenId='{{ids.opponentTokenId}}'
|
||||
data-attackerId='{{ids.opponentId}}'
|
||||
data-attackerTokenId='{{ids.opponentTokenId}}'
|
||||
data-defenderId='{{ids.actorId}}'
|
||||
data-defenderTokenId='{{ids.actorTokenId}}'
|
||||
>
|
||||
<img src="systems/foundryvtt-reve-de-dragon/assets/actions/defense.svg"/>
|
||||
Se défendre
|
||||
{{#if (or (eq attaqueCategorie 'tir') (eq attaqueCategorie 'lancer'))}}
|
||||
{{#if (or (eq attackerRoll.attaqueCategorie 'tir') (eq attackerRoll.attaqueCategorie 'lancer'))}}
|
||||
(difficulté à déterminer)
|
||||
{{else}}
|
||||
à {{current.diff.value}}
|
||||
à {{attackerRoll.current.diff.value}}
|
||||
{{/if}}
|
||||
</a>
|
||||
{{/unless}}
|
||||
{{#if (eq dmg.mortalite 'empoignade')}}
|
||||
<a class='chat-card-button point-empoignade' data-tooltip="Subir un point d'empoignade">
|
||||
<img src="systems/foundryvtt-reve-de-dragon/assets/actions/empoignade.svg"/>
|
||||
Marquer le point d'empoignade
|
||||
</a>
|
||||
{{else}}
|
||||
<a class='chat-card-button encaissement'
|
||||
data-tooltip="Encaisser à {{plusMoins dmg.total}} {{#if (eq dmg.mortalite 'non-mortel')~}}(non-mortel){{/if}}"
|
||||
>
|
||||
<img src="systems/foundryvtt-reve-de-dragon/assets/actions/encaisser.svg"/>
|
||||
Encaisser à {{plusMoins dmg.total}}
|
||||
{{#if (eq dmg.mortalite 'non-mortel')~}}(non-mortel){{/if}}
|
||||
</a>
|
||||
{{/if}}
|
||||
{{> 'partial-encaissement'}}
|
||||
</div>
|
||||
|
||||
<div class="chat-buttons">
|
||||
|
||||
@@ -1,15 +1,29 @@
|
||||
{{log 'partial-encaissement' this}}
|
||||
{{#if show.encaissement}}
|
||||
{{#if done.encaissement}}
|
||||
<span class='chat-card-info'>
|
||||
<img src="systems/foundryvtt-reve-de-dragon/assets/actions/encaisser.svg"/>
|
||||
{{active.name}} a encaissé
|
||||
</span>
|
||||
<span class='chat-card-info'>
|
||||
{{#if (eq attackerRoll.dmg.mortalite 'empoignade')}}
|
||||
<img src="systems/foundryvtt-reve-de-dragon/assets/actions/empoignade.svg"/>
|
||||
{{opponent.name}} a {{done.empoignade.system.pointsemp}} point d'empoignade contre {{active.name}}.
|
||||
{{#if (gt done.empoignade.system.pointsemp 2)}} Si {{active.name}} ne se libère pas, il sera immobilisé à la fin du round{{/if}}
|
||||
{{else}}
|
||||
<img src="systems/foundryvtt-reve-de-dragon/assets/actions/encaisser.svg"/>
|
||||
{{active.name}} a encaissé
|
||||
{{/if}}
|
||||
</span>
|
||||
{{else}}
|
||||
<a class='chat-card-button encaissement'
|
||||
data-tooltip="Encaisser à {{plusMoins attackerRoll.dmg.total}} {{#if (eq attackerRoll.dmg.mortalite 'non-mortel')~}}(non-mortel){{/if}}"
|
||||
>
|
||||
<img src="systems/foundryvtt-reve-de-dragon/assets/actions/encaisser.svg"/> Encaisser à {{plusMoins attackerRoll.dmg.total}}
|
||||
{{#if (eq attackerRoll.dmg.mortalite 'non-mortel')~}}(non-mortel){{/if}}
|
||||
</a>
|
||||
{{#if (eq attackerRoll.dmg.mortalite 'empoignade')}}
|
||||
<a class='chat-card-button encaissement' data-tooltip="Marquer un point d'empoignade">
|
||||
<img src="systems/foundryvtt-reve-de-dragon/assets/actions/empoignade.svg"/>
|
||||
Marquer un point d'empoignade
|
||||
</a>
|
||||
{{else}}
|
||||
<a class='chat-card-button encaissement'
|
||||
data-tooltip="Encaisser à {{plusMoins attackerRoll.dmg.total}} {{#if (eq attackerRoll.dmg.mortalite 'non-mortel')~}}(non-mortel){{/if}}"
|
||||
>
|
||||
<img src="systems/foundryvtt-reve-de-dragon/assets/actions/encaisser.svg"/> Encaisser à {{plusMoins attackerRoll.dmg.total}}
|
||||
{{#if (eq attackerRoll.dmg.mortalite 'non-mortel')~}}(non-mortel){{/if}}
|
||||
</a>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
Reference in New Issue
Block a user