Compare commits

..

33 Commits

Author SHA1 Message Date
928a60f092 Add flags 2023-03-23 17:03:40 +01:00
e5c2f52b0e Merge pull request 'Version 10.7.3 - Les tisanes de Sémolosse' (#637) from VincentVk/foundryvtt-reve-de-dragon:v10 into v10
Reviewed-on: public/foundryvtt-reve-de-dragon#637
2023-03-23 17:02:56 +01:00
f9391523f8 Version 10.7.3
Les tisanes de Sémolosse
2023-03-23 01:44:35 +01:00
55434762f4 Masquer bonus premiers soins si soins complets 2023-03-23 01:43:41 +01:00
5e6ffc7846 Fix: bonus d'herbe de potion non enchantée 2023-03-23 01:42:48 +01:00
3344e20936 Fix: consommation potion enchantée 2023-03-23 01:41:37 +01:00
5a66e4e741 Fix horloge aiguille des heures
L'aiguille des heures pointe sur l'heure au début de l'heure
draconique, comme pour une montre.

Début couronne, l'aiguille des heures et des minutes sont donc
toutes les deux en haut.
2023-03-21 22:00:24 +01:00
d329724d63 Merge pull request '10.7.2 - les maux de dents de Semolosse' (#636) from VincentVk/foundryvtt-reve-de-dragon:v10 into v10
Reviewed-on: public/foundryvtt-reve-de-dragon#636
2023-03-20 23:32:08 +01:00
8a5405c9f5 Version 10.7.2
les maux de dents de Semolosse
2023-03-20 23:29:46 +01:00
ea992aae46 Fix: récupération des blessures 2023-03-20 23:28:25 +01:00
0bfcfec58f Fix jet carac 2023-03-16 23:17:52 +01:00
88e00c59bc Fix actor 2023-03-16 23:12:08 +01:00
d314dc39a0 Fix actor 2023-03-16 23:10:17 +01:00
30bb803da2 Merge pull request 'v10.7.0 - l'os de Sémolosse' (#635) from VincentVk/foundryvtt-reve-de-dragon:v10 into v10
Reviewed-on: public/foundryvtt-reve-de-dragon#635
2023-03-16 23:09:10 +01:00
dd79e16ea5 Version 10.7.0 2023-03-15 01:29:55 +01:00
83e2d56fd4 Boutons soins&blessures 2023-03-15 01:29:48 +01:00
afc23dfa7b Fix: message sans jet d'endurance 2023-03-15 01:29:48 +01:00
3e189cbe5f Ajout des blessures sur encaissement 2023-03-15 01:29:48 +01:00
d0475e8677 Suppression anciennes blessures 2023-03-15 00:41:48 +01:00
a3694c1673 Cleanup 2023-03-15 00:41:47 +01:00
9e6d5856b1 Gestion des soins avancés
- raccourci soins HUD
- edition rapide des Item blessure
- gestion des taches de soins liées aux blessures
2023-03-15 00:41:47 +01:00
acc880b53f Preparation soins HUD 2023-03-15 00:41:47 +01:00
2598ae3489 Ajout item Blessure 2023-03-15 00:35:22 +01:00
4f5fb63751 Tri alphabétique des constantes 2023-03-15 00:35:21 +01:00
d739a7993a rollCaracCompetence avec dialog 2023-03-15 00:35:21 +01:00
41335cd433 Renommage méthode jet sans dialog 2023-03-15 00:35:21 +01:00
e470d76ea0 Méthode de fenêtre de jet partagée 2023-03-15 00:35:21 +01:00
ffccc819f1 Fix: merge d'options sur token 2023-03-15 00:35:21 +01:00
45bfc69b39 Ajout d'option pour informer si pas de cible
Pour le HUD, on peut vouloir utiliser la cible (soins)
2023-03-15 00:23:21 +01:00
79e9358072 Préparation Calendrier avant migration
Les migrations peuvent avoir besoin du temps courant.
Le calendrier est recréé après.
2023-03-15 00:23:21 +01:00
5cab418e62 Merge pull request 'v10.6.25 - fix erreur synchro astrologie/heure' (#634) from VincentVk/foundryvtt-reve-de-dragon:v10 into v10
Reviewed-on: public/foundryvtt-reve-de-dragon#634
2023-03-14 22:41:45 +01:00
7809f7c21a Version 10.6.25 2023-03-14 22:14:04 +01:00
1bac204071 Fix astrologie 2023-03-14 21:56:59 +01:00
41 changed files with 983 additions and 694 deletions

1
.gitignore vendored
View File

@@ -1,5 +1,6 @@
.vscode/settings.json
.idea
.history
todo.md
/.vscode
/ignored/

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
icons/sante/blessure.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

BIN
icons/sante/eraflure.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

BIN
icons/sante/mort.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@@ -7,47 +7,48 @@
"TypeVehicule": "Véhicule"
},
"ITEM": {
"TypeObjet": "Objet",
"TypeGemme": "Gemme",
"TypeCompetence": "Compétence",
"TypeCompetencecreature": "Compétence de créature",
"TypeMaladie": "Maladie",
"TypePoison": "Poison",
"TypeNombreastral": "Nombre astral",
"TypeTarot": "Carte de tarot",
"TypeCasetmr": "TMR spéciale",
"TypeRencontre": "Rencontre TMR",
"TypeMunition": "Munition",
"TypeMonnaie": "Monnaie",
"TypeHerbe": "Herbe",
"TypePlante": "Plante",
"TypeIngredient": "Ingrédient",
"TypeFaune": "Faune",
"TypeLivre": "Livre",
"TypePotion": "Potion",
"TypeArme": "Arme",
"TypeArmure": "Armure",
"TypeConteneur": "Conteneur",
"TypeNourritureboisson": "Nourriture & boisson",
"TypeService": "Service",
"TypeBlessure": "Blessure",
"TypeCasetmr": "TMR spéciale",
"TypeChant": "Chant",
"TypeCompetence": "Compétence",
"TypeCompetencecreature": "Compétence de créature",
"TypeConteneur": "Conteneur",
"TypeDanse": "Danse",
"TypeMusique": "Musique",
"TypeOeuvre": "Oeuvre",
"TypeTache": "Tâche",
"TypeExtraitpoetique": "Extrait poetique",
"TypeFaune": "Faune",
"TypeGemme": "Gemme",
"TypeHerbe": "Herbe",
"TypeIngredient": "Ingrédient",
"TypeJeu": "Jeu",
"TypeLivre": "Livre",
"TypeMaladie": "Maladie",
"TypeMeditation": "Méditation",
"TypeMonnaie": "Monnaie",
"TypeMunition": "Munition",
"TypeMusique": "Musique",
"TypeNombreastral": "Nombre astral",
"TypeNourritureboisson": "Nourriture & boisson",
"TypeObjet": "Objet",
"TypeOeuvre": "Oeuvre",
"TypeOmbre": "Ombre de Thanatos",
"TypePlante": "Plante",
"TypePoison": "Poison",
"TypePossession": "Possession",
"TypePotion": "Potion",
"TypeQueue": "Queue de Dragon",
"TypeRecettealchimique": "Recette alchimique",
"TypeRecettecuisine": "Recette de cuisine",
"TypeSort": "Sort",
"TypeMeditation": "Méditation",
"TypeRencontre": "Rencontre TMR",
"TypeService": "Service",
"TypeSignedraconique": "Signe draconique",
"TypeQueue": "Queue de Dragon",
"TypeOmbre": "Ombre de Thanatos",
"TypeSouffle": "Souffle de Dragon",
"TypeTete": "Tête de Dragon",
"TypePossession": "Possession",
"TypeSort": "Sort",
"TypeSortreserve": "Sort en réserve",
"TypeExtraitpoetique": "Extrait poetique"
"TypeSouffle": "Souffle de Dragon",
"TypeTache": "Tâche",
"TypeTarot": "Carte de tarot",
"TypeTete": "Tête de Dragon"
},
"EFFECT": {
"StatusStunned": "Sonné",

View File

@@ -13,6 +13,7 @@ import { STATUSES } from "./settings/status-effects.js";
import { MAINS_DIRECTRICES } from "./actor.js";
import { RdDBaseActorSheet } from "./actor/base-actor-sheet.js";
import { RdDItem } from "./item.js";
import { RdDItemBlessure } from "./item/blessure.js";
/* -------------------------------------------- */
/**
@@ -151,42 +152,31 @@ export class RdDActorSheet extends RdDBaseActorSheet {
this.html.find('.creer-tache').click(async event => {
this.createEmptyTache();
});
this.html.find('.creer-tache-blessure-legere').click(async event => {
this.actor.createTacheBlessure('legere');
});
this.html.find('.creer-tache-blessure-grave').click(async event => {
this.actor.createTacheBlessure('grave');
});
this.html.find('.creer-tache-blessure-critique').click(async event => {
this.actor.createTacheBlessure('critique');
});
this.html.find('.creer-tache-blessure-legere').click(async event => RdDItemBlessure.createTacheSoinBlessure(this.actor, 2));
this.html.find('.creer-tache-blessure-grave').click(async event => RdDItemBlessure.createTacheSoinBlessure(this.actor, 4));
this.html.find('.creer-tache-blessure-critique').click(async event => RdDItemBlessure.createTacheSoinBlessure(this.actor, 6));
this.html.find('.creer-blessure-legere').click(async event => RdDItemBlessure.createBlessure(this.actor, 2));
this.html.find('.creer-blessure-grave').click(async event => RdDItemBlessure.createBlessure(this.actor, 4));
this.html.find('.creer-blessure-critique').click(async event => RdDItemBlessure.createBlessure(this.actor, 6));
this.html.find('.creer-une-oeuvre').click(async event => {
this.selectTypeOeuvreToCreate();
});
// Blessure control
this.html.find('.blessure-control').click(async event => {
const tr = this.html.find(event.currentTarget).parents(".item");
let btype = tr.data("blessure-type");
let index = tr.data('blessure-index');
let active = this.html.find(event.currentTarget).data('blessure-active');
//console.log(btype, index, active);
await this.actor.manageBlessureFromSheet(btype, index, active);
this.html.find('.blessure-premierssoins-done').change(async event => {
const blessure = this.getBlessure(event);
await blessure?.setSoinsBlessure({ premierssoins: { done: event.currentTarget.checked } });
});
// Blessure data
this.html.find('.blessure-soins').change(async event => {
const tr = this.html.find(event.currentTarget).parents(".item");
let btype = tr.data('blessure-type');
let index = tr.data('blessure-index');
let psoins = tr.find('.blessure-premiers_soins').val();
let pcomplets = tr.find('.blessure-soins_complets').val();
let jours = tr.find('.blessure-jours').val();
let loc = tr.find('.blessure-localisation').val();
let psdone = tr.find('.blessure-psdone:checked').val();
let scdone = tr.find('.blessure-scdone:checked').val();
console.log(btype, index, psoins, pcomplets, jours, loc, psdone, scdone);
await this.actor.setDataBlessureFromSheet(btype, index, psoins, pcomplets, jours, loc, psdone, scdone);
this.html.find('.blessure-soinscomplets-done').change(async event => {
const blessure = this.getBlessure(event);
await blessure?.setSoinsBlessure({ soinscomplets: { done: event.currentTarget.checked } })
});
this.html.find('.blessure-premierssoins-bonus').change(async event => {
const blessure = this.getBlessure(event);
await blessure?.setSoinsBlessure({ premierssoins: { bonus: Number(event.currentTarget.value) } })
});
this.html.find('.blessure-soinscomplets-bonus').change(async event => {
const blessure = this.getBlessure(event);
await blessure?.setSoinsBlessure({ soinscomplets: { bonus: Number(event.currentTarget.value) } })
});
// Equip Inventory Item
@@ -426,6 +416,12 @@ export class RdDActorSheet extends RdDBaseActorSheet {
});
}
getBlessure(event) {
const itemId = this.html.find(event.currentTarget).parents(".item-blessure").data('item-id');
const blessure = this.actor.getItem(itemId, 'blessure');
return blessure;
}
isCompetenceAffichable(competence) {
return !this.options.showCompNiveauBase || !RdDItemCompetence.isNiveauBase(competence);
}

File diff suppressed because it is too large Load Diff

View File

@@ -78,6 +78,7 @@ export class RdDBaseActorSheet extends ActorSheet {
/* -------------------------------------------- */
static filterItemsPerTypeForSheet(formData, itemTypes) {
formData.blessures = Misc.arrayOrEmpty(itemTypes['blessure']);
formData.recettescuisine = Misc.arrayOrEmpty(itemTypes['recettecuisine']);
formData.recettesAlchimiques = Misc.arrayOrEmpty(itemTypes['recettealchimique']);
formData.maladies = Misc.arrayOrEmpty(itemTypes['maladie']);

View File

@@ -5,6 +5,7 @@ import { Misc } from "../misc.js";
import { RdDAudio } from "../rdd-audio.js";
import { RdDUtility } from "../rdd-utility.js";
import { SystemCompendiums } from "../settings/system-compendiums.js";
import { APP_ASTROLOGIE_REFRESH } from "../sommeil/app-astrologie.js";
export class RdDBaseActor extends Actor {
@@ -20,7 +21,6 @@ export class RdDBaseActor extends Actor {
Hooks.on("updateActor", (actor, change, options, actorId) => actor.onUpdateActor(change, options, actorId));
}
static onSocketMessage(sockmsg) {
switch (sockmsg.msg) {
case "msg_remote_actor_call":

View File

@@ -1,18 +0,0 @@
const BASE_TACHE_SOIN_BLESSURE = { type: "tache", img: 'systems/foundryvtt-reve-de-dragon/icons/competence_chirurgie.webp', system: { carac: "dexterite", competence: "Chirurgie", periodicite: "1 round", fatigue: 0, } }
const TACHES_SOIN_BLESSURE = {
'critique': { name: 'Blessure critique', system: { difficulte: -6, points_de_tache: 6 } },
'grave': { name: 'Blessure grave', system: { difficulte: -4, points_de_tache: 4 } },
'legere': { name: 'Blessure légère', system: { difficulte: -2, points_de_tache: 2 } },
}
export class RdDItemTache extends Item {
static prepareTacheSoin(gravite) {
const blessure = TACHES_SOIN_BLESSURE[gravite]
if (blessure) {
return mergeObject(duplicate(BASE_TACHE_SOIN_BLESSURE), blessure)
}
ui.notifications.warn(`Pas de tâche de soins pour une blessure ${gravite}`)
return undefined;
}
}

View File

@@ -31,9 +31,9 @@ const typesInventaire = {
const typesObjetsOeuvres = ["oeuvre", "recettecuisine", "musique", "chant", "danse", "jeu"]
const typesObjetsDraconiques = ["queue", "ombre", "souffle", "tete", "signedraconique", "sortreserve", "rencontre"]
const typesObjetsConnaissance = ["meditation", "recettealchimique", "sort"]
const typesObjetsEffet = ["possession", "poison", "maladie"]
const typesObjetsEffet = ["possession", "poison", "maladie", "blessure"]
const typesObjetsCompetence = ["competence", "competencecreature"]
const typesObjetsTemporels = ["poison", "maladie", "queue", "ombre", "souffle", "signedraconique", "rencontre"]
const typesObjetsTemporels = ["blessure", "poison", "maladie", "queue", "ombre", "souffle", "signedraconique", "rencontre"]
const typesEnvironnement = typesInventaireMateriel;
const encBrin = 0.00005; // un brin = 1 décigramme = 1/10g = 1/10000kg = 1/20000 enc
const encPepin = 0.0007; /* un pépin de gemme = 1/10 cm3 = 1/1000 l = 3.5/1000 kg = 7/2000 kg = 7/1000 enc
@@ -176,6 +176,7 @@ export class RdDItem extends Item {
isBoisson() { return this.isNourritureBoisson() && this.system.boisson; }
isAlcool() { return this.isNourritureBoisson() && this.system.boisson && this.system.alcoolise; }
isHerbeAPotion() { return this.type == 'herbe' && (this.system.categorie == 'Soin' || this.system.categorie == 'Repos'); }
isBlessure() { return this.type == 'blessure' }
isPresentDansMilieux(milieux) {
return this.getEnvironnements(milieux).length > 0

181
module/item/blessure.js Normal file
View File

@@ -0,0 +1,181 @@
import { RdDItem } from "../item.js";
import { Misc } from "../misc.js";
import { RdDTimestamp } from "../rdd-timestamp.js";
const BASE_TACHE_SOIN_BLESSURE = {
type: "tache",
img: 'systems/foundryvtt-reve-de-dragon/icons/competence_chirurgie.webp',
system: { carac: "dexterite", competence: "Chirurgie", periodicite: "1 round", fatigue: 0, }
}
const TACHES_SOIN_BLESSURE = {
6: { name: 'Blessure critique', system: { difficulte: -6, points_de_tache: 6 } },
4: { name: 'Blessure grave', system: { difficulte: -4, points_de_tache: 4 } },
2: { name: 'Blessure légère', system: { difficulte: -2, points_de_tache: 2 } },
}
const definitionsBlessures = [
{ type: "contusion", gravite: 0, labelGravite: 'Contusion/éraflure', max: 100, icon: "systems/foundryvtt-reve-de-dragon/icons/sante/eraflure.webp" },
{ type: "legere", gravite: 2, labelGravite: 'Légère', max: 5, icon: "systems/foundryvtt-reve-de-dragon/icons/sante/blessure.webp" },
{ type: "grave", gravite: 4, labelGravite: 'Grave', max: 2, icon: "systems/foundryvtt-reve-de-dragon/icons/sante/blessure.webp" },
{ type: "critique", gravite: 6, labelGravite: 'Critique', max: 1, icon: "systems/foundryvtt-reve-de-dragon/icons/sante/blessure.webp" },
{ type: "mort", gravite: 8, labelGravite: 'Mort', max: 1, icon: "systems/foundryvtt-reve-de-dragon/icons/sante/mort.webp" }
]
export class RdDItemBlessure extends RdDItem {
static get defaultIcon() {
return "systems/foundryvtt-reve-de-dragon/icons/sante/blessure.webp";
}
prepareDerivedData() {
super.prepareDerivedData();
this.system.labelGravite = this.getLabelGravite()
}
static prepareTacheSoin(gravite) {
const tache = TACHES_SOIN_BLESSURE[gravite]
if (!tache) {
ui.notifications.warn(`Pas de tâche de soins pour une blessure ${gravite}`)
return undefined;
}
return mergeObject(duplicate(BASE_TACHE_SOIN_BLESSURE), tache)
}
static async createBlessure(actor, gravite, localisation = '') {
const definition = RdDItemBlessure.getDefinition(gravite)
const blessure = {
name: definition.labelGravite,
type: 'blessure',
img: definition.icon,
system: {
gravite: gravite,
difficulte: - gravite,
localisation: localisation
}
}
const blessures = await actor.createEmbeddedDocuments('Item', [blessure])
return blessures[0]
}
static async createTacheSoinBlessure(actor, gravite) {
const tache = RdDItemBlessure.prepareTacheSoin(gravite)
if (tache) {
const taches = await actor.createEmbeddedDocuments('Item', [tache], { renderSheet: false });
return taches[0];
}
return undefined
}
async updateTacheSoinBlessure(tache) {
if (tache) {
await tache.update({
system: {
itemId: this.id,
difficulte: Math.min(this.system.difficulte, tache.system.difficulte),
points_de_tache_courant: Math.max(0, this.system.premierssoins.tache)
}
});
}
}
async setSoinsBlessure(systemUpdate = {}) {
systemUpdate = mergeObject(systemUpdate, this.system, { overwrite: false }),
systemUpdate.soinscomplets.done = systemUpdate.premierssoins.done && systemUpdate.soinscomplets.done
await this.update({
img: this.getImgSoins(systemUpdate.gravite, systemUpdate.soinscomplets.done),
system: systemUpdate
});
}
async recuperationBlessure({ actor, timestamp, message, isMaladeEmpoisonne, blessures }) {
if (this.parent != actor || actor == undefined) {
return
}
if (new RdDTimestamp(this.system.temporel.fin).compare(timestamp) > 0) {
// attente periode
return
}
if (this.system.gravite > 0) {
const update = { system: { premierssoins: { bonus: 0 }, soinscomplets: { bonus: 0 } } }
const gravite = this.system.gravite;
const graviteMoindre = gravite - 2;
const moindres = blessures.filter(it => it.system.gravite == graviteMoindre, 'blessures').length
const labelGravite = this.getLabelGravite();
let rolled = await actor.jetRecuperationConstitution(this.system.soinscomplets.bonus, message);
if (rolled.isETotal) {
message.content += ` -- une blessure ${labelGravite} s'infecte (temps de guérison augmenté de ${gravite} jours, perte de vie)`;
await actor.santeIncDec("vie", -1);
mergeObject(update, {
system: { fin: { indexDate: timestamp.addJours(gravite).indexDate } }
});
}
else {
if (!isMaladeEmpoisonne && rolled.isSuccess && this.peutRetrograder(graviteMoindre, moindres)) {
message.content += ` -- une blessure ${labelGravite} cicatrise`;
mergeObject(update, {
system: { gravite: graviteMoindre, fin: { indexDate: timestamp.addJours(graviteMoindre).indexDate } }
});
}
else {
message.content += ` -- une blessure ${labelGravite} reste stable`;
}
}
await this.update(update);
}
}
peutRetrograder(graviteMoindre, moindres) {
return moindres < RdDItemBlessure.getDefinition(graviteMoindre).max
}
async calculerFinPeriodeTemporel(debut) {
return await debut.nouveauJour().addJours(this.system.gravite);
}
async onFinPeriode(oldTimestamp, newTimestamp) {
if (this.system.gravite <= 0) {
await super.onFinPeriode(oldTimestamp, newTimestamp)
}
}
getImgSoins(gravite, soins) {
let img = 'blessure'
if (gravite > 6) {
img = 'mort'
}
if (gravite <= 0) {
img = 'eraflure'
}
return `systems/foundryvtt-reve-de-dragon/icons/sante/${soins ? 'blessure-soins' : img}.webp`
}
getLabelGravite() {
return RdDItemBlessure.getDefinition(this.system.gravite).labelGravite
}
static getDefinition(gravite) {
return definitionsBlessures.sort(Misc.ascending(it => it.gravite))
.find(it => it.gravite >= gravite);
}
static maxBlessures(gravite) {
return RdDItemBlessure.getDefinition(gravite).max
}
isContusion() {
return this.system.gravite <= 0
}
isLegere() {
return this.system.gravite > 0 && this.system.gravite <= 2
}
isGrave() {
return this.system.gravite > 2 && this.system.gravite <= 4
}
isCritique() {
return this.system.gravite > 4 && this.system.gravite <= 6
}
isMort() {
return this.system.gravite > 6
}
}

View File

@@ -0,0 +1,29 @@
import { RdDItemSheet } from "../item-sheet.js";
export class RdDBlessureItemSheet extends RdDItemSheet {
static get ITEM_TYPE() { return "blessure" };
async getData() {
const formData = await super.getData();
formData.disabled = formData.options.isGM || formData.options.isOwned ? '' : 'disabled';
return formData;
}
activateListeners(html) {
super.activateListeners(html);
if (!this.options.editable) return;
this.html.find('[name="premierssoins-done"]').change(async event => {
await this.item.setSoinsBlessure({ premierssoins: { done: event.currentTarget.checked } });
});
this.html.find('[name="soinscomplets-done"]').change(async event => {
await this.item.setSoinsBlessure({ soinscomplets: { done: event.currentTarget.checked } })
});
this.html.find('[name="system-gravite"]').change(async event => {
const gravite = Number(event.currentTarget.value)
await this.item.setSoinsBlessure({ gravite: gravite, difficulte: - gravite })
});
}
}

View File

@@ -416,6 +416,49 @@ class _10_5_0_UpdatePeriodicite extends Migration {
}
}
class _10_7_0_MigrationBlessures extends Migration {
get code() { return "migration-blessures"; }
get version() { return "10.7.0"; }
async migrate() {
const timestamp = game.system.rdd.calendrier.getTimestamp()
await Promise.all(game.actors.filter(it => it.isPersonnage() || it.isCreature())
.map(async (actor) => {
const legeres = actor.system.blessures?.legeres.liste.filter(it => it.active).map(it => this.creerBlessure(2, 'légère', it, timestamp)) ?? [];
const graves = actor.system.blessures?.graves.liste.filter(it => it.active).map(it => this.creerBlessure(4, 'grave', it, timestamp)) ?? [];
const critiques = actor.system.blessures?.critiques.liste.filter(it => it.active).map(it => this.creerBlessure(6, 'critique', it, timestamp));
const blessures = legeres.concat(graves).concat(critiques);
if (blessures.length > 0) {
await actor.createEmbeddedDocuments("Item", blessures);
}
await actor.update({
'system.blessures.legeres.liste': [],
'system.blessures.graves.liste': [],
'system.blessures.critiques.liste': []
})
}));
}
creerBlessure(gravite, graviteTexte, blessure, timestamp) {
const dateBlessure = timestamp.addJours(-blessure.jours);
const datePremiereRecup = dateBlessure.addJours(gravite);
return {
name: `Blessure ${graviteTexte}`,
type: 'blessure',
img: `systems/foundryvtt-reve-de-dragon/icons/sante/blessure${blessure.psdone ? '-soins' : ''}.webp`,
system: {
gravite: gravite,
difficulte: -gravite,
debut: { indexDate: dateBlessure.indexDate, indexMinute: 0 },
fin: { indexDate: datePremiereRecup.indexDate, indexMinute: 0 },
premierssoins: { done: blessure.psdone, bonus: blessure.premiers_soins },
soinscomplets: { done: blessure.scdone, bonus: blessure.soins_complets },
localisation: blessure.localisation,
jours: blessure.jours
}
}
}
}
export class Migrations {
static getMigrations() {
return [
@@ -431,6 +474,7 @@ export class Migrations {
new _10_3_17_Monnaies(),
new _10_4_6_ServicesEnCommerces(),
new _10_5_0_UpdatePeriodicite(),
new _10_7_0_MigrationBlessures(),
];
}
@@ -447,7 +491,7 @@ export class Migrations {
migrate() {
const currentVersion = game.settings.get(SYSTEM_RDD, "systemMigrationVersion");
if (isNewerVersion(game.system.version, currentVersion)) {
//if (true) { /* comment previous and uncomment here to test before upgrade */
//if (true) { /* comment previous and uncomment here to test before upgrade */
const migrations = Migrations.getMigrations().filter(m => isNewerVersion(m.version, currentVersion));
if (migrations.length > 0) {
migrations.sort((a, b) => this.compareVersions(a, b));

View File

@@ -28,7 +28,7 @@ export class RdDBonus {
}
/* -------------------------------------------- */
static dmg(rollData, dmgActor, isCauchemar = false) {
static dmg(rollData, dmgActor, isEntiteIncarnee = false) {
let dmg = { total: 0 };
if (rollData.arme && rollData.arme.name.toLowerCase() == "esquive") {
// Specific case management
@@ -41,7 +41,7 @@ export class RdDBonus {
dmg.dmgSurprise = RdDBonus.dmgBonus(rollData.ajustements?.attaqueDefenseurSurpris.used);
dmg.dmgActor = rollData.selectedCarac ? RdDBonus._dmgPerso(dmgActor, rollData.selectedCarac.label, dmg.dmgArme) : 0;
dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere;
dmg.mortalite = RdDBonus._calculMortalite(rollData, isCauchemar)
dmg.mortalite = RdDBonus._calculMortalite(rollData, isEntiteIncarnee)
}
return dmg;
}
@@ -62,11 +62,8 @@ export class RdDBonus {
}
/* -------------------------------------------- */
static _calculMortalite(rollData, isCauchemar) {
if (isCauchemar) {
return "cauchemar";
}
return isCauchemar ? "cauchemar"
static _calculMortalite(rollData, isEntiteIncarnee) {
return isEntiteIncarnee ? "entiteincarnee"
: rollData.dmg?.mortalite
?? rollData.arme?.system.mortalite
?? "mortel";

View File

@@ -45,6 +45,14 @@ export class RdDCalendrier extends Application {
Hooks.on('updateSetting', async (setting, update, options, id) => this.onUpdateSetting(setting, update, options, id));
}
display() {
let templatePath = "systems/foundryvtt-reve-de-dragon/templates/calendar-template.html";
renderTemplate(templatePath, {}).then(html => {
this.render(true);
});
return this;
}
async onUpdateSetting(setting, update, options, id) {
if (setting.key == SYSTEM_RDD + '.' + WORLD_TIMESTAMP_SETTING) {
this.timestamp = RdDTimestamp.getWorldTime();

View File

@@ -1295,13 +1295,8 @@ export class RdDCombat {
blessuresStatus: actor.computeResumeBlessure(),
SConst: actor.getSConst(),
actorId: actor.id,
isGrave: false,
isCritique: false
}
if (actor.countBlessuresNonSoigneeByName("critiques") > 0) { // Pour éviter le cumul grave + critique
formData.isCritique = true;
} else if (actor.countBlessuresNonSoigneeByName("graves") > 0) {
formData.isGrave = true;
isGrave: actor.countBlessures(it => it.isGrave()) > 0,
isCritique: actor.countBlessures(it => it.isCritique()) > 0
}
ChatUtility.createChatWithRollMode(actor.name, {

View File

@@ -332,7 +332,7 @@ export class RdDCommands {
let competence = length > 1 ? actors[0].getCompetence(Misc.join(params.slice(1, length), ' ')) : { name: undefined };
if (competence) {
for (let actor of actors) {
await actor.rollCaracCompetence(caracName, competence.name, diff);
await actor.doRollCaracCompetence(caracName, competence.name, diff);
}
}
return;

View File

@@ -36,6 +36,7 @@ import { RdDActorVehiculeSheet } from "./actor-vehicule-sheet.js";
import { RdDActorEntiteSheet } from "./actor-entite-sheet.js";
import { RdDItem } from "./item.js";
import { RdDItemBlessure } from "./item/blessure.js";
import { RdDItemService } from "./item/service.js";
import { RdDItemMaladie } from "./item/maladie.js";
import { RdDItemPoison } from "./item/poison.js";
@@ -46,6 +47,7 @@ import { RdDItemSouffle } from "./item/souffle.js";
import { RdDRencontre } from "./item/rencontre.js";
import { RdDItemSheet } from "./item-sheet.js";
import { RdDBlessureItemSheet } from "./item/sheet-blessure.js";
import { RdDServiceItemSheet } from "./item/sheet-service.js";
import { RdDRencontreItemSheet } from "./item/sheet-rencontre.js";
import { RdDHerbeItemSheet } from "./item/sheet-herbe.js";
@@ -74,21 +76,22 @@ export class SystemReveDeDragon {
this.RdDUtility = RdDUtility;
this.RdDHotbar = RdDHotbar;
this.itemClasses = {
service: RdDItemService,
blessure: RdDItemBlessure,
maladie: RdDItemMaladie,
ombre: RdDItemOmbre,
poison: RdDItemPoison,
queue: RdDItemQueue,
ombre: RdDItemOmbre,
souffle: RdDItemSouffle,
rencontre: RdDRencontre,
service: RdDItemService,
signedraconique: RdDItemSigneDraconique,
rencontre: RdDRencontre
souffle: RdDItemSouffle,
}
this.actorClasses = {
commerce: RdDCommerce,
creature: RdDActor,
entite: RdDActor,
personnage: RdDActor,
vehicule: RdDActor,
commerce: RdDCommerce,
}
}
@@ -157,6 +160,7 @@ export class SystemReveDeDragon {
RdDItemSheet.register(RdDPlanteItemSheet);
RdDItemSheet.register(RdDIngredientItemSheet);
RdDItemSheet.register(RdDServiceItemSheet);
RdDItemSheet.register(RdDBlessureItemSheet);
Items.registerSheet(SYSTEM_RDD, RdDItemInventaireSheet, {
types: [
@@ -276,8 +280,8 @@ export class SystemReveDeDragon {
let sidebar = document.getElementById("sidebar");
sidebar.style.width = "min-content";
}
if (Misc.isUniqueConnectedGM()) {
game.system.rdd.calendrier = new RdDCalendrier();
new Migrations().migrate();
}
@@ -286,13 +290,7 @@ export class SystemReveDeDragon {
RdDDice.onReady();
/* -------------------------------------------- */
/* Affiche/Init le calendrier */
let calendrier = new RdDCalendrier();
let templatePath = "systems/foundryvtt-reve-de-dragon/templates/calendar-template.html";
let templateData = {};
renderTemplate(templatePath, templateData).then(html => {
calendrier.render(true);
});
game.system.rdd.calendrier = calendrier; // Reference;
game.system.rdd.calendrier = new RdDCalendrier().display();
// Avertissement si joueur sans personnage
if (!game.user.isGM && game.user.character == undefined) {

View File

@@ -30,9 +30,9 @@ export class RdDEncaisser extends Dialog {
};
}
else if (actor.isEntite([ENTITE_BLURETTE, ENTITE_INCARNE])) {
dialogConf.default = "cauchemar"
dialogConf.default = "entiteincarnee"
dialogConf.buttons = {
"cauchemar": { label: "Cauchemar", callback: html => this.performEncaisser("cauchemar") }
"entiteincarnee": { label: "Entité incarnée", callback: html => this.performEncaisser("entiteincarnee") }
}
}
@@ -70,7 +70,6 @@ export class RdDEncaisser extends Dialog {
total: Number(this.modifier),
ajustement: Number(this.modifier),
encaisserSpecial: this.encaisserSpecial,
loc: { result: 0, label: "" },
mortalite: mortalite
}
});

View File

@@ -7,15 +7,16 @@ export class RdDSheetUtility {
const userRightLevel = game.user.isGM
? CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER
: document.getUserLevel(game.user);
mergeObject(options, {
let newOptions = {
isGM: game.user.isGM,
isOwned: document.parent,
isOwned: document.parent ? true : false,
editable: editable,
cssClass: editable ? "editable" : "locked",
isLimited: userRightLevel >= CONST.DOCUMENT_OWNERSHIP_LEVELS.LIMITED,
isObserver: userRightLevel >= CONST.DOCUMENT_OWNERSHIP_LEVELS.OBSERVER,
isOwner: userRightLevel >= CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER
});
}
mergeObject(options, newOptions);
return options;
}

View File

@@ -252,7 +252,7 @@ export class RdDTimestamp {
get heure() { return Math.floor(this.indexMinute / RDD_MINUTES_PAR_HEURES) }
get minute() { return this.indexMinute % RDD_MINUTES_PAR_HEURES }
get round() { return ROUNDS_PAR_MINUTE * (this.indexMinute - Math.floor(this.indexMinute)) }
get angleHeure() { return this.indexMinute / RDD_MINUTES_PAR_JOUR * 360 - 60 }
get angleHeure() { return this.indexMinute / RDD_MINUTES_PAR_JOUR * 360 - 45 }
get angleMinute() { return this.indexMinute / RDD_MINUTES_PAR_HEURES * 360 + 45}
formatDate() {

View File

@@ -2,6 +2,7 @@
import { HtmlUtility } from "./html-utility.js";
import { Misc } from "./misc.js";
import { RdDCombatManager } from "./rdd-combat.js";
import { Targets } from "./targets.js";
/* -------------------------------------------- */
export class RdDTokenHud {
@@ -18,29 +19,39 @@ export class RdDTokenHud {
}
/* -------------------------------------------- */
static async addExtensionHud(app, html, tokenId) {
static async addExtensionHud(app, html, tokenId, isCombat) {
let token = canvas.tokens.get(tokenId);
let actor = token.actor;
let combatant = game.combat.combatants.find(c => c.tokenId == tokenId);
if (! (combatant?.actor) ) {
app.hasExtension = true;
// soins
await RdDTokenHud.addExtensionHudSoins(html, actor);
if (isCombat) {
let combatant = game.combat.combatants.find(c => c.tokenId == tokenId);
if (!(combatant?.actor)) {
ui.notifications.warn(`Le combatant ${token.name} n'est pas associé à un acteur, impossible de déterminer ses actions de combat!`)
return;
}
let actions = RdDCombatManager.listActionsCombat(combatant);
// initiative
await RdDTokenHud.addExtensionHudInit(html, combatant, actions);
// combat
await RdDTokenHud.addExtensionHudCombat(html, combatant, actions);
}
app.hasExtension = true;
let actionsCombat = RdDCombatManager.listActionsCombat(combatant);
}
static async addExtensionHudInit(html, combatant, actions) {
const hudData = {
combatant: combatant,
actions: actionsCombat,
combatant, actions,
commandes: [
{ name: "Autre action", command: 'autre' },
{ name: 'Initiative +1', command: 'inc', value: 0.01 },
{ name: 'Initiative +1', command: 'inc', value: 0.01 },
{ name: 'Initiative -1', command: 'dec', value: -0.01 }]
};
const controlIconCombat = html.find('.control-icon[data-action=combat]');
// initiative
await RdDTokenHud._configureSubMenu(controlIconCombat,
'systems/foundryvtt-reve-de-dragon/templates/hud-actor-init.html',
hudData,
@@ -51,48 +62,70 @@ export class RdDTokenHud {
RdDTokenHud._initiativeCommand(initCommand, combatantId);
} else {
let index = event.currentTarget.attributes['data-action-index'].value;
let action = actionsCombat[index];
let action = hudData.actions[index];
RdDCombatManager.rollInitiativeAction(combatantId, action);
}
}
});
}
static async addExtensionHudCombat(html, combatant, actions) {
const hudData = { combatant, actions, commandes: [] };
const controlIconTarget = html.find('.control-icon[data-action=target]');
// combat
await RdDTokenHud._configureSubMenu(controlIconTarget, 'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.html', hudData,
(event) => {
const actionIndex = event.currentTarget.attributes['data-action-index']?.value;
const action = actionsCombat[actionIndex];
const action = hudData.actions[actionIndex];
if (action.action == 'conjurer') {
actor.conjurerPossession(actor.getPossession(action.system.possessionid));
const possession = combatant.actor.getPossession(action.system.possessionid);
combatant.actor.conjurerPossession(possession);
}
else {
actor.rollArme(action);
combatant.actor.rollArme(action);
}
});
}
static async addExtensionHudSoins(html, sourceActor) {
const target = Targets.getTarget({ warn: false });
if (target?.actor) {
const hudSoins = { blessures: target.actor.blessuresASoigner() ?? [] };
if (hudSoins.blessures.length > 0) {
// soins
const controlIconTarget = html.find('.control-icon[data-action=combat]');
await RdDTokenHud._configureSubMenu(controlIconTarget,
'systems/foundryvtt-reve-de-dragon/templates/hud-actor-soins.hbs',
hudSoins,
(event) => {
const blessureId = event.currentTarget.attributes['data-blessure-id']?.value;
sourceActor.rollSoins(target.actor, blessureId)
});
}
}
}
static _initiativeCommand(initCommand, combatantId) {
switch (initCommand) {
case 'inc': return RdDCombatManager.incDecInit(combatantId, 0.01);
case 'dec': return RdDCombatManager.incDecInit(combatantId, -0.01);
case 'autre': return RdDCombatManager.rollInitiativeAction(combatantId,
case 'autre': return RdDCombatManager.rollInitiativeAction(combatantId,
{ name: "Autre action", action: 'autre', system: { initOnly: true, competence: "Autre action" } });
}
}
/* -------------------------------------------- */
static async addTokenHudExtensions(app, html, tokenId) {
const controlIconCombat = html.find('.control-icon[data-action=combat]');
controlIconCombat.click(event => {
if (event.currentTarget.className.includes('active')) {
RdDTokenHud.removeExtensionHud(app, html, tokenId);
} else {
setTimeout(function () { RdDTokenHud.addExtensionHud(app, html, tokenId) }, 200);
}
});
const controlIconCombat = html.find('.control-icon[data-action=combat]');
if (controlIconCombat.length > 0) {
controlIconCombat.click(event => {
if (event.currentTarget.className.includes('active')) {
RdDTokenHud.removeExtensionHud(app, html, tokenId);
} else {
setTimeout(() => RdDTokenHud.addExtensionHud(app, html, tokenId), 200);
}
});
if (controlIconCombat.length>0 && controlIconCombat[0].className.includes('active')) {
RdDTokenHud.addExtensionHud(app, html, tokenId);
const isCombat = controlIconCombat[0].className.includes('active');
RdDTokenHud.addExtensionHud(app, html, tokenId, isCombat);
}
}
@@ -100,9 +133,9 @@ export class RdDTokenHud {
static async _configureSubMenu(insertionPoint, template, hudData, onMenuItem) {
const hud = $(await renderTemplate(template, hudData));
const list = hud.find('div.rdd-hud-list');
RdDTokenHud._toggleHudListActive(hud, list);
hud.find('img.rdd-hud-togglebutton').click(event => RdDTokenHud._toggleHudListActive(hud, list));
list.find('.rdd-hud-menu').click(onMenuItem);

View File

@@ -19,7 +19,7 @@ import { RdDRaretes } from "./item/raretes.js";
/* -------------------------------------------- */
// This table starts at 0 -> niveau -10
const carac_array = ["taille", "apparence", "constitution", "force", "agilite", "dexterite", "vue", "ouie", "odoratgout", "volonte", "intellect", "empathie", "reve", "chance", "melee", "tir", "lancer", "derobee"];
const difficultesLibres = Misc.intArray(0, -11);
const difficultesLibres = Misc.intArray(0, -11);
const ajustementsConditions = Misc.intArray(-10, 11);
const ajustementsEncaissement = Misc.intArray(-10, 26);
@@ -66,38 +66,31 @@ const fatigueMarche = {
"tresdifficile": { "4": 4, "6": 6 }
}
/* -------------------------------------------- */
const definitionsBlessures = [
{ type: "legere", facteur: 2 },
{ type: "grave", facteur: 4 },
{ type: "critique", facteur: 6 }
]
/* -------------------------------------------- */
const nomEthylisme = ["Emeché", "Gris", "Pinté", "Pas frais", "Ivre", "Bu", "Complètement fait", "Ivre mort"];
/* -------------------------------------------- */
const definitionsEncaissement = {
"mortel": [
{ minimum: undefined, maximum: 0, endurance: "0", vie: "0", eraflures: 0, legeres: 0, graves: 0, critiques: 0 },
{ minimum: 1, maximum: 10, endurance: "1d4", vie: "0", eraflures: 1, legeres: 0, graves: 0, critiques: 0 },
{ minimum: 11, maximum: 15, endurance: "1d6", vie: "0", eraflures: 0, legeres: 1, graves: 0, critiques: 0 },
{ minimum: 16, maximum: 19, endurance: "2d6", vie: "2", eraflures: 0, legeres: 0, graves: 1, critiques: 0 },
{ minimum: 20, maximum: undefined, endurance: "100", vie: "4 + @over20", eraflures: 0, legeres: 0, graves: 0, critiques: 1 },
{ minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1},
{ minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0},
{ minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 2},
{ minimum: 16, maximum: 19, endurance: "2d6", vie: "2", gravite: 4},
{ minimum: 20, maximum: undefined, endurance: "100", vie: "4 + @over20", gravite: 6},
],
"non-mortel": [
{ minimum: undefined, maximum: 0, endurance: "0", vie: "0", eraflures: 0, legeres: 0, graves: 0, critiques: 0 },
{ minimum: 1, maximum: 10, endurance: "1d4", vie: "0", eraflures: 1, legeres: 0, graves: 0, critiques: 0 },
{ minimum: 11, maximum: 15, endurance: "1d6", vie: "0", eraflures: 1, legeres: 0, graves: 0, critiques: 0 },
{ minimum: 16, maximum: 19, endurance: "2d6", vie: "0", eraflures: 0, legeres: 1, graves: 0, critiques: 0 },
{ minimum: 20, maximum: undefined, endurance: "100", vie: "0", eraflures: 0, legeres: 1, graves: 0, critiques: 0 },
{ minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1},
{ minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0 },
{ minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 0 },
{ minimum: 16, maximum: 19, endurance: "2d6", vie: "0", gravite: 2 },
{ minimum: 20, maximum: undefined, endurance: "100", vie: "0", gravite: 2 },
],
"cauchemar": [
{ minimum: undefined, maximum: 0, endurance: "0", vie: "0", eraflures: 0, legeres: 0, graves: 0, critiques: 0 },
{ minimum: 1, maximum: 10, endurance: "1d4", vie: "0", eraflures: 1, legeres: 0, graves: 0, critiques: 0 },
{ minimum: 11, maximum: 15, endurance: "1d6", vie: "0", eraflures: 1, legeres: 0, graves: 0, critiques: 0 },
{ minimum: 16, maximum: 19, endurance: "2d6", vie: "0", eraflures: 1, legeres: 0, graves: 0, critiques: 0 },
{ minimum: 20, maximum: undefined, endurance: "3d6 + @over20", vie: "0", eraflures: 1, legeres: 0, graves: 0, critiques: 0 },
"entiteincarnee": [
{ minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1},
{ minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0},
{ minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 0 },
{ minimum: 16, maximum: 19, endurance: "2d6", vie: "0", gravite: 0 },
{ minimum: 20, maximum: undefined, endurance: "3d6 + @over20", vie: "0", gravite: 0 },
]
};
@@ -139,7 +132,7 @@ export class RdDUtility {
'systems/foundryvtt-reve-de-dragon/templates/actor/xp-competences.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/combat.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/blessures.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/blessure.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/blessure.hbs',
'systems/foundryvtt-reve-de-dragon/templates/actor/maladies-poisons.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/possessions.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/taches.html',
@@ -276,7 +269,8 @@ export class RdDUtility {
Handlebars.registerHelper('computeResolutionChances', (row, col) => RdDResolutionTable.computeChances(row, col));
Handlebars.registerHelper('upperFirst', str => Misc.upperFirst(str ?? 'Null'));
Handlebars.registerHelper('lowerFirst', str => Misc.lowerFirst(str ?? 'Null'));
Handlebars.registerHelper('upper', str => str?.toUpperCase() ?? 'NULL');
Handlebars.registerHelper('upper', str => str?.toUpperCase() ?? '');
Handlebars.registerHelper('lowercase', str => str?.toLowerCase() ?? '');
Handlebars.registerHelper('le', str => Grammar.articleDetermine(str));
Handlebars.registerHelper('apostrophe', (article, str) => Grammar.apostrophe(article, str));
Handlebars.registerHelper('un', str => Grammar.articleIndetermine(str));
@@ -472,10 +466,6 @@ export class RdDUtility {
return ajustementsEncaissement;
}
static getDefinitionsBlessures() {
return definitionsBlessures;
}
/* -------------------------------------------- */
static getSegmentsFatigue(maxEnd) {
maxEnd = Math.max(maxEnd, 1);
@@ -616,17 +606,10 @@ export class RdDUtility {
encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;';
encaissement.roll = roll;
encaissement.armure = armure;
encaissement.penetration = rollData.arme?.system.penetration ?? 0;
encaissement.total = jetTotal;
encaissement.vie = await RdDUtility._evaluatePerte(encaissement.vie, over20);
encaissement.endurance = await RdDUtility._evaluatePerte(encaissement.endurance, over20);
encaissement.penetration = rollData.arme?.system.penetration ?? 0;
encaissement.blessures = (
encaissement.critiques > 0 ? "Critique" :
encaissement.graves > 0 ? "Grave" :
encaissement.legeres > 0 ? "Légère" :
encaissement.eraflures > 0 ? "Contusions/Eraflures" :
'Aucune'
);
return encaissement;
}

View File

@@ -39,18 +39,18 @@ export class Targets {
}
}
static getTarget() {
static getTarget(options = { warn: true }) {
const targets = Targets.listTargets();
switch (targets.length) {
case 1:
return targets[0];
case 0:
ui.notifications.warn("Vous devez choisir une cible à attaquer!");
if (options.warn) ui.notifications.warn("Vous devez choisir une cible à attaquer!");
break;
default:
ui.notifications.warn("Vous devez choisir une cible (et <strong>une seule</strong>) à attaquer!");
return;
if (options.warn) ui.notifications.warn("Vous devez choisir une cible (et <strong>une seule</strong>) à attaquer!");
}
return undefined;
}
}

View File

@@ -186,7 +186,7 @@ i:is(.fas, .far) {
}
.system-foundryvtt-reve-de-dragon .sheet-header :is(.header-compteurs,.header-etats,.profile-img, .profile-img-token){
padding: 0 3%;
padding: 0 0.4rem;
}
.system-foundryvtt-reve-de-dragon .sheet-header :is(.profile-img, .profile-img-token) {
@@ -213,11 +213,13 @@ i:is(.fas, .far) {
}
.system-foundryvtt-reve-de-dragon .sheet-header .header-compteurs {
width: calc(60% - 110px - 1rem);
text-align: right;
max-width: fit-content;
}
.system-foundryvtt-reve-de-dragon .sheet-header div.header-etats {
width: calc(40% - 32px - 1rem);
height: 48px;
max-width: fit-content;
flex: initial;
@@ -426,6 +428,7 @@ span.equipement-detail-buttons {
justify-content: center;
text-align: left;
}
.blessure-control {
flex-grow: 1;
flex-direction: row;
@@ -457,14 +460,17 @@ input:is(.blessure-premiers_soins, .blessure-soins_complets) {
.blessure-inactive {
color:rgba(150, 150, 150, 0.4);
}
.blessure-active-2,
.blessure-active-legere {
color:rgba(60, 60, 60, 0.9);
text-shadow: 1px 1px 4px rgba(60, 60, 60, 1);
}
.blessure-active-4,
.blessure-active-grave {
color: rgba(218, 126, 21, 0.9);
text-shadow: 1px 1px 4px rgba(60, 60, 60, 1);
}
.blessure-active-6,
.blessure-active-critique {
color: rgba(173, 36, 26, 0.9);
text-shadow: 1px 1px 4px rgba(60, 60, 60, 1);
@@ -1386,27 +1392,36 @@ table.table-nombres-astraux tr:hover {
}
/* ======================================== */
.tokenhudext {
.token-hud-ext {
display: flex;
flex: 0 !important;
font-family: CaslonPro;
font-weight: 600;
}
.tokenhudext.left {
.token-hud-ext.left {
justify-content: flex-start;
flex-direction: column;
position: absolute;
top: 2.75rem;
right: 4rem;
}
.tokenhudext.right {
.token-hud-ext.soins {
justify-content: flex-start;
flex-direction: column;
position: absolute;
top: 13.2rem;
left: -5rem;
max-width: 8.5rem
}
.token-hud-ext.right {
justify-content: flex-start;
flex-direction: column;
position: absolute;
top: 2.75rem;
left: 4rem;
}
.control-icon.tokenhudicon {
.control-icon.token-hud-icon {
width: fit-content;
height: fit-content;
min-width: 6rem;
@@ -1415,7 +1430,7 @@ table.table-nombres-astraux tr:hover {
line-height: 1rem;
margin: 0.2rem;
}
.control-icon.tokenhudicon.right {
.control-icon.token-hud-icon.right {
margin-left: 8px;
}
.rdd-hud-menu label {

View File

@@ -1,8 +1,8 @@
{
"id": "foundryvtt-reve-de-dragon",
"title": "Rêve de Dragon",
"version": "10.6.24",
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.6.24.zip",
"version": "10.7.3",
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.7.3.zip",
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v10/system.json",
"compatibility": {
"minimum": "10",
@@ -379,4 +379,4 @@
"flags": {}
}
]
}
}

View File

@@ -179,23 +179,8 @@
"value": 10,
"label": "Endurance",
"derivee": false
}
},
"blessures": {
"legeres": {
"liste": [ { "active": false, "psdone": false, "premiers_soins": -1, "scdone": false, "soins_complets": -1, "jours": 0, "localisation": "" },
{ "active": false, "psdone": false, "premiers_soins": -1, "scdone": false, "soins_complets": -1, "jours": 0, "localisation": "" },
{ "active": false, "psdone": false, "premiers_soins": -1, "scdone": false, "soins_complets": -1, "jours": 0, "localisation": "" },
{ "active": false, "psdone": false, "premiers_soins": -1, "scdone": false, "soins_complets": -1, "jours": 0, "localisation": "" },
{ "active": false, "psdone": false, "premiers_soins": -1, "scdone": false, "soins_complets": -1, "jours": 0, "localisation": "" } ]
},
"graves": {
"liste": [ { "active": false, "psdone": false, "premiers_soins": -1, "scdone": false, "soins_complets": -1, "jours": 0, "localisation": "" },
{ "active": false, "psdone": false, "premiers_soins": -1, "scdone": false, "soins_complets": -1, "jours": 0, "localisation": "" } ]
},
"critiques": {
"liste": [ { "active": false, "psdone": false, "premiers_soins": -1, "scdone": false, "soins_complets": -1, "jours": 0, "localisation": "" } ]
}
"bonusPotion": 0
},
"attributs": {
"plusdom": {
@@ -380,23 +365,8 @@
"value": 0,
"label": "Fatigue",
"derivee": true
}
},
"blessures": {
"legeres": {
"liste": [ { "active": false, "premiers_soins": 0, "soins_complets": 0, "jours": 0, "localisation": "" },
{ "active": false, "premiers_soins": 0, "soins_complets": 0, "jours": 0, "localisation": "" },
{ "active": false, "premiers_soins": 0, "soins_complets": 0, "jours": 0, "localisation": "" },
{ "active": false, "premiers_soins": 0, "soins_complets": 0, "jours": 0, "localisation": "" },
{ "active": false, "premiers_soins": 0, "soins_complets": 0, "jours": 0, "localisation": "" } ]
},
"graves": {
"liste": [ { "active": false, "premiers_soins": 0, "soins_complets": 0, "jours": 0, "localisation": "" },
{ "active": false, "premiers_soins": 0, "soins_complets": 0, "jours": 0, "localisation": "" } ]
},
"critiques": {
"liste": [ { "active": false, "premiers_soins": 0, "soins_complets": 0, "jours": 0, "localisation": "" } ]
}
"bonusPotion": 0
},
"attributs": {
"sconst": {
@@ -567,7 +537,7 @@
"monnaie", "nourritureboisson", "gemme",
"service",
"meditation", "rencontre", "queue", "ombre", "souffle", "tete", "casetmr", "signedraconique", "sort", "sortreserve",
"nombreastral", "tache", "maladie", "poison", "possession",
"nombreastral", "tache", "blessure", "maladie", "poison", "possession",
"tarot", "extraitpoetique"
],
"templates": {
@@ -636,6 +606,22 @@
"compteur": 0,
"date": 0
},
"blessure": {
"templates": ["temporel"],
"gravite": 0,
"difficulte": 0,
"premierssoins": {
"tache": 0,
"done": false,
"bonus": 0
},
"soinscomplets": {
"done": false,
"bonus": 0
},
"localisation": "",
"jours": 0
},
"maladie": {
"templates": ["description", "temporel"],
"identifie": false,
@@ -833,7 +819,8 @@
"points_de_tache_courant": 0,
"nb_jet_echec": 0,
"nb_jet_succes": 0,
"cacher_points_de_tache": false
"cacher_points_de_tache": false,
"itemId": ""
},
"sort": {
"templates": ["description"],

View File

@@ -0,0 +1,40 @@
<li class="item item-blessure flexrow list-item blessure-active-{{lowercase system.labelGravite}}" data-item-id="{{id}}">
<span class="blessure-control">
<img class="sheet-competence-img" src="{{img}}" />
<i class="fas fa-skull-crossbones"></i>
{{system.labelGravite}}
</span>
{{#if (gt system.gravite 6)}}
<span class="flexrow"></span>
<span class="flexrow"></span>
{{else}}
<span class="flexrow">
<input type="checkbox" class="blessure-premierssoins-done" name="blessure.{{id}}.premierssoins.done" {{#if system.premierssoins.done}}checked{{/if}}/>
{{#if system.premierssoins.done}}
{{#unless system.soinscomplets.done}}
<input type="text" class="blessure-premierssoins-bonus number-x2" name="blessure.{{id}}.premierssoins.bonus" data-dtype="number" value="{{system.premierssoins.bonus}}"/>
{{/unless}}
{{else}}
<label>{{system.premierssoins.tache}} / {{system.gravite}}</label>
{{/if}}
</span>
<span class="flexrow">
{{#if system.premierssoins.done}}
<input type="checkbox" class="blessure-soinscomplets-done" name="blessure.{{id}}.system.soinscomplets.done" {{#if system.soinscomplets.done}}checked{{/if}}/>
{{#if system.soinscomplets.done}}
<input type="text" class="blessure-soinscomplets-bonus number-x2" name="blessure.{{id}}.system.soinscomplets.bonus" data-dtype="number" value="{{system.soinscomplets.bonus}}"/>
{{/if}}
{{else}}
<label>Difficulté {{system.difficulte}}</label>
{{/if}}
</span>
{{/if}}
<span>
{{system.localisation}}
</span>
<span class="item-controls">
<a class="item-edit" title="Editer"><i class="fas fa-edit"></i></a>
<a class="item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
<a class="item-montrer" title="Montrer"><i class="fas fa-comment"></i></a>
</span>
</li>

View File

@@ -1,27 +0,0 @@
<li class="item flexrow list-item {{#if blessure.active}}blessure-active-{{gravite}}{{else}}blessure-inactive{{/if}}"
data-blessure-type="{{gravite}}"
data-attribute={{key}}
data-blessure-index="{{key}}"
data-blessure-active="{{blessure.active}}">
<span class="blessure-control" title="Blessure {{title}}">
<i class="fas fa-skull-crossbones" name="blessure-{{gravite}}-{{key}}-active"></i>
{{title}}
</span>
{{#if blessure.active}}
<span class="blessure-soins flexrow">
<input class="blessure-psdone" name="blessure-{{gravite}}-{{key}}-psdone" type="checkbox" name="blessure.psdone" {{#if blessure.psdone}}checked{{/if}}/>
<input class="blessure-premiers_soins" type="text" name="blessure-{{gravite}}-{{key}}-premiers_soins" data-dtype="number" value="{{blessure.premiers_soins}}"/>
</span>
<span class="blessure-soins flexrow">
<input class="blessure-scdone" name="blessure-{{gravite}}-{{key}}-scdone" type="checkbox" name="blessure.scdone" {{#if blessure.scdone}}checked{{/if}}/>
<input class="blessure-soins_complets" type="text" name="blessure-{{gravite}}-{{key}}-soins_complets" data-dtype="number" value="{{blessure.soins_complets}}"/>
</span>
<input class="blessure-jours" type="text" name="blessure-{{gravite}}-{{key}}-jours" name="jours" data-dtype="number" value="{{blessure.jours}}"/>
<input class="blessure-localisation" type="text" name="blessure-{{gravite}}-{{key}}-localisation" data-dtype="String" value="{{blessure.loc}}"/>
{{else}}
<span></span>
<span></span>
<span></span>
<span></span>
{{/if}}
</li>

View File

@@ -1,18 +1,20 @@
<h4>blessures</h4>
<div>
<a class="chat-card-button creer-blessure-legere"><i class="fas fa-plus-circle"></i> légère</a>
<a class="chat-card-button creer-blessure-grave"><i class="fas fa-plus-circle"></i> grave</a>
<a class="chat-card-button creer-blessure-critique"><i class="fas fa-plus-circle"></i> critique</a>
</div>
<ul class="item-list alterne-list">
<li class="competence-header flexrow" >
<span>Blessures</span>
<span></span>
<span>Premiers soins</span>
<span>Soins complets</span>
<span>Age (jours)</span>
<span>Localisation</span>
<span>Loc.</span>
<span>Actions</span>
</li>
{{#each system.blessures.legeres.liste as |blessure key|}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/blessure.html" blessure=blessure key=key gravite="legere" title="Légère"}}
{{/each}}
{{#each system.blessures.graves.liste as |blessure key|}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/blessure.html" blessure=blessure key=key gravite="grave" title="Grave"}}
{{/each}}
{{#each system.blessures.critiques.liste as |blessure key|}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/blessure.html" blessure=blessure key=key gravite="critique" title="Critique"}}
{{#each blessures as |blessure|}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/blessure.hbs" blessure}}
{{/each}}
</ul>

View File

@@ -1,7 +1,9 @@
<h4>Soins</h4>
<a class="chat-card-button creer-tache-blessure-legere">Blessure légère</a>
<a class="chat-card-button creer-tache-blessure-grave">Blessure grave</a>
<a class="chat-card-button creer-tache-blessure-critique">Blessure critique</a>
<div>
<a class="chat-card-button creer-tache-blessure-legere"><i class="fas fa-first-aid"></i> légère</a>
<a class="chat-card-button creer-tache-blessure-grave"><i class="fas fa-first-aid"></i> grave</a>
<a class="chat-card-button creer-tache-blessure-critique"><i class="fas fa-first-aid"></i> critique</a>
</div>
<ul class="item-list alterne-list">
{{#each taches as |tache id|}}
{{#if (eq tache.system.competence 'Chirurgie')}}

View File

@@ -1,4 +1,4 @@
<span>
<div>
{{#if effects}}
{{#each effects as |effect key|}}
<span class="active-effect" data-effect="{{effect.flags.core.statusId}}">
@@ -9,4 +9,4 @@
{{else}}
Aucun effet actif
{{/if}}
</span>
</div>

View File

@@ -1,8 +1,8 @@
<div class="flex-group-left header-etats">
<div class="flexcol">
<span>{{system.compteurs.etat.label}}: {{system.compteurs.etat.value}}</span>
<span>Sur-encombrement: {{calc.surenc}}</span>
<span>{{calc.resumeBlessures}}</span>
<div>{{system.compteurs.etat.label}}: {{system.compteurs.etat.value}}</div>
<div>Sur-encombrement: {{calc.surenc}}</div>
<div>{{calc.resumeBlessures}}</div>
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/header-effects.html"}}
</div>
</div>

View File

@@ -1,17 +1,18 @@
{{#if isGM}}
{{log this}}
<span>
{{#if (gt endurance 0)}}
De plus, {{alias}} a perdu {{endurance}} points d'endurance
{{#if (ne vie 0)}}et <span class="rdd-roll-echec">{{vie}} points de vie</span>{{/if}}
{{/if}}
{{#if (gt endurance 1)}}Jet d'endurance : {{jetEndurance}} / {{resteEndurance}} {{/if}}
{{#if (and jetEndurance (gt endurance 1))}}Jet d'endurance : {{jetEndurance}} / {{resteEndurance}} {{/if}}
</span>
{{else}}
<h4>{{alias}} encaisse à
<span>
{{numberFormat dmg.total decimals=0 sign=true}}
{{#if (eq dmg.mortalite 'non-mortel')~}}(coups non mortels)
{{~else if (eq dmg.mortalite 'cauchemar')}}(entité de cauchemar)
{{~else if (eq dmg.mortalite 'entiteincarnee')}}(entité incarnée)
{{~/if}}
</span>
</h4>
@@ -22,15 +23,16 @@
{{~/unless}}, total: <span class="rdd-roll-echec">{{total}}</span>
<br>
{{alias}}
{{#if (eq dmg.mortalite 'cauchemar')}}subit le coup
{{else if eraflures}}subit une contusion
{{else if legeres}}subit une blessure légère
{{else if graves}}subit une blessure grave
{{else if critiques}}subit une blessure critique
{{#if (eq dmg.mortalite 'entiteincarnee')}}subit le coup
{{else if mort}}vient de mourir
{{else if blessure}}
{{#if (gt blessure.system.gravite 0)}}subit une blessure {{blessure.system.labelGravite}}
{{else}}subit une contusion
{{~/if~}}
{{else}}s'en sort sans une égratignure
{{~/if~}}
{{~#unless (eq dmg.mortalite 'cauchemar')}}
{{~#unless (eq dmg.mortalite 'entiteincarnee')}}
{{#if dmg.loc.label}}
{{#if (gt roll.total 0)}}({{dmg.loc.label}}){{/if}}
{{/if}}
@@ -39,7 +41,7 @@
{{~#if hasPlayerOwner}}, a perdu {{endurance}} points d'endurance
{{#if (ne vie 0)}}, <span class="rdd-roll-echec">{{vie}} points de vie</span>{{/if}}
{{/if}}
{{#if (ne dmg.mortalite 'cauchemar')}}
{{#if (ne dmg.mortalite 'entiteincarnee')}}
{{#if (gt endurance 1)}}et
{{#if sonne}}est <strong>sonné</strong><img class="chat-icon" src="icons/svg/stoned.svg" alt="charge" height="16" width="16" /> jusqu'à la fin du prochain round{{else}}n'est pas sonné{{/if}}!
{{#if hasPlayerOwner}}Jet d'endurance : Jet d'endurance : {{jetEndurance}} / {{resteEndurance}}{{/if}}

View File

@@ -1,9 +1,9 @@
<div class="control-icon rdd-combat ">
<img class="rdd-hud-togglebutton" src="systems/foundryvtt-reve-de-dragon/icons/heures/hd06.svg" width="36" height="36" title="Attaque"/>
<div class="rdd-hud-list tokenhudext left">
<div class="rdd-hud-list token-hud-ext left">
{{#each actions as |action key|}}
{{#unless action.system.initOnly}}
<div class="control-icon tokenhudicon rdd-hud-menu rdd-attaque"
<div class="control-icon token-hud-icon rdd-hud-menu rdd-attaque"
data-combatant-id="{{../combatant.id}}"
data-action-index="{{action.index}}"
title="{{action.name}}">

View File

@@ -1,8 +1,8 @@
<div class="control-icon rdd-initiative ">
<img class="rdd-hud-togglebutton" src="icons/svg/sword.svg" width="36" height="36" title="Initiative" />
<div class="rdd-hud-list tokenhudext right">
<div class="rdd-hud-list token-hud-ext right">
{{#each actions as |action key|}}
<div class="control-icon tokenhudicon rdd-hud-menu"
<div class="control-icon token-hud-icon rdd-hud-menu"
data-combatant-id="{{../combatant.id}}"
data-action-index="{{action.index}}"
title="{{action.name}}">
@@ -10,7 +10,7 @@
</div>
{{/each}}
{{#each commandes as |commande key|}}
<div class="control-icon tokenhudicon rdd-hud-menu"
<div class="control-icon token-hud-icon rdd-hud-menu"
data-command="{{commande.command}}"
data-combatant-id="{{../combatant.id}}"
data-action-index="{{commande.index}}"

View File

@@ -0,0 +1,12 @@
<div class="control-icon rdd-soins ">
<img class="rdd-hud-togglebutton" src="icons/svg/regen.svg" width="36" height="36" title="Soins" />
<div class="rdd-hud-list token-hud-ext soins">
{{#each blessures as |blessure|}}
<div class="control-icon token-hud-icon rdd-hud-menu"
data-blessure-id="{{blessure.id}}"
title="{{blessure.name}}">
<label>Soigner: {{blessure.name}}</label>
</div>
{{/each}}
</div>
</div>

View File

@@ -0,0 +1,57 @@
<form class="{{cssClass}}" autocomplete="off">
{{>"systems/foundryvtt-reve-de-dragon/templates/header-item.html"}}
<section class="sheet-body">
<div class="form-group">
<label for="system-gravite">Gravité</label>
<select name="system-gravite" class="gravite" data-dtype="Number">
{{#select system.gravite}}
<option value="0">Contusion / Eraflure</option>
<option value="2">Légère</option>
<option value="4">Grave</option>
<option value="6">Critique</option>
<option value="8">Mort</option>
{{/select}}
</select>
</div>
<div class="form-group">
<label for="system.localisation">Localisation</label>
<input class="attribute-value" type="text" name="system.localisation" value="{{system.localisation}}" data-dtype="String"/>
</div>
{{#if (lt system.gravite 7)}}
<div class="form-group">
<label for="system.difficulte">Difficulté des soins</label>
<input class="attribute-value number-x" type="text" name="system.difficulte" value="{{system.difficulte}}" data-dtype="Number"/>
</div>
<div class="form-group">
<label for="premierssoins-done">Premiers soins
<input class="attribute-value" type="checkbox" name="premierssoins-done" {{#if system.premierssoins.done}}checked{{/if}}/>
</label>
{{#if system.premierssoins.done}}
{{#unless system.soinscomplets.done}}
<input class="attribute-value number-x" type="text" name="system.premierssoins.bonus" value="{{system.premierssoins.bonus}}" data-dtype="Number"/>
{{/unless}}
{{else}}
<label for="system.premierssoins.tache">Points de tâches</label>
<input class="attribute-value number-x" type="text" name="system.premierssoins.tache" value="{{system.premierssoins.tache}}" data-dtype="Number"/>
{{/if}}
</div>
{{#if system.premierssoins.done}}
<div class="form-group">
<label for="soinscomplets-done">Soins complets
<input class="attribute-value" type="checkbox" name="soinscomplets-done" {{#if system.soinscomplets.done}}checked{{/if}}/>
</label>
{{#if system.soinscomplets.done}}
<input class="attribute-value number-x" type="text" name="system.soinscomplets.bonus" value="{{system.soinscomplets.bonus}}" data-dtype="Number"/>
{{/if}}
</div>
{{/if}}
{{/if}}
{{#if options.isOwned}}
{{>"systems/foundryvtt-reve-de-dragon/templates/item/temporel.hbs" this labeldebut="Obtenue" labelfin="Prochain jet"}}
{{/if}}
</section>
</form>