Compare commits
258 Commits
foundryvtt
...
foundryvtt
| Author | SHA1 | Date | |
|---|---|---|---|
| c04b179176 | |||
|
|
63770790b9 | ||
|
|
aefc7a434b | ||
|
|
f02959adee | ||
|
|
e652027b02 | ||
|
|
2122a54db7 | ||
| f027e3318b | |||
|
|
31b4d1cfcc | ||
|
|
5056c35038 | ||
|
|
7b58407634 | ||
|
|
7efa7be1c0 | ||
|
|
717bb6fc6e | ||
| 51273bcc3e | |||
|
|
b8f3a9af27 | ||
|
|
ab704c46d2 | ||
|
|
db8fd6dbf8 | ||
|
|
d998a4cb08 | ||
|
|
b1e27a9597 | ||
| eaac9564b4 | |||
|
|
0826c7e9e3 | ||
|
|
bdd3802e72 | ||
|
|
b07cea40e2 | ||
|
|
bb7f4c42ad | ||
|
|
ac15a022df | ||
| a43c725b06 | |||
|
|
1276c64835 | ||
|
|
4b4d778d9c | ||
|
|
86f9c37b30 | ||
|
|
ac77c6da9e | ||
| 344540ea8e | |||
|
|
8a5cf3cb09 | ||
|
|
3a29570bae | ||
|
|
02c48f4796 | ||
| ee01878fae | |||
| 2e1005e909 | |||
|
|
98c016696d | ||
|
|
e67ac96e93 | ||
|
|
979a48e4d9 | ||
|
|
faff6e54ef | ||
| d493e99bcb | |||
|
|
92ae0b7431 | ||
|
|
13135ff2ca | ||
|
|
453e7da848 | ||
|
|
b7a0e5d034 | ||
|
|
b7a8b0c08d | ||
|
|
7557d33c73 | ||
|
|
e35f77b5a8 | ||
|
|
dd4484c17b | ||
|
|
4bd2c1c2b4 | ||
|
|
42c4fe0b29 | ||
|
|
39c6478422 | ||
|
|
c06491eb2f | ||
|
|
e869d15b24 | ||
|
|
7045b6d8e1 | ||
| 431d3199db | |||
|
|
5555705912 | ||
|
|
4a51f698ab | ||
|
|
029bece877 | ||
|
|
31eabbce23 | ||
|
|
7200ff529f | ||
|
|
0dacbefd6b | ||
| 970be67537 | |||
| 53aa9cd643 | |||
|
|
c435bfa343 | ||
|
|
8667d77169 | ||
|
|
5e7fcf3c9b | ||
|
|
e78ae3b292 | ||
|
|
97ee5bc331 | ||
|
|
c3c0bbc922 | ||
|
|
9992b64cae | ||
|
|
7698147e97 | ||
| 81aaf9e8d7 | |||
|
|
8e1b33d964 | ||
|
|
eca61fff57 | ||
|
|
acc5ddac08 | ||
| 06024a0007 | |||
| da9158e718 | |||
|
|
f57f03547a | ||
|
|
5424763ad6 | ||
| 3543ce60cb | |||
| 5ba86f12df | |||
|
|
424cdd3e65 | ||
|
|
3362f2473a | ||
|
|
5565bb7a48 | ||
|
|
f953348f4e | ||
|
|
702af37961 | ||
| 73718070cf | |||
| 091ce15dce | |||
|
|
cdde7c5f2f | ||
|
|
eb0afffbd6 | ||
| 6b0c7f4d38 | |||
| dd2109735d | |||
|
|
0b192d66c3 | ||
|
|
472cbb372e | ||
|
|
8d2e7fd0c8 | ||
|
|
c8526a2270 | ||
|
|
8b6abcc8bb | ||
|
|
468982b07b | ||
|
|
95179ffff2 | ||
|
|
884733e54b | ||
| a2d4b1049e | |||
| 3ce3898326 | |||
|
|
32fc0019d5 | ||
|
|
f3f928e43f | ||
|
|
374a0e1846 | ||
|
|
1e5a99e009 | ||
| 64320fc260 | |||
| ff923ebab2 | |||
|
|
bcd25dd0ed | ||
|
|
ccb6709f5b | ||
| 2fe6b472a2 | |||
| 01642ba495 | |||
|
|
191d23e903 | ||
|
|
be57a52f61 | ||
|
|
c2e8621405 | ||
|
|
d3533f5627 | ||
|
|
db448028f9 | ||
|
|
f659a7508a | ||
|
|
d20a6a1506 | ||
|
|
d724e9eb17 | ||
|
|
2106e6ebef | ||
|
|
dc07b60acf | ||
|
|
d77f046a6a | ||
|
|
73c490a91d | ||
|
|
ce562b6b8a | ||
|
|
9ea4c05199 | ||
|
|
e198cb60b1 | ||
|
|
d183ce505a | ||
|
|
9d1dec4179 | ||
| e5e4ca75ea | |||
| adc8645453 | |||
|
|
708d00e75c | ||
|
|
ecd1652403 | ||
|
|
42e4f5b391 | ||
|
|
afb0f58ec1 | ||
|
|
42e3caa448 | ||
|
|
12a5cebc2d | ||
|
|
65e7574106 | ||
|
|
ca01bc2605 | ||
|
|
ad9f04de4a | ||
| f6a3ec8634 | |||
|
|
7870263656 | ||
|
|
fd934a5eae | ||
|
|
2ab8db94c5 | ||
|
|
37bbcf38df | ||
|
|
086ad4f23a | ||
|
|
cf4be389b4 | ||
|
|
f1d7cfa1f8 | ||
| 269b4ec0ca | |||
| 637be29b7b | |||
|
|
f388d6550c | ||
|
|
5d32f7e493 | ||
|
|
d10c86c684 | ||
| 484f02277b | |||
|
|
0ef9123cd5 | ||
|
|
e6b71faa02 | ||
|
|
9a1a464cb6 | ||
|
|
32af9bf1b4 | ||
|
|
362fd964d0 | ||
| e4f9b0f589 | |||
| 975e525fd5 | |||
|
|
296bff2c5d | ||
|
|
3e65bcb848 | ||
| 8bb2afe83e | |||
|
|
37e5b3c0aa | ||
|
|
e1aecb05c3 | ||
|
|
168127d8fe | ||
|
|
21ec043e98 | ||
|
|
00b3b7f9b3 | ||
|
|
d1be242791 | ||
|
|
fa75828bc1 | ||
| 232f414a62 | |||
| 14e76ac631 | |||
|
|
43763dbe3a | ||
|
|
81ae15a6a2 | ||
|
|
6dc7272ef6 | ||
|
|
d75eef1926 | ||
|
|
18039e905b | ||
|
|
6d0e5321a2 | ||
| 3073670afa | |||
| 690dd1f0a2 | |||
|
|
0dcce5456b | ||
|
|
35f1f2437c | ||
|
|
3e17dd9b7e | ||
|
|
4f8406360f | ||
|
|
d316bba8fa | ||
|
|
9621d72f92 | ||
| 5382fb5df3 | |||
| fd6fbba9cb | |||
| 3739204b42 | |||
|
|
7e2a867bdd | ||
|
|
e983715ad2 | ||
|
|
d8d5a20904 | ||
|
|
5410dd6ec0 | ||
|
|
4443548b0e | ||
|
|
3c86e1b97c | ||
|
|
5cde57e07c | ||
|
|
970c8b0244 | ||
| ade977ed68 | |||
| f83d51b72d | |||
|
|
34f2e33d6d | ||
|
|
0a5c5c5486 | ||
|
|
6becca6672 | ||
|
|
b2d4dc5d00 | ||
|
|
22091ef431 | ||
|
|
efdc676776 | ||
|
|
d25c6b7f1c | ||
| 0cc6b1de98 | |||
| c41b59b703 | |||
|
|
b4ca941065 | ||
|
|
322506250b | ||
|
|
5d36ea9e0c | ||
|
|
dc0fab2957 | ||
|
|
2e158f9d39 | ||
|
|
7e1bbcada0 | ||
|
|
02ccb1f287 | ||
| 4afa313ffc | |||
| 1b8ad316b9 | |||
| b35eaad757 | |||
| e325ab9278 | |||
|
|
ebe19959fa | ||
|
|
5a2bc69fbb | ||
| 57dfdf0b65 | |||
| 028e8b883f | |||
|
|
4bab69b88f | ||
|
|
be0c0fbf3a | ||
|
|
cd4bf203e6 | ||
|
|
fc5674a7d8 | ||
|
|
fe80881405 | ||
|
|
3a29c25b09 | ||
|
|
e2ff813226 | ||
|
|
b67f230212 | ||
|
|
47f9e1adaa | ||
|
|
33808b8cf0 | ||
| 0d67d9af88 | |||
| 45a562f502 | |||
|
|
21fc62b302 | ||
|
|
c37c68e6db | ||
|
|
ca893088d2 | ||
|
|
e69fb222c3 | ||
|
|
c76bf912d1 | ||
|
|
4b1573ab8b | ||
| e0049cc2f7 | |||
| 8e0949442d | |||
|
|
28427bc7c7 | ||
|
|
50980d5216 | ||
|
|
a75ee8fbc6 | ||
|
|
78c757a21a | ||
|
|
6d06c96497 | ||
|
|
5402508b26 | ||
|
|
43d097581e | ||
|
|
7785851719 | ||
| 8f127bc66b | |||
| 8c5f6b8f1b | |||
|
|
00630849cb | ||
|
|
c4392f0320 | ||
|
|
7a92ee85ef | ||
|
|
56ea9dd2e4 |
2
.gitignore
vendored
@@ -1,5 +1,5 @@
|
|||||||
.vscode/settings.json
|
.vscode/settings.json
|
||||||
.idea
|
.idea
|
||||||
todo.txt
|
|
||||||
todo.md
|
todo.md
|
||||||
/.vscode
|
/.vscode
|
||||||
|
/ignored/
|
||||||
|
|||||||
BIN
icons/faune/cerf.webp
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
BIN
icons/faune/chevre.webp
Normal file
|
After Width: | Height: | Size: 6.6 KiB |
BIN
icons/faune/crabe.webp
Normal file
|
After Width: | Height: | Size: 7.1 KiB |
BIN
icons/faune/lapin.webp
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
BIN
icons/faune/oie.webp
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
icons/faune/oiseau.webp
Normal file
|
After Width: | Height: | Size: 8.0 KiB |
BIN
icons/faune/poisson.webp
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
icons/faune/raton-laveur.webp
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
icons/faune/rongeur.webp
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
BIN
icons/faune/saumon.webp
Normal file
|
After Width: | Height: | Size: 8.0 KiB |
BIN
icons/faune/singe-vert.webp
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
@@ -15,11 +15,12 @@
|
|||||||
"TypeNombreastral": "Nombre astral",
|
"TypeNombreastral": "Nombre astral",
|
||||||
"TypeTarot": "Carte de tarot",
|
"TypeTarot": "Carte de tarot",
|
||||||
"TypeCasetmr": "TMR spéciale",
|
"TypeCasetmr": "TMR spéciale",
|
||||||
"TypeRencontrestmr": "Rencontre TMR",
|
"TypeRencontre": "Rencontre TMR",
|
||||||
"TypeMunition": "Munition",
|
"TypeMunition": "Munition",
|
||||||
"TypeMonnaie": "Monnaie",
|
"TypeMonnaie": "Monnaie",
|
||||||
"TypeHerbe": "Herbe ou plante",
|
"TypeHerbe": "Herbe ou plante",
|
||||||
"TypeIngredient": "Ingrédient",
|
"TypeIngredient": "Ingrédient",
|
||||||
|
"TypeFaune": "Faune",
|
||||||
"TypeLivre": "Livre",
|
"TypeLivre": "Livre",
|
||||||
"TypePotion": "Potion",
|
"TypePotion": "Potion",
|
||||||
"TypeArme": "Arme",
|
"TypeArme": "Arme",
|
||||||
@@ -41,7 +42,9 @@
|
|||||||
"TypeOmbre": "Ombre de Thanatos",
|
"TypeOmbre": "Ombre de Thanatos",
|
||||||
"TypeSouffle": "Souffle de Dragon",
|
"TypeSouffle": "Souffle de Dragon",
|
||||||
"TypeTete": "Tête de Dragon",
|
"TypeTete": "Tête de Dragon",
|
||||||
"TypePossession": "Possession"
|
"TypePossession": "Possession",
|
||||||
|
"TypeSortreserve": "Sort en réserve",
|
||||||
|
"TypeExtraitpoetique": "Extrait poetique"
|
||||||
},
|
},
|
||||||
"EFFECT": {
|
"EFFECT": {
|
||||||
"StatusStunned": "Sonné",
|
"StatusStunned": "Sonné",
|
||||||
|
|||||||
@@ -1,15 +1,9 @@
|
|||||||
|
import { RdDActorSheet } from "./actor-sheet.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extend the basic ActorSheet with some very simple modifications
|
* Extend the basic ActorSheet with some very simple modifications
|
||||||
* @extends {ActorSheet}
|
* @extends {ActorSheet}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { HtmlUtility } from "./html-utility.js";
|
|
||||||
import { RdDUtility } from "./rdd-utility.js";
|
|
||||||
import { RdDActorSheet } from "./actor-sheet.js";
|
|
||||||
import { RdDCarac } from "./rdd-carac.js";
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
export class RdDActorCreatureSheet extends RdDActorSheet {
|
export class RdDActorCreatureSheet extends RdDActorSheet {
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
@@ -20,51 +14,28 @@ export class RdDActorCreatureSheet extends RdDActorSheet {
|
|||||||
width: 640,
|
width: 640,
|
||||||
height: 720,
|
height: 720,
|
||||||
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }],
|
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }],
|
||||||
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: null }]
|
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: undefined }]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async getData() {
|
|
||||||
let formData = await super.getData()
|
|
||||||
//console.log("Creature : ", formData, formData.system)
|
|
||||||
formData.calc = {
|
|
||||||
caracTotal: RdDCarac.computeTotal(formData.system.carac),
|
|
||||||
resumeBlessures: this.actor.computeResumeBlessure(formData.system.blessures),
|
|
||||||
encTotal: await this.actor.computeEncombrementTotalEtMalusArmure(),
|
|
||||||
surEncombrementMessage: this.actor.getMessageSurEncombrement()
|
|
||||||
}
|
|
||||||
|
|
||||||
RdDUtility.filterItemsPerTypeForSheet(formData);
|
|
||||||
this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.objets);
|
|
||||||
formData.conteneurs = RdDUtility.conteneursRacine(formData.conteneurs);
|
|
||||||
|
|
||||||
console.log("Creature : ", this.objetVersConteneur, formData);
|
|
||||||
|
|
||||||
return formData;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/** @override */
|
/** @override */
|
||||||
activateListeners(html) {
|
activateListeners(html) {
|
||||||
super.activateListeners(html);
|
super.activateListeners(html);
|
||||||
|
|
||||||
HtmlUtility._showControlWhen($(".gm-only"), game.user.isGM);
|
|
||||||
|
|
||||||
// Everything below here is only needed if the sheet is editable
|
// Everything below here is only needed if the sheet is editable
|
||||||
if (!this.options.editable) return;
|
if (!this.options.editable) return;
|
||||||
|
|
||||||
// On competence change
|
// On competence change
|
||||||
html.find('.creature-carac').change(async event => {
|
this.html.find('.creature-carac').change(async event => {
|
||||||
let compName = event.currentTarget.attributes.compname.value;
|
let compName = event.currentTarget.attributes.compname.value;
|
||||||
this.actor.updateCreatureCompetence(compName, "carac_value", parseInt(event.target.value));
|
this.actor.updateCreatureCompetence(compName, "carac_value", parseInt(event.target.value));
|
||||||
});
|
});
|
||||||
html.find('.creature-niveau').change(async event => {
|
this.html.find('.creature-niveau').change(async event => {
|
||||||
let compName = event.currentTarget.attributes.compname.value;
|
let compName = event.currentTarget.attributes.compname.value;
|
||||||
this.actor.updateCreatureCompetence(compName, "niveau", parseInt(event.target.value));
|
this.actor.updateCreatureCompetence(compName, "niveau", parseInt(event.target.value));
|
||||||
});
|
});
|
||||||
html.find('.creature-dommages').change(async event => {
|
this.html.find('.creature-dommages').change(async event => {
|
||||||
let compName = event.currentTarget.attributes.compname.value;
|
let compName = event.currentTarget.attributes.compname.value;
|
||||||
this.actor.updateCreatureCompetence(compName, "dommages", parseInt(event.target.value));
|
this.actor.updateCreatureCompetence(compName, "dommages", parseInt(event.target.value));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,14 +1,6 @@
|
|||||||
/**
|
import { RdDActorSheet } from "./actor-sheet.js";
|
||||||
* Extend the basic ActorSheet with some very simple modifications
|
|
||||||
* @extends {ActorSheet}
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { HtmlUtility } from "./html-utility.js";
|
export class RdDActorEntiteSheet extends RdDActorSheet {
|
||||||
import { Misc } from "./misc.js";
|
|
||||||
import { RdDUtility } from "./rdd-utility.js";
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
export class RdDActorEntiteSheet extends ActorSheet {
|
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
static get defaultOptions() {
|
static get defaultOptions() {
|
||||||
@@ -18,127 +10,31 @@ export class RdDActorEntiteSheet extends ActorSheet {
|
|||||||
width: 640,
|
width: 640,
|
||||||
height: 720,
|
height: 720,
|
||||||
tabs: [{navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac"}],
|
tabs: [{navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac"}],
|
||||||
dragDrop: [{dragSelector: ".item-list .item", dropSelector: null}]
|
dragDrop: [{dragSelector: ".item-list .item", dropSelector: undefined}]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async getData() {
|
|
||||||
let formData = {
|
|
||||||
title: this.title,
|
|
||||||
id: this.actor.id,
|
|
||||||
type: this.actor.type,
|
|
||||||
img: this.actor.img,
|
|
||||||
name: this.actor.name,
|
|
||||||
editable: this.isEditable,
|
|
||||||
cssClass: this.isEditable ? "editable" : "locked",
|
|
||||||
system: foundry.utils.deepClone(this.actor.system),
|
|
||||||
effects: this.actor.effects.map(e => foundry.utils.deepClone(e)),
|
|
||||||
// items: items,
|
|
||||||
limited: this.actor.limited,
|
|
||||||
options: this.options,
|
|
||||||
owner: this.actor.isOwner,
|
|
||||||
itemsByType: Misc.classify(this.actor.items.map(i => foundry.utils.deepClone(i))),
|
|
||||||
};
|
|
||||||
|
|
||||||
formData.options.isGM = game.user.isGM;
|
|
||||||
RdDUtility.filterItemsPerTypeForSheet(formData);
|
|
||||||
|
|
||||||
|
|
||||||
return formData;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/** @override */
|
/** @override */
|
||||||
activateListeners(html) {
|
activateListeners(html) {
|
||||||
super.activateListeners(html);
|
super.activateListeners(html);
|
||||||
|
|
||||||
HtmlUtility._showControlWhen($(".gm-only"), game.user.isGM);
|
|
||||||
|
|
||||||
// Everything below here is only needed if the sheet is editable
|
// Everything below here is only needed if the sheet is editable
|
||||||
if (!this.options.editable) return;
|
if (!this.options.editable) return;
|
||||||
|
|
||||||
// Update Inventory Item
|
|
||||||
html.find('.item-edit').click(event => {
|
|
||||||
const li = $(event.currentTarget).parents(".item");
|
|
||||||
const item = this.actor.getEmbeddedDocument('Item', li.data("itemId"));
|
|
||||||
item.sheet.render(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Delete Inventory Item
|
|
||||||
html.find('.item-delete').click(event => {
|
|
||||||
const li = $(event.currentTarget).parents(".item");
|
|
||||||
this.actor.deleteEmbeddedDocuments('Item', [li.data("itemId")]);
|
|
||||||
li.slideUp(200, () => this.render(false));
|
|
||||||
});
|
|
||||||
|
|
||||||
// Roll Carac
|
|
||||||
html.find('.carac-label a').click(async event => {
|
|
||||||
let caracName = event.currentTarget.attributes.name.value;
|
|
||||||
this.actor.rollCarac( caracName.toLowerCase() );
|
|
||||||
});
|
|
||||||
|
|
||||||
// On competence change
|
// On competence change
|
||||||
html.find('.creature-carac').change(async event => {
|
this.html.find('.creature-carac').change(async event => {
|
||||||
let compName = event.currentTarget.attributes.compname.value;
|
let compName = event.currentTarget.attributes.compname.value;
|
||||||
this.actor.updateCreatureCompetence( compName, "carac_value", parseInt(event.target.value) );
|
this.actor.updateCreatureCompetence( compName, "carac_value", parseInt(event.target.value) );
|
||||||
} );
|
} );
|
||||||
html.find('.creature-niveau').change(async event => {
|
this.html.find('.creature-niveau').change(async event => {
|
||||||
let compName = event.currentTarget.attributes.compname.value;
|
let compName = event.currentTarget.attributes.compname.value;
|
||||||
this.actor.updateCreatureCompetence( compName, "niveau", parseInt(event.target.value) );
|
this.actor.updateCreatureCompetence( compName, "niveau", parseInt(event.target.value) );
|
||||||
} );
|
} );
|
||||||
html.find('.creature-dommages').change(async event => {
|
this.html.find('.creature-dommages').change(async event => {
|
||||||
let compName = event.currentTarget.attributes.compname.value;
|
let compName = event.currentTarget.attributes.compname.value;
|
||||||
this.actor.updateCreatureCompetence( compName, "dommages", parseInt(event.target.value) );
|
this.actor.updateCreatureCompetence( compName, "dommages", parseInt(event.target.value) );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
// Roll Skill
|
|
||||||
html.find('.competence-label a').click(async event => {
|
|
||||||
let compName = event.currentTarget.text;
|
|
||||||
this.actor.rollCompetence( compName );
|
|
||||||
});
|
|
||||||
|
|
||||||
html.find('.endurance-plus').click(event => {
|
|
||||||
this.actor.santeIncDec("endurance", 1);
|
|
||||||
this.render(true);
|
|
||||||
});
|
|
||||||
html.find('.endurance-moins').click(event => {
|
|
||||||
this.actor.santeIncDec("endurance", -1);
|
|
||||||
this.render(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
html.find('.encaisser-direct').click(event => {
|
|
||||||
this.actor.encaisser();
|
|
||||||
});
|
|
||||||
|
|
||||||
html.find('.remise-a-neuf').click(event => {
|
|
||||||
if (game.user.isGM) {
|
|
||||||
this.actor.remiseANeuf();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
|
|
||||||
/** @override */
|
|
||||||
setPosition(options = {}) {
|
|
||||||
const position = super.setPosition(options);
|
|
||||||
const sheetHeader = this.element.find(".sheet-header");
|
|
||||||
const sheetTabs = this.element.find(".sheet-tabs");
|
|
||||||
const sheetBody = this.element.find(".sheet-body");
|
|
||||||
const bodyHeight = position.height - sheetHeader[0].clientHeight - sheetTabs[0].clientHeight;
|
|
||||||
sheetBody.css("height", bodyHeight);
|
|
||||||
return position;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
|
|
||||||
/** @override */
|
|
||||||
_updateObject(event, formData) {
|
|
||||||
// Update the Actor
|
|
||||||
return this.actor.update(formData);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,3 @@
|
|||||||
/**
|
|
||||||
* Extend the basic ActorSheet with some very simple modifications
|
|
||||||
* @extends {ActorSheet}
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { RdDUtility } from "./rdd-utility.js";
|
import { RdDUtility } from "./rdd-utility.js";
|
||||||
import { HtmlUtility } from "./html-utility.js";
|
import { HtmlUtility } from "./html-utility.js";
|
||||||
import { RdDItemArme } from "./item-arme.js";
|
import { RdDItemArme } from "./item-arme.js";
|
||||||
@@ -12,12 +7,16 @@ import { Misc } from "./misc.js";
|
|||||||
import { RdDCombatManager } from "./rdd-combat.js";
|
import { RdDCombatManager } from "./rdd-combat.js";
|
||||||
import { RdDCarac } from "./rdd-carac.js";
|
import { RdDCarac } from "./rdd-carac.js";
|
||||||
import { DialogSplitItem } from "./dialog-split-item.js";
|
import { DialogSplitItem } from "./dialog-split-item.js";
|
||||||
import { ReglesOptionelles } from "./regles-optionelles.js";
|
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
||||||
import { DialogRepos } from "./dialog-repos.js";
|
import { DialogRepos } from "./dialog-repos.js";
|
||||||
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
|
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
|
||||||
import { TMRUtility } from "./tmr-utility.js";
|
import { STATUSES } from "./settings/status-effects.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
/**
|
||||||
|
* Extend the basic ActorSheet with some very simple modifications
|
||||||
|
* @extends {ActorSheet}
|
||||||
|
*/
|
||||||
export class RdDActorSheet extends ActorSheet {
|
export class RdDActorSheet extends ActorSheet {
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
@@ -26,10 +25,9 @@ export class RdDActorSheet extends ActorSheet {
|
|||||||
return mergeObject(super.defaultOptions, {
|
return mergeObject(super.defaultOptions, {
|
||||||
classes: ["rdd", "sheet", "actor"],
|
classes: ["rdd", "sheet", "actor"],
|
||||||
template: "systems/foundryvtt-reve-de-dragon/templates/actor-sheet.html",
|
template: "systems/foundryvtt-reve-de-dragon/templates/actor-sheet.html",
|
||||||
width: 640,
|
width: 550,
|
||||||
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }],
|
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }],
|
||||||
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: null }],
|
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: undefined }],
|
||||||
editCaracComp: false,
|
|
||||||
showCompNiveauBase: false,
|
showCompNiveauBase: false,
|
||||||
vueDetaillee: false
|
vueDetaillee: false
|
||||||
});
|
});
|
||||||
@@ -38,7 +36,8 @@ export class RdDActorSheet extends ActorSheet {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async getData() {
|
async getData() {
|
||||||
this.timerRecherche = undefined;
|
this.timerRecherche = undefined;
|
||||||
|
this.actor.computeEtatGeneral();
|
||||||
|
|
||||||
let formData = {
|
let formData = {
|
||||||
title: this.title,
|
title: this.title,
|
||||||
id: this.actor.id,
|
id: this.actor.id,
|
||||||
@@ -52,165 +51,93 @@ export class RdDActorSheet extends ActorSheet {
|
|||||||
limited: this.actor.limited,
|
limited: this.actor.limited,
|
||||||
options: this.options,
|
options: this.options,
|
||||||
owner: this.actor.isOwner,
|
owner: this.actor.isOwner,
|
||||||
itemsByType: Misc.classify(this.actor.items.map(i => foundry.utils.deepClone(i))),
|
description: await TextEditor.enrichHTML(this.object.system.description, {async: true}),
|
||||||
}
|
biographie: await TextEditor.enrichHTML(this.object.system.biographie, {async: true}),
|
||||||
RdDUtility.filterItemsPerTypeForSheet(formData)
|
notes: await TextEditor.enrichHTML(this.object.system.notes, {async: true}),
|
||||||
|
notesmj: await TextEditor.enrichHTML(this.object.system.notesmj, {async: true}),
|
||||||
formData.options.isGM = game.user.isGM;
|
calc: {
|
||||||
|
encTotal: await this.actor.computeEncombrementTotalEtMalusArmure(),
|
||||||
if (formData.type == 'creature') return formData; // Shortcut
|
prixTotalEquipement: this.actor.computePrixTotalEquipement(),
|
||||||
|
surprise: RdDBonus.find(this.actor.getSurprise(false)).descr,
|
||||||
formData.competenceByCategory = Misc.classify(formData.competences, it => it.system.categorie)
|
resumeBlessures: this.actor.computeResumeBlessure(this.actor.system.blessures),
|
||||||
|
caracTotal: RdDCarac.computeTotal(this.actor.system.carac, this.actor.system.beaute),
|
||||||
formData.calc = {
|
surEncombrementMessage: this.actor.getMessageSurEncombrement(),
|
||||||
comptageArchetype: RdDItemCompetence.computeResumeArchetype(formData.competences),
|
},
|
||||||
competenceXPTotal: RdDItemCompetence.computeTotalXP(formData.competences),
|
|
||||||
caracTotal: RdDCarac.computeTotal(formData.system.carac, formData.system.beaute),
|
|
||||||
// Mise à jour de l'encombrement total et du prix de l'équipement
|
|
||||||
encTotal: await this.actor.computeEncombrementTotalEtMalusArmure(),
|
|
||||||
prixTotalEquipement: this.actor.computePrixTotalEquipement(),
|
|
||||||
surprise: RdDBonus.find(this.actor.getSurprise(false)).descr,
|
|
||||||
fatigue: RdDUtility.calculFatigueHtml(formData.system.sante.fatigue.value, formData.system.sante.endurance.max),
|
|
||||||
resumeBlessures: this.actor.computeResumeBlessure(formData.system.blessures),
|
|
||||||
surEncombrementMessage: this.actor.getMessageSurEncombrement()
|
|
||||||
};
|
|
||||||
|
|
||||||
formData.competences.forEach(item => {
|
|
||||||
item.system.isVisible = this.options.recherche
|
|
||||||
? RdDItemCompetence.nomContientTexte(item, this.options.recherche.text)
|
|
||||||
: (!this.options.showCompNiveauBase || !RdDItemCompetence.isNiveauBase(item));
|
|
||||||
RdDItemCompetence.levelUp(item, formData.system.compteurs.experience.value);
|
|
||||||
});
|
|
||||||
Object.values(formData.system.carac).forEach(c => {
|
|
||||||
RdDCarac.levelUp(c);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// toujours avoir une liste d'armes (pour mettre esquive et corps à corps)
|
|
||||||
formData.combat = duplicate(formData.armes ?? []);
|
|
||||||
RdDItemArme.computeNiveauArmes(formData.combat, formData.competences);
|
|
||||||
RdDItemArme.ajoutCorpsACorps(formData.combat, formData.competences, formData.system.carac);
|
|
||||||
formData.esquives = this.actor.getCompetences("Esquive");
|
|
||||||
formData.combat = RdDCombatManager.listActionsArmes(formData.combat, formData.competences, formData.system.carac);
|
|
||||||
|
|
||||||
this.armesList = formData.combat;
|
|
||||||
|
|
||||||
// Common data
|
|
||||||
formData.ajustementsConditions = CONFIG.RDD.ajustementsConditions;
|
|
||||||
formData.difficultesLibres = CONFIG.RDD.difficultesLibres;
|
|
||||||
|
|
||||||
formData.hautreve = {
|
|
||||||
isDemiReve: this.actor.getEffectByLabel("Demi-rêve"),
|
|
||||||
sortsReserve: formData.system.reve.reserve.list,
|
|
||||||
rencontres: duplicate(formData.system.reve.rencontre.list),
|
|
||||||
casesTmr: formData.itemsByType.casetmr,
|
|
||||||
cacheTMR: this.actor.isTMRCache()
|
|
||||||
}
|
}
|
||||||
|
formData.options.isGM = game.user.isGM;
|
||||||
|
|
||||||
|
RdDUtility.filterItemsPerTypeForSheet(formData, this.actor.itemTypes);
|
||||||
this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.objets);
|
this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.objets);
|
||||||
formData.conteneurs = RdDUtility.conteneursRacine(formData.conteneurs);
|
formData.conteneurs = RdDUtility.conteneursRacine(formData.conteneurs);
|
||||||
|
|
||||||
formData.subacteurs = {
|
if (formData.type == 'personnage') {
|
||||||
vehicules: this.actor.listeVehicules(),
|
formData.byCateg = Misc.classify(formData.competences, it => it.system.categorie)
|
||||||
montures: this.actor.listeMontures(),
|
formData.calc.comptageArchetype = RdDItemCompetence.computeResumeArchetype(formData.competences);
|
||||||
suivants: this.actor.listeSuivants()
|
formData.calc.competenceXPTotal= RdDItemCompetence.computeTotalXP(formData.competences);
|
||||||
}
|
formData.calc.fatigue= RdDUtility.calculFatigueHtml(formData.system.sante.fatigue.value, formData.system.sante.endurance.max);
|
||||||
if (this.actor.getBestDraconic().system.niveau > -11 && !this.actor.isHautRevant()) {
|
|
||||||
ui.notifications.error(`${this.actor.name} a des compétences draconiques, mais pas le don de Haut-Rêve!
|
formData.competences.forEach(item => {
|
||||||
<br>Ajoutez-lui la tête "Don de Haut-Rêve" pour lui permettre d'utiliser ses compétences et d'accéder aux terres médianes du rêve`);
|
item.system.isVisible = this.options.recherche
|
||||||
|
? RdDItemCompetence.nomContientTexte(item, this.options.recherche.text)
|
||||||
|
: (!this.options.showCompNiveauBase || !RdDItemCompetence.isNiveauBase(item));
|
||||||
|
RdDItemCompetence.levelUp(item, formData.system.compteurs.experience.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.values(formData.system.carac).forEach(c => {
|
||||||
|
RdDCarac.levelUp(c);
|
||||||
|
});
|
||||||
|
|
||||||
|
// toujours avoir une liste d'armes (pour mettre esquive et corps à corps)
|
||||||
|
formData.combat = duplicate(formData.armes ?? []);
|
||||||
|
RdDItemArme.computeNiveauArmes(formData.combat, formData.competences);
|
||||||
|
RdDItemArme.ajoutCorpsACorps(formData.combat, formData.competences, formData.system.carac);
|
||||||
|
formData.esquives = this.actor.getCompetences("Esquive");
|
||||||
|
formData.combat = RdDCombatManager.listActionsArmes(formData.combat, formData.competences, formData.system.carac);
|
||||||
|
|
||||||
|
this.armesList = formData.combat;
|
||||||
|
|
||||||
|
// Common data
|
||||||
|
formData.ajustementsConditions = CONFIG.RDD.ajustementsConditions;
|
||||||
|
formData.difficultesLibres = CONFIG.RDD.difficultesLibres;
|
||||||
|
|
||||||
|
formData.hautreve = {
|
||||||
|
isDemiReve: this.actor.getEffect(STATUSES.StatusDemiReve),
|
||||||
|
cacheTMR: this.actor.isTMRCache()
|
||||||
|
}
|
||||||
|
|
||||||
|
formData.subacteurs = {
|
||||||
|
vehicules: this.actor.listeVehicules(),
|
||||||
|
montures: this.actor.listeMontures(),
|
||||||
|
suivants: this.actor.listeSuivants()
|
||||||
|
}
|
||||||
|
if (this.actor.getBestDraconic().system.niveau > -11 && !this.actor.isHautRevant()) {
|
||||||
|
ui.notifications.error(`${this.actor.name} a des compétences draconiques, mais pas le don de Haut-Rêve!
|
||||||
|
<br>Ajoutez-lui la tête "Don de Haut-Rêve" pour lui permettre d'utiliser ses compétences et d'accéder aux terres médianes du rêve`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return formData;
|
return formData;
|
||||||
}
|
}
|
||||||
|
|
||||||
isCompetenceAffichable(competence) {
|
|
||||||
return !this.options.showCompNiveauBase || !RdDItemCompetence.isNiveauBase(competence);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async _onDropActor(event, dragData) {
|
|
||||||
const dropActor = fromUuidSync(dragData.uuid);
|
|
||||||
this.actor.addSubActeur(dropActor);
|
|
||||||
super._onDropActor(event, dragData);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async _onDropItem(event, dragData) {
|
|
||||||
const destItemId = $(event.target)?.closest('.item').attr('data-item-id')
|
|
||||||
const dropParams = RdDSheetUtility.prepareItemDropParameters(destItemId, this.actor.id, dragData, this.objetVersConteneur)
|
|
||||||
const callSuper = await this.actor.processDropItem(dropParams)
|
|
||||||
if (callSuper) {
|
|
||||||
await super._onDropItem(event, dragData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async createItem(name, type) {
|
|
||||||
await this.actor.createEmbeddedDocuments('Item', [{ name: name, type: type }], { renderSheet: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async createEmptyTache() {
|
|
||||||
await this.createItem('Nouvelle tache', 'tache');
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */ /** @override */
|
/* -------------------------------------------- */ /** @override */
|
||||||
activateListeners(html) {
|
activateListeners(html) {
|
||||||
super.activateListeners(html);
|
super.activateListeners(html);
|
||||||
|
this.html = html;
|
||||||
|
|
||||||
HtmlUtility._showControlWhen($(".gm-only"), game.user.isGM);
|
HtmlUtility._showControlWhen(this.html.find(".appliquerFatigue"), ReglesOptionelles.isUsing("appliquer-fatigue"));
|
||||||
HtmlUtility._showControlWhen($(".appliquerFatigue"), ReglesOptionelles.isUsing("appliquer-fatigue"));
|
|
||||||
|
|
||||||
// Everything below here is only needed if the sheet is editable
|
// Everything below here is only needed if the sheet is editable
|
||||||
if (!this.options.editable) return;
|
if (!this.options.editable) return;
|
||||||
|
|
||||||
html.find('.item-split').click(async event => {
|
this.html.find('.item-split').click(async event => {
|
||||||
const item = RdDSheetUtility.getItem(event, this.actor);
|
const item = RdDSheetUtility.getItem(event, this.actor);
|
||||||
RdDSheetUtility.splitItem(item, this.actor);
|
RdDSheetUtility.splitItem(item, this.actor);
|
||||||
});
|
});
|
||||||
html.find('.item-edit').click(async event => {
|
this.html.find('.item-edit').click(async event => RdDSheetUtility.getItem(event, this.actor)?.sheet.render(true))
|
||||||
const item = RdDSheetUtility.getItem(event, this.actor)
|
this.html.find('.item-delete').click(async event => RdDUtility.confirmerSuppressionItem(this, RdDSheetUtility.getItem(event, this.actor)));
|
||||||
console.log("ITEM :", item)
|
this.html.find('.item-vendre').click(async event => RdDSheetUtility.getItem(event, this.actor)?.proposerVente());
|
||||||
item.sheet.render(true)
|
this.html.find('.item-montrer').click(async event => RdDSheetUtility.getItem(event, this.actor)?.postItem());
|
||||||
})
|
this.html.find('.item-action').click(async event => RdDSheetUtility.getItem(event, this.actor)?.actionPrincipale(this.actor));
|
||||||
html.find('.display-label a').click(async event => {
|
this.html.find('.subacteur-delete').click(async event => {
|
||||||
const item = RdDSheetUtility.getItem(event, this.actor);
|
|
||||||
item.sheet.render(true);
|
|
||||||
});
|
|
||||||
html.find('.rencontre-delete').click(async event => {
|
|
||||||
this.actor.deleteTMRRencontre(RdDSheetUtility.getItemId(event));
|
|
||||||
});
|
|
||||||
html.find('.item-delete').click(async event => {
|
|
||||||
const li = RdDSheetUtility.getEventElement(event);
|
|
||||||
const item = this.actor.getObjet(li.data("item-id"));
|
|
||||||
RdDUtility.confirmerSuppressionItem(this, item, li);
|
|
||||||
});
|
|
||||||
html.find('.sort-reserve-delete').click(async event => {
|
|
||||||
const li = RdDSheetUtility.getEventElement(event);
|
|
||||||
const index = li.data('index');
|
|
||||||
const sortReserve = this.actor.system.reve.reserve.list[index];
|
|
||||||
RdDUtility.confirmerSuppression(this, li, {
|
|
||||||
supprimer: `le sort en réserve ${sortReserve.sort.name} en ${TMRUtility.getTMR(sortReserve.coord).label}`,
|
|
||||||
deleteLabel: "Supprimer le sort en réserve",
|
|
||||||
onDelete: () => {
|
|
||||||
console.log("Delete : ", sortReserve.name);
|
|
||||||
this.actor.deleteSortReserveKey(index);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
html.find('.item-vendre').click(async event => {
|
|
||||||
const item = RdDSheetUtility.getItem(event, this.actor);
|
|
||||||
item?.proposerVente();
|
|
||||||
});
|
|
||||||
html.find('.item-montrer').click(async event => {
|
|
||||||
const item = RdDSheetUtility.getItem(event, this.actor);
|
|
||||||
item?.postItem();
|
|
||||||
});
|
|
||||||
|
|
||||||
html.find('.item-action').click(async event => {
|
|
||||||
const item = RdDSheetUtility.getItem(event, this.actor)
|
|
||||||
this.actor.actionItem(item);
|
|
||||||
});
|
|
||||||
html.find('.subacteur-delete').click(async event => {
|
|
||||||
const li = RdDSheetUtility.getEventElement(event);
|
const li = RdDSheetUtility.getEventElement(event);
|
||||||
const actorId = li.data("actor-id");
|
const actorId = li.data("actor-id");
|
||||||
if (actorId) {
|
if (actorId) {
|
||||||
@@ -218,45 +145,54 @@ export class RdDActorSheet extends ActorSheet {
|
|||||||
RdDUtility.confirmerSuppressionSubacteur(this, subActor, li);
|
RdDUtility.confirmerSuppressionSubacteur(this, subActor, li);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.html.find('.experiencelog-delete').click(async event => {
|
||||||
html.find('.encaisser-direct').click(async event => {
|
const li = this.html.find(event.currentTarget)?.parents(".experiencelog");
|
||||||
|
const key = Number(li.data("key") ?? -1);
|
||||||
|
await this.actor.deleteExperienceLog(key, 1);
|
||||||
|
});
|
||||||
|
this.html.find('.experiencelog-delete-previous').click(async event => {
|
||||||
|
const li = this.html.find(event.currentTarget)?.parents(".experiencelog");
|
||||||
|
const key = Number(li.data("key") ?? -1);
|
||||||
|
await this.actor.deleteExperienceLog(0, key + 1);
|
||||||
|
});
|
||||||
|
this.html.find('.encaisser-direct').click(async event => {
|
||||||
this.actor.encaisser();
|
this.actor.encaisser();
|
||||||
})
|
})
|
||||||
html.find('.sheet-possession-attack').click(async event => {
|
this.html.find('.sheet-possession-attack').click(async event => {
|
||||||
const poss = RdDSheetUtility.getItem(event, this.actor)
|
const poss = RdDSheetUtility.getItem(event, this.actor)
|
||||||
this.actor.conjurerPossession(poss)
|
this.actor.conjurerPossession(poss)
|
||||||
})
|
})
|
||||||
html.find('.remise-a-neuf').click(async event => {
|
this.html.find('.remise-a-neuf').click(async event => {
|
||||||
if (game.user.isGM) {
|
if (game.user.isGM) {
|
||||||
this.actor.remiseANeuf();
|
this.actor.remiseANeuf();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
html.find('.creer-tache').click(async event => {
|
this.html.find('.creer-tache').click(async event => {
|
||||||
this.createEmptyTache();
|
this.createEmptyTache();
|
||||||
});
|
});
|
||||||
html.find('.creer-un-objet').click(async event => {
|
this.html.find('.creer-un-objet').click(async event => {
|
||||||
RdDUtility.selectObjetType(this);
|
RdDUtility.selectObjetType(this);
|
||||||
});
|
});
|
||||||
html.find('.creer-une-oeuvre').click(async event => {
|
this.html.find('.creer-une-oeuvre').click(async event => {
|
||||||
RdDUtility.selectTypeOeuvre(this);
|
RdDUtility.selectTypeOeuvre(this);
|
||||||
});
|
});
|
||||||
html.find('#nettoyer-conteneurs').click(async event => {
|
this.html.find('.nettoyer-conteneurs').click(async event => {
|
||||||
this.actor.nettoyerConteneurs();
|
this.actor.nettoyerConteneurs();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Blessure control
|
// Blessure control
|
||||||
html.find('.blessure-control').click(async event => {
|
this.html.find('.blessure-control').click(async event => {
|
||||||
const tr = $(event.currentTarget).parents(".item");
|
const tr = this.html.find(event.currentTarget).parents(".item");
|
||||||
let btype = tr.data("blessure-type");
|
let btype = tr.data("blessure-type");
|
||||||
let index = tr.data('blessure-index');
|
let index = tr.data('blessure-index');
|
||||||
let active = $(event.currentTarget).data('blessure-active');
|
let active = this.html.find(event.currentTarget).data('blessure-active');
|
||||||
//console.log(btype, index, active);
|
//console.log(btype, index, active);
|
||||||
await this.actor.manageBlessureFromSheet(btype, index, active);
|
await this.actor.manageBlessureFromSheet(btype, index, active);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Blessure data
|
// Blessure data
|
||||||
html.find('.blessures-soins').change(async event => {
|
this.html.find('.blessure-soins').change(async event => {
|
||||||
const tr = $(event.currentTarget).parents(".item");
|
const tr = this.html.find(event.currentTarget).parents(".item");
|
||||||
let btype = tr.data('blessure-type');
|
let btype = tr.data('blessure-type');
|
||||||
let index = tr.data('blessure-index');
|
let index = tr.data('blessure-index');
|
||||||
let psoins = tr.find('.blessure-premiers_soins').val();
|
let psoins = tr.find('.blessure-premiers_soins').val();
|
||||||
@@ -270,57 +206,57 @@ export class RdDActorSheet extends ActorSheet {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Equip Inventory Item
|
// Equip Inventory Item
|
||||||
html.find('.item-equip').click(async event => {
|
this.html.find('.item-equip').click(async event => {
|
||||||
this.actor.equiperObjet(RdDSheetUtility.getItemId(event));
|
this.actor.equiperObjet(RdDSheetUtility.getItemId(event));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Roll Carac
|
// Roll Carac
|
||||||
html.find('.carac-label a').click(async event => {
|
this.html.find('.carac-label a').click(async event => {
|
||||||
let caracName = event.currentTarget.attributes.name.value;
|
let caracName = event.currentTarget.attributes.name.value;
|
||||||
this.actor.rollCarac(caracName.toLowerCase());
|
this.actor.rollCarac(caracName.toLowerCase());
|
||||||
});
|
});
|
||||||
|
|
||||||
html.find('.chance-actuelle').click(async event => {
|
this.html.find('.chance-actuelle').click(async event => {
|
||||||
this.actor.rollCarac('chance-actuelle');
|
this.actor.rollCarac('chance-actuelle');
|
||||||
});
|
});
|
||||||
|
|
||||||
html.find('.chance-appel').click(async event => {
|
this.html.find('.chance-appel').click(async event => {
|
||||||
this.actor.rollAppelChance();
|
this.actor.rollAppelChance();
|
||||||
});
|
});
|
||||||
|
|
||||||
html.find('#jet-astrologie').click(async event => {
|
this.html.find('[name="jet-astrologie"]').click(async event => {
|
||||||
this.actor.astrologieNombresAstraux();
|
this.actor.astrologieNombresAstraux();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Roll Skill
|
// Roll Skill
|
||||||
html.find('a.competence-label').click(async event => {
|
this.html.find('a.competence-label').click(async event => {
|
||||||
this.actor.rollCompetence(RdDSheetUtility.getItemId(event));
|
this.actor.rollCompetence(RdDSheetUtility.getItemId(event));
|
||||||
});
|
});
|
||||||
html.find('.tache-label a').click(async event => {
|
this.html.find('.tache-label a').click(async event => {
|
||||||
this.actor.rollTache(RdDSheetUtility.getItemId(event));
|
this.actor.rollTache(RdDSheetUtility.getItemId(event));
|
||||||
});
|
});
|
||||||
html.find('.meditation-label a').click(async event => {
|
this.html.find('.meditation-label a').click(async event => {
|
||||||
this.actor.rollMeditation(RdDSheetUtility.getItemId(event));
|
this.actor.rollMeditation(RdDSheetUtility.getItemId(event));
|
||||||
});
|
});
|
||||||
html.find('.chant-label a').click(async event => {
|
this.html.find('.chant-label a').click(async event => {
|
||||||
this.actor.rollChant(RdDSheetUtility.getItemId(event));
|
this.actor.rollChant(RdDSheetUtility.getItemId(event));
|
||||||
});
|
});
|
||||||
html.find('.danse-label a').click(async event => {
|
this.html.find('.danse-label a').click(async event => {
|
||||||
this.actor.rollDanse(RdDSheetUtility.getItemId(event));
|
this.actor.rollDanse(RdDSheetUtility.getItemId(event));
|
||||||
});
|
});
|
||||||
html.find('.musique-label a').click(async event => {
|
this.html.find('.musique-label a').click(async event => {
|
||||||
this.actor.rollMusique(RdDSheetUtility.getItemId(event));
|
this.actor.rollMusique(RdDSheetUtility.getItemId(event));
|
||||||
});
|
});
|
||||||
html.find('.oeuvre-label a').click(async event => {
|
this.html.find('.oeuvre-label a').click(async event => {
|
||||||
this.actor.rollOeuvre(RdDSheetUtility.getItemId(event));
|
this.actor.rollOeuvre(RdDSheetUtility.getItemId(event));
|
||||||
});
|
});
|
||||||
html.find('.jeu-label a').click(async event => {
|
this.html.find('.jeu-label a').click(async event => {
|
||||||
this.actor.rollJeu(RdDSheetUtility.getItemId(event));
|
this.actor.rollJeu(RdDSheetUtility.getItemId(event));
|
||||||
});
|
});
|
||||||
html.find('.recettecuisine-label a').click(async event => {
|
this.html.find('.recettecuisine-label a').click(async event => {
|
||||||
this.actor.rollRecetteCuisine(RdDSheetUtility.getItemId(event));
|
this.actor.rollRecetteCuisine(RdDSheetUtility.getItemId(event));
|
||||||
});
|
});
|
||||||
html.find('.subacteur-label a').click(async event => {
|
this.html.find('.subacteur-label a').click(async event => {
|
||||||
let actorId = RdDSheetUtility.getEventItemData(event, 'actor-id');
|
let actorId = RdDSheetUtility.getEventItemData(event, 'actor-id');
|
||||||
let actor = game.actors.get(actorId);
|
let actor = game.actors.get(actorId);
|
||||||
if (actor) {
|
if (actor) {
|
||||||
@@ -329,25 +265,25 @@ export class RdDActorSheet extends ActorSheet {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Boutons spéciaux MJs
|
// Boutons spéciaux MJs
|
||||||
html.find('.forcer-tmr-aleatoire').click(async event => {
|
this.html.find('.forcer-tmr-aleatoire').click(async event => {
|
||||||
this.actor.reinsertionAleatoire("Action MJ");
|
this.actor.reinsertionAleatoire("Action MJ");
|
||||||
});
|
});
|
||||||
html.find('.afficher-tmr').click(async event => {
|
this.html.find('.afficher-tmr').click(async event => {
|
||||||
this.actor.afficheTMRetMessage();
|
this.actor.changeTMRVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Points de reve actuel
|
// Points de reve actuel
|
||||||
html.find('.ptreve-actuel a').click(async event => {
|
this.html.find('.ptreve-actuel a').click(async event => {
|
||||||
this.actor.rollCarac('reve-actuel');
|
this.actor.rollCarac('reve-actuel');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Roll Weapon1
|
// Roll Weapon1
|
||||||
html.find('.arme-label a').click(async event => {
|
this.html.find('.arme-label a').click(async event => {
|
||||||
let arme = this._getEventArmeCombat(event);
|
let arme = this._getEventArmeCombat(event);
|
||||||
this.actor.rollArme(duplicate(arme));
|
this.actor.rollArme(duplicate(arme));
|
||||||
});
|
});
|
||||||
// Initiative pour l'arme
|
// Initiative pour l'arme
|
||||||
html.find('.arme-initiative a').click(async event => {
|
this.html.find('.arme-initiative a').click(async event => {
|
||||||
let combatant = game.combat.combatants.find(c => c.actor.id == this.actor.id);
|
let combatant = game.combat.combatants.find(c => c.actor.id == this.actor.id);
|
||||||
if (combatant) {
|
if (combatant) {
|
||||||
let action = this._getEventArmeCombat(event);
|
let action = this._getEventArmeCombat(event);
|
||||||
@@ -357,88 +293,88 @@ export class RdDActorSheet extends ActorSheet {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Display TMR, visualisation
|
// Display TMR, visualisation
|
||||||
html.find('.visu-tmr').click(async event => {
|
this.html.find('.visu-tmr').click(async event => {
|
||||||
this.actor.displayTMR("visu");
|
this.actor.displayTMR("visu");
|
||||||
});
|
});
|
||||||
|
|
||||||
// Display TMR, normal
|
// Display TMR, normal
|
||||||
html.find('.monte-tmr').click(async event => {
|
this.html.find('.monte-tmr').click(async event => {
|
||||||
this.actor.displayTMR("normal");
|
this.actor.displayTMR("normal");
|
||||||
});
|
});
|
||||||
|
|
||||||
// Display TMR, fast
|
// Display TMR, fast
|
||||||
html.find('.monte-tmr-rapide').click(async event => {
|
this.html.find('.monte-tmr-rapide').click(async event => {
|
||||||
this.actor.displayTMR("rapide");
|
this.actor.displayTMR("rapide");
|
||||||
});
|
});
|
||||||
|
|
||||||
html.find('.repos').click(async event => {
|
this.html.find('.repos').click(async event => {
|
||||||
await DialogRepos.create(this.actor);
|
await DialogRepos.create(this.actor);
|
||||||
});
|
});
|
||||||
html.find('.delete-active-effect').click(async event => {
|
this.html.find('.delete-active-effect').click(async event => {
|
||||||
let id = $(event.currentTarget).parents(".active-effect").data('id');
|
if (game.user.isGM) {
|
||||||
this.actor.enleverActiveEffectById(id);
|
let effect = this.html.find(event.currentTarget).parents(".active-effect").data('effect');
|
||||||
|
this.actor.removeEffect(effect);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
html.find('.enlever-tous-effets').click(async event => {
|
this.html.find('.enlever-tous-effets').click(async event => {
|
||||||
this.actor.enleverTousLesEffets();
|
if (game.user.isGM) {
|
||||||
|
await this.actor.removeEffects();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
html.find('.conteneur-name a').click(async event => {
|
this.html.find('.conteneur-name a').click(async event => {
|
||||||
RdDUtility.toggleAfficheContenu(RdDSheetUtility.getItemId(event));
|
RdDUtility.toggleAfficheContenu(RdDSheetUtility.getItemId(event));
|
||||||
this.render(true);
|
this.render(true);
|
||||||
});
|
});
|
||||||
html.find('.carac-xp-augmenter').click(async event => {
|
this.html.find('.carac-xp-augmenter').click(async event => {
|
||||||
let caracName = event.currentTarget.name.replace("augmenter.", "");
|
let caracName = event.currentTarget.name.replace("augmenter.", "");
|
||||||
this.actor.updateCaracXPAuto(caracName);
|
this.actor.updateCaracXPAuto(caracName);
|
||||||
});
|
});
|
||||||
html.find('.competence-xp-augmenter').click(async event => {
|
this.html.find('.competence-xp-augmenter').click(async event => {
|
||||||
this.actor.updateCompetenceXPAuto(RdDSheetUtility.getItemId(event));
|
this.actor.updateCompetenceXPAuto(RdDSheetUtility.getItemId(event));
|
||||||
});
|
});
|
||||||
html.find('.competence-stress-augmenter').click(async event => {
|
this.html.find('.competence-stress-augmenter').click(async event => {
|
||||||
this.actor.updateCompetenceStress(RdDSheetUtility.getItemId(event));
|
this.actor.updateCompetenceStress(RdDSheetUtility.getItemId(event));
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.options.editCaracComp) {
|
if (this.options.vueDetaillee) {
|
||||||
// On carac change
|
// On carac change
|
||||||
html.find('.carac-value').change(async event => {
|
this.html.find('.carac-value').change(async event => {
|
||||||
let caracName = event.currentTarget.name.replace(".value", "").replace("system.carac.", "");
|
let caracName = event.currentTarget.name.replace(".value", "").replace("system.carac.", "");
|
||||||
this.actor.updateCarac(caracName, parseInt(event.target.value));
|
this.actor.updateCarac(caracName, parseInt(event.target.value));
|
||||||
});
|
});
|
||||||
html.find('input.carac-xp').change(async event => {
|
this.html.find('input.carac-xp').change(async event => {
|
||||||
let caracName = event.currentTarget.name.replace(".xp", "").replace("system.carac.", "");
|
let caracName = event.currentTarget.name.replace(".xp", "").replace("system.carac.", "");
|
||||||
this.actor.updateCaracXP(caracName, parseInt(event.target.value));
|
this.actor.updateCaracXP(caracName, parseInt(event.target.value));
|
||||||
});
|
});
|
||||||
// On competence change
|
// On competence change
|
||||||
html.find('.competence-value').change(async event => {
|
this.html.find('.competence-value').change(async event => {
|
||||||
let compName = event.currentTarget.attributes.compname.value;
|
let compName = event.currentTarget.attributes.compname.value;
|
||||||
//console.log("Competence changed :", compName);
|
//console.log("Competence changed :", compName);
|
||||||
this.actor.updateCompetence(compName, parseInt(event.target.value));
|
this.actor.updateCompetence(compName, parseInt(event.target.value));
|
||||||
});
|
});
|
||||||
// On competence xp change
|
// On competence xp change
|
||||||
html.find('input.competence-xp').change(async event => {
|
this.html.find('input.competence-xp').change(async event => {
|
||||||
let compName = event.currentTarget.attributes.compname.value;
|
let compName = event.currentTarget.attributes.compname.value;
|
||||||
this.actor.updateCompetenceXP(compName, parseInt(event.target.value));
|
this.actor.updateCompetenceXP(compName, parseInt(event.target.value));
|
||||||
});
|
});
|
||||||
// On competence xp change
|
// On competence xp change
|
||||||
html.find('input.competence-xp-sort').change(async event => {
|
this.html.find('input.competence-xp-sort').change(async event => {
|
||||||
let compName = event.currentTarget.attributes.compname.value;
|
let compName = event.currentTarget.attributes.compname.value;
|
||||||
this.actor.updateCompetenceXPSort(compName, parseInt(event.target.value));
|
this.actor.updateCompetenceXPSort(compName, parseInt(event.target.value));
|
||||||
});
|
});
|
||||||
// On competence archetype change
|
// On competence archetype change
|
||||||
html.find('.competence-archetype').change(async event => {
|
this.html.find('.competence-archetype').change(async event => {
|
||||||
let compName = event.currentTarget.attributes.compname.value;
|
let compName = event.currentTarget.attributes.compname.value;
|
||||||
this.actor.updateCompetenceArchetype(compName, parseInt(event.target.value));
|
this.actor.updateCompetenceArchetype(compName, parseInt(event.target.value));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
html.find('.show-hide-competences').click(async event => {
|
this.html.find('.show-hide-competences').click(async event => {
|
||||||
this.options.showCompNiveauBase = !this.options.showCompNiveauBase;
|
this.options.showCompNiveauBase = !this.options.showCompNiveauBase;
|
||||||
this.render(true);
|
this.render(true);
|
||||||
});
|
});
|
||||||
html.find('.lock-unlock-sheet').click(async event => {
|
|
||||||
this.options.editCaracComp = !this.options.editCaracComp;
|
|
||||||
this.render(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
html.find('.recherche')
|
this.html.find('.recherche')
|
||||||
.each((index, field) => {
|
.each((index, field) => {
|
||||||
if (this.options.recherche) {
|
if (this.options.recherche) {
|
||||||
field.focus();
|
field.focus();
|
||||||
@@ -461,92 +397,125 @@ export class RdDActorSheet extends ActorSheet {
|
|||||||
.change(async event =>
|
.change(async event =>
|
||||||
this.options.recherche = this._optionRecherche(event.currentTarget)
|
this.options.recherche = this._optionRecherche(event.currentTarget)
|
||||||
);
|
);
|
||||||
html.find('.vue-detaillee').click(async event => {
|
this.html.find('.vue-detaillee').click(async event => {
|
||||||
this.options.vueDetaillee = !this.options.vueDetaillee;
|
this.options.vueDetaillee = !this.options.vueDetaillee;
|
||||||
this.render(true);
|
this.render(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
// On pts de reve change
|
// On pts de reve change
|
||||||
html.find('.pointsreve-value').change(async event => {
|
this.html.find('.pointsreve-value').change(async event => {
|
||||||
let reveValue = event.currentTarget.value;
|
let reveValue = event.currentTarget.value;
|
||||||
this.actor.update({ "system.reve.reve.value": reveValue });
|
this.actor.update({ "system.reve.reve.value": reveValue });
|
||||||
});
|
});
|
||||||
|
|
||||||
// On seuil de reve change
|
// On seuil de reve change
|
||||||
html.find('.seuil-reve-value').change(async event => {
|
this.html.find('.seuil-reve-value').change(async event => {
|
||||||
console.log("seuil-reve-value", event.currentTarget)
|
console.log("seuil-reve-value", event.currentTarget)
|
||||||
this.actor.setPointsDeSeuil(event.currentTarget.value);
|
this.actor.setPointsDeSeuil(event.currentTarget.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
html.find('#attribut-protection-edit').change(async event => {
|
this.html.find('#attribut-protection-edit').change(async event => {
|
||||||
this.actor.updateAttributeValue(event.currentTarget.attributes.name.value, parseInt(event.target.value));
|
this.actor.updateAttributeValue(event.currentTarget.attributes.name.value, parseInt(event.target.value));
|
||||||
});
|
});
|
||||||
|
|
||||||
// On stress change
|
// On stress change
|
||||||
html.find('.compteur-edit').change(async event => {
|
this.html.find('.compteur-edit').change(async event => {
|
||||||
let fieldName = event.currentTarget.attributes.name.value;
|
let fieldName = event.currentTarget.attributes.name.value;
|
||||||
this.actor.updateCompteurValue(fieldName, parseInt(event.target.value));
|
this.actor.updateCompteurValue(fieldName, parseInt(event.target.value));
|
||||||
});
|
});
|
||||||
|
|
||||||
html.find('#ethylisme').change(async event => {
|
this.html.find('#ethylisme').change(async event => {
|
||||||
this.actor.setEthylisme(parseInt(event.target.value));
|
this.actor.setEthylisme(parseInt(event.target.value));
|
||||||
});
|
});
|
||||||
html.find('.stress-test').click(async event => {
|
this.html.find('.stress-test').click(async event => {
|
||||||
this.actor.transformerStress();
|
this.actor.transformerStress();
|
||||||
});
|
});
|
||||||
html.find('.moral-malheureux').click(async event => {
|
this.html.find('.moral-malheureux').click(async event => {
|
||||||
this.actor.jetDeMoral('malheureuse');
|
this.actor.jetDeMoral('malheureuse');
|
||||||
});
|
});
|
||||||
html.find('.moral-neutre').click(async event => {
|
this.html.find('.moral-neutre').click(async event => {
|
||||||
this.actor.jetDeMoral('neutre');
|
this.actor.jetDeMoral('neutre');
|
||||||
});
|
});
|
||||||
html.find('.moral-heureux').click(async event => {
|
this.html.find('.moral-heureux').click(async event => {
|
||||||
this.actor.jetDeMoral('heureuse');
|
this.actor.jetDeMoral('heureuse');
|
||||||
});
|
});
|
||||||
html.find('#ethylisme-test').click(async event => {
|
this.html.find('.ethylisme-test').click(async event => {
|
||||||
this.actor.jetEthylisme();
|
this.actor.jetEthylisme();
|
||||||
});
|
});
|
||||||
|
|
||||||
html.find('.jet-vie').click(async event => {
|
this.html.find('.jet-vie').click(async event => {
|
||||||
this.actor.jetVie();
|
this.actor.jetVie();
|
||||||
});
|
});
|
||||||
html.find('.jet-endurance').click(async event => {
|
this.html.find('.jet-endurance').click(async event => {
|
||||||
this.actor.jetEndurance();
|
this.actor.jetEndurance();
|
||||||
});
|
});
|
||||||
|
|
||||||
html.find('.monnaie-plus').click(async event => {
|
this.html.find('.monnaie-plus').click(async event => {
|
||||||
this.actor.monnaieIncDec(RdDSheetUtility.getItemId(event), 1);
|
this.actor.monnaieIncDec(RdDSheetUtility.getItemId(event), 1);
|
||||||
});
|
});
|
||||||
html.find('.monnaie-moins').click(async event => {
|
this.html.find('.monnaie-moins').click(async event => {
|
||||||
this.actor.monnaieIncDec(RdDSheetUtility.getItemId(event), -1);
|
this.actor.monnaieIncDec(RdDSheetUtility.getItemId(event), -1);
|
||||||
});
|
});
|
||||||
|
|
||||||
html.find('.vie-plus').click(async event => {
|
this.html.find('.vie-plus').click(async event => {
|
||||||
this.actor.santeIncDec("vie", 1);
|
this.actor.santeIncDec("vie", 1);
|
||||||
});
|
});
|
||||||
html.find('.vie-moins').click(async event => {
|
this.html.find('.vie-moins').click(async event => {
|
||||||
this.actor.santeIncDec("vie", -1);
|
this.actor.santeIncDec("vie", -1);
|
||||||
});
|
});
|
||||||
html.find('.endurance-plus').click(async event => {
|
this.html.find('.endurance-plus').click(async event => {
|
||||||
this.actor.santeIncDec("endurance", 1);
|
this.actor.santeIncDec("endurance", 1);
|
||||||
});
|
});
|
||||||
html.find('.endurance-moins').click(async event => {
|
this.html.find('.endurance-moins').click(async event => {
|
||||||
this.actor.santeIncDec("endurance", -1);
|
this.actor.santeIncDec("endurance", -1);
|
||||||
});
|
});
|
||||||
html.find('.ptreve-actuel-plus').click(async event => {
|
this.html.find('.ptreve-actuel-plus').click(async event => {
|
||||||
this.actor.reveActuelIncDec(1);
|
this.actor.reveActuelIncDec(1);
|
||||||
});
|
});
|
||||||
html.find('.ptreve-actuel-moins').click(async event => {
|
this.html.find('.ptreve-actuel-moins').click(async event => {
|
||||||
this.actor.reveActuelIncDec(-1);
|
this.actor.reveActuelIncDec(-1);
|
||||||
});
|
});
|
||||||
html.find('.fatigue-plus').click(async event => {
|
this.html.find('.fatigue-plus').click(async event => {
|
||||||
this.actor.santeIncDec("fatigue", 1);
|
this.actor.santeIncDec("fatigue", 1);
|
||||||
});
|
});
|
||||||
html.find('.fatigue-moins').click(async event => {
|
this.html.find('.fatigue-moins').click(async event => {
|
||||||
this.actor.santeIncDec("fatigue", -1);
|
this.actor.santeIncDec("fatigue", -1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isCompetenceAffichable(competence) {
|
||||||
|
return !this.options.showCompNiveauBase || !RdDItemCompetence.isNiveauBase(competence);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async _onDropActor(event, dragData) {
|
||||||
|
const dropActor = fromUuidSync(dragData.uuid);
|
||||||
|
this.actor.addSubActeur(dropActor);
|
||||||
|
super._onDropActor(event, dragData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async _onDropItem(event, dragData) {
|
||||||
|
const destItemId = this.html.find(event.target)?.closest('.item').attr('data-item-id')
|
||||||
|
const dropParams = RdDSheetUtility.prepareItemDropParameters(destItemId, this.actor, dragData, this.objetVersConteneur)
|
||||||
|
if (dropParams) {
|
||||||
|
const callSuper = await this.actor.processDropItem(dropParams)
|
||||||
|
if (callSuper) {
|
||||||
|
await super._onDropItem(event, dragData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async createItem(name, type) {
|
||||||
|
await this.actor.createEmbeddedDocuments('Item', [{ name: name, type: type }], { renderSheet: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async createEmptyTache() {
|
||||||
|
await this.createItem('Nouvelle tache', 'tache');
|
||||||
|
}
|
||||||
|
|
||||||
_optionRecherche(target) {
|
_optionRecherche(target) {
|
||||||
if (!target.value?.length){
|
if (!target.value?.length){
|
||||||
return undefined;
|
return undefined;
|
||||||
@@ -559,7 +528,7 @@ export class RdDActorSheet extends ActorSheet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_getEventArmeCombat(event) {
|
_getEventArmeCombat(event) {
|
||||||
const li = $(event.currentTarget)?.parents(".item");
|
const li = this.html.find(event.currentTarget)?.parents(".item");
|
||||||
let armeName = li.data("arme-name");
|
let armeName = li.data("arme-name");
|
||||||
let compName = li.data('competence-name');
|
let compName = li.data('competence-name');
|
||||||
const arme = this.armesList.find(a => a.name == armeName && a.system.competence == compName);
|
const arme = this.armesList.find(a => a.name == armeName && a.system.competence == compName);
|
||||||
@@ -576,7 +545,10 @@ export class RdDActorSheet extends ActorSheet {
|
|||||||
const sheetHeader = this.element.find(".sheet-header");
|
const sheetHeader = this.element.find(".sheet-header");
|
||||||
const sheetTabs = this.element.find(".sheet-tabs");
|
const sheetTabs = this.element.find(".sheet-tabs");
|
||||||
const sheetBody = this.element.find(".sheet-body");
|
const sheetBody = this.element.find(".sheet-body");
|
||||||
const bodyHeight = position.height - sheetHeader[0].clientHeight - sheetTabs[0].clientHeight;
|
let bodyHeight = position.height - sheetHeader[0].clientHeight;
|
||||||
|
if (sheetTabs.length>0) {
|
||||||
|
bodyHeight -= sheetTabs[0].clientHeight;
|
||||||
|
}
|
||||||
sheetBody.css("height", bodyHeight);
|
sheetBody.css("height", bodyHeight);
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,8 @@
|
|||||||
/**
|
|
||||||
* Extend the basic ActorSheet with some very simple modifications
|
|
||||||
* @extends {ActorSheet}
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { RdDUtility } from "./rdd-utility.js";
|
import { RdDUtility } from "./rdd-utility.js";
|
||||||
import { HtmlUtility } from "./html-utility.js";
|
import { RdDActorSheet } from "./actor-sheet.js";
|
||||||
import { Misc } from "./misc.js";
|
|
||||||
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
export class RdDActorVehiculeSheet extends ActorSheet {
|
export class RdDActorVehiculeSheet extends RdDActorSheet {
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
static get defaultOptions() {
|
static get defaultOptions() {
|
||||||
@@ -21,145 +14,26 @@ export class RdDActorVehiculeSheet extends ActorSheet {
|
|||||||
width: 640,
|
width: 640,
|
||||||
height: 720,
|
height: 720,
|
||||||
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }],
|
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }],
|
||||||
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: null }]
|
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: undefined }]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async getData() {
|
|
||||||
let formData = {
|
|
||||||
title: this.title,
|
|
||||||
id: this.actor.id,
|
|
||||||
type: this.actor.type,
|
|
||||||
img: this.actor.img,
|
|
||||||
name: this.actor.name,
|
|
||||||
editable: this.isEditable,
|
|
||||||
cssClass: this.isEditable ? "editable" : "locked",
|
|
||||||
system: foundry.utils.deepClone(this.actor.system),
|
|
||||||
effects: this.actor.effects.map(e => foundry.utils.deepClone(e)),
|
|
||||||
limited: this.actor.limited,
|
|
||||||
options: this.options,
|
|
||||||
owner: this.actor.isOwner,
|
|
||||||
itemsByType: Misc.classify(this.actor.items.map(i => foundry.utils.deepClone(i))),
|
|
||||||
};
|
|
||||||
|
|
||||||
RdDUtility.filterItemsPerTypeForSheet(formData);
|
|
||||||
this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.objets);
|
|
||||||
formData.conteneurs = RdDUtility.conteneursRacine(formData.conteneurs);
|
|
||||||
|
|
||||||
formData.options.isGM = game.user.isGM;
|
|
||||||
|
|
||||||
formData.calc = {
|
|
||||||
encTotal: await this.actor.computeEncombrementTotalEtMalusArmure(),
|
|
||||||
surEncombrementMessage: this.actor.getMessageSurEncombrement()
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("DATA", formData);
|
|
||||||
|
|
||||||
return formData;
|
|
||||||
}
|
|
||||||
|
|
||||||
async computeMalusArmure() {
|
|
||||||
// pas de malus armure
|
|
||||||
}
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async _onDropItem(event, dragData) {
|
|
||||||
const destItemId = $(event.target)?.closest('.item').attr('data-item-id');
|
|
||||||
const dropParams = RdDSheetUtility.prepareItemDropParameters(destItemId, this.actor.id, dragData, this.objetVersConteneur);
|
|
||||||
const callSuper = await this.actor.processDropItem(dropParams);
|
|
||||||
if (callSuper) {
|
|
||||||
await super._onDropItem(event, dragData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async createItem(name, type) {
|
|
||||||
await this.actor.createEmbeddedDocuments('Item', [{ name: name, type: type }], { renderSheet: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async monnaieIncDec(id, value) {
|
|
||||||
let monnaie = this.getMonnaie(id);
|
|
||||||
if (monnaie) {
|
|
||||||
const quantite = Math.max(0, monnaie.system.quantite + value);
|
|
||||||
await this.updateEmbeddedDocuments('Item', [{ _id: monnaie.id, 'data.quantite': quantite }]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
/** @override */
|
|
||||||
activateListeners(html) {
|
activateListeners(html) {
|
||||||
super.activateListeners(html);
|
super.activateListeners(html);
|
||||||
|
|
||||||
HtmlUtility._showControlWhen($(".gm-only"), game.user.isGM);
|
|
||||||
|
|
||||||
// Everything below here is only needed if the sheet is editable
|
|
||||||
if (!this.options.editable) return;
|
if (!this.options.editable) return;
|
||||||
|
|
||||||
// Update Inventory Item
|
this.html.find('.resistance-moins').click(async event => {
|
||||||
html.find('.item-edit').click(async event => {
|
this.actor.vehicleIncDec("resistance", -1);
|
||||||
const item = RdDSheetUtility.getItem(event, this.actor);
|
|
||||||
item.sheet.render(true);
|
|
||||||
});
|
});
|
||||||
// Delete Inventory Item
|
this.html.find('.resistance-plus').click(async event => {
|
||||||
html.find('.item-delete').click(async event => {
|
this.actor.vehicleIncDec("resistance", 1);
|
||||||
const li = RdDSheetUtility.getEventElement(event);
|
|
||||||
const item = this.actor.getObjet(li.data("item-id"));
|
|
||||||
RdDUtility.confirmerSuppressionItem(this, item, li);
|
|
||||||
});
|
});
|
||||||
html.find('.item-vendre').click(async event => {
|
this.html.find('.structure-moins').click(async event => {
|
||||||
const item = RdDSheetUtility.getItem(event, this.actor);
|
this.actor.vehicleIncDec("structure", -1);
|
||||||
item?.proposerVente();
|
|
||||||
});
|
});
|
||||||
html.find('.item-montrer').click(async event => {
|
this.html.find('.structure-plus').click(async event => {
|
||||||
const item = RdDSheetUtility.getItem(event, this.actor);
|
this.actor.vehicleIncDec("structure", 1);
|
||||||
item?.postItem();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
html.find('.item-action').click(async event => {
|
|
||||||
const item = RdDSheetUtility.getItem(event, this.actor);
|
|
||||||
this.actor.actionItem(item);
|
|
||||||
});
|
|
||||||
|
|
||||||
html.find('.creer-un-objet').click(async event => {
|
|
||||||
RdDUtility.selectObjetType(this);
|
|
||||||
});
|
|
||||||
html.find('#nettoyer-conteneurs').click(async event => {
|
|
||||||
this.actor.nettoyerConteneurs();
|
|
||||||
});
|
|
||||||
|
|
||||||
html.find('.monnaie-plus').click(async event => {
|
|
||||||
this.actor.monnaieIncDec(RdDSheetUtility.getItemId(event), 1);
|
|
||||||
});
|
|
||||||
html.find('.monnaie-moins').click(async event => {
|
|
||||||
this.actor.monnaieIncDec(RdDSheetUtility.getItemId(event), -1);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Display info about queue
|
|
||||||
html.find('.conteneur-name a').click((event) => {
|
|
||||||
RdDUtility.toggleAfficheContenu(RdDSheetUtility.getItemId(event));
|
|
||||||
this.render(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
/** @override */
|
|
||||||
setPosition(options = {}) {
|
|
||||||
const position = super.setPosition(options);
|
|
||||||
const sheetHeader = this.element.find(".sheet-header");
|
|
||||||
const sheetTabs = this.element.find(".sheet-tabs");
|
|
||||||
const sheetBody = this.element.find(".sheet-body");
|
|
||||||
const bodyHeight = position.height - sheetHeader[0].clientHeight - sheetTabs[0].clientHeight;
|
|
||||||
sheetBody.css("height", bodyHeight);
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
/** @override */
|
|
||||||
_updateObject(event, formData) {
|
|
||||||
// Update the Actor
|
|
||||||
return this.actor.update(formData);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
1241
module/actor.js
@@ -129,7 +129,7 @@ export class ChatUtility {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getUsers(filter) {
|
static getUsers(filter) {
|
||||||
return Misc.getUsers().filter(filter).map(user => user.id);
|
return game.users.filter(filter).map(user => user.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
export const SYSTEM_RDD = 'foundryvtt-reve-de-dragon';
|
export const SYSTEM_RDD = 'foundryvtt-reve-de-dragon';
|
||||||
export const SYSTEM_SOCKET_ID = 'system.foundryvtt-reve-de-dragon';
|
export const SYSTEM_SOCKET_ID = 'system.foundryvtt-reve-de-dragon';
|
||||||
|
export const LOG_HEAD = 'RdD | ';
|
||||||
|
|
||||||
export const HIDE_DICE = 'hide';
|
export const HIDE_DICE = 'hide';
|
||||||
export const SHOW_DICE = 'show';
|
export const SHOW_DICE = 'show';
|
||||||
|
|||||||
127
module/dialog-chronologie.js
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
import { SYSTEM_RDD } from "./constants.js";
|
||||||
|
import { Grammar } from "./grammar.js";
|
||||||
|
|
||||||
|
|
||||||
|
const LATEST_USED_JOURNAL_ID = "chronologie-dernier-journal";
|
||||||
|
|
||||||
|
export class DialogChronologie extends Dialog {
|
||||||
|
|
||||||
|
static init() {
|
||||||
|
game.settings.register(SYSTEM_RDD, LATEST_USED_JOURNAL_ID, {
|
||||||
|
name: "Dernier article de journal utilisé pour enregistrer la chronologie",
|
||||||
|
scope: "client",
|
||||||
|
config: false,
|
||||||
|
default: "",
|
||||||
|
type: String
|
||||||
|
});
|
||||||
|
}
|
||||||
|
static async create() {
|
||||||
|
const dateRdD = game.system.rdd.calendrier.getCalendrier();
|
||||||
|
const dialogData = {
|
||||||
|
auteur: game.user.name,
|
||||||
|
isGM: game.user.isGM,
|
||||||
|
information: "",
|
||||||
|
journalId: game.settings.get(SYSTEM_RDD, LATEST_USED_JOURNAL_ID),
|
||||||
|
journaux: game.journal.filter(it => it.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)),
|
||||||
|
dateRdD: dateRdD,
|
||||||
|
jourRdD: dateRdD.jour +1,
|
||||||
|
heureRdD: game.system.rdd.calendrier.getCurrentHeure(),
|
||||||
|
dateReel: DialogChronologie.getCurrentDateTime()
|
||||||
|
};
|
||||||
|
const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-chronologie.html", dialogData);
|
||||||
|
const dialog = new DialogChronologie(html);
|
||||||
|
dialog.render(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(html) {
|
||||||
|
const options = {
|
||||||
|
classes: ["DialogChronologie"],
|
||||||
|
width: 500,
|
||||||
|
height: 'fit-content',
|
||||||
|
'z-index': 99999
|
||||||
|
};
|
||||||
|
const conf = {
|
||||||
|
title: "Chronologie",
|
||||||
|
content: html,
|
||||||
|
buttons: {
|
||||||
|
ajout: { label: "Ajouter", callback: it => this.ajouter() },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
super(conf, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getCurrentDateTime() {
|
||||||
|
return new Date().toLocaleString("sv-SE", {
|
||||||
|
year: "numeric",
|
||||||
|
month: "2-digit",
|
||||||
|
day: "2-digit",
|
||||||
|
hour: "2-digit",
|
||||||
|
minute: "2-digit"
|
||||||
|
}).replace(" ", "T");
|
||||||
|
}
|
||||||
|
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
this.html = html;
|
||||||
|
}
|
||||||
|
|
||||||
|
async ajouter() {
|
||||||
|
await this.forceValidation();
|
||||||
|
const { journalId, journalEntry } = this.findJournal();
|
||||||
|
// ajouter à la page ou créer une page
|
||||||
|
this.addContentToJournal(journalEntry, await this.prepareChronologieEntry());
|
||||||
|
|
||||||
|
this.storeLatestUsedJournalEntry(journalId);
|
||||||
|
}
|
||||||
|
|
||||||
|
async forceValidation() {
|
||||||
|
await this.html.find("form.rdddialogchrono :input").change();
|
||||||
|
}
|
||||||
|
|
||||||
|
findJournal() {
|
||||||
|
const journalId = this.html.find("form.rdddialogchrono :input[name='journalId']").val();
|
||||||
|
const journalEntry = game.journal.get(journalId);
|
||||||
|
return { journalId, journalEntry };
|
||||||
|
}
|
||||||
|
|
||||||
|
async prepareChronologieEntry() {
|
||||||
|
return await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/chronologie-entry.html", this.extractJournalParameters());
|
||||||
|
}
|
||||||
|
|
||||||
|
extractJournalParameters() {
|
||||||
|
return {
|
||||||
|
auteur: this.html.find("form.rdddialogchrono :input[name='auteur']").val(),
|
||||||
|
information: this.html.find("form.rdddialogchrono :input[name='information']").val(),
|
||||||
|
dateRdD: {
|
||||||
|
jour: this.html.find("form.rdddialogchrono :input[name='jourRdD']").val(),
|
||||||
|
moisRdD: this.html.find("form.rdddialogchrono :input[name='dateRdD.moisRdD.key']").val(),
|
||||||
|
annee: this.html.find("form.rdddialogchrono :input[name='dateRdD.annee']").val()
|
||||||
|
},
|
||||||
|
heureRdD: this.html.find("form.rdddialogchrono :input[name='heureRdD']").val(),
|
||||||
|
dateReel: this.html.find("form.rdddialogchrono :input[name='dateReel']").val().replace('T', ' ')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addContentToJournal(journalEntry, content) {
|
||||||
|
let page = journalEntry.pages.find(p => p.type == 'text' && Grammar.equalsInsensitive(p.name, 'Chronologie'));
|
||||||
|
if (page) {
|
||||||
|
page.update({ 'text.content': content + '\n' + page.text.content });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
journalEntry.createEmbeddedDocuments('JournalEntryPage', [this.newPageChronologie(content)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newPageChronologie(content) {
|
||||||
|
return new JournalEntryPage({
|
||||||
|
name: 'Chronologie',
|
||||||
|
type: 'text',
|
||||||
|
title: { show: true, level: 1 },
|
||||||
|
text: { content: content, format: 1 }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
storeLatestUsedJournalEntry(journalId) {
|
||||||
|
game.settings.set(SYSTEM_RDD, LATEST_USED_JOURNAL_ID, journalId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
import { ChatUtility } from "./chat-utility.js";
|
import { ChatUtility } from "./chat-utility.js";
|
||||||
import { HtmlUtility } from "./html-utility.js";
|
import { HtmlUtility } from "./html-utility.js";
|
||||||
import { RdDItemSigneDraconique } from "./item-signedraconique.js";
|
import { RdDItemSigneDraconique } from "./item-signedraconique.js";
|
||||||
import { Misc } from "./misc.js";
|
|
||||||
import { TMRUtility } from "./tmr-utility.js";
|
import { TMRUtility } from "./tmr-utility.js";
|
||||||
|
|
||||||
export class DialogCreateSigneDraconique extends Dialog {
|
export class DialogCreateSigneDraconique extends Dialog {
|
||||||
@@ -10,12 +9,13 @@ export class DialogCreateSigneDraconique extends Dialog {
|
|||||||
const signe = await RdDItemSigneDraconique.randomSigneDraconique({ephemere: true});
|
const signe = await RdDItemSigneDraconique.randomSigneDraconique({ephemere: true});
|
||||||
let dialogData = {
|
let dialogData = {
|
||||||
signe: signe,
|
signe: signe,
|
||||||
tmrs: TMRUtility.listSelectedTMR(signe.system.typesTMR ?? []),
|
tmrs: TMRUtility.buildSelectionTypesTMR(signe.system.typesTMR),
|
||||||
actors: game.actors.filter(actor => actor.isHautRevant()).map(actor => {
|
actors: game.actors.filter(actor => actor.isPersonnage() && actor.isHautRevant())
|
||||||
let actorData = duplicate(actor);
|
.map(actor => ({
|
||||||
actorData.selected = actor.hasPlayerOwner;
|
id: actor.id,
|
||||||
return actorData;
|
name: actor.name,
|
||||||
})
|
selected: true
|
||||||
|
}))
|
||||||
};
|
};
|
||||||
|
|
||||||
const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-create-signedraconique.html", dialogData);
|
const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-create-signedraconique.html", dialogData);
|
||||||
@@ -23,12 +23,11 @@ export class DialogCreateSigneDraconique extends Dialog {
|
|||||||
.render(true);
|
.render(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(dialogData, html, callback) {
|
constructor(dialogData, html) {
|
||||||
let options = { classes: ["DialogCreateSigneDraconiqueActorsActors"], width: 500, height: 650, 'z-index': 99999 };
|
let options = { classes: ["DialogCreateSigneDraconiqueActorsActors"], width: 500, height: 650, 'z-index': 99999 };
|
||||||
let conf = {
|
let conf = {
|
||||||
title: "Créer un signe",
|
title: "Créer un signe",
|
||||||
content: html,
|
content: html,
|
||||||
default: "Ajouter aux haut-rêvants",
|
|
||||||
buttons: {
|
buttons: {
|
||||||
"Ajouter aux haut-rêvants": { label: "Ajouter aux haut-rêvants", callback: it => { this._onCreerSigneActeurs(); } }
|
"Ajouter aux haut-rêvants": { label: "Ajouter aux haut-rêvants", callback: it => { this._onCreerSigneActeurs(); } }
|
||||||
}
|
}
|
||||||
@@ -36,15 +35,16 @@ export class DialogCreateSigneDraconique extends Dialog {
|
|||||||
super(conf, options);
|
super(conf, options);
|
||||||
this.dialogData = dialogData;
|
this.dialogData = dialogData;
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onCreerSigneActeurs() {
|
async _onCreerSigneActeurs() {
|
||||||
await $("[name='signe.system.ephemere']").change();
|
await this.html.find("[name='signe.system.ephemere']").change();
|
||||||
await $(".signe-xp-sort").change();
|
await this.html.find(".signe-xp-sort").change();
|
||||||
this.validerSigne();
|
this.validerSigne();
|
||||||
this.dialogData.actors.filter(it => it.selected).map(it => game.actors.get(it._id))
|
this.dialogData.actors.filter(it => it.selected)
|
||||||
.forEach(actor => this._createSigneForActor(actor, this.dialogData.signe));
|
.map(it => game.actors.get(it.id))
|
||||||
|
.forEach(actor => this._createSigneForActor(actor, this.dialogData.signe));
|
||||||
}
|
}
|
||||||
|
|
||||||
async _createSigneForActor(actor, signe) {
|
async _createSigneForActor(actor, signe) {
|
||||||
actor.createEmbeddedDocuments("Item", [signe]);
|
actor.createEmbeddedDocuments("Item", [signe]);
|
||||||
ChatMessage.create({
|
ChatMessage.create({
|
||||||
@@ -57,57 +57,67 @@ export class DialogCreateSigneDraconique extends Dialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
validerSigne() {
|
validerSigne() {
|
||||||
this.dialogData.signe.name = $("[name='signe.name']").val();
|
this.dialogData.signe.name = this.html.find("[name='signe.name']").val();
|
||||||
this.dialogData.signe.system.valeur.norm = $("[name='signe.system.valeur.norm']").val();
|
this.dialogData.signe.system.valeur.norm = this.html.find("[name='signe.system.valeur.norm']").val();
|
||||||
this.dialogData.signe.system.valeur.sign = $("[name='signe.system.valeur.sign']").val();
|
this.dialogData.signe.system.valeur.sign = this.html.find("[name='signe.system.valeur.sign']").val();
|
||||||
this.dialogData.signe.system.valeur.part = $("[name='signe.system.valeur.part']").val();
|
this.dialogData.signe.system.valeur.part = this.html.find("[name='signe.system.valeur.part']").val();
|
||||||
this.dialogData.signe.system.difficulte = $("[name='signe.system.difficulte']").val();
|
this.dialogData.signe.system.difficulte = this.html.find("[name='signe.system.difficulte']").val();
|
||||||
this.dialogData.signe.system.ephemere = $("[name='signe.system.ephemere']").prop("checked");
|
this.dialogData.signe.system.ephemere = this.html.find("[name='signe.system.ephemere']").prop("checked");
|
||||||
this.dialogData.signe.system.duree = $("[name='signe.system.duree']").val();
|
this.dialogData.signe.system.duree = this.html.find("[name='signe.system.duree']").val();
|
||||||
this.dialogData.signe.system.typesTMR = $(".select-tmr").val();
|
this.dialogData.signe.system.typesTMR = TMRUtility.buildListTypesTMRSelection(this.dialogData.tmrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
activateListeners(html) {
|
activateListeners(html) {
|
||||||
super.activateListeners(html);
|
super.activateListeners(html);
|
||||||
|
this.html = html;
|
||||||
this.setEphemere(this.dialogData.signe.system.ephemere);
|
this.setEphemere(this.dialogData.signe.system.ephemere);
|
||||||
html.find(".signe-aleatoire").click(event => this.setSigneAleatoire());
|
html.find(".signe-aleatoire").click(event => this.setSigneAleatoire());
|
||||||
html.find("[name='signe.system.ephemere']").change((event) => this.setEphemere(event.currentTarget.checked));
|
html.find("[name='signe.system.ephemere']").change((event) => this.setEphemere(event.currentTarget.checked));
|
||||||
html.find(".select-actor").change((event) => this.onSelectActor(event));
|
|
||||||
html.find(".signe-xp-sort").change((event) => this.onValeurXpSort(event));
|
html.find(".signe-xp-sort").change((event) => this.onValeurXpSort(event));
|
||||||
|
html.find("input.select-actor").change((event) => this.onSelectActor(event));
|
||||||
|
html.find("input.select-tmr").change((event) => this.onSelectTmr(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
async setSigneAleatoire() {
|
async setSigneAleatoire() {
|
||||||
const newSigne = await RdDItemSigneDraconique.randomSigneDraconique({ephemere: true});
|
const newSigne = await RdDItemSigneDraconique.randomSigneDraconique({ephemere: true});
|
||||||
|
|
||||||
$("[name='signe.name']").val(newSigne.name);
|
this.html.find("[name='signe.name']").val(newSigne.name);
|
||||||
$("[name='signe.system.valeur.norm']").val(newSigne.system.valeur.norm);
|
this.html.find("[name='signe.system.valeur.norm']").val(newSigne.system.valeur.norm);
|
||||||
$("[name='signe.system.valeur.sign']").val(newSigne.system.valeur.sign);
|
this.html.find("[name='signe.system.valeur.sign']").val(newSigne.system.valeur.sign);
|
||||||
$("[name='signe.system.valeur.part']").val(newSigne.system.valeur.part);
|
this.html.find("[name='signe.system.valeur.part']").val(newSigne.system.valeur.part);
|
||||||
$("[name='signe.system.difficulte']").val(newSigne.system.difficulte);
|
this.html.find("[name='signe.system.difficulte']").val(newSigne.system.difficulte);
|
||||||
$("[name='signe.system.duree']").val(newSigne.system.duree);
|
this.html.find("[name='signe.system.duree']").val(newSigne.system.duree);
|
||||||
$("[name='signe.system.ephemere']").prop("checked", newSigne.system.ephemere);
|
this.html.find("[name='signe.system.ephemere']").prop("checked", newSigne.system.ephemere);
|
||||||
$(".select-tmr").val(newSigne.system.typesTMR);
|
this.dialogData.tmrs = TMRUtility.buildSelectionTypesTMR(newSigne.system.typesTMR);
|
||||||
|
this.dialogData.tmrs.forEach(t => {
|
||||||
|
this.html.find(`[data-tmr-name='${t.name}']`).prop( "checked", t.selected);
|
||||||
|
})
|
||||||
this.setEphemere(newSigne.system.ephemere);
|
this.setEphemere(newSigne.system.ephemere);
|
||||||
}
|
}
|
||||||
|
|
||||||
async setEphemere(ephemere) {
|
async setEphemere(ephemere) {
|
||||||
this.dialogData.signe.system.ephemere = ephemere;
|
this.dialogData.signe.system.ephemere = ephemere;
|
||||||
HtmlUtility._showControlWhen($(".signe-system-duree"), ephemere);
|
HtmlUtility._showControlWhen(this.html.find(".signe-system-duree"), ephemere);
|
||||||
}
|
}
|
||||||
|
|
||||||
async onSelectActor(event) {
|
async onSelectActor(event) {
|
||||||
event.preventDefault();
|
const actorId = this.html.find(event.currentTarget)?.data("actor-id");
|
||||||
const options = event.currentTarget.options;
|
const actor = this.dialogData.actors.find(it => it.id == actorId);
|
||||||
for (var i = 0; i < options.length; i++) { // looping over the options
|
if (actor) {
|
||||||
const actorId = options[i].attributes["data-actor-id"].value;
|
actor.selected = event.currentTarget.checked;
|
||||||
const actor = this.dialogData.actors.find(it => it._id == actorId);
|
}
|
||||||
if (actor) {
|
|
||||||
actor.selected = options[i].selected;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onSelectTmr(event) {
|
||||||
|
const tmrName = this.html.find(event.currentTarget)?.data("tmr-name");
|
||||||
|
const onTmr = this.tmrs.find(it => it.name == tmrName);
|
||||||
|
if (onTmr){
|
||||||
|
onTmr.selected = event.currentTarget.checked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
onValeurXpSort(event) {
|
onValeurXpSort(event) {
|
||||||
const codeReussite = event.currentTarget.attributes['data-typereussite']?.value ?? 0;
|
const codeReussite = event.currentTarget.attributes['data-typereussite']?.value ?? 0;
|
||||||
const xp = Number(event.currentTarget.value);
|
const xp = Number(event.currentTarget.value);
|
||||||
|
|||||||
@@ -6,36 +6,43 @@ export class DialogFabriquerPotion extends Dialog {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async create(actor, item, dialogConfig) {
|
static async create(actor, item, dialogConfig) {
|
||||||
|
const min = DialogFabriquerPotion.nombreBrinsMinimum(item);
|
||||||
|
if (item.system.quantite < min) {
|
||||||
|
ui.notifications.warn(`Vous avez ${item.system.quantite} brins de ${item.name}, il en faut au moins ${min} pour faire une potion!`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
let potionData = DialogFabriquerPotion.prepareData(actor, item);
|
let potionData = DialogFabriquerPotion.prepareData(actor, item);
|
||||||
|
|
||||||
let conf = {
|
const html = await renderTemplate(dialogConfig.html, potionData);
|
||||||
title: `Fabriquer une potion de ${potionData.system.categorie}`,
|
|
||||||
content: await renderTemplate(dialogConfig.html, potionData),
|
|
||||||
default: potionData.buttonName,
|
|
||||||
};
|
|
||||||
|
|
||||||
let options = { classes: ["dialogfabriquerpotion"], width: 600, height: 160, 'z-index': 99999 };
|
let options = { classes: ["dialogfabriquerpotion"], width: 600, height: 160, 'z-index': 99999 };
|
||||||
mergeObject(options, dialogConfig.options ?? {}, { overwrite: true })
|
mergeObject(options, dialogConfig.options ?? {}, { overwrite: true })
|
||||||
|
|
||||||
const dialog = new DialogFabriquerPotion(actor, potionData, conf, options);
|
new DialogFabriquerPotion(actor, potionData, html, options).render(true);
|
||||||
dialog.render(true);
|
|
||||||
return dialog;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static prepareData(actor, item) {
|
static prepareData(actor, item) {
|
||||||
let potionData = duplicate(item)
|
let potionData = duplicate(item)
|
||||||
potionData.nbBrinsSelect = RdDUtility.buildListOptions(1, potionData.system.quantite);
|
potionData.nbBrinsSelect = RdDUtility.buildListOptions(
|
||||||
potionData.nbBrins = Math.min(potionData.system.quantite, DialogFabriquerPotion.getNombreBrinOptimal(potionData));
|
DialogFabriquerPotion.nombreBrinsMinimum(item),
|
||||||
|
DialogFabriquerPotion.nombreBrinsOptimal(item));
|
||||||
|
potionData.nbBrins = Math.min(potionData.system.quantite, DialogFabriquerPotion.nombreBrinsOptimal(potionData));
|
||||||
|
potionData.herbebonus = item.system.niveau;
|
||||||
potionData.buttonName = "Fabriquer";
|
potionData.buttonName = "Fabriquer";
|
||||||
return potionData;
|
return potionData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
constructor(actor, potionData, conf, options) {
|
constructor(actor, potionData, html, options) {
|
||||||
conf.buttons = {
|
const conf = {
|
||||||
[potionData.buttonName]: {
|
title: `Fabriquer une potion de ${potionData.system.categorie}`,
|
||||||
label: potionData.buttonName, callback: it => this.onFabriquer(it)
|
content: html,
|
||||||
|
default: 'fabriquer',
|
||||||
|
buttons: {
|
||||||
|
'fabriquer': {
|
||||||
|
label: potionData.buttonName, callback: it => this.onFabriquer(html)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -45,27 +52,37 @@ export class DialogFabriquerPotion extends Dialog {
|
|||||||
this.potionData = potionData;
|
this.potionData = potionData;
|
||||||
}
|
}
|
||||||
|
|
||||||
static getNombreBrinOptimal(herbeData) {
|
/* -------------------------------------------- */
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
this.html = html;
|
||||||
|
this.html.find("[name='nbBrins']").change(event => {
|
||||||
|
this.potionData.nbBrins = Misc.toInt(event.currentTarget.value);
|
||||||
|
const brinsManquants = Math.max(0, DialogFabriquerPotion.nombreBrinsOptimal(this.potionData) - this.potionData.nbBrins);
|
||||||
|
this.potionData.herbebonus = Math.max(0, this.potionData.system.niveau - brinsManquants)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async onFabriquer(html) {
|
||||||
|
await this.html.find("[name='nbBrins']").change();
|
||||||
|
this.actor.fabriquerPotion(this.potionData);
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
static nombreBrinsMinimum(herbeData) {
|
||||||
|
switch (herbeData.system.categorie ?? '') {
|
||||||
|
case "Soin": return 1 + Math.max(0, 12 - 2 * herbeData.system.niveau);
|
||||||
|
case "Repos": return 1 + Math.max(0, 7 - 2 * herbeData.system.niveau);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static nombreBrinsOptimal(herbeData) {
|
||||||
switch (herbeData.system.categorie ?? '') {
|
switch (herbeData.system.categorie ?? '') {
|
||||||
case "Soin": return 12 - herbeData.system.niveau;
|
case "Soin": return 12 - herbeData.system.niveau;
|
||||||
case "Repos": return 7 - herbeData.system.niveau;
|
case "Repos": return 7 - herbeData.system.niveau;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
activateListeners(html) {
|
|
||||||
super.activateListeners(html);
|
|
||||||
|
|
||||||
html.find("#nbBrins").change(event => {
|
|
||||||
this.potionData.nbBrins = Misc.toInt(event.currentTarget.value);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async onFabriquer(it) {
|
|
||||||
await $("#nbBrins").change();
|
|
||||||
this.actor.fabriquerPotion(this.potionData);
|
|
||||||
this.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,69 +1,33 @@
|
|||||||
|
|
||||||
import { Misc } from "./misc.js";
|
import { Monnaie } from "./item-monnaie.js";
|
||||||
import { RdDUtility } from "./rdd-utility.js";
|
import { RdDUtility } from "./rdd-utility.js";
|
||||||
|
|
||||||
export class DialogItemAchat extends Dialog {
|
export class DialogItemAchat extends Dialog {
|
||||||
|
|
||||||
static async onButtonAcheter(event) {
|
static venteData(button) {
|
||||||
const buttonAcheter = event.currentTarget;
|
const vendeurId = button.attributes['data-vendeurId']?.value;
|
||||||
if (!buttonAcheter.attributes['data-jsondata']?.value) {
|
|
||||||
ui.notifications.warn("Impossible d'acheter: informations sur l'objet manquantes")
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const chatMessageIdVente = RdDUtility.findChatMessageId(buttonAcheter);
|
|
||||||
|
|
||||||
const vendeurId = buttonAcheter.attributes['data-vendeurId']?.value;
|
|
||||||
const vendeur = vendeurId ? game.actors.get(vendeurId) : undefined;
|
const vendeur = vendeurId ? game.actors.get(vendeurId) : undefined;
|
||||||
const acheteur = RdDUtility.getSelectedActor();
|
const acheteur = RdDUtility.getSelectedActor();
|
||||||
|
const json = button.attributes['data-jsondata']?.value;
|
||||||
if (!acheteur && !vendeur) {
|
if (!acheteur && !vendeur) {
|
||||||
ui.notifications.info("Pas d'acheteur ni de vendeur, aucun changement");
|
ui.notifications.info("Pas d'acheteur ni de vendeur, aucun changement");
|
||||||
return;
|
return undefined;
|
||||||
|
}
|
||||||
|
if (!json) {
|
||||||
|
ui.notifications.warn("Impossible d'acheter: informations sur l'objet manquantes")
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
let venteData = DialogItemAchat.prepareVenteData(buttonAcheter, vendeurId, vendeur, acheteur);
|
const prixLot = Number(button.attributes['data-prixLot']?.value ?? 0);
|
||||||
const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-achat.html`, venteData);
|
return {
|
||||||
const dialog = new DialogItemAchat(html, vendeur, acheteur, venteData, chatMessageIdVente);
|
item: json ? JSON.parse(json) : undefined,
|
||||||
dialog.render(true);
|
actingUserId: game.user.id,
|
||||||
}
|
|
||||||
|
|
||||||
constructor(html, vendeur, acheteur, venteData, chatMessageIdVente) {
|
|
||||||
const isConsommable = venteData.item.type == 'nourritureboisson';
|
|
||||||
let options = { classes: ["dialogachat"], width: 400, height: isConsommable ? 450 : 350, 'z-index': 99999 };
|
|
||||||
|
|
||||||
const actionAchat = venteData.prixLot > 0 ? "Acheter" : "Prendre";
|
|
||||||
const buttons = {};
|
|
||||||
if (isConsommable) {
|
|
||||||
buttons["consommer"] = { label: venteData.item.system.boisson ? "Boire" : "Manger", callback: it => { this.onAchatConsommer(); } }
|
|
||||||
}
|
|
||||||
buttons[actionAchat] = { label: actionAchat, callback: it => { this.onAchat(); } };
|
|
||||||
buttons["decliner"] = { label: "Décliner", callback: it => { } };
|
|
||||||
let conf = {
|
|
||||||
title: venteData.acheteur? venteData.acheteur.name + " - " + actionAchat : actionAchat,
|
|
||||||
content: html,
|
|
||||||
default: actionAchat,
|
|
||||||
buttons: buttons
|
|
||||||
};
|
|
||||||
|
|
||||||
super(conf, options);
|
|
||||||
|
|
||||||
this.vendeur = vendeur;
|
|
||||||
this.acheteur = acheteur;
|
|
||||||
this.chatMessageIdVente = chatMessageIdVente;
|
|
||||||
this.venteData = venteData;
|
|
||||||
}
|
|
||||||
|
|
||||||
static prepareVenteData(buttonAcheter, vendeurId, vendeur, acheteur) {
|
|
||||||
const jsondata = buttonAcheter.attributes['data-jsondata']?.value;
|
|
||||||
const prixLot = parseInt(buttonAcheter.attributes['data-prixLot']?.value ?? 0);
|
|
||||||
let venteData = {
|
|
||||||
item: JSON.parse(jsondata),
|
|
||||||
vendeurId: vendeurId,
|
vendeurId: vendeurId,
|
||||||
vendeur: vendeur,
|
vendeur: vendeur,
|
||||||
acheteur:acheteur,
|
acheteur: acheteur,
|
||||||
tailleLot: parseInt(buttonAcheter.attributes['data-tailleLot']?.value ?? 1),
|
tailleLot: parseInt(button.attributes['data-tailleLot']?.value ?? 1),
|
||||||
quantiteIllimite: buttonAcheter.attributes['data-quantiteIllimite']?.value == 'true',
|
quantiteIllimite: button.attributes['data-quantiteIllimite']?.value == 'true',
|
||||||
quantiteNbLots: parseInt(buttonAcheter.attributes['data-quantiteNbLots']?.value),
|
quantiteNbLots: parseInt(button.attributes['data-quantiteNbLots']?.value),
|
||||||
choix: {
|
choix: {
|
||||||
nombreLots: 1,
|
nombreLots: 1,
|
||||||
seForcer: false,
|
seForcer: false,
|
||||||
@@ -71,23 +35,51 @@ export class DialogItemAchat extends Dialog {
|
|||||||
},
|
},
|
||||||
prixLot: prixLot,
|
prixLot: prixLot,
|
||||||
prixTotal: prixLot,
|
prixTotal: prixLot,
|
||||||
isVente: prixLot > 0
|
isVente: prixLot > 0,
|
||||||
|
chatMessageIdVente: RdDUtility.findChatMessageId(button)
|
||||||
};
|
};
|
||||||
return venteData;
|
}
|
||||||
|
|
||||||
|
static async onAcheter(venteData) {
|
||||||
|
const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-achat.html`, venteData);
|
||||||
|
new DialogItemAchat(html, venteData).render(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(html, venteData) {
|
||||||
|
const isConsommable = venteData.item.type == 'nourritureboisson' && venteData.acheteur?.isPersonnage();
|
||||||
|
let options = { classes: ["dialogachat"], width: 400, height: 'fit-content', 'z-index': 99999 };
|
||||||
|
|
||||||
|
const actionAchat = venteData.prixLot > 0 ? "Acheter" : "Prendre";
|
||||||
|
const buttons = {};
|
||||||
|
if (isConsommable) {
|
||||||
|
buttons["consommer"] = { label: venteData.item.system.boisson ? "Boire" : "Manger", callback: it => this.onAchatConsommer() }
|
||||||
|
}
|
||||||
|
buttons[actionAchat] = { label: actionAchat, callback: it => { this.onAchat(); } };
|
||||||
|
buttons["decliner"] = { label: "Décliner", callback: it => { } };
|
||||||
|
let conf = {
|
||||||
|
title: venteData.acheteur ? venteData.acheteur.name + " - " + actionAchat : actionAchat,
|
||||||
|
content: html,
|
||||||
|
default: actionAchat,
|
||||||
|
buttons: buttons
|
||||||
|
};
|
||||||
|
|
||||||
|
super(conf, options);
|
||||||
|
this.venteData = venteData;
|
||||||
}
|
}
|
||||||
|
|
||||||
async onAchat() {
|
async onAchat() {
|
||||||
await $(".nombreLots").change();
|
await this.html.find(".nombreLots").change();
|
||||||
(this.vendeur ?? this.acheteur).achatVente({
|
(this.venteData.vendeur ?? this.venteData.acheteur).achatVente({
|
||||||
userId: game.user.id,
|
userId: game.user.id,
|
||||||
vendeurId: this.vendeur?.id,
|
vendeurId: this.venteData.vendeur?.id,
|
||||||
acheteurId: this.acheteur?.id,
|
acheteurId: this.venteData.acheteur?.id,
|
||||||
prixTotal: this.venteData.prixTotal,
|
prixTotal: this.venteData.prixTotal,
|
||||||
chatMessageIdVente: this.chatMessageIdVente,
|
chatMessageIdVente: this.venteData.chatMessageIdVente,
|
||||||
choix: this.venteData.choix
|
choix: this.venteData.choix,
|
||||||
|
vente: this.venteData
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async onAchatConsommer() {
|
async onAchatConsommer() {
|
||||||
this.venteData.choix.consommer = true;
|
this.venteData.choix.consommer = true;
|
||||||
await this.onAchat();
|
await this.onAchat();
|
||||||
@@ -96,9 +88,9 @@ export class DialogItemAchat extends Dialog {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
activateListeners(html) {
|
activateListeners(html) {
|
||||||
super.activateListeners(html);
|
super.activateListeners(html);
|
||||||
|
this.html = html;
|
||||||
html.find(".nombreLots").change(event => this.setNombreLots(Number(event.currentTarget.value)));
|
this.html.find(".nombreLots").change(event => this.setNombreLots(Number(event.currentTarget.value)));
|
||||||
html.find(".se-forcer").change(event => this.setSeForcer(event));
|
this.html.find(".se-forcer").change(event => this.setSeForcer(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
setSeForcer(event) {
|
setSeForcer(event) {
|
||||||
@@ -106,9 +98,13 @@ export class DialogItemAchat extends Dialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setNombreLots(nombreLots) {
|
setNombreLots(nombreLots) {
|
||||||
this.venteData.choix.nombreLots = nombreLots;
|
if (nombreLots > this.venteData.quantiteNbLots) {
|
||||||
|
ui.notifications.warn(`Seulement ${this.venteData.quantiteNbLots} lots disponibles, vous ne pouvez pas en prendre ${nombreLots}`)
|
||||||
|
}
|
||||||
|
this.venteData.choix.nombreLots = Math.min(nombreLots, this.venteData.quantiteNbLots);
|
||||||
this.venteData.prixTotal = (nombreLots * this.venteData.prixLot).toFixed(2);
|
this.venteData.prixTotal = (nombreLots * this.venteData.prixLot).toFixed(2);
|
||||||
$(".prixTotal").text(this.venteData.prixTotal);
|
this.html.find(".nombreLots").val(this.venteData.choix.nombreLots);
|
||||||
|
this.html.find(".prixTotal").text(this.venteData.prixTotal);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2,14 +2,14 @@ import { Misc } from "./misc.js";
|
|||||||
|
|
||||||
export class DialogConsommer extends Dialog {
|
export class DialogConsommer extends Dialog {
|
||||||
|
|
||||||
static async create(actor, item, onActionItem = async ()=>{}) {
|
static async create(actor, item, onActionItem = async () => { }) {
|
||||||
const consommerData = DialogConsommer.prepareData(actor, item);
|
const consommerData = DialogConsommer.prepareData(actor, item);
|
||||||
const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-item-consommer.html', consommerData);
|
const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-item-consommer.html', consommerData);
|
||||||
return new DialogConsommer(actor, item, consommerData, html, onActionItem)
|
return new DialogConsommer(actor, item, consommerData, html, onActionItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(actor, item, consommerData, html, onActionItem = async ()=>{}) {
|
constructor(actor, item, consommerData, html, onActionItem = async () => { }) {
|
||||||
const options = { classes: ["dialogconsommer"], width: 350, height: 450, 'z-index': 99999 };
|
const options = { classes: ["dialogconsommer"], width: 350, height: 'fit-content', 'z-index': 99999 };
|
||||||
let conf = {
|
let conf = {
|
||||||
title: consommerData.title,
|
title: consommerData.title,
|
||||||
content: html,
|
content: html,
|
||||||
@@ -17,8 +17,9 @@ export class DialogConsommer extends Dialog {
|
|||||||
buttons: {
|
buttons: {
|
||||||
[consommerData.buttonName]: {
|
[consommerData.buttonName]: {
|
||||||
label: consommerData.buttonName, callback: async it => {
|
label: consommerData.buttonName, callback: async it => {
|
||||||
await this.onConsommer(it);
|
await this.onConsommer();
|
||||||
await onActionItem();}
|
await onActionItem();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -30,17 +31,23 @@ export class DialogConsommer extends Dialog {
|
|||||||
this.consommerData = consommerData;
|
this.consommerData = consommerData;
|
||||||
}
|
}
|
||||||
|
|
||||||
async onConsommer(event) {
|
activateListeners(html) {
|
||||||
await $(".se-forcer").change();
|
super.activateListeners(html);
|
||||||
await $(".consommer-doses").change();
|
this.html = html;
|
||||||
|
this.html.find(".se-forcer").change(event => this.setSeForcer(event));
|
||||||
|
this.html.find(".consommer-doses").change(event => this.selectDoses(event));
|
||||||
|
}
|
||||||
|
|
||||||
|
async onConsommer() {
|
||||||
|
await this.html.find(".se-forcer").change();
|
||||||
|
await this.html.find(".consommer-doses").change();
|
||||||
await this.actor.consommer(this.item, this.consommerData.choix);
|
await this.actor.consommer(this.item, this.consommerData.choix);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static prepareData(actor, item) {
|
static prepareData(actor, item) {
|
||||||
item = duplicate(item);
|
|
||||||
let consommerData = {
|
let consommerData = {
|
||||||
item: item,
|
item: duplicate(item),
|
||||||
cuisine: actor.getCompetence('cuisine'),
|
cuisine: actor.getCompetence('cuisine'),
|
||||||
choix: {
|
choix: {
|
||||||
doses: 1,
|
doses: 1,
|
||||||
@@ -48,33 +55,47 @@ export class DialogConsommer extends Dialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (item.type) {
|
switch (item.type) {
|
||||||
|
case 'herbe': case 'faune':
|
||||||
|
consommerData.title = 'Manger une portion crue: ';
|
||||||
|
consommerData.buttonName = "Manger";
|
||||||
|
break;
|
||||||
case 'nourritureboisson':
|
case 'nourritureboisson':
|
||||||
consommerData.title = item.system.boisson ? `${item.name}: boire une dose` : `${item.name}: manger une portion`;
|
consommerData.title = item.system.boisson ? 'Boire une dose: ' : 'Manger une portion: ';
|
||||||
consommerData.buttonName = item.system.boisson ? "Boire" : "Manger";
|
consommerData.buttonName = item.system.boisson ? "Boire" : "Manger";
|
||||||
break;
|
break;
|
||||||
case 'potion':
|
case 'potion':
|
||||||
consommerData.title = `${item.name}: boire la potion`;
|
consommerData.title = 'Boire la potion: ';
|
||||||
consommerData.buttonName = "Boire";
|
consommerData.buttonName = "Boire";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DialogConsommer.calculDoses(consommerData, consommerData.choix.doses)
|
consommerData.title += item.name;
|
||||||
|
DialogConsommer.calculDoses(consommerData, item)
|
||||||
return consommerData;
|
return consommerData;
|
||||||
}
|
}
|
||||||
|
|
||||||
static calculDoses(consommer) {
|
static calculDoses(consommer, item) {
|
||||||
const doses = consommer.choix.doses;
|
const doses = consommer.choix.doses;
|
||||||
consommer.totalSust = Misc.keepDecimals(doses * (consommer.item.system.sust ?? 0), 2);
|
switch (item.type) {
|
||||||
consommer.totalDesaltere = consommer.item.system.boisson
|
case 'herbe': case 'faune':
|
||||||
? Misc.keepDecimals(doses * (consommer.item.system.desaltere ?? 0), 2)
|
consommer.totalSust = doses;
|
||||||
: 0;
|
consommer.totalDesaltere = 0;
|
||||||
}
|
consommer.choix.sust = 1;
|
||||||
|
consommer.choix.quantite = 0;
|
||||||
|
consommer.choix.encombrement = Misc.keepDecimals(consommer.item.system.encombrement / item.system.sust, 2);
|
||||||
/* -------------------------------------------- */
|
return;
|
||||||
activateListeners(html) {
|
case 'nourritureboisson':
|
||||||
super.activateListeners(html);
|
consommer.choix.sust = consommer.item.system.sust;
|
||||||
html.find(".se-forcer").change(event => this.setSeForcer(event));
|
consommer.choix.quantite = doses;
|
||||||
html.find(".consommer-doses").change(event => this.selectDoses(event));
|
consommer.choix.encombrement = 0
|
||||||
|
consommer.totalSust = Misc.keepDecimals(doses * (consommer.item.system.sust ?? 0), 2);
|
||||||
|
consommer.totalDesaltere = consommer.item.system.boisson
|
||||||
|
? Misc.keepDecimals(doses * (consommer.item.system.desaltere ?? 0), 2)
|
||||||
|
: 0;
|
||||||
|
break;
|
||||||
|
case 'potion':
|
||||||
|
consommer.totalSust = 0
|
||||||
|
consommer.totalDesaltere = 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -84,8 +105,8 @@ export class DialogConsommer extends Dialog {
|
|||||||
|
|
||||||
selectDoses(event) {
|
selectDoses(event) {
|
||||||
this.consommerData.choix.doses = Number(event.currentTarget.value);
|
this.consommerData.choix.doses = Number(event.currentTarget.value);
|
||||||
DialogConsommer.calculDoses(this.consommerData);
|
DialogConsommer.calculDoses(this.consommerData, this.item);
|
||||||
$(".total-sust").text(this.consommerData.totalSust);
|
this.html.find(".total-sust").text(this.consommerData.totalSust);
|
||||||
$(".total-desaltere").text(this.consommerData.totalDesaltere);
|
this.html.find(".total-desaltere").text(this.consommerData.totalDesaltere);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
import { HtmlUtility } from "./html-utility.js";
|
import { HtmlUtility } from "./html-utility.js";
|
||||||
import { Misc } from "./misc.js";
|
|
||||||
|
|
||||||
export class DialogItemVente extends Dialog {
|
export class DialogItemVente extends Dialog {
|
||||||
|
|
||||||
static async create(item, callback) {
|
static async display(item, callback) {
|
||||||
const quantite = item.isConteneur() ? 1 : item.system.quantite;
|
const quantite = item.isConteneur() ? 1 : item.system.quantite;
|
||||||
const venteData = {
|
const venteData = {
|
||||||
item: item,
|
item: item,
|
||||||
@@ -20,11 +19,11 @@ export class DialogItemVente extends Dialog {
|
|||||||
isOwned: item.isOwned,
|
isOwned: item.isOwned,
|
||||||
};
|
};
|
||||||
const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-vente.html`, venteData);
|
const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-vente.html`, venteData);
|
||||||
return new DialogItemVente(venteData, html, callback);
|
return new DialogItemVente(venteData, html, callback).render(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(venteData, html, callback) {
|
constructor(venteData, html, callback) {
|
||||||
let options = { classes: ["dialogvente"], width: 400, height: 300, 'z-index': 99999 };
|
let options = { classes: ["dialogvente"], width: 400, height: 'fit-content', 'z-index': 99999 };
|
||||||
|
|
||||||
let conf = {
|
let conf = {
|
||||||
title: "Proposer",
|
title: "Proposer",
|
||||||
@@ -38,26 +37,26 @@ export class DialogItemVente extends Dialog {
|
|||||||
this.venteData = venteData;
|
this.venteData = venteData;
|
||||||
}
|
}
|
||||||
|
|
||||||
async onProposer(it) {
|
|
||||||
await $(".tailleLot").change();
|
|
||||||
await $(".quantiteNbLots").change();
|
|
||||||
await $(".quantiteIllimite").change();
|
|
||||||
await $(".prixLot").change();
|
|
||||||
this.callback(this.venteData);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
activateListeners(html) {
|
activateListeners(html) {
|
||||||
super.activateListeners(html);
|
super.activateListeners(html);
|
||||||
|
this.html = html;
|
||||||
|
HtmlUtility._showControlWhen(this.html.find(".quantiteNbLots"), !this.venteData.quantiteIllimite)
|
||||||
|
|
||||||
HtmlUtility._showControlWhen($(".quantiteNbLots"), !this.venteData.quantiteIllimite)
|
this.html.find(".tailleLot").change(event => this.setTailleLot(Number(event.currentTarget.value)));
|
||||||
|
this.html.find(".quantiteNbLots").change(event => this.setNbLots(Number(event.currentTarget.value)));
|
||||||
html.find(".tailleLot").change(event => this.setTailleLot(Number(event.currentTarget.value)));
|
this.html.find(".quantiteIllimite").change(event => this.setQuantiteIllimite(event.currentTarget.checked));
|
||||||
html.find(".quantiteNbLots").change(event => this.setNbLots(Number(event.currentTarget.value)));
|
this.html.find(".prixLot").change(event => this.setPrixLot(Number(event.currentTarget.value)));
|
||||||
html.find(".quantiteIllimite").change(event => this.setQuantiteIllimite(event.currentTarget.checked));
|
|
||||||
html.find(".prixLot").change(event => this.setPrixLot(Number(event.currentTarget.value)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async onProposer(it) {
|
||||||
|
await this.html.find(".tailleLot").change();
|
||||||
|
await this.html.find(".quantiteNbLots").change();
|
||||||
|
await this.html.find(".quantiteIllimite").change();
|
||||||
|
await this.html.find(".prixLot").change();
|
||||||
|
this.callback(this.venteData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
setPrixLot(prixLot) {
|
setPrixLot(prixLot) {
|
||||||
this.venteData.prixLot = prixLot;
|
this.venteData.prixLot = prixLot;
|
||||||
}
|
}
|
||||||
@@ -66,15 +65,15 @@ export class DialogItemVente extends Dialog {
|
|||||||
// recalculer le prix du lot
|
// recalculer le prix du lot
|
||||||
if (tailleLot != this.venteData.tailleLot) {
|
if (tailleLot != this.venteData.tailleLot) {
|
||||||
this.venteData.prixLot = (tailleLot * this.venteData.prixOrigine).toFixed(2);
|
this.venteData.prixLot = (tailleLot * this.venteData.prixOrigine).toFixed(2);
|
||||||
$(".prixLot").val(this.venteData.prixLot);
|
this.html.find(".prixLot").val(this.venteData.prixLot);
|
||||||
}
|
}
|
||||||
this.venteData.tailleLot = tailleLot;
|
this.venteData.tailleLot = tailleLot;
|
||||||
if (this.venteData.isOwned) {
|
if (this.venteData.isOwned) {
|
||||||
// recalculer le nombre de lots max
|
// recalculer le nombre de lots max
|
||||||
this.venteData.quantiteMaxLots = Math.floor(this.venteData.quantiteMax / tailleLot);
|
this.venteData.quantiteMaxLots = Math.floor(this.venteData.quantiteMax / tailleLot);
|
||||||
this.venteData.quantiteNbLots = Math.min(this.venteData.quantiteMaxLots, this.venteData.quantiteNbLots);
|
this.venteData.quantiteNbLots = Math.min(this.venteData.quantiteMaxLots, this.venteData.quantiteNbLots);
|
||||||
$(".quantiteNbLots").val(this.venteData.quantiteNbLots);
|
this.html.find(".quantiteNbLots").val(this.venteData.quantiteNbLots);
|
||||||
$(".quantiteNbLots").attr("max", this.venteData.quantiteMaxLots)
|
this.html.find(".quantiteNbLots").attr("max", this.venteData.quantiteMaxLots)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,12 +82,12 @@ export class DialogItemVente extends Dialog {
|
|||||||
nbLots = Math.max(0, Math.min(nbLots, this.venteData.quantiteMaxLots));
|
nbLots = Math.max(0, Math.min(nbLots, this.venteData.quantiteMaxLots));
|
||||||
}
|
}
|
||||||
this.venteData.quantiteNbLots = nbLots;
|
this.venteData.quantiteNbLots = nbLots;
|
||||||
$(".quantiteNbLots").val(this.venteData.quantiteNbLots);
|
this.html.find(".quantiteNbLots").val(this.venteData.quantiteNbLots);
|
||||||
}
|
}
|
||||||
|
|
||||||
setQuantiteIllimite(checked) {
|
setQuantiteIllimite(checked) {
|
||||||
this.venteData.quantiteIllimite = checked;
|
this.venteData.quantiteIllimite = checked;
|
||||||
$(".label-quantiteIllimite").text(this.venteData.quantiteIllimite ? "Illimités" : "disponibles");
|
this.html.find(".label-quantiteIllimite").text(this.venteData.quantiteIllimite ? "Illimités" : "disponibles");
|
||||||
HtmlUtility._showControlWhen($(".quantiteNbLots"), !this.venteData.quantiteIllimite)
|
HtmlUtility._showControlWhen(this.html.find(".quantiteNbLots"), !this.venteData.quantiteIllimite)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,9 +3,9 @@ import { Misc } from "./misc.js";
|
|||||||
export class DialogRepos extends Dialog {
|
export class DialogRepos extends Dialog {
|
||||||
|
|
||||||
static async create(actor) {
|
static async create(actor) {
|
||||||
let actorData = actor
|
const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-repos.html", actor);
|
||||||
const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-repos.html", actorData);
|
const dialog = new DialogRepos(html, actor);
|
||||||
new DialogRepos(html, actor).render(true);
|
dialog.render(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(html, actor) {
|
constructor(html, actor) {
|
||||||
@@ -21,13 +21,18 @@ export class DialogRepos extends Dialog {
|
|||||||
super(conf, options);
|
super(conf, options);
|
||||||
this.actor = actor;
|
this.actor = actor;
|
||||||
}
|
}
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
this.html = html;
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
async repos() {
|
async repos() {
|
||||||
await $("[name='nb-heures']").change();
|
await this.html.find("[name='nb-heures']").change();
|
||||||
await $("[name='nb-jours']").change();
|
await this.html.find("[name='nb-jours']").change();
|
||||||
const selection = await $("[name='repos']:checked").val();
|
const selection = await this.html.find("[name='repos']:checked").val();
|
||||||
const nbHeures = Number.parseInt(await $("[name='nb-heures']").val());
|
const nbHeures = Number.parseInt(await this.html.find("[name='nb-heures']").val());
|
||||||
const nbJours = Number.parseInt(await $("[name='nb-jours']").val());
|
const nbJours = Number.parseInt(await this.html.find("[name='nb-jours']").val());
|
||||||
switch (selection) {
|
switch (selection) {
|
||||||
case "sieste": {
|
case "sieste": {
|
||||||
await this.actor.dormir(nbHeures);
|
await this.actor.dormir(nbHeures);
|
||||||
@@ -35,7 +40,7 @@ export class DialogRepos extends Dialog {
|
|||||||
}
|
}
|
||||||
case "nuit": {
|
case "nuit": {
|
||||||
let heuresDormies = await this.actor.dormir(nbHeures);
|
let heuresDormies = await this.actor.dormir(nbHeures);
|
||||||
if (heuresDormies == nbHeures){
|
if (heuresDormies == nbHeures) {
|
||||||
await this.actor.dormirChateauDormant();
|
await this.actor.dormirChateauDormant();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -49,8 +54,4 @@ export class DialogRepos extends Dialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
|
||||||
activateListeners(html) {
|
|
||||||
super.activateListeners(html);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
37
module/dialog-select-target.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
export class DialogSelectTarget extends Dialog {
|
||||||
|
constructor(html, onSelectTarget, targets) {
|
||||||
|
const options = {
|
||||||
|
classes: ["rdd-dialog-select-target"],
|
||||||
|
width: 'fit-content',
|
||||||
|
height: 'fit-content',
|
||||||
|
'max-height': 600,
|
||||||
|
'z-index': 99999
|
||||||
|
};
|
||||||
|
const conf = {
|
||||||
|
title: "Choisir une cible",
|
||||||
|
content: html,
|
||||||
|
buttons: {}
|
||||||
|
};
|
||||||
|
super(conf, options);
|
||||||
|
this.onSelectTarget = onSelectTarget;
|
||||||
|
this.targets = targets;
|
||||||
|
}
|
||||||
|
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
this.html = html;
|
||||||
|
this.html.find("li.select-target").click((event) => {
|
||||||
|
this.targetSelected(this.html.find(event.currentTarget)?.data("token-id"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
targetSelected(tokenId) {
|
||||||
|
const target = this.targets.find(it => it.id == tokenId);
|
||||||
|
this.close();
|
||||||
|
if (target) {
|
||||||
|
this.onSelectTarget(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,39 +13,33 @@ export class DialogSplitItem extends Dialog {
|
|||||||
|
|
||||||
constructor(item, splitData, html, callback) {
|
constructor(item, splitData, html, callback) {
|
||||||
let options = { classes: ["dialogsplit"], width: 300, height: 160, 'z-index': 99999 };
|
let options = { classes: ["dialogsplit"], width: 300, height: 160, 'z-index': 99999 };
|
||||||
|
|
||||||
let conf = {
|
let conf = {
|
||||||
title: "Séparer en deux",
|
title: "Séparer en deux",
|
||||||
content: html,
|
content: html,
|
||||||
default: "separer",
|
default: "separer",
|
||||||
buttons: {
|
buttons: {
|
||||||
"separer": {
|
"separer": { label: "Séparer", callback: it => this.onSplit() }
|
||||||
label: "Séparer", callback: it => {
|
|
||||||
this.onSplit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
super(conf, options);
|
super(conf, options);
|
||||||
|
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
this.item = item;
|
this.item = item;
|
||||||
this.splitData = splitData;
|
this.splitData = splitData;
|
||||||
}
|
}
|
||||||
|
|
||||||
async onSplit(){
|
|
||||||
await $(".choix-quantite").change();
|
|
||||||
this.callback(this.item, this.splitData.choix.quantite);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
activateListeners(html) {
|
activateListeners(html) {
|
||||||
super.activateListeners(html);
|
super.activateListeners(html);
|
||||||
|
this.html = html;
|
||||||
html.find(".choix-quantite").change(event => {
|
this.html.find(".choix-quantite").change(event => {
|
||||||
this.splitData.choix.quantite = Number(event.currentTarget.value);
|
this.splitData.choix.quantite = Number(event.currentTarget.value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async onSplit() {
|
||||||
|
await this.html.find(".choix-quantite").change();
|
||||||
|
this.callback(this.item, this.splitData.choix.quantite);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,18 +1,18 @@
|
|||||||
import { Misc } from "./misc.js";
|
|
||||||
|
|
||||||
export class DialogStress extends Dialog {
|
export class DialogStress extends Dialog {
|
||||||
|
|
||||||
static async distribuerStress() {
|
static async distribuerStress() {
|
||||||
let dialogData = {
|
const dialogData = {
|
||||||
motif: "Motif",
|
motif: "Motif",
|
||||||
stress: 10,
|
stress: 10,
|
||||||
immediat: false,
|
immediat: false,
|
||||||
actors: game.actors.filter(actor => actor.hasPlayerOwner && actor.isPersonnage())
|
actors: game.actors.filter(actor => actor.hasPlayerOwner && actor.isPersonnage())
|
||||||
.map(actor => {
|
.map(actor => ({
|
||||||
let actorData = duplicate(actor);
|
id: actor.id,
|
||||||
actorData.selected = actor.hasPlayerOwner;
|
name: actor.name,
|
||||||
return actorData;
|
selected: true
|
||||||
})
|
})
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-stress.html", dialogData);
|
const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-stress.html", dialogData);
|
||||||
@@ -21,52 +21,43 @@ export class DialogStress extends Dialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constructor(dialogData, html) {
|
constructor(dialogData, html) {
|
||||||
let options = { classes: ["DialogStress"], width: 400, height: 320, 'z-index': 99999 };
|
const options = { classes: ["DialogStress"],
|
||||||
let conf = {
|
width: 400,
|
||||||
|
height: 'fit-content',
|
||||||
|
'z-index': 99999
|
||||||
|
};
|
||||||
|
const conf = {
|
||||||
title: "Donner du stress",
|
title: "Donner du stress",
|
||||||
content: html,
|
content: html,
|
||||||
buttons: {
|
buttons: {
|
||||||
"Stress": { label: "Stress !", callback: it => { this._onStress(); } }
|
stress: { label: "Stress !", callback: it => { this.onStress(); } }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
super(conf, options);
|
super(conf, options);
|
||||||
this.dialogData = dialogData;
|
this.dialogData = dialogData;
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onStress() {
|
activateListeners(html) {
|
||||||
this.validerStress();
|
super.activateListeners(html);
|
||||||
const compteur = this.dialogData.immediat ? 'experience' : 'stress';
|
this.html = html;
|
||||||
const stress = this.dialogData.stress;
|
this.html.find("input.select-actor").change((event) => this.onSelectActor(event));
|
||||||
const motif = this.dialogData.motif;
|
}
|
||||||
|
|
||||||
|
async onStress() {
|
||||||
|
const motif = this.html.find("form.rdddialogstress input[name='motif']").val();
|
||||||
|
const stress = Number(this.html.find("form.rdddialogstress input[name='stress']").val());
|
||||||
|
const compteur = (this.html.find("form.rdddialogstress input[name='immediat']").prop("checked")) ? 'experience' : 'stress';
|
||||||
|
|
||||||
this.dialogData.actors.filter(it => it.selected)
|
this.dialogData.actors.filter(it => it.selected)
|
||||||
.map(it => game.actors.get(it._id))
|
.map(it => game.actors.get(it.id))
|
||||||
.forEach(actor => actor.distribuerStress(compteur, stress, motif));
|
.forEach(actor => actor.distribuerStress(compteur, stress, motif));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
validerStress() {
|
|
||||||
this.dialogData.motif = $("form.rdddialogstress input[name='motif']").val();
|
|
||||||
this.dialogData.stress = $("form.rdddialogstress input[name='stress']").val();
|
|
||||||
this.dialogData.immediat = $("form.rdddialogstress input[name='immediat']").prop("checked");;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
activateListeners(html) {
|
|
||||||
super.activateListeners(html);
|
|
||||||
html.find(".select-actor").change((event) => this.onSelectActor(event));
|
|
||||||
}
|
|
||||||
|
|
||||||
async onSelectActor(event) {
|
async onSelectActor(event) {
|
||||||
event.preventDefault();
|
const actorId = this.html.find(event.currentTarget)?.data("actor-id");
|
||||||
const options = event.currentTarget.options;
|
const actor = this.dialogData.actors.find(it => it.id == actorId);
|
||||||
for (var i = 0; i < options.length; i++) { // looping over the options
|
if (actor) {
|
||||||
const actorId = options[i].attributes["data-actor-id"].value;
|
actor.selected = event.currentTarget.checked;
|
||||||
const actor = this.dialogData.actors.find(it => it._id == actorId);
|
}
|
||||||
if (actor) {
|
|
||||||
actor.selected = options[i].selected;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
71
module/dialog-validation-encaissement.js
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
import { HIDE_DICE, SHOW_DICE } from "./constants.js";
|
||||||
|
import { RdDUtility } from "./rdd-utility.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extend the base Dialog entity by defining a custom window to perform roll.
|
||||||
|
* @extends {Dialog}
|
||||||
|
*/
|
||||||
|
export class DialogValidationEncaissement extends Dialog {
|
||||||
|
|
||||||
|
static async validerEncaissement(actor, rollData, armure, show, onEncaisser) {
|
||||||
|
let encaissement = await RdDUtility.jetEncaissement(rollData, armure, { showDice: HIDE_DICE });
|
||||||
|
const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-validation-encaissement.html', {
|
||||||
|
actor: actor,
|
||||||
|
rollData: rollData,
|
||||||
|
encaissement: encaissement,
|
||||||
|
show: show
|
||||||
|
});
|
||||||
|
const dialog = new DialogValidationEncaissement(html, actor, rollData, armure, encaissement, show, onEncaisser);
|
||||||
|
dialog.render(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
constructor(html, actor, rollData, armure, encaissement, show, onEncaisser) {
|
||||||
|
// Common conf
|
||||||
|
let buttons = {
|
||||||
|
"valider": { label: "Valider", callback: html => this.validerEncaissement() },
|
||||||
|
"annuler": { label: "Annuler", callback: html => { } },
|
||||||
|
};
|
||||||
|
|
||||||
|
let dialogConf = {
|
||||||
|
title: "Validation d'encaissement",
|
||||||
|
content: html,
|
||||||
|
buttons: buttons,
|
||||||
|
default: "valider"
|
||||||
|
}
|
||||||
|
|
||||||
|
let dialogOptions = {
|
||||||
|
classes: ["rdd-roll-dialog"],
|
||||||
|
width: 350,
|
||||||
|
height: 290
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select proper roll dialog template and stuff
|
||||||
|
super(dialogConf, dialogOptions);
|
||||||
|
|
||||||
|
this.actor = actor
|
||||||
|
this.rollData = rollData;
|
||||||
|
this.armure = armure;
|
||||||
|
this.encaissement = encaissement;
|
||||||
|
this.show = show;
|
||||||
|
this.onEncaisser = onEncaisser;
|
||||||
|
this.forceDiceResult = {total: encaissement.roll.result };
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
this.html = html;
|
||||||
|
this.html.find('input.encaissement-roll-result').keyup(async event => {
|
||||||
|
this.forceDiceResult.total = event.currentTarget.value;
|
||||||
|
this.encaissement = await RdDUtility.jetEncaissement(this.rollData, this.armure, { showDice: HIDE_DICE, forceDiceResult: this.forceDiceResult});
|
||||||
|
this.html.find('label.encaissement-total').text(this.encaissement.total);
|
||||||
|
this.html.find('label.encaissement-blessure').text(this.encaissement.blessures)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async validerEncaissement() {
|
||||||
|
this.encaissement = await RdDUtility.jetEncaissement(this.rollData, this.armure, { showDice: SHOW_DICE, forceDiceResult: this.forceDiceResult});
|
||||||
|
this.onEncaisser(this.encaissement, this.show)
|
||||||
|
}
|
||||||
|
}
|
||||||
137
module/effets-rencontres.js
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
import { ChatUtility } from "./chat-utility.js";
|
||||||
|
import { Poetique } from "./poetique.js";
|
||||||
|
import { RdDDice } from "./rdd-dice.js";
|
||||||
|
import { TMRUtility } from "./tmr-utility.js";
|
||||||
|
|
||||||
|
export class EffetsRencontre {
|
||||||
|
|
||||||
|
static messager = async (dialog, context) => {
|
||||||
|
dialog.setRencontreState('messager', TMRUtility.getTMRPortee(context.tmr.coord, context.rencontre.system.force));
|
||||||
|
}
|
||||||
|
|
||||||
|
static passeur = async (dialog, context) => {
|
||||||
|
dialog.setRencontreState('passeur', TMRUtility.getTMRPortee(context.tmr.coord, context.rencontre.system.force));
|
||||||
|
}
|
||||||
|
|
||||||
|
static teleportation_typecase = async (dialog, context) => {
|
||||||
|
dialog.setRencontreState('changeur', TMRUtility.getCasesType(context.tmr.type));
|
||||||
|
}
|
||||||
|
|
||||||
|
static rencontre_persistante = async (dialog, context) => {
|
||||||
|
dialog.setRencontreState('persistant', []);
|
||||||
|
}
|
||||||
|
|
||||||
|
static reve_plus_force = async (dialog, context) => { await EffetsRencontre.$reve_plus(context.actor, context.rencontre.system.force) }
|
||||||
|
static reve_plus_1 = async (dialog, context) => { await EffetsRencontre.$reve_plus(context.actor, 1) }
|
||||||
|
static reve_moins_force = async (dialog, context) => { await EffetsRencontre.$reve_plus(context.actor, -context.rencontre.system.force) }
|
||||||
|
static reve_moins_1 = async (dialog, context) => { await EffetsRencontre.$reve_plus(context.actor, -1) }
|
||||||
|
static $reve_plus = async (actor, valeur) => { await actor.reveActuelIncDec(valeur) }
|
||||||
|
|
||||||
|
static vie_moins_1 = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, -1) }
|
||||||
|
static vie_moins_force = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, -context.rencontre.system.force) }
|
||||||
|
static $vie_plus = async (actor, valeur) => { await actor.santeIncDec("vie", valeur) }
|
||||||
|
|
||||||
|
static moral_plus_1 = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, 1) }
|
||||||
|
static moral_moins_1 = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, -1) }
|
||||||
|
static $moral_plus = async (actor, valeur) => { await actor.moralIncDec(valeur) }
|
||||||
|
|
||||||
|
static end_moins_1 = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, -1) }
|
||||||
|
static end_moins_force = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, -context.rencontre.system.force) }
|
||||||
|
static $end_plus = async (actor, valeur) => { await actor.santeIncDec("endurance", valeur) }
|
||||||
|
|
||||||
|
static fatigue_plus_1 = async (dialog, context) => { await EffetsRencontre.$fatigue_plus(context.actor, 1) }
|
||||||
|
static fatigue_plus_force = async (dialog, context) => { await EffetsRencontre.$fatigue_plus(context.actor, context.rencontre.system.force) }
|
||||||
|
static fatigue_moins_1 = async (dialog, context) => { await EffetsRencontre.$fatigue_plus(context.actor, -1) }
|
||||||
|
static fatigue_moins_force = async (dialog, context) => { await EffetsRencontre.$fatigue_plus(context.actor, -context.rencontre.system.force) }
|
||||||
|
static $fatigue_plus = async (actor, valeur) => { await actor.santeIncDec("fatigue", valeur) }
|
||||||
|
|
||||||
|
static perte_chance = async (dialog, context) => {
|
||||||
|
const perte = context.rolled.isETotal ? context.rencontre.system.force : 1;
|
||||||
|
await context.actor.chanceActuelleIncDec("fatigue", -perte);
|
||||||
|
}
|
||||||
|
|
||||||
|
static xp_sort_force = async (dialog, context) => {
|
||||||
|
let competence = context.competence;
|
||||||
|
if (competence) {
|
||||||
|
const xpSort = Misc.toInt(competence.system.xp_sort) + context.rencontre.system.force;
|
||||||
|
await this.updateEmbeddedDocuments("Item", [{ _id: compData._id, 'system.xp_sort': xpSort }]);
|
||||||
|
await this.updateExperienceLog("XP Sort", xpSort, `Rencontre d'un ${context.rencontre.name} en TMR`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static stress_plus_1 = async (dialog, context) => {
|
||||||
|
await context.actor.addCompteurValue('stress', 1, `Rencontre d'un ${context.rencontre.name} en TMR`);
|
||||||
|
}
|
||||||
|
|
||||||
|
static reinsertion = async (dialog, context) => {
|
||||||
|
await EffetsRencontre.$reinsertion(dialog, context.actor, it => true)
|
||||||
|
}
|
||||||
|
|
||||||
|
static teleportation_aleatoire_typecase = async (dialog, context) => {
|
||||||
|
await EffetsRencontre.$reinsertion(dialog, context.actor, it => it.type == context.tmr.type && it.coord != context.tmr.coord)
|
||||||
|
}
|
||||||
|
|
||||||
|
static demireve_rompu = async (dialog, context) => {
|
||||||
|
dialog.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
static sort_aleatoire = async (dialog, context) => {
|
||||||
|
context.sortReserve = await RdDDice.rollOneOf(context.actor.itemTypes['sortreserve']);
|
||||||
|
if (context.sortReserve) {
|
||||||
|
context.newTMR = TMRUtility.getTMR(context.sortReserve.system.coord);
|
||||||
|
await dialog.positionnerDemiReve(context.newTMR.coord);
|
||||||
|
await dialog.processSortReserve(context.sortReserve);
|
||||||
|
dialog.close();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
await EffetsRencontre.$reinsertion(dialog, context.actor, it => true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static deplacement_aleatoire = async (dialog, context) => {
|
||||||
|
const oldCoord = context.actor.system.reve.tmrpos.coord;
|
||||||
|
const newTmr = await TMRUtility.deplaceTMRAleatoire(context.actor, oldCoord);
|
||||||
|
await dialog.positionnerDemiReve(newTmr.coord)
|
||||||
|
}
|
||||||
|
|
||||||
|
static rdd_part_tete = async (dialog, context) => {
|
||||||
|
mergeObject(context, {
|
||||||
|
tete: context.rolled.isPart,
|
||||||
|
poesie: await Poetique.getExtrait()
|
||||||
|
})
|
||||||
|
ChatMessage.create({
|
||||||
|
whisper: ChatUtility.getWhisperRecipientsAndGMs(context.actor.name),
|
||||||
|
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-reve-de-dragon.html`, context)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static rdd_echec_queue = async (dialog, context) => {
|
||||||
|
mergeObject(context, {
|
||||||
|
queues: [await context.actor.ajouterQueue()],
|
||||||
|
poesie: await Poetique.getExtrait()
|
||||||
|
})
|
||||||
|
if (context.rolled.isETotal) {
|
||||||
|
context.queues.push(await context.actor.ajouterQueue());
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatMessage.create({
|
||||||
|
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
|
||||||
|
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-reve-de-dragon.html`, context)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static experience_particuliere = async (dialog, context) => {
|
||||||
|
await context.actor.appliquerAjoutExperience(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
static regain_seuil = async (dialog, context) => {
|
||||||
|
await context.actor.regainPointDeSeuil()
|
||||||
|
}
|
||||||
|
|
||||||
|
static async $reinsertion(dialog, actor, filter) {
|
||||||
|
const newTMR = await TMRUtility.getTMRAleatoire(filter);
|
||||||
|
await actor.forcerPositionTMRInconnue(newTMR);
|
||||||
|
await dialog.positionnerDemiReve(newTMR.coord);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
223
module/environnement.js
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
import { SYSTEM_RDD } from "./constants.js";
|
||||||
|
import { Grammar } from "./grammar.js";
|
||||||
|
import { Misc } from "./misc.js";
|
||||||
|
import { CompendiumTableHelpers, CompendiumTable } from "./settings/system-compendiums.js";
|
||||||
|
|
||||||
|
const RARETES = [
|
||||||
|
{ name: 'Commune', frequence: 54, min: 27, max: 108 },
|
||||||
|
{ name: 'Frequente', frequence: 18, min: 9, max: 36 },
|
||||||
|
{ name: 'Rare', frequence: 6, min: 3, max: 12 },
|
||||||
|
{ name: 'Rarissime', frequence: 2, min: 1, max: 4 }]
|
||||||
|
const DEFAULT_RARETE = 1;
|
||||||
|
|
||||||
|
const SETTINGS_LISTE_MILIEUX = "liste-milieux";
|
||||||
|
const MILIEUX = [
|
||||||
|
"Collines",
|
||||||
|
"Cours d'eau",
|
||||||
|
"Déserts",
|
||||||
|
"Forêts",
|
||||||
|
"Marais",
|
||||||
|
"Maritimes",
|
||||||
|
"Montagnes",
|
||||||
|
"Plaines",
|
||||||
|
"Sous-sols"
|
||||||
|
]
|
||||||
|
const ITEM_ENVIRONNEMENT_TYPES = [
|
||||||
|
'herbe', 'ingredient', 'faune'
|
||||||
|
]
|
||||||
|
|
||||||
|
export class Environnement {
|
||||||
|
|
||||||
|
static init() {
|
||||||
|
game.settings.register(SYSTEM_RDD, SETTINGS_LISTE_MILIEUX, {
|
||||||
|
name: "Liste des milieux proposés",
|
||||||
|
hint: "Liste des milieux proposés pour la faune&flore, séparés par des virgules",
|
||||||
|
scope: "world",
|
||||||
|
config: true,
|
||||||
|
default: MILIEUX.reduce(Misc.joining(',')),
|
||||||
|
type: String
|
||||||
|
});
|
||||||
|
game.system.rdd.environnement = new Environnement();
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.table = new CompendiumTable('faune-flore-mineraux', 'Item', ITEM_ENVIRONNEMENT_TYPES)
|
||||||
|
}
|
||||||
|
|
||||||
|
static getRarete(name = undefined) {
|
||||||
|
return RARETES.find(it => it.name == name) ?? RARETES[DEFAULT_RARETE];
|
||||||
|
}
|
||||||
|
|
||||||
|
static getFrequenceRarete(rarete, field = undefined) {
|
||||||
|
const selected = this.getRarete(rarete);
|
||||||
|
return selected[field];
|
||||||
|
}
|
||||||
|
|
||||||
|
async milieux() {
|
||||||
|
return Object.values(await this.mapMilieux());
|
||||||
|
}
|
||||||
|
|
||||||
|
async mapMilieux() {
|
||||||
|
const compendiumItems = await this.getElements(it => 1, it => ITEM_ENVIRONNEMENT_TYPES.includes(it.type));
|
||||||
|
return Misc.indexLowercase(this.getMilieuxSettings().concat(Environnement.listMilieux(compendiumItems)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static listMilieux(items) {
|
||||||
|
return Misc.concat(items.map(it => Environnement.$itemToMilieux(it).filter(m => m)));
|
||||||
|
}
|
||||||
|
|
||||||
|
async autresMilieux(item) {
|
||||||
|
const mapMilieux = await this.mapMilieux();
|
||||||
|
const milieuxExistants = Environnement.$itemToMilieux(item).map(it => Grammar.toLowerCaseNoAccent(it));
|
||||||
|
return Object.keys(mapMilieux)
|
||||||
|
.filter(it => !milieuxExistants.includes(it))
|
||||||
|
.map(it => mapMilieux[it]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static $itemToMilieux(item) {
|
||||||
|
return item.system.environnement.map(env => env.milieu);
|
||||||
|
}
|
||||||
|
|
||||||
|
getMilieuxSettings() {
|
||||||
|
return game.settings.get(SYSTEM_RDD, SETTINGS_LISTE_MILIEUX).split(',').map(it => it.trim()).filter(it => it != '');
|
||||||
|
}
|
||||||
|
|
||||||
|
async findEnvironnementsLike(search) {
|
||||||
|
const milieux = await this.mapMilieux();
|
||||||
|
const searchLower = Grammar.toLowerCaseNoAccent(search);
|
||||||
|
const keys = Object.keys(milieux).filter(it => it.includes(searchLower));
|
||||||
|
if (keys.length > 1) {
|
||||||
|
const milieuExact = milieux[searchLower];
|
||||||
|
if (milieuExact) {
|
||||||
|
return [milieuExact];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return keys.map(k => milieux[k]);
|
||||||
|
}
|
||||||
|
|
||||||
|
async searchToChatMessage(milieux, typeName) {
|
||||||
|
const table = await this.buildEnvironnementTable(milieux);
|
||||||
|
await CompendiumTableHelpers.tableToChatMessage(table, 'Item', ITEM_ENVIRONNEMENT_TYPES, typeName);
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
async getRandom(milieux, typeName) {
|
||||||
|
const table = await this.buildEnvironnementTable(milieux);
|
||||||
|
return await CompendiumTableHelpers.getRandom(table, 'Item', ITEM_ENVIRONNEMENT_TYPES, undefined, typeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
async buildEnvironnementTable(milieux) {
|
||||||
|
const filterMilieux = item => item.system?.environnement.filter(env => milieux.includes(env.milieu));
|
||||||
|
const itemRareteEnMilieu = item => {
|
||||||
|
const raretes = filterMilieux(item);
|
||||||
|
const frequenceMax = Math.max(raretes.map(env => env.frequence));
|
||||||
|
return raretes.find(env => env.frequence == frequenceMax);
|
||||||
|
}
|
||||||
|
const itemFrequenceEnMilieu = item => itemRareteEnMilieu(item)?.frequence ?? 0;
|
||||||
|
const isPresentEnMilieu = item => itemFrequenceEnMilieu(item) > 0;
|
||||||
|
return await this.table.buildTable(itemFrequenceEnMilieu, isPresentEnMilieu);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async getElements(itemFrequence, filter) {
|
||||||
|
return await this.table.getContent(itemFrequence, filter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class EnvironmentSheetHelper {
|
||||||
|
|
||||||
|
static defaultOptions(defaultOptions) {
|
||||||
|
return mergeObject(defaultOptions, {
|
||||||
|
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "informations" }]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static setPosition(sheet, superPosition) {
|
||||||
|
const position = superPosition;
|
||||||
|
const sheetHeader = sheet.element.find(".sheet-header");
|
||||||
|
const sheetBody = sheet.element.find(".sheet-body");
|
||||||
|
sheetBody.css("height", position.height - sheetHeader[0].clientHeight)
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async getData(sheet, formData) {
|
||||||
|
return mergeObject(formData, {
|
||||||
|
milieux: await game.system.rdd.environnement.autresMilieux(sheet.item)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static activateListeners(sheet) {
|
||||||
|
if (!sheet.options.editable) return;
|
||||||
|
|
||||||
|
sheet.html.find("input.input-selection-milieu").keypress(event => {
|
||||||
|
if (event.keyCode == '13') {
|
||||||
|
EnvironmentSheetHelper.onAddMilieu(sheet, event);
|
||||||
|
}
|
||||||
|
event.stopPropagation();
|
||||||
|
})
|
||||||
|
sheet.html.find("a.milieu-add").click(event => EnvironmentSheetHelper.onAddMilieu(sheet, event));
|
||||||
|
sheet.html.find("div.environnement-milieu a.milieu-delete").click(event => EnvironmentSheetHelper.onDeleteMilieu(sheet, event));
|
||||||
|
sheet.html.find("div.environnement-milieu select.environnement-rarete").change(event => EnvironmentSheetHelper.onChange(sheet, event,
|
||||||
|
updated => EnvironmentSheetHelper.$changeRarete(sheet, event, updated)));
|
||||||
|
sheet.html.find("div.environnement-milieu input[name='environnement-frequence']").change(event => EnvironmentSheetHelper.onChange(sheet, event,
|
||||||
|
updated => EnvironmentSheetHelper.$changeFrequence(sheet, event, updated)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static $changeFrequence(sheet, event, updated) {
|
||||||
|
updated.frequence = Number(sheet.html.find(event.currentTarget).val());
|
||||||
|
}
|
||||||
|
|
||||||
|
static $changeRarete(sheet, event, updated) {
|
||||||
|
const name = sheet.html.find(event.currentTarget).val();
|
||||||
|
const rarete = Environnement.getRarete(name);
|
||||||
|
updated.rarete = rarete.name;
|
||||||
|
updated.frequence = rarete.frequence;
|
||||||
|
// updated.frequence = Math.min(
|
||||||
|
// Math.max(rarete.min, updated.frequence ?? rarete.frequence),
|
||||||
|
// rarete.max);
|
||||||
|
}
|
||||||
|
|
||||||
|
static async onAddMilieu(sheet, event) {
|
||||||
|
const milieu = sheet.html.find('input.input-selection-milieu').val();
|
||||||
|
if (!milieu) {
|
||||||
|
ui.notifications.warn(`Choisissez le milieu dans lequel se trouve le/la ${sheet.item.name}`);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const list = sheet.item.system.environnement;
|
||||||
|
const exists = list.find(it => it.milieu == milieu);
|
||||||
|
if (exists) {
|
||||||
|
ui.notifications.warn(`${sheet.item.name} a déjà une rareté ${exists.rarete} en ${milieu} (fréquence: ${exists.frequence})`);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const rarete = Environnement.getRarete();
|
||||||
|
const newList = [...list, { milieu, rarete: rarete.name, frequence: rarete.frequence }].sort(Misc.ascending(it => it.milieu))
|
||||||
|
await sheet.item.update({ 'system.environnement': newList })
|
||||||
|
}
|
||||||
|
|
||||||
|
static async onDeleteMilieu(sheet, event) {
|
||||||
|
const milieu = EnvironmentSheetHelper.$getEventMilieu(event);
|
||||||
|
if (milieu != undefined) {
|
||||||
|
const newList = sheet.item.system.environnement.filter(it => it.milieu != milieu)
|
||||||
|
.sort(Misc.ascending(it => it.milieu));
|
||||||
|
await sheet.item.update({ 'system.environnement': newList });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static async onChange(sheet, event, doMutation) {
|
||||||
|
const list = sheet.item.system.environnement;
|
||||||
|
const milieu = EnvironmentSheetHelper.$getEventMilieu(sheet, event);
|
||||||
|
const updated = list.find(it => it.milieu == milieu);
|
||||||
|
if (updated) {
|
||||||
|
doMutation(updated);
|
||||||
|
const newList = [...list.filter(it => it.milieu != milieu), updated]
|
||||||
|
.sort(Misc.ascending(it => it.milieu));
|
||||||
|
await sheet.item.update({ 'system.environnement': newList });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static $getEventMilieu(sheet, event) {
|
||||||
|
return sheet.html.find(event.currentTarget)?.parents("div.environnement-milieu").data("milieu");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -19,10 +19,14 @@ export class Grammar {
|
|||||||
return word.match(/^[aeiouy]/i)
|
return word.match(/^[aeiouy]/i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static equalsInsensitive(a, b) {
|
||||||
|
return Grammar.toLowerCaseNoAccent(a) == Grammar.toLowerCaseNoAccent(b)
|
||||||
|
}
|
||||||
|
|
||||||
static includesLowerCaseNoAccent(value, content) {
|
static includesLowerCaseNoAccent(value, content) {
|
||||||
return Grammar.toLowerCaseNoAccent(value).includes(Grammar.toLowerCaseNoAccent(content));
|
return Grammar.toLowerCaseNoAccent(value).includes(Grammar.toLowerCaseNoAccent(content));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static toLowerCaseNoAccent(words) {
|
static toLowerCaseNoAccent(words) {
|
||||||
return words?.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "") ?? words;
|
return words?.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "") ?? words;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
export class HtmlUtility{
|
export class HtmlUtility{
|
||||||
static _showControlWhen(control, condition) {
|
static _showControlWhen(jQuerySelector, condition) {
|
||||||
if (condition) {
|
if (condition) {
|
||||||
control.show();
|
jQuerySelector.show();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
control.hide();
|
jQuerySelector.hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,7 +28,7 @@ export class RdDItemArme extends Item {
|
|||||||
switch (arme ? arme.type : '') {
|
switch (arme ? arme.type : '') {
|
||||||
case 'arme': return arme;
|
case 'arme': return arme;
|
||||||
case 'competencecreature':
|
case 'competencecreature':
|
||||||
return RdDItemCompetenceCreature.toActionArme(arme);
|
return RdDItemCompetenceCreature.armeNaturelle(arme);
|
||||||
}
|
}
|
||||||
return RdDItemArme.mainsNues();
|
return RdDItemArme.mainsNues();
|
||||||
}
|
}
|
||||||
@@ -177,7 +177,7 @@ export class RdDItemArme extends Item {
|
|||||||
equipe: true,
|
equipe: true,
|
||||||
rapide: true,
|
rapide: true,
|
||||||
force: 0,
|
force: 0,
|
||||||
dommages: 0,
|
dommages: "0",
|
||||||
dommagesReels: 0,
|
dommagesReels: 0,
|
||||||
mortalite: 'non-mortel',
|
mortalite: 'non-mortel',
|
||||||
competence: 'Corps à corps',
|
competence: 'Corps à corps',
|
||||||
|
|||||||
@@ -34,13 +34,6 @@ const categorieCompetences = {
|
|||||||
"lancer": { base: -8, label: "Lancer" }
|
"lancer": { base: -8, label: "Lancer" }
|
||||||
}
|
}
|
||||||
|
|
||||||
const compendiumCompetences = {
|
|
||||||
"personnage": "foundryvtt-reve-de-dragon.competences",
|
|
||||||
"creature": "foundryvtt-reve-de-dragon.competences-creatures",
|
|
||||||
"entite": "foundryvtt-reve-de-dragon.competences-entites"
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
function _buildCumulXP() {
|
function _buildCumulXP() {
|
||||||
let cumulXP = { "-11": 0 };
|
let cumulXP = { "-11": 0 };
|
||||||
let cumul = 0;
|
let cumul = 0;
|
||||||
@@ -55,12 +48,6 @@ function _buildCumulXP() {
|
|||||||
const competence_xp_cumul = _buildCumulXP();
|
const competence_xp_cumul = _buildCumulXP();
|
||||||
|
|
||||||
export class RdDItemCompetence extends Item {
|
export class RdDItemCompetence extends Item {
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static actorCompendium(actorType) {
|
|
||||||
return compendiumCompetences[actorType];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getCategorieCompetences() {
|
static getCategorieCompetences() {
|
||||||
return categorieCompetences;
|
return categorieCompetences;
|
||||||
@@ -84,27 +71,36 @@ export class RdDItemCompetence extends Item {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getVoieDraconic(competences, voie) {
|
static getVoieDraconic(competences, voie) {
|
||||||
return RdDItemCompetence.findCompetence(competences.filter(it => RdDItemCompetence.isDraconic(it)), voie);
|
return RdDItemCompetence.findFirstItem(competences, voie, {
|
||||||
|
preFilter: it => it.isCompetence() && RdDItemCompetence.isDraconic(it),
|
||||||
|
description: 'Draconic',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static isCompetenceArme(competence) {
|
static isCompetenceArme(competence) {
|
||||||
switch (competence.system.categorie) {
|
if (competence.isCompetence()) {
|
||||||
case 'melee':
|
switch (competence.system.categorie) {
|
||||||
return competence.name != 'Esquive';
|
case 'melee':
|
||||||
case 'tir':
|
return !Grammar.toLowerCaseNoAccent(competence.name).includes('esquive');
|
||||||
case 'lancer':
|
case 'tir':
|
||||||
return true;
|
case 'lancer':
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static isArmeUneMain(competence) {
|
static isArmeUneMain(competence) {
|
||||||
return competence.name.toLowerCase().includes("1 main");
|
return RdDItemCompetence.isCompetenceArme(competence) && competence.name.toLowerCase().includes("1 main");
|
||||||
}
|
}
|
||||||
static isArme2Main(competence) {
|
static isArme2Main(competence) {
|
||||||
return competence.name.toLowerCase().includes("2 main");
|
return RdDItemCompetence.isCompetenceArme(competence) && competence.name.toLowerCase().includes("2 main");
|
||||||
|
}
|
||||||
|
|
||||||
|
static isThanatos(competence) {
|
||||||
|
return competence.isCompetencePersonnage() && Grammar.toLowerCaseNoAccent(competence.name).includes('thanatos');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -133,7 +129,7 @@ export class RdDItemCompetence extends Item {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static computeXP(competence) {
|
static computeXP(competence) {
|
||||||
const factor = competence.name.includes('Thanatos') ? 2 : 1; // Thanatos compte double !
|
const factor = RdDItemCompetence.isThanatos(competence) ? 2 : 1; // Thanatos compte double !
|
||||||
const xpNiveau = RdDItemCompetence.computeDeltaXP(competence.system.base, competence.system.niveau ?? competence.system.base);
|
const xpNiveau = RdDItemCompetence.computeDeltaXP(competence.system.base, competence.system.niveau ?? competence.system.base);
|
||||||
const xp = competence.system.xp ?? 0;
|
const xp = competence.system.xp ?? 0;
|
||||||
const xpSort = competence.system.xp_sort ?? 0;
|
const xpSort = competence.system.xp_sort ?? 0;
|
||||||
@@ -190,7 +186,7 @@ export class RdDItemCompetence extends Item {
|
|||||||
item.system.isStressLevelUp = (xpManquant > 0 && stressTransforme >= xpManquant && item.system.niveau < item.system.niveau_archetype);
|
item.system.isStressLevelUp = (xpManquant > 0 && stressTransforme >= xpManquant && item.system.niveau < item.system.niveau_archetype);
|
||||||
item.system.stressXpMax = 0;
|
item.system.stressXpMax = 0;
|
||||||
if (xpManquant > 0 && stressTransforme > 0 && item.system.niveau < item.system.niveau_archetype) {
|
if (xpManquant > 0 && stressTransforme > 0 && item.system.niveau < item.system.niveau_archetype) {
|
||||||
item.system.stressXpMax = Math.min(xpManquant , stressTransforme);
|
item.system.stressXpMax = Math.min(xpManquant, stressTransforme);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,24 +206,38 @@ export class RdDItemCompetence extends Item {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static findCompetence(list, idOrName, options = {}) {
|
static findCompetence(list, idOrName, options = {}) {
|
||||||
if (idOrName == undefined) {
|
if (idOrName == undefined || idOrName == "") {
|
||||||
return undefined;
|
return RdDItemCompetence.sansCompetence();
|
||||||
}
|
}
|
||||||
options = mergeObject(options, {
|
options = mergeObject(options, { preFilter: it => it.isCompetence(), description: 'compétence' }, { overwrite: false });
|
||||||
preFilter: it => RdDItemCompetence.isCompetence(it),
|
return RdDItemCompetence.findFirstItem(list, idOrName, options);
|
||||||
description: 'compétence',
|
|
||||||
});
|
|
||||||
return list.find(it => it.id == idOrName && RdDItemCompetence.isCompetence(it))
|
|
||||||
?? Misc.findFirstLike(idOrName, list, options);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static findCompetences(list, name) {
|
static findCompetences(list, name) {
|
||||||
return Misc.findAllLike(name, list, { filter: it => RdDItemCompetence.isCompetence(it), description: 'compétence' });
|
return Misc.findAllLike(name, list, { filter: it => it.isCompetence(), description: 'compétence' });
|
||||||
}
|
}
|
||||||
|
|
||||||
static isCompetence(item) {
|
static sansCompetence() {
|
||||||
return item.type == 'competence' || item.type == 'competencecreature';
|
return {
|
||||||
|
name: "Sans compétence",
|
||||||
|
type: "competence",
|
||||||
|
img: "systems/foundryvtt-reve-de-dragon/icons/templates/icone_parchement_vierge.webp",
|
||||||
|
system: {
|
||||||
|
niveau: 0,
|
||||||
|
default_diffLibre: 0,
|
||||||
|
base: 0,
|
||||||
|
categorie: "Aucune",
|
||||||
|
description: "",
|
||||||
|
descriptionmj: "",
|
||||||
|
defaut_carac: "",
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static findFirstItem(list, idOrName, options) {
|
||||||
|
return list.find(it => it.id == idOrName && options.preFilter(it))
|
||||||
|
?? Misc.findFirstLike(idOrName, list, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -271,4 +281,36 @@ export class RdDItemCompetence extends Item {
|
|||||||
return duplicate(limitesArchetypes);
|
return duplicate(limitesArchetypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static triVisible(competences) {
|
||||||
|
return competences.filter(it => it.system.isVisible)
|
||||||
|
.sort((a, b) => RdDItemCompetence.compare(a,b))
|
||||||
|
}
|
||||||
|
|
||||||
|
static $positionTri(comp) {
|
||||||
|
if (comp.name.startsWith("Survie")) {
|
||||||
|
if (comp.name.includes("Cité")) return 0;
|
||||||
|
if (comp.name.includes("Extérieur")) return 1;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if (comp.system.categorie.startsWith("melee")) {
|
||||||
|
if (comp.name.includes("Corps")) return 0;
|
||||||
|
if (comp.name.includes("Dague")) return 1;
|
||||||
|
if (comp.name.includes("Esquive")) return 2;
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
if (comp.system.categorie.startsWith("draconic")) {
|
||||||
|
if (comp.name.includes("Oniros")) return 0;
|
||||||
|
if (comp.name.includes("Hypnos")) return 1;
|
||||||
|
if (comp.name.includes("Narcos")) return 2;
|
||||||
|
if (comp.name.includes("Thanatos")) return 3;
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static compare(a,b) {
|
||||||
|
const diff = RdDItemCompetence.$positionTri(a) - RdDItemCompetence.$positionTri(b);
|
||||||
|
return diff ? diff : a.name.localeCompare(b.name);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Misc } from "./misc.js";
|
|
||||||
|
import { RdDCombatManager } from "./rdd-combat.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
export class RdDItemCompetenceCreature extends Item {
|
export class RdDItemCompetenceCreature extends Item {
|
||||||
@@ -11,29 +12,32 @@ export class RdDItemCompetenceCreature extends Item {
|
|||||||
rollData.competence.system.categorie = "creature"
|
rollData.competence.system.categorie = "creature"
|
||||||
rollData.selectedCarac = rollData.carac.carac_creature
|
rollData.selectedCarac = rollData.carac.carac_creature
|
||||||
if (rollData.competence.system.iscombat) {
|
if (rollData.competence.system.iscombat) {
|
||||||
rollData.arme = RdDItemCompetenceCreature.toActionArme(rollData.competence);
|
rollData.arme = RdDItemCompetenceCreature.armeNaturelle(rollData.competence);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static toActionArme(item) {
|
static armeNaturelle(competencecreature) {
|
||||||
if (RdDItemCompetenceCreature.isCompetenceAttaque(item)) {
|
if (RdDItemCompetenceCreature.isCompetenceAttaque(competencecreature)) {
|
||||||
// si c'est un Item compétence: cloner pour ne pas modifier lma compétence
|
// si c'est un Item compétence: cloner pour ne pas modifier lma compétence
|
||||||
let arme = (item instanceof Item) ? item.clone(): item;
|
let arme = (competencecreature instanceof Item) ? competencecreature.clone(): competencecreature;
|
||||||
mergeObject(arme.system,
|
mergeObject(arme.system,
|
||||||
{
|
{
|
||||||
competence: arme.name,
|
competence: arme.name,
|
||||||
resistance: 100,
|
initiative: RdDCombatManager.calculInitiative(competencecreature.system.niveau, competencecreature.system.carac_value),
|
||||||
|
niveau: competencecreature.system.niveau,
|
||||||
equipe: true,
|
equipe: true,
|
||||||
|
resistance: 100,
|
||||||
dommagesReels: arme.system.dommages,
|
dommagesReels: arme.system.dommages,
|
||||||
penetration: 0,
|
penetration: 0,
|
||||||
force: 0,
|
force: 0,
|
||||||
rapide: true,
|
rapide: true,
|
||||||
|
cac: competencecreature.system.isnaturelle ? "naturelle" : "",
|
||||||
action: 'attaque'
|
action: 'attaque'
|
||||||
});
|
});
|
||||||
return arme;
|
return arme;
|
||||||
}
|
}
|
||||||
console.error("RdDItemCompetenceCreature.toActionArme(", item, ") : impossible de transformer l'Item en arme");
|
console.error("RdDItemCompetenceCreature.toActionArme(", competencecreature, ") : impossible de transformer l'Item en arme");
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,6 +48,6 @@ export class RdDItemCompetenceCreature extends Item {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static isCompetenceParade(item) {
|
static isCompetenceParade(item) {
|
||||||
return item.type == 'competencecreature' && item.system.isparade;
|
return item.type == 'competencecreature' && item.system.categorie_parade !== "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
60
module/item-conteneur-sheet.js
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import { RdDItemSheet } from "./item-sheet.js";
|
||||||
|
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
|
||||||
|
import { RdDUtility } from "./rdd-utility.js";
|
||||||
|
|
||||||
|
export class RdDConteneurItemSheet extends RdDItemSheet {
|
||||||
|
|
||||||
|
static get ITEM_TYPE() { return "conteneur" };
|
||||||
|
|
||||||
|
async getData() {
|
||||||
|
const formData = await super.getData();
|
||||||
|
if (this.actor) {
|
||||||
|
this.prepareConteneurData(formData);
|
||||||
|
}
|
||||||
|
return formData;
|
||||||
|
}
|
||||||
|
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
|
||||||
|
if (!this.options.editable) return;
|
||||||
|
|
||||||
|
this.html.find('.conteneur-name a').click(async event => {
|
||||||
|
RdDUtility.toggleAfficheContenu(RdDSheetUtility.getItemId(event));
|
||||||
|
this.render(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
prepareConteneurData(formData) {
|
||||||
|
RdDUtility.filterEquipementParType(formData, this.actor.itemTypes);
|
||||||
|
|
||||||
|
this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.objets);
|
||||||
|
formData.subItems = formData.conteneurs.find(it => it._id == this.item.id)?.subItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
async _onDragStart(event) {
|
||||||
|
console.log("_onDragStart", event);
|
||||||
|
if (event.target.classList.contains("entity-link")) return;
|
||||||
|
|
||||||
|
const itemId = event.srcElement?.attributes["data-item-id"].value;
|
||||||
|
const item = this.actor.items.get(itemId);
|
||||||
|
// Create drag data
|
||||||
|
const dragData = {
|
||||||
|
actorId: this.actor.id,
|
||||||
|
type: "Item",
|
||||||
|
data: item.system
|
||||||
|
};
|
||||||
|
|
||||||
|
event.dataTransfer.setData("text/plain", JSON.stringify(dragData));
|
||||||
|
}
|
||||||
|
|
||||||
|
async _onDropItem(event, dragData) {
|
||||||
|
if (this.actor) {
|
||||||
|
const dropParams = RdDSheetUtility.prepareItemDropParameters(this.item.id, this.actor, dragData, this.objetVersConteneur);
|
||||||
|
await this.actor.processDropItem(dropParams);
|
||||||
|
await this.render(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
67
module/item-faune-sheet.js
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
import { EnvironmentSheetHelper } from "./environnement.js";
|
||||||
|
import { RdDItemSheet } from "./item-sheet.js";
|
||||||
|
import { RdDUtility } from "./rdd-utility.js";
|
||||||
|
|
||||||
|
export class RdDFauneItemSheet extends RdDItemSheet {
|
||||||
|
|
||||||
|
static get ITEM_TYPE() { return "faune" };
|
||||||
|
|
||||||
|
static get defaultOptions() {
|
||||||
|
return EnvironmentSheetHelper.defaultOptions(super.defaultOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
setPosition(options = {}) {
|
||||||
|
return EnvironmentSheetHelper.setPosition(this, super.setPosition(options));
|
||||||
|
}
|
||||||
|
|
||||||
|
async getData() {
|
||||||
|
const formData = await super.getData();
|
||||||
|
return await EnvironmentSheetHelper.getData(this, formData);
|
||||||
|
}
|
||||||
|
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
if (!this.options.editable) return;
|
||||||
|
|
||||||
|
EnvironmentSheetHelper.activateListeners(this);
|
||||||
|
|
||||||
|
html.find("a.linked-actor-delete").click(event => this.onDeleteLinkedActor());
|
||||||
|
html.find("a.preparer-nourriture").click(event => this.preparerNourriture(event));
|
||||||
|
html.find("a.manger-nourriture").click(event => this.mangerNourriture(event));
|
||||||
|
}
|
||||||
|
|
||||||
|
async _onDropActor(event, dragData) {
|
||||||
|
console.log('faune:dropActor', event, dragData)
|
||||||
|
const linkedActor = fromUuidSync(dragData.uuid);
|
||||||
|
if (linkedActor?.pack) {
|
||||||
|
this.item.update({
|
||||||
|
'system.actor.pack': linkedActor.pack,
|
||||||
|
'system.actor.id': linkedActor._id,
|
||||||
|
'system.actor.name': linkedActor.name
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ui.notifications.warn(`${linkedActor.name} ne provient pas d'un compendium.
|
||||||
|
<br>Choisissez une créature du compendium pour représenter un élément de faune générique`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async onDeleteLinkedActor() {
|
||||||
|
this.item.update({
|
||||||
|
'system.actor.pack': '',
|
||||||
|
'system.actor.id': '',
|
||||||
|
'system.actor.name': ''
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async preparerNourriture(event) {
|
||||||
|
if (this.actor) {
|
||||||
|
await this.actor.preparerNourriture(this.item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async mangerNourriture(event) {
|
||||||
|
if (this.actor) {
|
||||||
|
await this.actor.mangerNourriture(this.item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
25
module/item-herbe-sheet.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { EnvironmentSheetHelper } from "./environnement.js";
|
||||||
|
import { RdDItemSheet } from "./item-sheet.js";
|
||||||
|
|
||||||
|
export class RdDHerbeItemSheet extends RdDItemSheet {
|
||||||
|
|
||||||
|
static get ITEM_TYPE() { return "herbe" };
|
||||||
|
|
||||||
|
static get defaultOptions() {
|
||||||
|
return EnvironmentSheetHelper.defaultOptions(super.defaultOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
setPosition(options = {}) {
|
||||||
|
return EnvironmentSheetHelper.setPosition(this, super.setPosition(options));
|
||||||
|
}
|
||||||
|
|
||||||
|
async getData() {
|
||||||
|
const formData = await super.getData();
|
||||||
|
return await EnvironmentSheetHelper.getData(this, formData);
|
||||||
|
}
|
||||||
|
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
EnvironmentSheetHelper.activateListeners(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
25
module/item-ingredient-sheet.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { EnvironmentSheetHelper } from "./environnement.js";
|
||||||
|
import { RdDItemSheet } from "./item-sheet.js";
|
||||||
|
|
||||||
|
export class RdDIngredientItemSheet extends RdDItemSheet {
|
||||||
|
|
||||||
|
static get ITEM_TYPE() { return "ingredient" };
|
||||||
|
|
||||||
|
static get defaultOptions() {
|
||||||
|
return EnvironmentSheetHelper.defaultOptions(super.defaultOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
setPosition(options = {}) {
|
||||||
|
return EnvironmentSheetHelper.setPosition(this, super.setPosition(options));
|
||||||
|
}
|
||||||
|
|
||||||
|
async getData() {
|
||||||
|
const formData = await super.getData();
|
||||||
|
return await EnvironmentSheetHelper.getData(this, formData);
|
||||||
|
}
|
||||||
|
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
EnvironmentSheetHelper.activateListeners(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,67 +1,93 @@
|
|||||||
import { Misc } from "./misc.js";
|
import { Misc } from "./misc.js";
|
||||||
|
import { LOG_HEAD } from "./constants.js";
|
||||||
|
|
||||||
const MONNAIES_STANDARD = [
|
const MONNAIE_ETAIN = {
|
||||||
{
|
name: "Etain (1 denier)", type: 'monnaie',
|
||||||
name: "Etain (1 denier)", type: 'monnaie',
|
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_etain_poisson.webp",
|
||||||
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_etain_poisson.webp",
|
system: { quantite: 0, cout: 0.01, encombrement: 0.001, description: "" }
|
||||||
system: { quantite: 0, valeur_deniers: 1, encombrement: 0.001, description: "" }
|
};
|
||||||
},
|
const MONNAIE_BRONZE = {
|
||||||
{
|
name: "Bronze (10 deniers)", type: 'monnaie',
|
||||||
name: "Bronze (10 deniers)", type: 'monnaie',
|
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_bronze_epees.webp",
|
||||||
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_bronze_epees.webp",
|
system: { quantite: 0, cout: 0.10, encombrement: 0.002, description: "" }
|
||||||
system: { quantite: 0, valeur_deniers: 10, encombrement: 0.002, description: "" }
|
};
|
||||||
},
|
const MONNAIE_ARGENT = {
|
||||||
{
|
name: "Argent (1 sol)", type: 'monnaie',
|
||||||
name: "Argent (1 sol)", type: 'monnaie',
|
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_argent_sol.webp",
|
||||||
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_argent_sol.webp",
|
system: { quantite: 0, cout: 1, encombrement: 0.003, description: "" }
|
||||||
system: { quantite: 0, valeur_deniers: 100, encombrement: 0.003, description: "" }
|
};
|
||||||
},
|
const MONNAIE_OR = {
|
||||||
{
|
name: "Or (10 sols)", type: 'monnaie',
|
||||||
name: "Or (10 sols)", type: 'monnaie',
|
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_or_sol.webp",
|
||||||
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_or_sol.webp",
|
system: { quantite: 0, cout: 10, encombrement: 0.004, description: "" }
|
||||||
system: { quantite: 0, valeur_deniers: 1000, encombrement: 0.004, description: "" }
|
};
|
||||||
}
|
|
||||||
]
|
const MONNAIES_STANDARD = [MONNAIE_ETAIN, MONNAIE_BRONZE, MONNAIE_ARGENT, MONNAIE_OR];
|
||||||
const VALEURS_STANDARDS = MONNAIES_STANDARD.map(it =>it.system.valeur_deniers);
|
|
||||||
|
|
||||||
export class Monnaie {
|
export class Monnaie {
|
||||||
|
|
||||||
static isSystemMonnaie(item, items) {
|
static monnaiesStandard() {
|
||||||
if (item.type == 'monnaie') {
|
|
||||||
const valeur = item.system.valeur_deniers;
|
|
||||||
if (VALEURS_STANDARDS.includes(valeur)) {
|
|
||||||
const monnaiesDeValeur = items.filter(it => it.type == 'monnaie' && it.system.valeur_deniers == valeur)
|
|
||||||
return monnaiesDeValeur.length<=1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static monnaiesData() {
|
|
||||||
return MONNAIES_STANDARD;
|
return MONNAIES_STANDARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
static filtrerMonnaies(items) {
|
static monnaiesManquantes(actor) {
|
||||||
return items.filter(it => it.type == 'monnaie');
|
const disponibles = actor.itemTypes['monnaie'];
|
||||||
}
|
const manquantes = MONNAIES_STANDARD.filter(standard => !disponibles.find(disponible => Monnaie.deValeur(disponible, standard.system?.cout)));
|
||||||
|
|
||||||
static monnaiesManquantes(disponibles) {
|
|
||||||
const manquantes = MONNAIES_STANDARD.filter(standard => !disponibles.find(disponible => Monnaie.deValeur(disponible, standard.system?.valeur_deniers)));
|
|
||||||
if (manquantes.length > 0) {
|
if (manquantes.length > 0) {
|
||||||
console.error('monnaiesManquantes', manquantes, ' avec monnaies', disponibles, MONNAIES_STANDARD);
|
console.error(`${LOG_HEAD} monnaiesManquantes pour ${actor.name}`, manquantes, ' avec monnaies', disponibles, MONNAIES_STANDARD);
|
||||||
}
|
}
|
||||||
return manquantes;
|
return manquantes;
|
||||||
}
|
}
|
||||||
|
|
||||||
static deValeur(monnaie, valeur) {
|
static deValeur(monnaie, valeur) {
|
||||||
return valeur == monnaie.system.valeur_deniers
|
return Monnaie.valEntiere(valeur) == Monnaie.valEntiere(monnaie.system.cout)
|
||||||
}
|
}
|
||||||
|
|
||||||
static arrondiDeniers(sols) {
|
static valEntiere(sols) {
|
||||||
return sols.toFixed(2);
|
return Math.max(Math.floor((sols??0)*100), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static triValeurDenier() {
|
static triValeurEntiere() {
|
||||||
return Misc.ascending(item => item.system.valeur_deniers)
|
return Misc.ascending(item => Monnaie.valEntiere(item.system.cout))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async creerMonnaiesStandard(actor) {
|
||||||
|
await actor.createEmbeddedDocuments('Item', MONNAIES_STANDARD, { renderSheet: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
static async creerMonnaiesDeniers(actor, fortune) {
|
||||||
|
await actor.createEmbeddedDocuments('Item', [Monnaie.creerDeniers(fortune)], { renderSheet: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
static creerDeniers(fortune) {
|
||||||
|
const deniers = duplicate(MONNAIE_ETAIN);
|
||||||
|
deniers.system.quantite = fortune;
|
||||||
|
return deniers;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async optimiserFortune(actor, fortune) {
|
||||||
|
let resteEnDeniers = Math.round(fortune*100);
|
||||||
|
let monnaies = actor.itemTypes['monnaie'];
|
||||||
|
let updates = [];
|
||||||
|
let parValeur = Misc.classifyFirst(monnaies, it => Monnaie.valEntiere(it.system.cout));
|
||||||
|
for (let valeurDeniers of [1000, 100, 10, 1]) {
|
||||||
|
const itemPiece = parValeur[valeurDeniers];
|
||||||
|
if (itemPiece) {
|
||||||
|
const quantite = Math.floor(resteEnDeniers / valeurDeniers);
|
||||||
|
if (quantite != itemPiece.system.quantite) {
|
||||||
|
updates.push({ _id: parValeur[valeurDeniers].id, 'system.quantite': quantite });
|
||||||
|
}
|
||||||
|
resteEnDeniers -= quantite*valeurDeniers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log('Monnaie.optimiserFortune', actor.name, 'total', fortune, 'parValeur', parValeur, 'updates', updates, 'reste', resteEnDeniers);
|
||||||
|
if (updates.length > 0) {
|
||||||
|
await actor.updateEmbeddedDocuments('Item', updates);
|
||||||
|
}
|
||||||
|
if (resteEnDeniers > 0){
|
||||||
|
// créer le reste en deniers fortune en deniers
|
||||||
|
await Monnaie.creerMonnaiesDeniers(actor, resteEnDeniers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
85
module/item-rencontre-sheet.js
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
import { RdDRencontre } from "./item-rencontre.js";
|
||||||
|
import { RdDItemSheet } from "./item-sheet.js";
|
||||||
|
|
||||||
|
export class RdDRencontreItemSheet extends RdDItemSheet {
|
||||||
|
|
||||||
|
static get ITEM_TYPE() { return "rencontre" };
|
||||||
|
|
||||||
|
static get defaultOptions() {
|
||||||
|
return mergeObject(super.defaultOptions, {
|
||||||
|
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/** @override */
|
||||||
|
setPosition(options = {}) {
|
||||||
|
const position = super.setPosition(options);
|
||||||
|
const sheetHeader = this.element.find(".sheet-header");
|
||||||
|
const sheetBody = this.element.find(".sheet-body");
|
||||||
|
sheetBody.css("height", position.height - sheetHeader[0].clientHeight)
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async getData() {
|
||||||
|
const formData = duplicate(this.item);
|
||||||
|
mergeObject(formData, {
|
||||||
|
title: formData.name,
|
||||||
|
isGM: game.user.isGM,
|
||||||
|
owner: this.actor?.isOwner,
|
||||||
|
isOwned: this.actor ? true : false,
|
||||||
|
actorId: this.actor?.id,
|
||||||
|
editable: this.isEditable,
|
||||||
|
cssClass: this.isEditable ? "editable" : "locked",
|
||||||
|
effets: {
|
||||||
|
succes: {
|
||||||
|
liste: RdDRencontre.getEffetsSucces(),
|
||||||
|
select: RdDRencontre.mapEffets(this.item.system.succes.effets)
|
||||||
|
},
|
||||||
|
echec: {
|
||||||
|
liste: RdDRencontre.getEffetsEchec(),
|
||||||
|
select: RdDRencontre.mapEffets(this.item.system.echec.effets)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return formData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/** @override */
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
if (!this.options.editable) return;
|
||||||
|
this.html.find("a.effet-add").click(event => this.onAddEffet(event));
|
||||||
|
this.html.find("a.effet-delete").click(event => this.onDeleteEffet(event));
|
||||||
|
}
|
||||||
|
|
||||||
|
async onAddEffet(event) {
|
||||||
|
const resultat = this.html.find(event.currentTarget)?.data("effet-resultat");
|
||||||
|
const keyEffets = `system.${resultat}.effets`;
|
||||||
|
|
||||||
|
const code = this.html.find(event.currentTarget)?.data("effet-code");
|
||||||
|
const liste = RdDRencontre.getListeEffets(this.item, resultat);
|
||||||
|
liste.push(code);
|
||||||
|
|
||||||
|
await this._updateEffetsRencontre(keyEffets, liste);
|
||||||
|
}
|
||||||
|
|
||||||
|
async onDeleteEffet(event) {
|
||||||
|
const resultat = this.html.find(event.currentTarget)?.data("effet-resultat");
|
||||||
|
const keyEffets = `system.${resultat}.effets`;
|
||||||
|
|
||||||
|
const pos = this.html.find(event.currentTarget)?.data("effet-pos");
|
||||||
|
const liste = RdDRencontre.getListeEffets(this.item, resultat);
|
||||||
|
liste.splice(pos, 1);
|
||||||
|
|
||||||
|
await this._updateEffetsRencontre(keyEffets, liste);
|
||||||
|
}
|
||||||
|
|
||||||
|
async _updateEffetsRencontre(key, liste) {
|
||||||
|
const updates = {};
|
||||||
|
updates[key] = liste;
|
||||||
|
this.item.update(updates);
|
||||||
|
}
|
||||||
|
}
|
||||||
71
module/item-rencontre.js
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
import { EffetsRencontre } from "./effets-rencontres.js";
|
||||||
|
|
||||||
|
const tableEffets = [
|
||||||
|
{ code: "messager", resultat: "succes", description: "Envoie un message à (force) cases", method: EffetsRencontre.messager },
|
||||||
|
{ code: "passeur", resultat: "succes", description: "Déplacer le demi-rêve à (force) cases", method: EffetsRencontre.passeur},
|
||||||
|
{ code: "reve+f", resultat: "succes", description: "Gain de (force) points de rêve" , method: EffetsRencontre.reve_plus_force},
|
||||||
|
{ code: "teleport", resultat: "succes", description: "Déplacer le demi-rêve (même type)", method: EffetsRencontre.teleportation_typecase },
|
||||||
|
{ code: "part+tete", resultat: "succes", description: "Tête de dragon sur réussite particulière", method: EffetsRencontre.rdd_part_tete },
|
||||||
|
{ code: "part+xp", resultat: "succes", description: "Expérience sur réussite particulière", method: EffetsRencontre.experience_particuliere },
|
||||||
|
{ code: "seuil", resultat: "succes", description: "Récupération de seuil de rêve", method: EffetsRencontre.regain_seuil },
|
||||||
|
|
||||||
|
{ code: "reve-1", resultat: "echec", description: "Perte de 1 point de rêve", method: EffetsRencontre.reve_moins_1 },
|
||||||
|
{ code: "reve-f", resultat: "echec", description: "Perte de (force) points de rêve", method: EffetsRencontre.reve_moins_force },
|
||||||
|
{ code: "vie-1", resultat: "echec", description: "Perte de 1 point de vie", method: EffetsRencontre.vie_moins_1 },
|
||||||
|
{ code: "reinsere", resultat: "echec", description: "Réinsertion aléatoire", method: EffetsRencontre.reinsertion },
|
||||||
|
{ code: "persistant", resultat: "echec", description: "Bloque le demi-rêve", method: EffetsRencontre.rencontre_persistante },
|
||||||
|
{ code: "teleport-aleatoire", resultat: "echec", description: "Déplacement aléatoire (même type)", method: EffetsRencontre.teleportation_aleatoire_typecase },
|
||||||
|
{ code: "aleatoire", resultat: "echec", description: "Déplacement aléatoire", method: EffetsRencontre.deplacement_aleatoire },
|
||||||
|
{ code: "sort-aleatoire", resultat: "echec", description: "Déclenche un sort en réserve aléatoire", method: EffetsRencontre.sort_aleatoire },
|
||||||
|
{ code: "rompu", resultat: "echec", description: "Demi-rêve interrompu", method: EffetsRencontre.demireve_rompu },
|
||||||
|
{ code: "echec-queue", resultat: "echec", description: "Queue(s) de dragon sur échec", method: EffetsRencontre.rdd_echec_queue },
|
||||||
|
|
||||||
|
{ code: "reve+1", resultat: "succes", description: "Gain de 1 point de rêve", method: EffetsRencontre.reve_plus_1 },
|
||||||
|
{ code: "vie-f", resultat: "echec", description: "Perte de (force) points de vie", method: EffetsRencontre.vie_moins_force },
|
||||||
|
{ code: "moral+1", resultat: "succes", description: "Gain de 1 point de moral", method: EffetsRencontre.moral_plus_1 },
|
||||||
|
{ code: "moral-1", resultat: "echec", description: "Perte de 1 point de moral", method: EffetsRencontre.moral_moins_1 },
|
||||||
|
{ code: "xpsort+f", resultat: "succes", description: "Gain de (force) xp sort", method: EffetsRencontre.xp_sort_force },
|
||||||
|
{ code: "endurance-1", resultat: "echec", description: "Perte de 1 point d'endurance", method: EffetsRencontre.end_moins_1 },
|
||||||
|
{ code: "endurance-f", resultat: "echec", description: "Perte de (force) points d'endurance", method: EffetsRencontre.end_moins_force },
|
||||||
|
{ code: "fatigue+1", resultat: "echec", description: "Coup de fatigue de 1 point", method: EffetsRencontre.fatigue_plus_1},
|
||||||
|
{ code: "fatigue+f", resultat: "echec", description: "Coup de fatigue de 1 (force) points", method: EffetsRencontre.fatigue_plus_force },
|
||||||
|
{ code: "fatigue-1", resultat: "succes", description: "Récupération de 1 point de fatigue", method: EffetsRencontre.fatigue_moins_1},
|
||||||
|
{ code: "fatigue-f", resultat: "succes", description: "Récupération de 1 (force) points de fatigue", method: EffetsRencontre.fatigue_moins_force },
|
||||||
|
{ code: "perte-chance", resultat: "echec", description: "Perte de chance actuelle", method: EffetsRencontre.perte_chance },
|
||||||
|
{ code: "stress+1", resultat: "succes", description: "Gain de 1 point de stress", method: EffetsRencontre.stress_plus_1 },
|
||||||
|
// { code: "epart-souffle", resultat: "echec", description: "Souffle de dragon sur échec particulier" },
|
||||||
|
];
|
||||||
|
|
||||||
|
export class RdDRencontre {
|
||||||
|
|
||||||
|
static getEffetsSucces() { return RdDRencontre.getEffets("succes"); }
|
||||||
|
static getEffetsEchec() { return RdDRencontre.getEffets("echec"); }
|
||||||
|
static getEffets(resultat) {
|
||||||
|
return tableEffets.filter(e => resultat == e.resultat);
|
||||||
|
}
|
||||||
|
|
||||||
|
static mapEffets(liste) {
|
||||||
|
return liste.map(it => RdDRencontre.getEffet(it));
|
||||||
|
}
|
||||||
|
|
||||||
|
static getListeEffets(item, reussite) {
|
||||||
|
if (reussite == 'echec') {
|
||||||
|
return [...item.system.echec.effets];
|
||||||
|
}
|
||||||
|
if (reussite == 'succes') {
|
||||||
|
return [...item.system.succes.effets];
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
static getEffet(code) {
|
||||||
|
return tableEffets.find(it => code == it.code)
|
||||||
|
}
|
||||||
|
|
||||||
|
static async appliquer(codes, tmrDialog, rencData) {
|
||||||
|
for(const effet of RdDRencontre.mapEffets(codes)){
|
||||||
|
await effet.method(tmrDialog, rencData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -4,35 +4,59 @@ import { RdDAlchimie } from "./rdd-alchimie.js";
|
|||||||
import { RdDItemCompetence } from "./item-competence.js";
|
import { RdDItemCompetence } from "./item-competence.js";
|
||||||
import { RdDHerbes } from "./rdd-herbes.js";
|
import { RdDHerbes } from "./rdd-herbes.js";
|
||||||
import { RdDGemme } from "./rdd-gemme.js";
|
import { RdDGemme } from "./rdd-gemme.js";
|
||||||
import { Misc } from "./misc.js";
|
|
||||||
import { HtmlUtility } from "./html-utility.js";
|
import { HtmlUtility } from "./html-utility.js";
|
||||||
import { ReglesOptionelles } from "./regles-optionelles.js";
|
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
||||||
import { SYSTEM_RDD } from "./constants.js";
|
import { SYSTEM_RDD } from "./constants.js";
|
||||||
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
|
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
|
||||||
|
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
||||||
|
import { Misc } from "./misc.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extend the basic ItemSheet with some very simple modifications
|
* Extend the basic ItemSheet for RdD specific items
|
||||||
* @extends {ItemSheet}
|
|
||||||
*/
|
*/
|
||||||
export class RdDItemSheet extends ItemSheet {
|
export class RdDItemSheet extends ItemSheet {
|
||||||
|
|
||||||
|
static get ITEM_TYPE() {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
static defaultTemplate(type) {
|
||||||
|
return type ?
|
||||||
|
`systems/foundryvtt-reve-de-dragon/templates/item-${type}-sheet.html` :
|
||||||
|
"systems/foundryvtt-reve-de-dragon/templates/item-sheet.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
static register(sheetClass) {
|
||||||
|
Items.registerSheet(SYSTEM_RDD, sheetClass, {
|
||||||
|
label: Misc.typeName('Item', sheetClass.ITEM_TYPE),
|
||||||
|
types: [sheetClass.ITEM_TYPE],
|
||||||
|
makeDefault: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
static get defaultOptions() {
|
static get defaultOptions() {
|
||||||
return mergeObject(super.defaultOptions, {
|
return mergeObject(super.defaultOptions, {
|
||||||
classes: [SYSTEM_RDD, "sheet", "item"],
|
classes: [SYSTEM_RDD, "sheet", "item"],
|
||||||
template: "systems/foundryvtt-reve-de-dragon/templates/item-sheet.html",
|
template: RdDItemSheet.defaultTemplate(RdDItemSheet.ITEM_TYPE),
|
||||||
width: 550,
|
width: 550,
|
||||||
height: 550
|
height: 550
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
get template() {
|
||||||
|
return RdDItemSheet.defaultTemplate(this.item.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
get title() {
|
||||||
|
return `${Misc.typeName('Item', this.item.type)}: ${this.item.name}`;
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_getHeaderButtons() {
|
_getHeaderButtons() {
|
||||||
let buttons = super._getHeaderButtons();
|
let buttons = super._getHeaderButtons();
|
||||||
// Add "Post to chat" button
|
if (this.item.isInventaire() && this.item.isVideOuNonConteneur()) {
|
||||||
// We previously restricted this to GM and editable items only. If you ever find this comment because it broke something: eh, sorry!
|
|
||||||
if ("cout" in this.item.system && this.item.isVideOuNonConteneur()) {
|
|
||||||
buttons.unshift({
|
buttons.unshift({
|
||||||
class: "vendre",
|
class: "vendre",
|
||||||
icon: "fas fa-comments-dollar",
|
icon: "fas fa-comments-dollar",
|
||||||
@@ -67,155 +91,128 @@ export class RdDItemSheet extends ItemSheet {
|
|||||||
img: this.item.img,
|
img: this.item.img,
|
||||||
name: this.item.name,
|
name: this.item.name,
|
||||||
system: this.item.system,
|
system: this.item.system,
|
||||||
// TODO: v10 remove
|
|
||||||
data: this.item.system,
|
|
||||||
isGM: game.user.isGM,
|
isGM: game.user.isGM,
|
||||||
actorId: this.actor?.id,
|
actorId: this.actor?.id,
|
||||||
|
isOwned: this.actor ? true : false,
|
||||||
owner: this.item.isOwner,
|
owner: this.item.isOwner,
|
||||||
editable: this.isEditable,
|
editable: this.isEditable,
|
||||||
cssClass: this.isEditable ? "editable" : "locked",
|
cssClass: this.isEditable ? "editable" : "locked",
|
||||||
isSoins: false
|
isSoins: false,
|
||||||
}
|
description: await TextEditor.enrichHTML(this.item.system.description, { async: true }),
|
||||||
if (this.actor) {
|
descriptionmj: await TextEditor.enrichHTML(this.item.system.descriptionmj, { async: true }),
|
||||||
formData.isOwned = true;
|
isComestible: this.item.isComestible()
|
||||||
if (this.item.type == 'conteneur') {
|
|
||||||
this.prepareConteneurData(formData);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const competences = await SystemCompendiums.getCompetences(this.actor?.type);
|
||||||
formData.categorieCompetences = RdDItemCompetence.getCategorieCompetences()
|
formData.categorieCompetences = RdDItemCompetence.getCategorieCompetences()
|
||||||
if (formData.type == 'tache' || formData.type == 'livre' || formData.type == 'meditation' || formData.type == 'oeuvre') {
|
if (this.item.type == 'tache' || this.item.type == 'livre' || this.item.type == 'meditation' || this.item.type == 'oeuvre') {
|
||||||
formData.caracList = duplicate(game.system.model.Actor.personnage.carac)
|
formData.caracList = duplicate(game.system.model.Actor.personnage.carac)
|
||||||
formData.caracList["reve-actuel"] = duplicate(game.system.model.Actor.personnage.reve.reve)
|
formData.caracList["reve-actuel"] = duplicate(game.system.model.Actor.personnage.reve.reve)
|
||||||
formData.competences = await RdDUtility.loadCompendium('foundryvtt-reve-de-dragon.competences')
|
formData.competences = competences;
|
||||||
}
|
}
|
||||||
if (formData.type == 'arme') {
|
if (this.item.type == 'arme') {
|
||||||
formData.competences = await RdDUtility.loadCompendium('foundryvtt-reve-de-dragon.competences', it => RdDItemCompetence.isCompetenceArme(it));
|
formData.competences = competences.filter(it => RdDItemCompetence.isCompetenceArme(it));
|
||||||
console.log(formData.competences)
|
|
||||||
}
|
}
|
||||||
if (formData.type == 'recettealchimique') {
|
if (['sort', 'sortreserve'].includes(this.item.type)) {
|
||||||
|
formData.competences = competences.filter(it => RdDItemCompetence.isDraconic(it));
|
||||||
|
}
|
||||||
|
if (this.item.type == 'recettecuisine') {
|
||||||
|
formData.ingredients = await TextEditor.enrichHTML(this.object.system.ingredients, { async: true })
|
||||||
|
}
|
||||||
|
if (this.item.type == 'extraitpoetique') {
|
||||||
|
formData.extrait = await TextEditor.enrichHTML(this.object.system.extrait, { async: true })
|
||||||
|
formData.texte = await TextEditor.enrichHTML(this.object.system.texte, { async: true })
|
||||||
|
}
|
||||||
|
if (this.item.type == 'recettealchimique') {
|
||||||
RdDAlchimie.processManipulation(this.item, this.actor && this.actor.id);
|
RdDAlchimie.processManipulation(this.item, this.actor && this.actor.id);
|
||||||
|
formData.manipulation_update = await TextEditor.enrichHTML(this.object.system.manipulation_update, { async: true })
|
||||||
|
formData.utilisation = await TextEditor.enrichHTML(this.object.system.utilisation, { async: true })
|
||||||
|
formData.enchantement = await TextEditor.enrichHTML(this.object.system.enchantement, { async: true })
|
||||||
|
formData.sureffet = await TextEditor.enrichHTML(this.object.system.sureffet, { async: true })
|
||||||
}
|
}
|
||||||
if (formData.type == 'gemme') {
|
if (this.item.type == 'gemme') {
|
||||||
formData.gemmeTypeList = RdDGemme.getGemmeTypeOptionList();
|
formData.gemmeTypeList = RdDGemme.getGemmeTypeOptionList();
|
||||||
RdDGemme.calculDataDerivees(this.item);
|
RdDGemme.calculDataDerivees(this.item);
|
||||||
}
|
}
|
||||||
if (formData.type == 'potion') {
|
if (this.item.type == 'potion') {
|
||||||
if (this.dateUpdated) {
|
if (this.dateUpdated) {
|
||||||
formData.system.prdate = this.dateUpdated;
|
formData.system.prdate = this.dateUpdated;
|
||||||
this.dateUpdated = undefined;
|
this.dateUpdated = undefined;
|
||||||
}
|
}
|
||||||
RdDHerbes.updatePotionData(formData);
|
await RdDHerbes.updatePotionData(formData);
|
||||||
}
|
}
|
||||||
if (formData.isOwned && formData.type == 'herbe' && (formData.system.categorie == 'Soin' || formData.system.categorie == 'Repos')) {
|
if (formData.isOwned && this.item.type == 'herbe' && (formData.system.categorie == 'Soin' || formData.system.categorie == 'Repos')) {
|
||||||
formData.isIngredientPotionBase = true;
|
formData.isIngredientPotionBase = true;
|
||||||
}
|
}
|
||||||
|
if (this.item.type == 'sortreserve') {
|
||||||
|
const sortId = this.item.system.sortid;
|
||||||
|
formData.sort = formData.isOwned ? this.item.actor.items.get(sortId) : game.items.get(sortId);
|
||||||
|
}
|
||||||
formData.bonusCaseList = RdDItemSort.getBonusCaseList(formData, true);
|
formData.bonusCaseList = RdDItemSort.getBonusCaseList(formData, true);
|
||||||
|
|
||||||
return formData;
|
return formData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
prepareConteneurData(formData) {
|
|
||||||
formData.itemsByType = Misc.classify(this.actor.items.map(i => foundry.utils.deepClone(i)))
|
|
||||||
RdDUtility.filterEquipementParType(formData)
|
|
||||||
|
|
||||||
this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.objets);
|
|
||||||
formData.subItems = formData.conteneurs.find(it => it._id == this.item.id)?.subItems;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/** @override */
|
/** @override */
|
||||||
activateListeners(html) {
|
activateListeners(html) {
|
||||||
super.activateListeners(html);
|
super.activateListeners(html);
|
||||||
|
this.html = html;
|
||||||
if (this.item.type == 'conteneur') {
|
|
||||||
this.form.ondragstart = (event) => this._onDragStart(event);
|
|
||||||
this.form.ondrop = (event) => this._onDrop(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
let itemSheetDialog = this;
|
let itemSheetDialog = this;
|
||||||
|
|
||||||
HtmlUtility._showControlWhen($(".item-cout"), ReglesOptionelles.isUsing('afficher-prix-joueurs') || game.user.isGM || !this.item.isOwned);
|
HtmlUtility._showControlWhen(this.html.find(".item-cout"), ReglesOptionelles.isUsing('afficher-prix-joueurs') || game.user.isGM || !this.item.isOwned);
|
||||||
HtmlUtility._showControlWhen($(".item-magique"), this.item.isMagique());
|
HtmlUtility._showControlWhen(this.html.find(".item-magique"), this.item.isMagique());
|
||||||
|
|
||||||
// Everything below here is only needed if the sheet is editable
|
// Everything below here is only needed if the sheet is editable
|
||||||
if (!this.options.editable) return;
|
if (!this.options.editable) return;
|
||||||
|
|
||||||
// Select competence categorie
|
this.form.ondragstart = (event) => this._onDragStart(event);
|
||||||
html.find(".categorie").change(event => this._onSelectCategorie(event));
|
this.form.ondrop = (event) => this._onDrop(event);
|
||||||
|
|
||||||
html.find('.sheet-competence-xp').change((event) => {
|
// Select competence categorie
|
||||||
if (this.item.type == 'competence') {
|
this.html.find(".categorie").change(event => this._onSelectCategorie(event));
|
||||||
|
|
||||||
|
this.html.find('.sheet-competence-xp').change((event) => {
|
||||||
|
if (this.item.isCompetencePersonnage()) {
|
||||||
RdDUtility.checkThanatosXP(this.item.name);
|
RdDUtility.checkThanatosXP(this.item.name);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
html.find('.enchanteDate').change((event) => {
|
this.html.find('.enchanteDate').change((event) => {
|
||||||
let jour = Number($('#jourMois').val());
|
let jour = Number(this.html.find('[name="splitDate.day"]').val());
|
||||||
let mois = $('#nomMois').val();
|
let mois = this.html.find('[name="splitDate.month"]').val();
|
||||||
this.dateUpdated = game.system.rdd.calendrier.getIndexFromDate(jour, mois);
|
this.dateUpdated = game.system.rdd.calendrier.getIndexFromDate(jour, mois);
|
||||||
});
|
});
|
||||||
|
|
||||||
html.find('.creer-tache-livre').click((event) => {
|
this.html.find('.creer-tache-livre').click((event) => this._getEventActor(event).creerTacheDepuisLivre(this.item));
|
||||||
let actorId = event.currentTarget.attributes['data-actor-id'].value;
|
this.html.find('.consommer-potion').click((event) => this._getEventActor(event).consommerPotion(this.item));
|
||||||
let actor = game.actors.get(actorId);
|
this.html.find('.creer-potion-base').click((event) => this._getEventActor(event).dialogFabriquerPotion(this.item));
|
||||||
actor.creerTacheDepuisLivre(this.item);
|
|
||||||
});
|
|
||||||
html.find('.consommer-potion').click((event) => {
|
|
||||||
let actorId = event.currentTarget.attributes['data-actor-id'].value;
|
|
||||||
let actor = game.actors.get(actorId);
|
|
||||||
actor.consommerPotion(this.item);
|
|
||||||
});
|
|
||||||
html.find('.creer-potion-base').click((event) => {
|
|
||||||
let actorId = event.currentTarget.attributes['data-actor-id'].value;
|
|
||||||
let actor = game.actors.get(actorId);
|
|
||||||
actor.dialogFabriquerPotion(this.item);
|
|
||||||
});
|
|
||||||
|
|
||||||
html.find('.alchimie-tache a').click((event) => {
|
this.html.find('.alchimie-tache a').click((event) => {
|
||||||
let actorId = event.currentTarget.attributes['data-actor-id'].value;
|
let actor = this._getEventActor(event);
|
||||||
let recetteId = event.currentTarget.attributes['data-recette-id'].value;
|
|
||||||
let tacheName = event.currentTarget.attributes['data-alchimie-tache'].value;
|
|
||||||
let tacheData = event.currentTarget.attributes['data-alchimie-data'].value;
|
|
||||||
let actor = game.actors.get(actorId);
|
|
||||||
if (actor) {
|
if (actor) {
|
||||||
|
let recetteId = event.currentTarget.attributes['data-recette-id'].value;
|
||||||
|
let tacheName = event.currentTarget.attributes['data-alchimie-tache'].value;
|
||||||
|
let tacheData = event.currentTarget.attributes['data-alchimie-data'].value;
|
||||||
actor.effectuerTacheAlchimie(recetteId, tacheName, tacheData);
|
actor.effectuerTacheAlchimie(recetteId, tacheName, tacheData);
|
||||||
} else {
|
} else {
|
||||||
ui.notifications.info("Impossible trouver un acteur pour réaliser cette tache Alchimique.");
|
ui.notifications.info("Impossible trouver un acteur pour réaliser cette tache Alchimique.");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
html.find('.item-split').click(async event => {
|
this.html.find('.item-split').click(async event => RdDSheetUtility.splitItem(RdDSheetUtility.getItem(event, this.actor), this.actor, async () => itemSheetDialog.render(true)));
|
||||||
const item = RdDSheetUtility.getItem(event, this.actor);
|
this.html.find('.item-edit').click(async event => RdDSheetUtility.getItem(event, this.actor)?.sheet.render(true));
|
||||||
await RdDSheetUtility.splitItem(item, this.actor, async () => itemSheetDialog.render(true));
|
this.html.find('.item-delete').click(async event => RdDUtility.confirmerSuppressionItem(this, RdDSheetUtility.getItem(event, this.actor)));
|
||||||
});
|
this.html.find('.item-vendre').click(async event => RdDSheetUtility.getItem(event, this.actor)?.proposerVente());
|
||||||
html.find('.item-edit').click(async event => {
|
this.html.find('.item-montrer').click(async event => RdDSheetUtility.getItem(event, this.actor)?.postItem());
|
||||||
const item = RdDSheetUtility.getItem(event, this.actor);
|
this.html.find('.item-action').click(async event => RdDSheetUtility.getItem(event, this.actor)?.actionPrincipale(this.actor, async () => itemSheetDialog.render(true)));
|
||||||
item.sheet.render(true);
|
}
|
||||||
});
|
|
||||||
html.find('.item-delete').click(async event => {
|
_getEventActor(event) {
|
||||||
const li = RdDSheetUtility.getEventElement(event);
|
let actorId = event.currentTarget.attributes['data-actor-id'].value;
|
||||||
const item = this.actor.getObjet(li.data("item-id"));
|
let actor = game.actors.get(actorId);
|
||||||
RdDUtility.confirmerSuppressionItem(this, item, li);
|
return actor;
|
||||||
});
|
|
||||||
html.find('.item-vendre').click(async event => {
|
|
||||||
const item = RdDSheetUtility.getItem(event, this.actor);
|
|
||||||
item?.proposerVente();
|
|
||||||
});
|
|
||||||
html.find('.item-montrer').click(async event => {
|
|
||||||
const item = RdDSheetUtility.getItem(event, this.actor);
|
|
||||||
item?.postItem();
|
|
||||||
});
|
|
||||||
html.find('.item-action').click(async event => {
|
|
||||||
const item = RdDSheetUtility.getItem(event, this.actor);
|
|
||||||
this.actor.actionItem(item, async () => itemSheetDialog.render(true));
|
|
||||||
});
|
|
||||||
html.find('.conteneur-name a').click(async event => {
|
|
||||||
RdDUtility.toggleAfficheContenu(RdDSheetUtility.getItemId(event));
|
|
||||||
this.render(true);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -225,70 +222,56 @@ export class RdDItemSheet extends ItemSheet {
|
|||||||
if (this.item.isCompetence()) {
|
if (this.item.isCompetence()) {
|
||||||
let level = RdDItemCompetence.getNiveauBase(event.currentTarget.value);
|
let level = RdDItemCompetence.getNiveauBase(event.currentTarget.value);
|
||||||
this.item.system.base = level;
|
this.item.system.base = level;
|
||||||
$("#base").val(level);
|
this.html.find('[name="system.base"]').val(level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
get template() {
|
|
||||||
let type = this.item.type
|
|
||||||
return `systems/foundryvtt-reve-de-dragon/templates/item-${type}-sheet.html`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
_updateObject(event, formData) { // Deprecated en v0.8 à clarifier
|
_updateObject(event, formData) {
|
||||||
// Données de bonus de cases ?
|
if (this.item.type == 'sort') {
|
||||||
formData = RdDItemSort.buildBonusCaseStringFromFormData(formData);
|
// Données de bonus de cases ?
|
||||||
|
formData['system.bonuscase'] = RdDItemSort.buildBonusCaseStringFromFormData(formData.bonusValue, formData.caseValue);
|
||||||
|
}
|
||||||
|
|
||||||
return this.item.update(formData);
|
return this.item.update(formData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
async _onDragStart(event) {
|
async _onDragStart(event) {
|
||||||
console.log("_onDragStart", event);
|
|
||||||
if (event.target.classList.contains("entity-link")) return;
|
|
||||||
|
|
||||||
const itemId = event.srcElement?.attributes["data-item-id"].value;
|
|
||||||
const item = this.actor.items.get(itemId);
|
|
||||||
// Create drag data
|
|
||||||
const dragData = {
|
|
||||||
actorId: this.actor.id,
|
|
||||||
type: "Item",
|
|
||||||
data: item.system
|
|
||||||
};
|
|
||||||
|
|
||||||
event.dataTransfer.setData("text/plain", JSON.stringify(dragData));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onDrop(event) {
|
async _onDrop(event) {
|
||||||
// Try to extract the dragData
|
// Try to extract the dragData
|
||||||
let dragData;
|
let dragData = RdDItemSheet.$extractDragData(event);
|
||||||
try {
|
if (!dragData) return false;
|
||||||
dragData = JSON.parse(event.dataTransfer.getData('text/plain'));
|
|
||||||
} catch (err) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const allowed = Hooks.call("dropActorSheetData", this.actor, this, dragData);
|
const allowed = Hooks.call("dropActorSheetData", this.actor, this, dragData);
|
||||||
if (allowed === false) return;
|
if (allowed === false) return false;
|
||||||
|
|
||||||
// Handle different dragData types
|
// Handle different dragData types
|
||||||
switch (dragData.type) {
|
switch (dragData.type) {
|
||||||
case "Item":
|
case "Item":
|
||||||
return this._onDropItem(event, dragData);
|
return this._onDropItem(event, dragData);
|
||||||
|
case "Actor":
|
||||||
|
return this._onDropActor(event, dragData);
|
||||||
}
|
}
|
||||||
return super._onDrop(event);
|
return super._onDrop(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
static $extractDragData(event) {
|
||||||
async _onDropItem(event, dragData) {
|
try {
|
||||||
if (this.actor) {
|
const eventData = event?.dataTransfer?.getData('text/plain');
|
||||||
const dropParams = RdDSheetUtility.prepareItemDropParameters(this.item.id, this.actor.id, dragData, this.objetVersConteneur);
|
if (eventData) {
|
||||||
await this.actor.processDropItem(dropParams);
|
return JSON.parse(eventData);
|
||||||
await this.render(true);
|
}
|
||||||
}
|
} catch (err) { }
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _onDropItem(event, dragData) {
|
||||||
|
}
|
||||||
|
|
||||||
|
async _onDropActor(event, dragData) {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +1,14 @@
|
|||||||
import { SYSTEM_RDD } from "./constants.js";
|
import { RdDItemSheet } from "./item-sheet.js";
|
||||||
import { RdDItemSigneDraconique } from "./item-signedraconique.js";
|
import { RdDItemSigneDraconique } from "./item-signedraconique.js";
|
||||||
import { Misc } from "./misc.js";
|
import { TMRUtility } from "./tmr-utility.js";
|
||||||
import { TMRType, TMRUtility } from "./tmr-utility.js";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Item sheet pour signes draconiques
|
* Item sheet pour signes draconiques
|
||||||
* @extends {ItemSheet}
|
* @extends {RdDItemSheet}
|
||||||
*/
|
*/
|
||||||
export class RdDSigneDraconiqueItemSheet extends ItemSheet {
|
export class RdDSigneDraconiqueItemSheet extends RdDItemSheet {
|
||||||
|
|
||||||
/** @override */
|
static get ITEM_TYPE() { return "signedraconique" }
|
||||||
static get defaultOptions() {
|
|
||||||
return mergeObject(super.defaultOptions, {
|
|
||||||
classes: [SYSTEM_RDD, "sheet", "item"],
|
|
||||||
template: "systems/foundryvtt-reve-de-dragon/templates/item-signedraconique-sheet.html",
|
|
||||||
width: 550,
|
|
||||||
height: 550
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
_getHeaderButtons() {
|
|
||||||
let buttons = super._getHeaderButtons();
|
|
||||||
buttons.unshift({ class: "post", icon: "fas fa-comment", onclick: ev => this.item.postItem() });
|
|
||||||
return buttons;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/** @override */
|
/** @override */
|
||||||
@@ -32,8 +16,7 @@ export class RdDSigneDraconiqueItemSheet extends ItemSheet {
|
|||||||
const position = super.setPosition(options);
|
const position = super.setPosition(options);
|
||||||
const sheetHeader = this.element.find(".sheet-header");
|
const sheetHeader = this.element.find(".sheet-header");
|
||||||
const sheetBody = this.element.find(".sheet-body");
|
const sheetBody = this.element.find(".sheet-body");
|
||||||
const bodyHeight = position.height - sheetHeader[0].clientHeight;
|
sheetBody.css("height", position.height - sheetHeader[0].clientHeight)
|
||||||
sheetBody.css("height", bodyHeight);
|
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,16 +24,17 @@ export class RdDSigneDraconiqueItemSheet extends ItemSheet {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async getData() {
|
async getData() {
|
||||||
const formData = duplicate(this.item);
|
const formData = duplicate(this.item);
|
||||||
|
this.tmrs = TMRUtility.buildSelectionTypesTMR(this.item.system.typesTMR);
|
||||||
mergeObject(formData, {
|
mergeObject(formData, {
|
||||||
|
tmrs: this.tmrs,
|
||||||
title: formData.name,
|
title: formData.name,
|
||||||
isGM: game.user.isGM,
|
isGM: game.user.isGM,
|
||||||
owner: this.actor.isOwner,
|
owner: this.actor?.isOwner,
|
||||||
isOwned: this.actor ? true : false,
|
isOwned: this.actor ? true : false,
|
||||||
actorId: this.actor?.id,
|
actorId: this.actor?.id,
|
||||||
editable: this.isEditable,
|
editable: this.isEditable,
|
||||||
cssClass: this.isEditable ? "editable" : "locked",
|
cssClass: this.isEditable ? "editable" : "locked",
|
||||||
});
|
});
|
||||||
formData.tmrs = TMRUtility.listSelectedTMR(formData.system.typesTMR ?? []);
|
|
||||||
return formData;
|
return formData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,19 +46,24 @@ export class RdDSigneDraconiqueItemSheet extends ItemSheet {
|
|||||||
if (!this.options.editable) return;
|
if (!this.options.editable) return;
|
||||||
|
|
||||||
html.find(".signe-aleatoire").click(event => this.setSigneAleatoire());
|
html.find(".signe-aleatoire").click(event => this.setSigneAleatoire());
|
||||||
html.find(".select-tmr").change((event) => this.onSelectTmr(event));
|
html.find("input.select-tmr").change(event => this.onSelectTmr(event));
|
||||||
html.find(".signe-xp-sort").change((event) => this.onValeurXpSort(event.currentTarget.attributes['data-typereussite']?.value, Number(event.currentTarget.value)));
|
html.find(".signe-xp-sort").change(event => this.onValeurXpSort(event.currentTarget.attributes['data-typereussite']?.value, Number(event.currentTarget.value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
async setSigneAleatoire() {
|
async setSigneAleatoire() {
|
||||||
const newSigne = await RdDItemSigneDraconique.randomSigneDraconique();
|
const newSigne = await RdDItemSigneDraconique.randomSigneDraconique();
|
||||||
|
newSigne.name = this.item.name;
|
||||||
this.item.update(newSigne);
|
this.item.update(newSigne);
|
||||||
}
|
}
|
||||||
|
|
||||||
async onSelectTmr(event) {
|
async onSelectTmr(event) {
|
||||||
event.preventDefault();
|
const tmrName = $(event.currentTarget)?.data("tmr-name");
|
||||||
const selectedTMR = $(".select-tmr").val();
|
const onTmr = this.tmrs.find(it => it.name == tmrName);
|
||||||
this.item.update({ 'system.typesTMR': selectedTMR });
|
if (onTmr){
|
||||||
|
onTmr.selected = event.currentTarget.checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.item.update({ 'system.typesTMR': TMRUtility.buildListTypesTMRSelection(this.tmrs) });
|
||||||
}
|
}
|
||||||
|
|
||||||
async onValeurXpSort(event) {
|
async onValeurXpSort(event) {
|
||||||
@@ -85,12 +74,4 @@ export class RdDSigneDraconiqueItemSheet extends ItemSheet {
|
|||||||
await this.item.update({ 'system.valeur': newValeur });
|
await this.item.update({ 'system.valeur': newValeur });
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
get template() {
|
|
||||||
return `systems/foundryvtt-reve-de-dragon/templates/item-signedraconique-sheet.html`;
|
|
||||||
}
|
|
||||||
|
|
||||||
get title() {
|
|
||||||
return `Signe draconique: ${this.object.name}`;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,26 +63,21 @@ export class RdDItemSort extends Item {
|
|||||||
/** Met à jour les données de formulaire
|
/** Met à jour les données de formulaire
|
||||||
* si static des bonus de cases sont présents
|
* si static des bonus de cases sont présents
|
||||||
* */
|
* */
|
||||||
static buildBonusCaseStringFromFormData( formData ) {
|
static buildBonusCaseStringFromFormData( bonuses, cases ) {
|
||||||
if ( formData.bonusValue ) {
|
if ( bonuses ) {
|
||||||
let list = [];
|
let list = [];
|
||||||
let caseCheck = {};
|
let caseCheck = {};
|
||||||
for(let i=0; i<formData.bonusValue.length; i++) {
|
for (let i=0; i<bonuses.length; i++) {
|
||||||
let coord = formData.caseValue[i] || 'A1';
|
let coord = cases[i]?.toUpperCase() || 'A1';
|
||||||
coord = coord.toUpperCase();
|
let bonus = bonuses[i] || 0;
|
||||||
if ( TMRUtility.verifyTMRCoord( coord ) ) { // Sanity check
|
if ( TMRUtility.verifyTMRCoord( coord ) && bonus > 0 && caseCheck[coord] == undefined ) {
|
||||||
let bonus = formData.bonusValue[i] || 0;
|
caseCheck[coord] = bonus;
|
||||||
if ( bonus > 0 && caseCheck[coord] == undefined ) {
|
list.push( coord+":"+bonus );
|
||||||
caseCheck[coord] = bonus;
|
|
||||||
list.push( coord+":"+bonus );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
formData.bonusValue = undefined;
|
return list.toString();
|
||||||
formData.caseValue = undefined;
|
|
||||||
formData.system.bonuscase = list.toString(); // Reset
|
|
||||||
}
|
}
|
||||||
return formData;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|||||||
659
module/item.js
@@ -4,21 +4,44 @@ import { Misc } from "./misc.js";
|
|||||||
import { RdDHerbes } from "./rdd-herbes.js";
|
import { RdDHerbes } from "./rdd-herbes.js";
|
||||||
import { RdDUtility } from "./rdd-utility.js";
|
import { RdDUtility } from "./rdd-utility.js";
|
||||||
|
|
||||||
const typesObjetsEquipement = ["objet", "arme", "armure", "gemme", "conteneur", "herbe", "ingredient", "livre", "potion", "munition", "nourritureboisson", "monnaie"]
|
const typesObjetsInventaire = [
|
||||||
|
"arme",
|
||||||
|
"armure",
|
||||||
|
"conteneur",
|
||||||
|
"gemme",
|
||||||
|
"herbe",
|
||||||
|
"ingredient",
|
||||||
|
"faune",
|
||||||
|
"livre",
|
||||||
|
"monnaie",
|
||||||
|
"munition",
|
||||||
|
"nourritureboisson",
|
||||||
|
"objet",
|
||||||
|
"potion",
|
||||||
|
]
|
||||||
const typesObjetsOeuvres = ["oeuvre", "recettecuisine", "musique", "chant", "danse", "jeu"]
|
const typesObjetsOeuvres = ["oeuvre", "recettecuisine", "musique", "chant", "danse", "jeu"]
|
||||||
const encBrin = 0.00005;// un brin = 1 décigramme = 1/10g = 1/10000kg = 1/20000 enc
|
const typesObjetsDraconiques = ["queue", "ombre", "souffle", "tete", "signedraconique", "sortreserve", "rencontre"]
|
||||||
|
const typesObjetsConnaissance = ["meditation", "recettealchimique", "sort"]
|
||||||
|
const typesObjetsEffet = ["possession", "poison", "maladie"]
|
||||||
|
const typesObjetsCompetence = ["competence", "competencecreature"]
|
||||||
|
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
|
||||||
|
densité 3.5 (~2.3 à 4, parfois plus) -- https://www.juwelo.fr/guide-des-pierres/faits-et-chiffres/
|
||||||
|
*/
|
||||||
|
|
||||||
export const defaultItemImg = {
|
export const defaultItemImg = {
|
||||||
competence: "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp",
|
competence: "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp",
|
||||||
compcreature: "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp",
|
competencecreature: "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp",
|
||||||
arme: "systems/foundryvtt-reve-de-dragon/icons/armes_armures/epee_gnome.webp",
|
arme: "systems/foundryvtt-reve-de-dragon/icons/armes_armures/epee_gnome.webp",
|
||||||
armure: "systems/foundryvtt-reve-de-dragon/icons/armes_armures/armure_plaques.webp",
|
armure: "systems/foundryvtt-reve-de-dragon/icons/armes_armures/armure_plaques.webp",
|
||||||
conteneur: "systems/foundryvtt-reve-de-dragon/icons/objets/sac_a_dos.webp",
|
conteneur: "systems/foundryvtt-reve-de-dragon/icons/objets/sac_a_dos.webp",
|
||||||
sort: "systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp",
|
sort: "systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp",
|
||||||
herbe: "systems/foundryvtt-reve-de-dragon/icons/botanique/Endorlotte.webp",
|
herbe: "systems/foundryvtt-reve-de-dragon/icons/botanique/Endorlotte.webp",
|
||||||
|
faune: "systems/foundryvtt-reve-de-dragon/icons/faune/rongeur.webp",
|
||||||
ingredient: "systems/foundryvtt-reve-de-dragon/icons/objets/sable_poudre.webp",
|
ingredient: "systems/foundryvtt-reve-de-dragon/icons/objets/sable_poudre.webp",
|
||||||
livre: "systems/foundryvtt-reve-de-dragon/icons/objets/livre.webp",
|
livre: "systems/foundryvtt-reve-de-dragon/icons/objets/livre.webp",
|
||||||
potion: "systems/foundryvtt-reve-de-dragon/icons/objets/liqueur_de_bagdol.webp",
|
potion: "systems/foundryvtt-reve-de-dragon/icons/objets/liqueur_de_bagdol.webp",
|
||||||
|
rencontre: "systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp",
|
||||||
queue: "systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp",
|
queue: "systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp",
|
||||||
ombre: "systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp",
|
ombre: "systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp",
|
||||||
souffle: "systems/foundryvtt-reve-de-dragon/icons/souffle_dragon.webp",
|
souffle: "systems/foundryvtt-reve-de-dragon/icons/souffle_dragon.webp",
|
||||||
@@ -36,35 +59,107 @@ export const defaultItemImg = {
|
|||||||
nourritureboisson: "systems/foundryvtt-reve-de-dragon/icons/objets/provision_crue.webp",
|
nourritureboisson: "systems/foundryvtt-reve-de-dragon/icons/objets/provision_crue.webp",
|
||||||
signedraconique: "systems/foundryvtt-reve-de-dragon/icons/tmr/signe_draconique.webp",
|
signedraconique: "systems/foundryvtt-reve-de-dragon/icons/tmr/signe_draconique.webp",
|
||||||
gemme: "systems/foundryvtt-reve-de-dragon/icons/gemmes/almaze.webp",
|
gemme: "systems/foundryvtt-reve-de-dragon/icons/gemmes/almaze.webp",
|
||||||
possession: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp"
|
possession: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp",
|
||||||
|
sortreserve: "systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp",
|
||||||
|
extraitpoetique: "systems/foundryvtt-reve-de-dragon/icons/competence_ecriture.webp",
|
||||||
|
tarot: "systems/foundryvtt-reve-de-dragon/icons/tarots/dos-tarot.webp",
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
export class RdDItem extends Item {
|
export class RdDItem extends Item {
|
||||||
|
|
||||||
|
static getDefaultImg(itemType) {
|
||||||
|
return defaultItemImg[itemType];
|
||||||
|
}
|
||||||
|
|
||||||
|
static isItemInventaire(newLocal) {
|
||||||
|
return typesObjetsInventaire.includes(newLocal.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
static isFieldInventaireModifiable(type, field) {
|
||||||
|
switch (field) {
|
||||||
|
case 'quantite':
|
||||||
|
if (['conteneur'].includes(type)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'cout':
|
||||||
|
if (['monnaie'].includes(type)) {
|
||||||
|
return game.user.isGM;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
getUniteQuantite() {
|
||||||
|
switch (this.type) {
|
||||||
|
case "monnaie": return "(Pièces)"
|
||||||
|
case "herbe":
|
||||||
|
switch (this.system.categorie) {
|
||||||
|
case 'Alchimie': case 'Repos': case 'Soin':
|
||||||
|
return "(Brins)"
|
||||||
|
case 'Cuisine': return '';
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
case "ingredient": return "(Pépins ou Brins)"
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
constructor(itemData, context) {
|
constructor(itemData, context) {
|
||||||
if (!itemData.img) {
|
if (!itemData.img) {
|
||||||
itemData.img = defaultItemImg[itemData.type];
|
itemData.img = RdDItem.getDefaultImg(itemData.type);
|
||||||
}
|
}
|
||||||
super(itemData, context);
|
super(itemData, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static getTypeObjetsEquipement() {
|
static getItemTypesInventaire() {
|
||||||
return typesObjetsEquipement
|
return typesObjetsInventaire
|
||||||
}
|
}
|
||||||
|
|
||||||
static getTypesOeuvres() {
|
static getTypesOeuvres() {
|
||||||
return typesObjetsOeuvres
|
return typesObjetsOeuvres
|
||||||
}
|
}
|
||||||
|
|
||||||
isCompetence() {
|
isCompetencePersonnage() {
|
||||||
return this.type == 'competence';
|
return this.type == 'competence'
|
||||||
|
}
|
||||||
|
isCompetenceCreature() {
|
||||||
|
return this.type == 'competencecreature'
|
||||||
|
}
|
||||||
|
isCompetence() {
|
||||||
|
return typesObjetsCompetence.includes(this.type)
|
||||||
|
}
|
||||||
|
isInventaire() {
|
||||||
|
return RdDItem.isItemInventaire(this)
|
||||||
|
}
|
||||||
|
isOeuvre() {
|
||||||
|
return typesObjetsOeuvres.includes(this.type)
|
||||||
|
}
|
||||||
|
isDraconique() {
|
||||||
|
return typesObjetsDraconiques.includes(this.type)
|
||||||
|
}
|
||||||
|
isEffet() {
|
||||||
|
return typesObjetsEffet.includes(this.type)
|
||||||
|
}
|
||||||
|
isConnaissance() {
|
||||||
|
return typesObjetsConnaissance.includes(this.type)
|
||||||
}
|
}
|
||||||
|
|
||||||
isConteneur() {
|
isConteneur() {
|
||||||
return this.type == 'conteneur';
|
return this.type == 'conteneur';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getItemGroup() {
|
||||||
|
if (this.isInventaire()) return "equipement";
|
||||||
|
if (this.isOeuvre()) return "oeuvre";
|
||||||
|
if (this.isDraconique()) return "draconique";
|
||||||
|
if (this.isConnaissance()) return "connaissance";
|
||||||
|
if (this.isEffet()) return "effet";
|
||||||
|
if (this.isCompetence()) return "competence";
|
||||||
|
return "autres";
|
||||||
|
}
|
||||||
|
|
||||||
isConteneurNonVide() {
|
isConteneurNonVide() {
|
||||||
return this.isConteneur() && (this.system.contenu?.length ?? 0) > 0;
|
return this.isConteneur() && (this.system.contenu?.length ?? 0) > 0;
|
||||||
}
|
}
|
||||||
@@ -77,20 +172,31 @@ export class RdDItem extends Item {
|
|||||||
return !this.isConteneur() || (this.system.contenu?.length ?? 0) == 0;
|
return !this.isConteneur() || (this.system.contenu?.length ?? 0) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
isAlcool() {
|
isNourritureBoisson() {
|
||||||
return this.type == 'nourritureboisson' && this.system.boisson && this.system.alcoolise;
|
return this.type == 'nourritureboisson';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isComestible() {
|
||||||
|
switch (this.type) {
|
||||||
|
case 'nourritureboisson': return 'pret';
|
||||||
|
case 'herbe':
|
||||||
|
return this.system.categorie == 'Cuisine' && this.system.sust > 0 ? 'brut' : '';
|
||||||
|
case 'faune':
|
||||||
|
return this.system.sust > 0 ? 'brut' : '';
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
isAlcool() {
|
||||||
|
return this.isNourritureBoisson() && this.system.boisson && this.system.alcoolise;
|
||||||
|
}
|
||||||
|
|
||||||
isHerbeAPotion() {
|
isHerbeAPotion() {
|
||||||
return this.type == 'herbe' && (this.system.categorie == 'Soin' || this.system.categorie == 'Repos');
|
return this.type == 'herbe' && (this.system.categorie == 'Soin' || this.system.categorie == 'Repos');
|
||||||
}
|
}
|
||||||
isPotion() {
|
isPotion() {
|
||||||
return this.type == 'potion';
|
return this.type == 'potion';
|
||||||
}
|
}
|
||||||
|
|
||||||
isEquipement() {
|
|
||||||
return RdDItem.getTypeObjetsEquipement().includes(this.type)
|
|
||||||
}
|
|
||||||
|
|
||||||
isCristalAlchimique() {
|
isCristalAlchimique() {
|
||||||
return this.type == 'objet' && Grammar.toLowerCaseNoAccent(this.name) == 'cristal alchimique' && this.system.quantite > 0;
|
return this.type == 'objet' && Grammar.toLowerCaseNoAccent(this.name) == 'cristal alchimique' && this.system.quantite > 0;
|
||||||
}
|
}
|
||||||
@@ -99,22 +205,45 @@ export class RdDItem extends Item {
|
|||||||
return this.system.magique
|
return this.system.magique
|
||||||
}
|
}
|
||||||
|
|
||||||
getEncTotal() {
|
getQuantite() {
|
||||||
return Number(this.system.encombrement ?? 0) * Number(this.system.quantite ?? 1)
|
return Math.round(this.isConteneur() ? 1 : (this.system.quantite ?? 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getEncTotal() {
|
||||||
|
return this.getEnc() * this.getQuantite();
|
||||||
|
}
|
||||||
|
|
||||||
getEnc() {
|
getEnc() {
|
||||||
switch (this.type) {
|
switch (this.type) {
|
||||||
case 'herbe':
|
case 'herbe':
|
||||||
|
return this.getEncHerbe();
|
||||||
|
case 'gemme':
|
||||||
|
return encPepin * this.system.taille;
|
||||||
|
}
|
||||||
|
return Math.max(this.system.encombrement ?? 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
getEncHerbe() {
|
||||||
|
switch (this.system.categorie) {
|
||||||
|
case 'Repos': case 'Soin': case 'Alchimie':
|
||||||
return encBrin;
|
return encBrin;
|
||||||
}
|
}
|
||||||
return this.system.encombrement ?? 0;
|
return this.system.encombrement;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
valeurTotale() {
|
||||||
|
return this.getQuantite() * this.valeur()
|
||||||
|
}
|
||||||
|
|
||||||
|
valeur() {
|
||||||
|
return this.system.cout ?? 0
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareDerivedData() {
|
prepareDerivedData() {
|
||||||
super.prepareDerivedData();
|
super.prepareDerivedData();
|
||||||
if (this.isEquipement()) {
|
if (this.isInventaire()) {
|
||||||
this._calculsEquipement();
|
this.system.encTotal = this.getEncTotal();
|
||||||
|
|
||||||
if (this.isPotion()) {
|
if (this.isPotion()) {
|
||||||
this.prepareDataPotion()
|
this.prepareDataPotion()
|
||||||
}
|
}
|
||||||
@@ -127,37 +256,50 @@ export class RdDItem extends Item {
|
|||||||
this.system.magique = categorie.includes('enchante');
|
this.system.magique = categorie.includes('enchante');
|
||||||
if (this.system.magique) {
|
if (this.system.magique) {
|
||||||
if (categorie.includes('soin') || categorie.includes('repos')) {
|
if (categorie.includes('soin') || categorie.includes('repos')) {
|
||||||
// TODO: utiliser calculePointsRepos / calculePointsGuerison
|
// TODO: utiliser calculPointsRepos / calculPointsGuerison
|
||||||
this.system.puissance = RdDHerbes.calculePuissancePotion(this);
|
this.system.puissance = RdDHerbes.calculPuissancePotion(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_calculsEquipement() {
|
|
||||||
const quantite = this.isConteneur() ? 1 : (this.system.quantite ?? 0);
|
|
||||||
const enc = this.getEnc();
|
|
||||||
if (enc != undefined) {
|
|
||||||
this.system.encTotal = Math.max(enc, 0) * quantite;
|
|
||||||
}
|
|
||||||
if (this.cout != undefined) {
|
|
||||||
this.system.prixTotal = Math.max(this.cout, 0) * quantite;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getActionPrincipale(options = { warnIfNot: true }) {
|
getActionPrincipale(options = { warnIfNot: true }) {
|
||||||
const warn = options.warnIfNot;
|
|
||||||
switch (this.type) {
|
switch (this.type) {
|
||||||
case 'nourritureboisson': return this._actionOrWarnQuantiteZero(this.boisson ? 'Boire' : 'Manger', warn);
|
case 'conteneur': return 'Ouvrir';
|
||||||
case 'potion': return this._actionOrWarnQuantiteZero('Boire', warn);
|
}
|
||||||
case 'livre': return this._actionOrWarnQuantiteZero('Lire', warn);
|
if (this.actor?.isPersonnage()) {
|
||||||
case 'conteneur': return this._actionOrWarnQuantiteZero('Ouvrir', warn);
|
const warn = options.warnIfNot;
|
||||||
case 'herbe': return this.isHerbeAPotion() ? this._actionOrWarnQuantiteZero('Décoction', warn) : undefined;
|
if (this.isComestible() == 'brut') {
|
||||||
case 'queue': case 'ombre': return this.system.refoulement>0 ? 'Refouler' : undefined;
|
return 'Utiliser';
|
||||||
|
}
|
||||||
|
switch (this.type) {
|
||||||
|
case 'nourritureboisson': return this._actionOrWarnQuantiteZero(this.system.boisson ? 'Boire' : 'Manger', warn);
|
||||||
|
case 'potion': return this._actionOrWarnQuantiteZero('Boire', warn);
|
||||||
|
case 'livre': return this._actionOrWarnQuantiteZero('Lire', warn);
|
||||||
|
case 'herbe': return this.isHerbeAPotion() ? this._actionOrWarnQuantiteZero('Décoction', warn) : undefined;
|
||||||
|
case 'queue': case 'ombre': return this.system.refoulement > 0 ? 'Refouler' : undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async actionPrincipale(actor, onActionItem = async () => { }) {
|
||||||
|
if (!this.getActionPrincipale()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (await actor.actionNourritureboisson(this, onActionItem)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (this.type) {
|
||||||
|
case 'potion': return await actor.consommerPotion(this, onActionItem);
|
||||||
|
case 'livre': return await actor.actionLire(this);
|
||||||
|
case 'conteneur': return await this.sheet.render(true);
|
||||||
|
case 'herbe': return await actor.actionHerbe(this);
|
||||||
|
case 'queue': case 'ombre': return await actor.actionRefoulement(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_actionOrWarnQuantiteZero(actionName, warn){
|
_actionOrWarnQuantiteZero(actionName, warn) {
|
||||||
if ((this.system.quantite ?? 0) <= 0) {
|
if ((this.system.quantite ?? 0) <= 0) {
|
||||||
if (warn) {
|
if (warn) {
|
||||||
ui.notifications.warn(`Vous n'avez plus de ${this.name}.`);
|
ui.notifications.warn(`Vous n'avez plus de ${this.name}.`);
|
||||||
@@ -174,6 +316,42 @@ export class RdDItem extends Item {
|
|||||||
await this.quantiteIncDec(-nombre, options);
|
await this.quantiteIncDec(-nombre, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async onCreateDecoupeComestible(actor) {
|
||||||
|
if (actor && this.isComestible() == 'brut' && this.system.sust != 1) {
|
||||||
|
if (this.system.sust < 1) {
|
||||||
|
await actor.updateEmbeddedDocuments('Item', [{
|
||||||
|
_id: this.id,
|
||||||
|
'system.sust': 0
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const sust = Math.floor(this.system.sust);
|
||||||
|
await actor.updateEmbeddedDocuments('Item', [{
|
||||||
|
_id: this.id,
|
||||||
|
'system.quantite': this.system.quantite * sust,
|
||||||
|
'system.encombrement': Misc.keepDecimals(this.system.encombrement / sust, 2),
|
||||||
|
'system.cout': Misc.keepDecimals(this.system.cout / sust, 2),
|
||||||
|
'system.sust': 1
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async empiler(item) {
|
||||||
|
if (this.isComestible() == 'brut') {
|
||||||
|
const sust = this.system.sust + item.system.sust;
|
||||||
|
const encombrement = this.system.encombrement + item.system.encombrement;
|
||||||
|
await this.update({
|
||||||
|
"system.sust": sust,
|
||||||
|
"system.encombrement": encombrement
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
await this.quantiteIncDec(item.system.quantite);
|
||||||
|
}
|
||||||
|
await item.delete();
|
||||||
|
}
|
||||||
|
|
||||||
async quantiteIncDec(nombre, options = { diminuerQuantite: true, supprimerSiZero: false }) {
|
async quantiteIncDec(nombre, options = { diminuerQuantite: true, supprimerSiZero: false }) {
|
||||||
const quantite = Number(this.system.quantite ?? -1);
|
const quantite = Number(this.system.quantite ?? -1);
|
||||||
if (quantite >= 0) {
|
if (quantite >= 0) {
|
||||||
@@ -197,71 +375,70 @@ export class RdDItem extends Item {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
// détermine si deux équipements sont similaires: de même type, et avec les même champs hormis la quantité
|
// détermine si deux équipements sont similaires: de même type, et avec les même champs hormis la quantité
|
||||||
isEquipementSimilaire(other) {
|
isInventaireEmpilable(other) {
|
||||||
if (!this.isEquipement()) return false;
|
if (!other || !this.isInventaire()) {
|
||||||
let message = undefined;
|
return [false, undefined];
|
||||||
if (this.type != other.type) {
|
}
|
||||||
message = `Impossible de regrouper ${this.type} avec ${other.type}`;
|
if (this.system.quantite == undefined) {
|
||||||
|
return [false, `Impossible de regrouper des ${this.type}, ils ne sont pas empilables`];
|
||||||
|
}
|
||||||
|
else if (this.type != other.type) {
|
||||||
|
return [false, `Impossible de regrouper des ${this.type} avec des ${other.type}`];
|
||||||
}
|
}
|
||||||
else if (this.name != other.name) {
|
else if (this.name != other.name) {
|
||||||
message = `Impossible de regrouper ${this.name} avec ${other.name}`;
|
return [false, `Impossible de regrouper ${this.name} avec ${other.name}`];
|
||||||
}
|
}
|
||||||
else if (this.system.quantite == undefined) {
|
|
||||||
message = `Impossible de regrouper des ${this.type}, ils ne sont pas empilables`;
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
const differences = Object.entries(this.system)
|
const excludedProperties = ['quantite', 'cout', 'encTotal'];
|
||||||
.filter(([key, value]) => !['quantite', 'encTotal', 'prixTotal', 'cout'].includes(key) && value != other.system[key]);
|
if (this.isComestible()) {
|
||||||
|
excludedProperties.push('sust', 'encombrement');
|
||||||
|
}
|
||||||
|
let differences = Object.entries(this.system)
|
||||||
|
.filter(([key, value]) => !excludedProperties.includes(key))
|
||||||
|
.filter(([key, value]) => value != other.system[key])
|
||||||
if (differences.length > 0) {
|
if (differences.length > 0) {
|
||||||
message = `Impossible de regrouper les ${this.type} ${this.name}: `;
|
let message = `Impossible de regrouper les ${this.type} ${this.name}: `;
|
||||||
for (const [key, value] of differences) {
|
for (const [key, value] of differences) {
|
||||||
message += `<br>${key}: ${value} vs ${other.system[key]}`;
|
message += `<br>${key}: ${value} vs ${other.system[key]}`;
|
||||||
}
|
}
|
||||||
|
return [false, message];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (message){
|
return [true, undefined];
|
||||||
ui.notifications.info(message)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async proposerVente() {
|
async proposerVente() {
|
||||||
console.log(this);
|
console.log(this);
|
||||||
if (this.isConteneurNonVide()) {
|
if (this.isConteneurNonVide()) {
|
||||||
ui.notifications.warn(`Votre ${this.name} n'est pas vide, pas possible de le donner ou le vendre`);
|
ui.notifications.warn(`Votre ${this.name} n'est pas vide, pas possible de le proposer`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const dialog = await DialogItemVente.create(this, (vente) => this._onProposerVente(vente))
|
await DialogItemVente.display(this, async (vente) => {
|
||||||
dialog.render(true);
|
vente["properties"] = this.getProprietes();
|
||||||
}
|
if (vente.isOwned) {
|
||||||
|
if (vente.quantiteNbLots * vente.tailleLot > vente.quantiteMax) {
|
||||||
async _onProposerVente(venteData) {
|
ui.notifications.warn(`Vous avez ${vente.quantiteMax} ${vente.item.name}, ce n'est pas suffisant pour vendre ${vente.quantiteNbLots} de ${vente.tailleLot}`)
|
||||||
venteData["properties"] = this.getProprietes();
|
return;
|
||||||
if (venteData.isOwned) {
|
}
|
||||||
if (venteData.quantiteNbLots * venteData.tailleLot > venteData.quantiteMax) {
|
|
||||||
ui.notifications.warn(`Vous avez ${venteData.quantiteMax} ${venteData.item.name}, ce n'est pas suffisant pour vendre ${venteData.quantiteNbLots} de ${venteData.tailleLot}`)
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
vente.jsondata = JSON.stringify(vente.item);
|
||||||
venteData.jsondata = JSON.stringify(venteData.item);
|
|
||||||
|
|
||||||
console.log(venteData);
|
console.log(vente);
|
||||||
let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.html', venteData);
|
let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.html', vente);
|
||||||
ChatMessage.create(RdDUtility.chatDataSetup(html));
|
ChatMessage.create(RdDUtility.chatDataSetup(html));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getProprietes() {
|
getProprietes() {
|
||||||
return this[`_${this.type}ChatData`]();
|
return this[`_${this.type}ChatData`]().filter(it => it != undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async postItem(modeOverride) {
|
async postItem(modeOverride) {
|
||||||
console.log(this);
|
console.log(this);
|
||||||
let chatData = duplicate(this);
|
let chatData = duplicate(this);
|
||||||
const properties = this.getProprietes();
|
chatData["properties"] = this.getProprietes();
|
||||||
chatData["properties"] = properties
|
|
||||||
if (this.actor) {
|
if (this.actor) {
|
||||||
chatData.actor = { id: this.actor.id };
|
chatData.actor = { id: this.actor.id };
|
||||||
}
|
}
|
||||||
@@ -278,262 +455,237 @@ export class RdDItem extends Item {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static propertyIfDefined(name, val, condition = (it) => true) {
|
static propertyIfDefined(name, val, condition = true) {
|
||||||
return condition ? [`<b>${name}</b>: ${val}`] : [];
|
return condition ? `<b>${name}</b>: ${val}` : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_inventaireTemplateChatData() {
|
||||||
|
return [
|
||||||
|
RdDItem.propertyIfDefined('Qualité', this.system.qualite, this.system.qualite != 0),
|
||||||
|
RdDItem.propertyIfDefined('Encombrement', this.system.encombrement)
|
||||||
|
// cout et quantité masqués
|
||||||
|
]
|
||||||
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_objetChatData() {
|
_objetChatData() {
|
||||||
const tplData = this.system
|
return this._inventaireTemplateChatData()
|
||||||
let properties = [].concat(
|
|
||||||
RdDItem.propertyIfDefined('Résistance', tplData.resistance, tplData.resistance),
|
|
||||||
RdDItem.propertyIfDefined('Qualité', tplData.qualite, tplData.qualite),
|
|
||||||
RdDItem.propertyIfDefined('Encombrement', tplData.encombrement),
|
|
||||||
);
|
|
||||||
return properties;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_nourritureboissonChatData() {
|
_nourritureboissonChatData() {
|
||||||
const tplData = this.system
|
return [
|
||||||
let properties = [].concat(
|
RdDItem.propertyIfDefined('Sustentation', this.system.sust, this.system.sust > 0),
|
||||||
RdDItem.propertyIfDefined('Sustentation', tplData.sust, tplData.sust > 0),
|
RdDItem.propertyIfDefined('Désaltère', this.system.desaltere, this.system.boisson),
|
||||||
RdDItem.propertyIfDefined('Désaltère', tplData.desaltere, tplData.boisson),
|
RdDItem.propertyIfDefined('Force alcool', this.system.force, this.system.boisson && this.system.alcoolise),
|
||||||
RdDItem.propertyIfDefined('Force alcool', tplData.force, tplData.boisson && tplData.alcoolise),
|
RdDItem.propertyIfDefined('Exotisme', this.system.exotisme, this.system.exotisme < 0),
|
||||||
RdDItem.propertyIfDefined('Exotisme', tplData.exotisme, tplData.exotisme < 0),
|
...this._inventaireTemplateChatData()
|
||||||
RdDItem.propertyIfDefined('Qualité', tplData.qualite, tplData.qualite),
|
]
|
||||||
RdDItem.propertyIfDefined('Encombrement', tplData.encombrement),
|
|
||||||
);
|
|
||||||
return properties;
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_armeChatData() {
|
_armeChatData() {
|
||||||
const tplData = this.system
|
return [
|
||||||
let properties = [
|
`<b>Compétence</b>: ${this.system.competence}`,
|
||||||
`<b>Compétence</b>: ${tplData.competence}`,
|
`<b>Dommages</b>: ${this.system.dommages}`,
|
||||||
`<b>Dommages</b>: ${tplData.dommages}`,
|
`<b>Force minimum</b>: ${this.system.force}`,
|
||||||
`<b>Force minimum</b>: ${tplData.force}`,
|
`<b>Resistance</b>: ${this.system.resistance}`,
|
||||||
`<b>Resistance</b>: ${tplData.resistance}`,
|
...this._inventaireTemplateChatData()
|
||||||
`<b>Encombrement</b>: ${tplData.encombrement}`
|
|
||||||
]
|
]
|
||||||
return properties;
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_conteneurChatData() {
|
_conteneurChatData() {
|
||||||
const tplData = this.system
|
return [
|
||||||
let properties = [
|
`<b>Capacité</b>: ${this.system.capacite} Enc.`,
|
||||||
`<b>Capacité</b>: ${tplData.capacite} Enc.`,
|
...this._inventaireTemplateChatData()
|
||||||
`<b>Encombrement</b>: ${tplData.encombrement}`
|
|
||||||
]
|
]
|
||||||
return properties;
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_munitionChatData() {
|
_munitionChatData() {
|
||||||
const tplData = this.system
|
return this._inventaireTemplateChatData()
|
||||||
let properties = [
|
|
||||||
`<b>Encombrement</b>: ${tplData.encombrement}`
|
|
||||||
]
|
|
||||||
return properties;
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_armureChatData() {
|
_armureChatData() {
|
||||||
const tplData = this.system
|
return [
|
||||||
let properties = [
|
`<b>Protection</b>: ${this.system.protection}`,
|
||||||
`<b>Protection</b>: ${tplData.protection}`,
|
`<b>Détérioration</b>: ${this.system.deterioration}`,
|
||||||
`<b>Détérioration</b>: ${tplData.deterioration}`,
|
`<b>Malus armure</b>: ${this.system.malus}`,
|
||||||
`<b>Malus armure</b>: ${tplData.malus}`,
|
...this._inventaireTemplateChatData()
|
||||||
`<b>Encombrement</b>: ${tplData.encombrement}`
|
|
||||||
]
|
]
|
||||||
return properties;
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_competenceChatData() {
|
_competenceChatData() {
|
||||||
const tplData = this.system
|
return [
|
||||||
let properties = [
|
`<b>Catégorie</b>: ${this.system.categorie}`,
|
||||||
`<b>Catégorie</b>: ${tplData.categorie}`,
|
`<b>Niveau</b>: ${this.system.niveau}`,
|
||||||
`<b>Niveau</b>: ${tplData.niveau}`,
|
`<b>Caractéristique par défaut</b>: ${this.system.carac_defaut}`,
|
||||||
`<b>Caractéristique par défaut</b>: ${tplData.carac_defaut}`,
|
`<b>XP</b>: ${this.system.xp}`
|
||||||
`<b>XP</b>: ${tplData.xp}`
|
|
||||||
]
|
]
|
||||||
return properties;
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_competencecreatureChatData() {
|
_competencecreatureChatData() {
|
||||||
const tplData = this.system
|
return [
|
||||||
let properties = [
|
`<b>Catégorie</b>: ${this.system.categorie}`,
|
||||||
`<b>Catégorie</b>: ${tplData.categorie}`,
|
`<b>Niveau</b>: ${this.system.niveau}`,
|
||||||
`<b>Niveau</b>: ${tplData.niveau}`,
|
`<b>Caractéristique</b>: ${this.system.carac_value}`,
|
||||||
`<b>Caractéristique</b>: ${tplData.carac_value}`,
|
`<b>XP</b>: ${this.system.xp}`
|
||||||
`<b>XP</b>: ${tplData.xp}`
|
|
||||||
]
|
]
|
||||||
return properties;
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_sortChatData() {
|
_sortChatData() {
|
||||||
const tplData = this.system
|
return [
|
||||||
let properties = [
|
`<b>Draconic</b>: ${this.system.draconic}`,
|
||||||
`<b>Draconic</b>: ${tplData.draconic}`,
|
`<b>Difficulté</b>: ${this.system.difficulte}`,
|
||||||
`<b>Difficulté</b>: ${tplData.difficulte}`,
|
`<b>Case TMR</b>: ${this.system.caseTMR}`,
|
||||||
`<b>Case TMR</b>: ${tplData.caseTMR}`,
|
`<b>Points de Rêve</b>: ${this.system.ptreve}`
|
||||||
`<b>Points de Rêve</b>: ${tplData.ptreve}`
|
|
||||||
]
|
]
|
||||||
return properties;
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_herbeChatData() {
|
_herbeChatData() {
|
||||||
const tplData = this.system
|
return [
|
||||||
let properties = [
|
`<b>Milieu</b>: ${this.system.milieu}`,
|
||||||
`<b>Milieu</b>: ${tplData.milieu}`,
|
`<b>Catégorie</b>: ${this.system.categorie}`,
|
||||||
`<b>Rareté</b>: ${tplData.rarete}`,
|
...this._inventaireTemplateChatData()
|
||||||
`<b>Catégorie</b>: ${tplData.categorie}`,
|
|
||||||
]
|
]
|
||||||
return properties;
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_ingredientChatData() {
|
_ingredientChatData() {
|
||||||
const tplData = this.system
|
return [
|
||||||
let properties = [
|
`<b>Milieu</b>: ${this.system.milieu}`,
|
||||||
`<b>Milieu</b>: ${tplData.milieu}`,
|
`<b>Catégorie</b>: ${this.system.categorie}`,
|
||||||
`<b>Rareté</b>: ${tplData.rarete}`,
|
...this._inventaireTemplateChatData()
|
||||||
`<b>Catégorie</b>: ${tplData.categorie}`,
|
]
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
_fauneChatData() {
|
||||||
|
return [
|
||||||
|
`<b>Sustentation</b>: ${this.system.sust}`,
|
||||||
|
`<b>Milieu</b>: ${this.system.milieu}`,
|
||||||
|
...this._inventaireTemplateChatData()
|
||||||
]
|
]
|
||||||
return properties;
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_tacheChatData() {
|
_tacheChatData() {
|
||||||
const tplData = this.system
|
return [
|
||||||
let properties = [
|
`<b>Caractéristique</b>: ${this.system.carac}`,
|
||||||
`<b>Caractéristique</b>: ${tplData.carac}`,
|
`<b>Compétence</b>: ${this.system.competence}`,
|
||||||
`<b>Compétence</b>: ${tplData.competence}`,
|
`<b>Périodicité</b>: ${this.system.periodicite}`,
|
||||||
`<b>Périodicité</b>: ${tplData.periodicite}`,
|
`<b>Fatigue</b>: ${this.system.fatigue}`,
|
||||||
`<b>Fatigue</b>: ${tplData.fatigue}`,
|
`<b>Difficulté</b>: ${this.system.difficulte}`,
|
||||||
`<b>Difficulté</b>: ${tplData.difficulte}`
|
RdDItem.propertyIfDefined('Points de Tâche', this.system.points_de_tache, this.system.cacher_points_de_tache),
|
||||||
].concat([
|
`<b>Points de Tâche atteints</b>: ${this.system.points_de_tache_courant}`]
|
||||||
tplData.cacher_points_de_tache ? [] :`<b>Points de Tâche</b>: ${tplData.points_de_tache}`
|
|
||||||
]).concat([
|
|
||||||
`<b>Points de Tâche atteints</b>: ${tplData.points_de_tache_courant}`]
|
|
||||||
);
|
|
||||||
return properties;
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_livreChatData() {
|
_livreChatData() {
|
||||||
const tplData = this.system
|
return [
|
||||||
let properties = [
|
`<b>Compétence</b>: ${this.system.competence}`,
|
||||||
`<b>Compétence</b>: ${tplData.competence}`,
|
`<b>Auteur</b>: ${this.system.auteur}`,
|
||||||
`<b>Auteur</b>: ${tplData.auteur}`,
|
`<b>Difficulté</b>: ${this.system.difficulte}`,
|
||||||
`<b>Difficulté</b>: ${tplData.difficulte}`,
|
RdDItem.propertyIfDefined('Points de Tâche', this.system.points_de_tache, this.system.cacher_points_de_tache),
|
||||||
`<b>Points de Tâche</b>: ${tplData.points_de_tache}`,
|
...this._inventaireTemplateChatData()
|
||||||
`<b>Encombrement</b>: ${tplData.encombrement}`
|
|
||||||
]
|
]
|
||||||
return properties;
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_potionChatData() {
|
_potionChatData() {
|
||||||
const tplData = this.system
|
return [
|
||||||
let properties = [
|
`<b>Rareté</b>: ${this.system.rarete}`,
|
||||||
`<b>Rareté</b>: ${tplData.rarete}`,
|
`<b>Catégorie</b>: ${this.system.categorie}`,
|
||||||
`<b>Catégorie</b>: ${tplData.categorie}`,
|
...this._inventaireTemplateChatData()
|
||||||
`<b>Encombrement</b>: ${tplData.encombrement}`,
|
|
||||||
]
|
]
|
||||||
return properties;
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_queueChatData() {
|
_queueChatData() {
|
||||||
const tplData = this.system
|
function label(categorie) {
|
||||||
let properties = [
|
switch (categorie) {
|
||||||
`<b>Refoulement</b>: ${tplData.refoulement}`
|
case 'ideefixe': return 'Idée fixe';
|
||||||
|
case 'lancinant': return 'Désir lancinant';
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
`<b>Refoulement</b>: ${this.system.refoulement}`,
|
||||||
|
`<b>Catégorie</b>: ${label(this.system.categorie)}`,
|
||||||
|
`<b>Affecte</b>: ${this.system.hautrevant ? 'les haut-rêvants' : 'tout le monde'}`,
|
||||||
]
|
]
|
||||||
return properties;
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_ombreChatData() {
|
_ombreChatData() {
|
||||||
const tplData = this.system
|
return this._queueChatData()
|
||||||
let properties = [
|
|
||||||
`<b>Refoulement</b>: ${tplData.refoulement}`
|
|
||||||
]
|
|
||||||
return properties;
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_souffleChatData() {
|
_souffleChatData() {
|
||||||
const tplData = this.system
|
return [
|
||||||
let properties = [];
|
`<b>Affecte</b>: ${this.system.hautrevant ? 'les haut-rêvants' : 'tout le monde'}`,
|
||||||
return properties;
|
];
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_teteChatData() {
|
_teteChatData() {
|
||||||
const tplData = this.system
|
return [
|
||||||
let properties = [];
|
`<b>Affecte</b>: ${this.system.hautrevant ? 'les haut-rêvants' : 'tout le monde'}`,
|
||||||
return properties;
|
];
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_tarotChatData() {
|
_tarotChatData() {
|
||||||
const tplData = this.system
|
return [
|
||||||
let properties = [
|
RdDItem.propertyIfDefined('Carte', RdDUtility.linkCompendium(this.pack, this.id, this.name), this.pack),
|
||||||
`<b>Concept</b>: ${tplData.concept}`,
|
`<b>Concept</b>: ${this.system.concept}`,
|
||||||
`<b>Aspect</b>: ${tplData.aspect}`,
|
`<b>Aspect</b>: ${this.system.aspect}`,
|
||||||
]
|
]
|
||||||
return properties;
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_nombreastralChatData() {
|
_nombreastralChatData() {
|
||||||
const tplData = this.system
|
return [
|
||||||
let properties = [
|
`<b>Valeur</b>: ${this.system.value}`,
|
||||||
`<b>Valeur</b>: ${tplData.value}`,
|
`<b>Jour</b>: ${this.system.jourlabel}`,
|
||||||
`<b>Jour</b>: ${tplData.jourlabel}`,
|
|
||||||
]
|
]
|
||||||
return properties;
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_monnaieChatData() {
|
_monnaieChatData() {
|
||||||
const tplData = this.system
|
return this._inventaireTemplateChatData()
|
||||||
let properties = [
|
|
||||||
`<b>Valeur en Deniers</b>: ${tplData.valeur_deniers}`,
|
|
||||||
`<b>Encombrement</b>: ${tplData.encombrement}`
|
|
||||||
]
|
|
||||||
return properties;
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_meditationChatData() {
|
_meditationChatData() {
|
||||||
const tplData = this.system
|
return [
|
||||||
let properties = [
|
`<b>Thème</b>: ${this.system.theme}`,
|
||||||
`<b>Thème</b>: ${tplData.theme}`,
|
`<b>Compétence</b>: ${this.system.competence}`,
|
||||||
`<b>Compétence</b>: ${tplData.competence}`,
|
`<b>Support</b>: ${this.system.support}`,
|
||||||
`<b>Support</b>: ${tplData.support}`,
|
`<b>Heure</b>: ${this.system.heure}`,
|
||||||
`<b>Heure</b>: ${tplData.heure}`,
|
`<b>Purification</b>: ${this.system.purification}`,
|
||||||
`<b>Purification</b>: ${tplData.purification}`,
|
`<b>Vêture</b>: ${this.system.veture}`,
|
||||||
`<b>Vêture</b>: ${tplData.veture}`,
|
`<b>Comportement</b>: ${this.system.comportement}`,
|
||||||
`<b>Comportement</b>: ${tplData.comportement}`,
|
`<b>Case TMR</b>: ${this.system.tmr}`
|
||||||
`<b>Case TMR</b>: ${tplData.tmr}`
|
]
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
_rencontreChatData() {
|
||||||
|
if (this.system.coord) {
|
||||||
|
return [
|
||||||
|
`<b>Force</b>: ${this.system.force}`,
|
||||||
|
`<b>Coordonnées</b>: ${this.system.coord}`,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
`<b>Force</b>: ${this.system.formule}`,
|
||||||
|
`<b>Refoulement</b>: ${this.system.refoulement}`,
|
||||||
|
RdDItem.propertyIfDefined('<b>Présent de cités</b>', '', this.system.presentCite),
|
||||||
]
|
]
|
||||||
return properties;
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_casetmrChatData() {
|
_casetmrChatData() {
|
||||||
const tplData = this.system
|
return [
|
||||||
let properties = [
|
`<b>Coordonnée</b>: ${this.system.coord}`,
|
||||||
`<b>Coordonnée</b>: ${tplData.coord}`,
|
`<b>Spécificité</b>: ${this.system.specific}`
|
||||||
`<b>Spécificité</b>: ${tplData.specific}`
|
|
||||||
]
|
]
|
||||||
return properties;
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_maladieChatData() {
|
_maladieChatData() {
|
||||||
const tplData = this.system
|
if (!this.system.identifie) {
|
||||||
let properties
|
return [`<b>Inconnue</b>`]
|
||||||
if (tplData.identifie) {
|
|
||||||
properties = [
|
|
||||||
`<b>Malignité</b>: ${tplData.malignite}`,
|
|
||||||
`<b>Périodicité</b>: ${tplData.periodicite}`,
|
|
||||||
`<b>Dommages</b>: ${tplData.dommages}`
|
|
||||||
]
|
|
||||||
if (tplData.remedesconnus) {
|
|
||||||
properties.push(`<b>Remedes</b>: ${tplData.remedes}`)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
properties = [
|
|
||||||
`<b>Inconnue</b>`]
|
|
||||||
}
|
}
|
||||||
return properties;
|
return [
|
||||||
|
`<b>Malignité</b>: ${this.system.malignite}`,
|
||||||
|
`<b>Périodicité</b>: ${this.system.periodicite}`,
|
||||||
|
`<b>Dommages</b>: ${this.system.dommages}`,
|
||||||
|
RdDItem.propertyIfDefined('<b>Remedes</b>', this.system.remedes, this.system.remedesconnus),
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -543,16 +695,13 @@ export class RdDItem extends Item {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_gemmeChatData() {
|
_gemmeChatData() {
|
||||||
const tplData = this.system
|
return [
|
||||||
let properties = [
|
`<b>Pureté</b>: ${this.system.purete}`,
|
||||||
`<b>Pureté</b>: ${tplData.purete}`,
|
`<b>Taille</b>: ${this.system.taille}`,
|
||||||
`<b>Taille</b>: ${tplData.taille}`,
|
`<b>Inertie</b>: ${this.system.inertie}`,
|
||||||
`<b>Inertie</b>: ${tplData.inertie}`,
|
`<b>Enchantabilité</b>: ${this.system.enchantabilite}`,
|
||||||
`<b>Enchantabilité</b>: ${tplData.enchantabilite}`,
|
...this._inventaireTemplateChatData()
|
||||||
`<b>Prix</b>: ${tplData.cout}`,
|
|
||||||
]
|
]
|
||||||
return properties;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
324
module/migrations.js
Normal file
@@ -0,0 +1,324 @@
|
|||||||
|
import { LOG_HEAD, SYSTEM_RDD } from "./constants.js";
|
||||||
|
import { Environnement } from "./environnement.js";
|
||||||
|
import { Grammar } from "./grammar.js";
|
||||||
|
|
||||||
|
class Migration {
|
||||||
|
get code() { return "sample"; }
|
||||||
|
get version() { return "0.0.0"; }
|
||||||
|
async migrate() { }
|
||||||
|
|
||||||
|
async applyItemsUpdates(computeUpdates) {
|
||||||
|
await game.actors.forEach(async (actor) => {
|
||||||
|
const actorItemUpdates = computeUpdates(actor.items);
|
||||||
|
if (actorItemUpdates.length > 0) {
|
||||||
|
console.log(
|
||||||
|
this.code,
|
||||||
|
`Applying updates on actor ${actor.name} items`,
|
||||||
|
actorItemUpdates
|
||||||
|
);
|
||||||
|
await actor.updateEmbeddedDocuments("Item", actorItemUpdates);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const itemUpdates = computeUpdates(game.items);
|
||||||
|
if (itemUpdates.length > 0) {
|
||||||
|
console.log(this.code, "Applying updates on items", itemUpdates);
|
||||||
|
await Item.updateDocuments(itemUpdates);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class _10_0_16_MigrationSortsReserve extends Migration {
|
||||||
|
get code() { return "creation-item-sort-reserve"; }
|
||||||
|
get version() { return "10.0.16"; }
|
||||||
|
|
||||||
|
async migrate() {
|
||||||
|
await game.actors
|
||||||
|
.filter((actor) => actor.type == "personnage")
|
||||||
|
.filter((actor) => actor.system.reve?.reserve?.list?.length ?? 0 > 0)
|
||||||
|
.forEach(async (actor) => {
|
||||||
|
const sortsReserve = actor.system.reve.reserve.list.map(this.conversionSortReserve);
|
||||||
|
console.log(`${LOG_HEAD} Migration des sorts en réserve de ${actor.name}`, sortsReserve);
|
||||||
|
await actor.createEmbeddedDocuments("Item", sortsReserve, {
|
||||||
|
renderSheet: false,
|
||||||
|
});
|
||||||
|
await actor.update({ 'system.reve.reserve': undefined })
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
conversionSortReserve(it) {
|
||||||
|
return {
|
||||||
|
type: 'sortreserve',
|
||||||
|
name: it.sort.name,
|
||||||
|
img: it.sort.img,
|
||||||
|
system: {
|
||||||
|
// ATTENTION, utilisation de data / _id possibles, encore présents pour les anciens sorts en réserve
|
||||||
|
sortid: it.sort._id,
|
||||||
|
draconic: it.sort.draconic,
|
||||||
|
ptreve: (it.sort.system ?? it.sort.data).ptreve_reel,
|
||||||
|
coord: it.coord,
|
||||||
|
heurecible: 'Vaisseau',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _10_0_17_MigrationCompetenceCreature extends Migration {
|
||||||
|
get code() { return "competences-creature-parade"; }
|
||||||
|
get version() { return "10.0.17"; }
|
||||||
|
|
||||||
|
async migrate() {
|
||||||
|
await this.applyItemsUpdates(items => items
|
||||||
|
.filter(it => it.type == "competencecreature" && it.system.isparade && it.system.categorie_parade == "")
|
||||||
|
.map(it => { return { _id: it.id, "system.categorie_parade": "armes-naturelles" } }));
|
||||||
|
|
||||||
|
await this.applyItemsUpdates(items => items
|
||||||
|
.filter(it => it.type == "competencecreature" && it.system.iscombat)
|
||||||
|
.map(it => { return { _id: it.id, "system.categorie": (Grammar.includesLowerCaseNoAccent(it.name, "lancee") ? "lancer" : "melee") } })
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _10_0_21_VehiculeStructureResistanceMax extends Migration {
|
||||||
|
get code() { return "vehicule-structure-resistance-max"; }
|
||||||
|
get version() { return "10.0.21"; }
|
||||||
|
|
||||||
|
async migrate() {
|
||||||
|
await game.actors
|
||||||
|
.filter((actor) => actor.type == "vehicule")
|
||||||
|
.forEach(async (actor) => {
|
||||||
|
await actor.update({
|
||||||
|
'system.etat.resistance.value': actor.system.resistance,
|
||||||
|
'system.etat.resistance.max': actor.system.resistance,
|
||||||
|
'system.etat.structure.value': actor.system.structure,
|
||||||
|
'system.etat.structure.max': actor.system.structure
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _10_0_33_MigrationNomsDraconic extends Migration {
|
||||||
|
get code() { return "competences-creature-parade"; }
|
||||||
|
get version() { return "10.0.33"; }
|
||||||
|
|
||||||
|
migrationNomDraconic(ancien) {
|
||||||
|
if (typeof ancien == 'string') {
|
||||||
|
switch (ancien) {
|
||||||
|
case 'oniros': case "Voie d'Oniros": return "Voie d'Oniros";
|
||||||
|
case 'hypnos': case "Voie d'Hypnos": return "Voie d'Hypnos";
|
||||||
|
case 'narcos': case "Voie de Narcos": return "Voie de Narcos";
|
||||||
|
case 'thanatos': case "Voie de Thanatos": return "Voie de Thanatos";
|
||||||
|
}
|
||||||
|
return ancien;
|
||||||
|
}
|
||||||
|
else if (typeof ancien.name == 'string') {
|
||||||
|
return this.migrationNomDraconic(ancien.name)
|
||||||
|
}
|
||||||
|
return ancien;
|
||||||
|
}
|
||||||
|
async migrate() {
|
||||||
|
|
||||||
|
await this.applyItemsUpdates(items => items
|
||||||
|
.filter(it => ["sort", "sortreserve"].includes(it.type)
|
||||||
|
&& (typeof it.system.draconic == 'string') || (typeof it.system.draconic?.name == 'string'))
|
||||||
|
.map(it => { return { _id: it.id, "system.draconic": this.migrationNomDraconic(it.system.draconic) } }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _10_2_5_ArmesTirLancer extends Migration {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.dagues = { "system.competence": 'Dague', "system.lancer": 'Dague de jet', "system.portee_courte": 3, "system.portee_moyenne": 8, "system.portee_extreme": 15 }
|
||||||
|
this.javelot = { "system.competence": 'Lance', "system.lancer": 'Javelot', "system.portee_courte": 6, "system.portee_moyenne": 12, "system.portee_extreme": 20 }
|
||||||
|
this.fouet = { "system.competence": '', "system.lancer": 'Fouet', "system.portee_courte": 2, "system.portee_moyenne": 2, "system.portee_extreme": 3, "system.penetration": -1 }
|
||||||
|
this.arc = { "system.competence": '', "system.tir": 'Arc' }
|
||||||
|
this.arbalete = { "system.competence": '', "system.tir": 'Arbalète' }
|
||||||
|
this.fronde = { "system.competence": '', "system.tir": 'Fronde' }
|
||||||
|
|
||||||
|
this.mappings = {
|
||||||
|
'dague': { filter: it => true, updates: this.dagues },
|
||||||
|
'dague de jet': { filter: it => true, updates: this.dagues },
|
||||||
|
'javelot': { filter: it => true, updates: this.javelot },
|
||||||
|
'lance': { filter: it => it.name == 'Javeline', updates: this.javelot },
|
||||||
|
'fouet': { filter: it => true, updates: this.fouet },
|
||||||
|
'arc': { filter: it => true, updates: this.arc },
|
||||||
|
'arbalete': { filter: it => true, updates: this.arbalete },
|
||||||
|
'fronde': { filter: it => true, updates: this.fronde },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get code() { return "separation-competences-tir-lancer"; }
|
||||||
|
get version() { return "10.2.5"; }
|
||||||
|
|
||||||
|
migrateArmeTirLancer(it) {
|
||||||
|
let updates = mergeObject({ _id: it.id }, this.getMapping(it).updates);
|
||||||
|
console.log(it.name, updates);
|
||||||
|
return updates;
|
||||||
|
}
|
||||||
|
|
||||||
|
async migrate() {
|
||||||
|
await this.applyItemsUpdates(items => items
|
||||||
|
.filter(it => "arme" == it.type)
|
||||||
|
.filter(it => this.isTirLancer(it))
|
||||||
|
.filter(it => this.getMapping(it).filter(it))
|
||||||
|
.map(it => this.migrateArmeTirLancer(it)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
isTirLancer(it) {
|
||||||
|
return Object.keys(this.mappings).includes(this.getCompKey(it));
|
||||||
|
}
|
||||||
|
|
||||||
|
getMapping(it) {
|
||||||
|
return this.mappings[this.getCompKey(it)];
|
||||||
|
}
|
||||||
|
|
||||||
|
getCompKey(it) {
|
||||||
|
return Grammar.toLowerCaseNoAccent(it.system.competence);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _10_2_10_DesirLancinant_IdeeFixe extends Migration {
|
||||||
|
get code() { return "desir-lancinat-idee-fixe"; }
|
||||||
|
get version() { return "10.2.10"; }
|
||||||
|
|
||||||
|
migrateQueue(it) {
|
||||||
|
let categorie = undefined
|
||||||
|
let name = it.name
|
||||||
|
if (Grammar.toLowerCaseNoAccent(name).includes('desir')) {
|
||||||
|
categorie = 'lancinant';
|
||||||
|
name = it.name.replace('Désir lancinant : ', '');
|
||||||
|
|
||||||
|
}
|
||||||
|
if (Grammar.toLowerCaseNoAccent(name).includes('idee fixe')) {
|
||||||
|
categorie = 'ideefixe';
|
||||||
|
name = it.name.replace('Idée fixe : ', '')
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
_id: it.id, name: name,
|
||||||
|
'system.ideefixe': undefined,
|
||||||
|
'system.lancinant': undefined,
|
||||||
|
'system.categorie': categorie
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async migrate() {
|
||||||
|
await this.applyItemsUpdates(items => items
|
||||||
|
.filter(it => ['queue', 'ombre'].includes(it.type))
|
||||||
|
.map(it => this.migrateQueue(it))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _10_3_0_Inventaire extends Migration {
|
||||||
|
get code() { return "migration-equipement-inventaire"; }
|
||||||
|
get version() { return "10.3.0"; }
|
||||||
|
|
||||||
|
async migrate() {
|
||||||
|
await this.applyItemsUpdates(items => {
|
||||||
|
return this._updatesMonnaies(items)
|
||||||
|
.concat(this._updatesNonEquipe(items))
|
||||||
|
.concat(this._updatesObjets(items))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_updatesNonEquipe(items) {
|
||||||
|
return items
|
||||||
|
.filter(it => ['munition'].includes(it.type))
|
||||||
|
.map(it => { return { _id: it.id, 'system.equipe': undefined } });
|
||||||
|
}
|
||||||
|
_updatesObjets(items) {
|
||||||
|
return items
|
||||||
|
.filter(it => ['objet'].includes(it.type))
|
||||||
|
.map(it => { return { _id: it.id, 'system.resistance': undefined, 'system.equipe': undefined } });
|
||||||
|
}
|
||||||
|
_updatesMonnaies(items) {
|
||||||
|
return items
|
||||||
|
.filter(it => ['monnaie'].includes(it.type) && it.system.cout == undefined)
|
||||||
|
.map(it => { return { _id: it.id, 'system.cout': it.system.valeur_deniers / 100, 'system.valeur_deniers': undefined } });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _10_3_0_FrequenceEnvironnement extends Migration {
|
||||||
|
get code() { return "migration-frequence-resources"; }
|
||||||
|
get version() { return "10.3.0"; }
|
||||||
|
|
||||||
|
async migrate() {
|
||||||
|
await this.applyItemsUpdates(items => items.filter(it => ['herbe', 'ingredient'].includes(it.type))
|
||||||
|
.map(it => this._updatesFrequences(it)));
|
||||||
|
}
|
||||||
|
|
||||||
|
_updatesFrequences(it) {
|
||||||
|
return {
|
||||||
|
_id: it.id,
|
||||||
|
'system.rarete': undefined,
|
||||||
|
'system.environnement': [{ milieu: it.system.milieu, rarete: it.system.rarete, frequence: Environnement.getFrequenceRarete(it.system.rarete, 'frequence') }]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Migrations {
|
||||||
|
static getMigrations() {
|
||||||
|
return [
|
||||||
|
new _10_0_16_MigrationSortsReserve(),
|
||||||
|
new _10_0_17_MigrationCompetenceCreature(),
|
||||||
|
new _10_0_21_VehiculeStructureResistanceMax(),
|
||||||
|
new _10_0_33_MigrationNomsDraconic(),
|
||||||
|
new _10_2_5_ArmesTirLancer(),
|
||||||
|
new _10_2_10_DesirLancinant_IdeeFixe(),
|
||||||
|
new _10_3_0_Inventaire(),
|
||||||
|
new _10_3_0_FrequenceEnvironnement()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
game.settings.register(SYSTEM_RDD, "systemMigrationVersion", {
|
||||||
|
name: "System Migration Version",
|
||||||
|
scope: "world",
|
||||||
|
config: false,
|
||||||
|
type: String,
|
||||||
|
default: "0.0.0",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
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 */
|
||||||
|
const migrations = Migrations.getMigrations().filter(m => isNewerVersion(m.version, currentVersion));
|
||||||
|
if (migrations.length > 0) {
|
||||||
|
migrations.sort((a, b) =>
|
||||||
|
isNewerVersion(a.version, b.version)
|
||||||
|
? 1
|
||||||
|
: isNewerVersion(b.version, a.version)
|
||||||
|
? -1
|
||||||
|
: 0
|
||||||
|
);
|
||||||
|
migrations.forEach(async (m) => {
|
||||||
|
ui.notifications.info(
|
||||||
|
`Executing migration ${m.code}: version ${currentVersion} is lower than ${m.version}`
|
||||||
|
);
|
||||||
|
await m.migrate();
|
||||||
|
});
|
||||||
|
ui.notifications.info(
|
||||||
|
`Migrations done, version will change to ${game.system.version}`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.log(
|
||||||
|
LOG_HEAD +
|
||||||
|
`No migration needeed, version will change to ${game.system.version}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
game.settings.set(
|
||||||
|
SYSTEM_RDD,
|
||||||
|
"systemMigrationVersion",
|
||||||
|
game.system.version
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.log(LOG_HEAD + `No system version changed`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,7 +24,7 @@ export class Misc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static sum() {
|
static sum() {
|
||||||
return (a, b) => a + b;
|
return (a, b) => Number(a) + Number(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ascending(orderFunction = x => x) {
|
static ascending(orderFunction = x => x) {
|
||||||
@@ -41,6 +41,11 @@ export class Misc {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static typeName(type, subType) {
|
||||||
|
return subType ? game.i18n.localize(`${type.toUpperCase()}.Type${Misc.upperFirst(subType)}`)
|
||||||
|
: '';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts the value to an integer, or to 0 if undefined/null/not representing integer
|
* Converts the value to an integer, or to 0 if undefined/null/not representing integer
|
||||||
* @param {*} value value to convert to an integer using parseInt
|
* @param {*} value value to convert to an integer using parseInt
|
||||||
@@ -68,6 +73,19 @@ export class Misc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static indexLowercase(list) {
|
||||||
|
const obj = {};
|
||||||
|
const addToObj = (map, val) => {
|
||||||
|
const key = Grammar.toLowerCaseNoAccent(val);
|
||||||
|
if (key && !map[key]) map[key] = val
|
||||||
|
}
|
||||||
|
list.forEach(it => addToObj(obj, it))
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
static concat(lists) {
|
||||||
|
return lists.reduce((a, b) => a.concat(b), []);
|
||||||
|
}
|
||||||
|
|
||||||
static classify(items, classifier = it => it.type) {
|
static classify(items, classifier = it => it.type) {
|
||||||
let itemsBy = {}
|
let itemsBy = {}
|
||||||
Misc.classifyInto(itemsBy, items, classifier)
|
Misc.classifyInto(itemsBy, items, classifier)
|
||||||
@@ -102,18 +120,11 @@ export class Misc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static join(params, separator = '') {
|
static join(params, separator = '') {
|
||||||
return params.reduce((a, b) => a + separator + b);
|
return params?.reduce(Misc.joining(separator)) ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static joining(separator = '') {
|
||||||
static getEntityTypeLabel(entity) {
|
return (a, b) => a + separator + b;
|
||||||
const documentName = entity?.documentName
|
|
||||||
const type = entity?.type
|
|
||||||
if (documentName === 'Actor' || documentName === 'Item') {
|
|
||||||
const label = CONFIG[documentName]?.typeLabels?.[type] ?? type;
|
|
||||||
return game.i18n.has(label) ? game.i18n.localize(label) : t;
|
|
||||||
}
|
|
||||||
return type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static connectedGMOrUser(ownerId = undefined) {
|
static connectedGMOrUser(ownerId = undefined) {
|
||||||
@@ -123,17 +134,20 @@ export class Misc {
|
|||||||
return Misc.firstConnectedGM()?.id ?? game.user.id;
|
return Misc.firstConnectedGM()?.id ?? game.user.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static getUsers() {
|
static isRollModeHiddenToPlayer() {
|
||||||
return game.version ? game.users : game.users.entities;
|
switch (game.settings.get("core", "rollMode")) {
|
||||||
|
case CONST.DICE_ROLL_MODES.BLIND:
|
||||||
|
case CONST.DICE_ROLL_MODES.SELF: return true;
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
static getActiveUser(id) {
|
static getActiveUser(id) {
|
||||||
return Misc.getUsers().find(u => u.id == id && u.active);
|
return game.users.find(u => u.id == id && u.active);
|
||||||
}
|
}
|
||||||
|
|
||||||
static firstConnectedGM() {
|
static firstConnectedGM() {
|
||||||
return Misc.getUsers().filter(u => u.isGM && u.active).sort(Misc.ascending(u => u.id)).find(u => u.isGM && u.active);
|
return game.users.filter(u => u.isGM && u.active).sort(Misc.ascending(u => u.id)).find(u => u.isGM && u.active);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static isOwnerPlayer(actor, user=undefined) {
|
static isOwnerPlayer(actor, user=undefined) {
|
||||||
@@ -148,12 +162,16 @@ export class Misc {
|
|||||||
* @returns true pour un seul utilisateur: le premier GM connecté par ordre d'id
|
* @returns true pour un seul utilisateur: le premier GM connecté par ordre d'id
|
||||||
*/
|
*/
|
||||||
static isUniqueConnectedGM() {
|
static isUniqueConnectedGM() {
|
||||||
return game.user.id == Misc.firstConnectedGM()?.id;
|
return game.user.id == Misc.firstConnectedGMId();
|
||||||
|
}
|
||||||
|
|
||||||
|
static firstConnectedGMId() {
|
||||||
|
return Misc.firstConnectedGM()?.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static findPlayer(name) {
|
static findPlayer(name) {
|
||||||
return Misc.findFirstLike(name, Misc.getUsers(), { description: 'joueur' });
|
return Misc.findFirstLike(name, game.users, { description: 'joueur' });
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -206,4 +224,4 @@ export class Misc {
|
|||||||
}
|
}
|
||||||
return subset;
|
return subset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,72 +1,13 @@
|
|||||||
import { Misc } from "./misc.js"
|
|
||||||
import { RdDDice } from "./rdd-dice.js";
|
import { RdDDice } from "./rdd-dice.js";
|
||||||
|
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
||||||
const poesieHautReve = [
|
|
||||||
{
|
|
||||||
reference: 'Le Ratier Bretonien',
|
|
||||||
extrait: `Le courant du Fleuve
|
|
||||||
<br>Te domine et te Porte
|
|
||||||
<br>Avant que tu te moeuves
|
|
||||||
<br>Combat le, ou il t'emporte`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
reference: 'Incompatibilité, Charles Beaudelaire',
|
|
||||||
extrait: `Et lorsque par hasard une nuée errante
|
|
||||||
<br>Assombrit dans son vol le lac silencieux,
|
|
||||||
<br>On croirait voir la robe ou l'ombre transparente
|
|
||||||
<br>D'un esprit qui voyage et passe dans les cieux.`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
reference: 'Au fleuve de Loire, Joachim du Bellay',
|
|
||||||
extrait: `Ô de qui la vive course
|
|
||||||
<br>Prend sa bienheureuse source,
|
|
||||||
<br>D’une argentine fontaine,
|
|
||||||
<br>Qui d’une fuite lointaine,
|
|
||||||
<br>Te rends au sein fluctueux
|
|
||||||
<br>De l’Océan monstrueux`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
reference: 'Denis Gerfaud',
|
|
||||||
extrait: `Et l'on peut savoir qui est le maître d'Oniros, c'est le Fleuve de l'Oubli.
|
|
||||||
Et l'on sait qui est le créateur du Fleuve de l'Oubli, c'est Hypnos et Narcos.
|
|
||||||
Mais l'on ne sait pas qui est le maître du Fleuve de l'Oubli,
|
|
||||||
sinon peut-être lui-même, ou peut-être Thanatos` },
|
|
||||||
{
|
|
||||||
reference: 'Denis Gerfaud',
|
|
||||||
extrait: `Narcos est la source du Fleuve de l'Oubli et Hypnos l'embouchure
|
|
||||||
Remonter le Fleuve est la Voie de la Nuit, la Voie du Souvenir.
|
|
||||||
Descendre le Fleuve est la Voie du Jour, la Voie de l'Oubli`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
reference: 'Denis Gerfaud',
|
|
||||||
extrait: `Narcos engendre le fils dont il est la mère à l'heure du Vaisseau,
|
|
||||||
car Oniros s'embarque pour redescendre le Fleuve
|
|
||||||
vers son père Hypnos sur la Voie de l'Oubli`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
reference: 'Denis Gerfaud',
|
|
||||||
extrait: `Hypnos engendre le fils dont il est la mère à l'heure du Serpent, car
|
|
||||||
tel les serpents, Oniros commence à remonter le Fleuve
|
|
||||||
sur le Voie du Souvenir vers son père Narcos`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
reference: 'Denis Gerfaud',
|
|
||||||
extrait: `Ainsi se succèdent les Jours et les Ages.
|
|
||||||
<br>Les jours des Dragons sont les Ages des Hommes.`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
reference: 'Denis Gerfaud',
|
|
||||||
extrait: `Ainsi parlent les sages:
|
|
||||||
«Les Dragons sont créateurs de leurs rêves, mais ils ne sont pas créateurs d'Oniros
|
|
||||||
Les Dragons ne sont pas les maîtres de leurs rêvezs, car ils ne sont pas maîtres d'Oniros.
|
|
||||||
Nul ne sait qui est le créateur des Dragons, ni qui est leur maître.
|
|
||||||
Mais l'on peut supposer qui est le maître du Rêve des Dragons, c'est Oniros»`
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
export class Poetique {
|
export class Poetique {
|
||||||
static async getExtrait(){
|
static async getExtrait() {
|
||||||
return await RdDDice.rollOneOf(poesieHautReve);
|
const items = await SystemCompendiums.getItems('extrait-poetique', 'extraitpoetique')
|
||||||
|
const selected = await RdDDice.rollOneOf(items);
|
||||||
|
return {
|
||||||
|
reference: selected?.name,
|
||||||
|
extrait: selected?.system.extrait
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
Le courant du Fleuve
|
|
||||||
Te domine et te Porte
|
|
||||||
Avant que tu te moeuves
|
|
||||||
Combat le, ou il t'emporte
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
A vous qui faites ripaille
|
|
||||||
sourds aux damnés de la faim
|
|
||||||
à vous qui livrez
|
|
||||||
une inégale bataille
|
|
||||||
à ceux qui vous tendent la main
|
|
||||||
|
|
||||||
Ils sont tout près ! - Tenons fermée
|
|
||||||
<br>Cette salle, où nous les narguons.
|
|
||||||
<br>Quel bruit dehors ! Hideuse armée
|
|
||||||
<br>De vampires et de dragons !
|
|
||||||
<br>La poutre du toit descellée
|
|
||||||
<br>Ploie ainsi qu'une herbe mouillée,
|
|
||||||
<br>Et la vieille porte rouillée
|
|
||||||
<br>Tremble, à déraciner ses gonds !`),
|
|
||||||
|
|
||||||
https://www.poetica.fr/poeme-1423/guy-de-maupassant-le-sommeil-du-mandarin/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Le monde est un rêve de Dragons. Nous
|
|
||||||
ne savons pas qui sont les Dragons ni à quoi
|
|
||||||
ils ressemblent, en dépit de l’antique iconographie qui les dépeint comme de gigantesques créatures ailées capables de cracher
|
|
||||||
feu et flammes.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Car parmi les humains, autre nom lui est donné,
|
|
||||||
Nom sinistre parmi tous, nom funèbre, c'est la mort!
|
|
||||||
Un ami disparu... Thanatos est passé...
|
|
||||||
|
|
||||||
|
|
||||||
Messieurs, ne crachez pas de jurons ni d'ordure
|
|
||||||
Au visage fardé de cette pauvre impure
|
|
||||||
Que déesse Famine a par un soir d'hiver,
|
|
||||||
Contrainte à relever ses jupons en plein air.
|
|
||||||
|
|
||||||
@@ -15,13 +15,19 @@
|
|||||||
|
|
||||||
// Common conf
|
// Common conf
|
||||||
let dialogConf = { content: html, title: "Editeur d'Astrologie", buttons: myButtons, default: "saveButton" };
|
let dialogConf = { content: html, title: "Editeur d'Astrologie", buttons: myButtons, default: "saveButton" };
|
||||||
let dialogOptions = { classes: ["rdddialog"], width: 600, height: 300, 'z-index': 99999 }
|
let dialogOptions = { classes: ["rdd-roll-dialog"], width: 600, height: 300, 'z-index': 99999 }
|
||||||
super(dialogConf, dialogOptions)
|
super(dialogConf, dialogOptions)
|
||||||
|
|
||||||
this.calendrier = calendrier;
|
this.calendrier = calendrier;
|
||||||
this.updateData( calendrierData );
|
this.updateData( calendrierData );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
this.html = html;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async resetNombreAstraux() {
|
async resetNombreAstraux() {
|
||||||
game.system.rdd.calendrier.resetNombreAstral();
|
game.system.rdd.calendrier.resetNombreAstral();
|
||||||
@@ -39,15 +45,4 @@
|
|||||||
this.calendrierData = duplicate(calendrierData);
|
this.calendrierData = duplicate(calendrierData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
activateListeners(html) {
|
|
||||||
super.activateListeners(html);
|
|
||||||
|
|
||||||
let astrologieData = this.astrologieData;
|
|
||||||
|
|
||||||
$(function () {
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export class RdDAstrologieJoueur extends Dialog {
|
|||||||
astrologie: RdDItemCompetence.findCompetence(actor.items, 'Astrologie')
|
astrologie: RdDItemCompetence.findCompetence(actor.items, 'Astrologie')
|
||||||
}
|
}
|
||||||
const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-astrologie-joueur.html', dialogData);
|
const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-astrologie-joueur.html', dialogData);
|
||||||
let options = { classes: ["rdddialog"], width: 600, height: 500, 'z-index': 99999 };
|
let options = { classes: ["rdd-roll-dialog"], width: 600, height: 500, 'z-index': 99999 };
|
||||||
if (dialogConfig.options) {
|
if (dialogConfig.options) {
|
||||||
mergeObject(options, dialogConfig.options, { overwrite: true });
|
mergeObject(options, dialogConfig.options, { overwrite: true });
|
||||||
}
|
}
|
||||||
@@ -29,21 +29,35 @@ export class RdDAstrologieJoueur extends Dialog {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
constructor(html, actor, dialogData) {
|
constructor(html, actor, dialogData) {
|
||||||
|
const dialogConf = {
|
||||||
let myButtons = {
|
title: "Nombres Astraux",
|
||||||
saveButton: { label: "Fermer", callback: html => this.quitDialog() }
|
content: html,
|
||||||
|
default: "saveButton",
|
||||||
|
buttons: {
|
||||||
|
saveButton: { label: "Fermer", callback: html => this.quitDialog() }
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
const dialogOptions = { classes: ["rdd-roll-dialog"], width: 600, height: 300, 'z-index': 99999 };
|
||||||
// Get all n
|
|
||||||
// Common conf
|
|
||||||
let dialogConf = { content: html, title: "Nombres Astraux", buttons: myButtons, default: "saveButton" };
|
|
||||||
let dialogOptions = { classes: ["rdddialog"], width: 600, height: 300, 'z-index': 99999 };
|
|
||||||
super(dialogConf, dialogOptions);
|
super(dialogConf, dialogOptions);
|
||||||
|
|
||||||
this.actor = actor;
|
this.actor = actor;
|
||||||
this.dataNombreAstral = duplicate(dialogData);
|
this.dataNombreAstral = duplicate(dialogData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
this.html = html;
|
||||||
|
|
||||||
|
this.html.find(function () {
|
||||||
|
this.html.find("[name='diffConditions']").val(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.html.find('[name="jet-astrologie"]').click((event) => {
|
||||||
|
this.requestJetAstrologie();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static organizeNombres(actor) {
|
static organizeNombres(actor) {
|
||||||
let itemNombres = actor.listItemsData('nombreastral');
|
let itemNombres = actor.listItemsData('nombreastral');
|
||||||
@@ -68,8 +82,8 @@ export class RdDAstrologieJoueur extends Dialog {
|
|||||||
carac_vue: this.actor.system.carac['vue'].value,
|
carac_vue: this.actor.system.carac['vue'].value,
|
||||||
etat: this.dataNombreAstral.etat,
|
etat: this.dataNombreAstral.etat,
|
||||||
astrologie: this.dataNombreAstral.astrologie,
|
astrologie: this.dataNombreAstral.astrologie,
|
||||||
conditions: $("#diffConditions").val(),
|
conditions: this.html.find('[name="diffConditions"]').val(),
|
||||||
date: $("#joursAstrologie").val(),
|
date: this.html.find('[name="joursAstrologie"]').val(),
|
||||||
userId: game.user.id
|
userId: game.user.id
|
||||||
}
|
}
|
||||||
if (Misc.isUniqueConnectedGM()) {
|
if (Misc.isUniqueConnectedGM()) {
|
||||||
@@ -87,17 +101,4 @@ export class RdDAstrologieJoueur extends Dialog {
|
|||||||
quitDialog() {
|
quitDialog() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
activateListeners(html) {
|
|
||||||
super.activateListeners(html);
|
|
||||||
|
|
||||||
$(function () {
|
|
||||||
$("#diffConditions").val(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
html.find('#jet-astrologie').click((event) => {
|
|
||||||
this.requestJetAstrologie();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,50 +8,45 @@ export class RdDCalendrierEditeur extends Dialog {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
constructor(html, calendrier, calendrierData) {
|
constructor(html, calendrier, calendrierData) {
|
||||||
|
let dialogConf = {
|
||||||
let myButtons = {
|
content: html,
|
||||||
saveButton: { label: "Enregistrer", callback: html => this.fillData() }
|
title: "Editeur de date/heure",
|
||||||
};
|
buttons: {
|
||||||
|
save: { label: "Enregistrer", callback: html => this.fillData() }
|
||||||
// Common conf
|
},
|
||||||
let dialogConf = { content: html, title: "Editeur de date/heure", buttons: myButtons, default: "saveButton" };
|
default: "save"
|
||||||
let dialogOptions = { classes: ["rdddialog"], width: 400, height: 300, 'z-index': 99999 }
|
};
|
||||||
|
let dialogOptions = { classes: ["rdd-dialog-calendar-editor"], width: 400, height: 'fit-content', 'z-index': 99999 }
|
||||||
super(dialogConf, dialogOptions)
|
super(dialogConf, dialogOptions)
|
||||||
|
|
||||||
this.calendrier = calendrier;
|
this.calendrier = calendrier;
|
||||||
this.calendrierData = calendrierData; //duplicate(calendrierData);
|
this.calendrierData = calendrierData;
|
||||||
|
}
|
||||||
|
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
this.html = html;
|
||||||
|
this.html.find("input[name='nomMois']").val(this.calendrierData.moisKey);
|
||||||
|
this.html.find("select[name='nomHeure']").val(this.calendrierData.heureKey);
|
||||||
|
this.html.find("select[name='jourMois']").val(this.calendrierData.jourMois);
|
||||||
|
this.html.find("select[name='minutesRelative']").val(calendrierData.minutesRelative);
|
||||||
|
this.html.find("select[name='annee']").val(this.calendrierData.annee);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
fillData( ) {
|
fillData() {
|
||||||
this.calendrierData.moisKey = $("#nomMois").val();
|
this.calendrierData.annee = this.html.find("input[name='annee']").val();
|
||||||
this.calendrierData.heureKey = $("#nomHeure").val();
|
this.calendrierData.moisKey = this.html.find("select[name='nomMois']").val();
|
||||||
this.calendrierData.jourMois = $("#jourMois").val();
|
this.calendrierData.heureKey = this.html.find("select[name='nomHeure']").val();
|
||||||
this.calendrierData.minutesRelative = $("#minutesRelative").val();
|
this.calendrierData.jourMois = this.html.find("select[name='jourMois']").val();
|
||||||
|
this.calendrierData.minutesRelative = this.html.find("select[name='minutesRelative']").val();
|
||||||
console.log("UPDATE ", this.calendrierData);
|
|
||||||
this.calendrier.saveEditeur( this.calendrierData )
|
this.calendrier.saveEditeur(this.calendrierData)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
updateData( calendrierData ) {
|
updateData(calendrierData) {
|
||||||
this.calendrierData = duplicate(calendrierData);
|
this.calendrierData = duplicate(calendrierData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
activateListeners(html) {
|
|
||||||
super.activateListeners(html);
|
|
||||||
|
|
||||||
let calendrierData = this.calendrierData;
|
|
||||||
|
|
||||||
$(function () {
|
|
||||||
console.log(calendrierData);
|
|
||||||
$("#nomMois").val(calendrierData.moisKey);
|
|
||||||
$("#nomHeure").val(calendrierData.heureKey);
|
|
||||||
$("#jourMois").val(calendrierData.jourMois);
|
|
||||||
$("#minutesRelative").val(calendrierData.minutesRelative);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,23 +8,24 @@ import { Grammar } from "./grammar.js";
|
|||||||
import { RdDDice } from "./rdd-dice.js";
|
import { RdDDice } from "./rdd-dice.js";
|
||||||
import { Misc } from "./misc.js";
|
import { Misc } from "./misc.js";
|
||||||
import { HIDE_DICE, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
import { HIDE_DICE, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
||||||
|
import { DialogChronologie } from "./dialog-chronologie.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
const dossierIconesHeures = 'systems/foundryvtt-reve-de-dragon/icons/heures/'
|
const dossierIconesHeures = 'systems/foundryvtt-reve-de-dragon/icons/heures/'
|
||||||
const heuresList = ["vaisseau", "sirene", "faucon", "couronne", "dragon", "epees", "lyre", "serpent", "poissonacrobate", "araignee", "roseau", "chateaudormant"];
|
const heuresList = ["vaisseau", "sirene", "faucon", "couronne", "dragon", "epees", "lyre", "serpent", "poissonacrobate", "araignee", "roseau", "chateaudormant"];
|
||||||
const heuresDef = {
|
const heuresDef = {
|
||||||
"vaisseau": { label: "Vaisseau", lettreFont: 'v', saison: "printemps", heure: 0, icon: 'hd01.svg' },
|
"vaisseau": {key: "vaisseau", label: "Vaisseau", lettreFont: 'v', saison: "printemps", heure: 0, icon: 'hd01.svg' },
|
||||||
"sirene": { label: "Sirène", lettreFont: 'i', saison: "printemps", heure: 1, icon: 'hd02.svg' },
|
"sirene": { key: "sirene", label: "Sirène", lettreFont: 'i', saison: "printemps", heure: 1, icon: 'hd02.svg' },
|
||||||
"faucon": { label: "Faucon", lettreFont: 'f', saison: "printemps", heure: 2, icon: 'hd03.svg' },
|
"faucon": { key: "faucon", label: "Faucon", lettreFont: 'f', saison: "printemps", heure: 2, icon: 'hd03.svg' },
|
||||||
"couronne": { label: "Couronne", lettreFont: '', saison: "ete", heure: 3, icon: 'hd04.svg' },
|
"couronne": { key: "couronne", label: "Couronne", lettreFont: '', saison: "ete", heure: 3, icon: 'hd04.svg' },
|
||||||
"dragon": { label: "Dragon", lettreFont: 'd', saison: "ete", heure: 4, icon: 'hd05.svg' },
|
"dragon": { key: "dragon", label: "Dragon", lettreFont: 'd', saison: "ete", heure: 4, icon: 'hd05.svg' },
|
||||||
"epees": { label: "Epées", lettreFont: 'e', saison: "ete", heure: 5, icon: 'hd06.svg' },
|
"epees": { key: "epees", label: "Epées", lettreFont: 'e', saison: "ete", heure: 5, icon: 'hd06.svg' },
|
||||||
"lyre": { label: "Lyre", lettreFont: 'l', saison: "automne", heure: 6, icon: 'hd07.svg' },
|
"lyre": { key: "lyre", label: "Lyre", lettreFont: 'l', saison: "automne", heure: 6, icon: 'hd07.svg' },
|
||||||
"serpent": { label: "Serpent", lettreFont: 's', saison: "automne", heure: 7, icon: 'hd08.svg' },
|
"serpent": { key: "serpent", label: "Serpent", lettreFont: 's', saison: "automne", heure: 7, icon: 'hd08.svg' },
|
||||||
"poissonacrobate": { label: "Poisson Acrobate", lettreFont: 'p', saison: "automne", heure: 8, icon: 'hd09.svg' },
|
"poissonacrobate": { key: "poissonacrobate", label: "Poisson Acrobate", lettreFont: 'p', saison: "automne", heure: 8, icon: 'hd09.svg' },
|
||||||
"araignee": { label: "Araignée", lettreFont: 'a', saison: "hiver", heure: 9, icon: 'hd10.svg' },
|
"araignee": { key: "araignee", label: "Araignée", lettreFont: 'a', saison: "hiver", heure: 9, icon: 'hd10.svg' },
|
||||||
"roseau": { label: "Roseau", lettreFont: 'r', saison: "hiver", heure: 10, icon: 'hd11.svg' },
|
"roseau": { key: "roseau", label: "Roseau", lettreFont: 'r', saison: "hiver", heure: 10, icon: 'hd11.svg' },
|
||||||
"chateaudormant": { label: "Château Dormant", lettreFont: 'c', saison: "hiver", heure: 11, icon: 'hd12.svg' }
|
"chateaudormant": { key: "chateaudormant", label: "Château Dormant", lettreFont: 'c', saison: "hiver", heure: 11, icon: 'hd12.svg' }
|
||||||
};
|
};
|
||||||
const saisonsDef = {
|
const saisonsDef = {
|
||||||
"printemps": { label: "Printemps" },
|
"printemps": { label: "Printemps" },
|
||||||
@@ -42,6 +43,14 @@ const MAX_NOMBRE_ASTRAL = 12;
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
export class RdDCalendrier extends Application {
|
export class RdDCalendrier extends Application {
|
||||||
|
|
||||||
|
static get defaultOptions() {
|
||||||
|
return mergeObject(super.defaultOptions, {
|
||||||
|
template: "systems/foundryvtt-reve-de-dragon/templates/calendar-template.html",
|
||||||
|
popOut: false,
|
||||||
|
resizable: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static createCalendrierPos() {
|
static createCalendrierPos() {
|
||||||
return { top: 200, left: 200 };
|
return { top: 200, left: 200 };
|
||||||
}
|
}
|
||||||
@@ -51,21 +60,50 @@ export class RdDCalendrier extends Application {
|
|||||||
return Object.values(heuresDef).find(h => h.heure == chiffre);
|
return Object.values(heuresDef).find(h => h.heure == chiffre);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getSigneAs(key, value) {
|
||||||
|
const heure = (typeof value == 'string' || typeof value == 'number') && Number.isInteger(Number(value))
|
||||||
|
? Number(value)
|
||||||
|
: (typeof value == 'string') ? RdDCalendrier.getChiffreFromSigne(value)
|
||||||
|
: undefined
|
||||||
|
|
||||||
|
if (heure != undefined && ['key', 'label', 'lettreFont', 'saison', 'heure', 'icon'].includes(key)) {
|
||||||
|
return RdDCalendrier.getDefSigne(heure)[key]
|
||||||
|
}
|
||||||
|
if (heure != undefined && ['webp'].includes(key)) {
|
||||||
|
return RdDCalendrier.getDefSigne(heure)['icon'].replace('svg', 'webp');
|
||||||
|
}
|
||||||
|
console.error(`Appel à getSigneAs('${key}', ${value}) avec une clé/heure incorrects`);
|
||||||
|
return value;
|
||||||
|
|
||||||
|
}
|
||||||
static getChiffreFromSigne(signe) {
|
static getChiffreFromSigne(signe) {
|
||||||
return heuresList.indexOf(signe);
|
return heuresList.indexOf(signe);
|
||||||
}
|
}
|
||||||
|
|
||||||
static getCalendrier(index) {
|
static createCalendrierInitial() {
|
||||||
let calendrier = {
|
return {
|
||||||
|
heureRdD: 0,
|
||||||
|
minutesRelative: 0,
|
||||||
|
indexJour: 0,
|
||||||
|
annee: 0,
|
||||||
|
moisRdD: 0,
|
||||||
|
moisLabel: heuresDef["vaisseau"].label,
|
||||||
|
jour: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getCalendrier(index) {
|
||||||
|
index = index ?? this.getCurrentDayIndex();
|
||||||
|
const mois = Math.floor(index / RDD_JOUR_PAR_MOIS) % RDD_MOIS_PAR_AN;
|
||||||
|
return {
|
||||||
heureRdD: 0, // Index dans heuresList / heuresDef[x].heure
|
heureRdD: 0, // Index dans heuresList / heuresDef[x].heure
|
||||||
minutesRelative: 0,
|
minutesRelative: 0,
|
||||||
indexJour: index,
|
indexJour: index,
|
||||||
annee: Math.floor(index / (RDD_JOUR_PAR_MOIS * RDD_MOIS_PAR_AN)),
|
annee: Math.floor(index / (RDD_JOUR_PAR_MOIS * RDD_MOIS_PAR_AN)),
|
||||||
moisRdD: Math.floor(index / RDD_JOUR_PAR_MOIS) % RDD_MOIS_PAR_AN,
|
moisRdD: RdDCalendrier.getDefSigne(mois).heure,
|
||||||
|
moisLabel: RdDCalendrier.getDefSigne(mois).label,
|
||||||
jour: (index % RDD_JOUR_PAR_MOIS) // Le calendrier stocke le jour en 0-27, mais en 1-28 à l'affichage
|
jour: (index % RDD_JOUR_PAR_MOIS) // Le calendrier stocke le jour en 0-27, mais en 1-28 à l'affichage
|
||||||
}
|
}
|
||||||
calendrier.moisLabel = RdDCalendrier.getDefSigne(calendrier.moisRdD).label;
|
|
||||||
return calendrier;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -78,7 +116,7 @@ export class RdDCalendrier extends Application {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calendrier
|
// Calendrier
|
||||||
this.calendrier = duplicate(game.settings.get(SYSTEM_RDD, "calendrier") ?? RdDCalendrier.getCalendrier(0));
|
this.calendrier = duplicate(game.settings.get(SYSTEM_RDD, "calendrier") ?? RdDCalendrier.createCalendrierInitial());
|
||||||
this.calendrier.annee = this.calendrier.annee ?? Math.floor((this.calendrier.moisRdD ?? 0) / RDD_MOIS_PAR_AN);
|
this.calendrier.annee = this.calendrier.annee ?? Math.floor((this.calendrier.moisRdD ?? 0) / RDD_MOIS_PAR_AN);
|
||||||
this.calendrier.moisRdD = (this.calendrier.moisRdD ?? 0) % RDD_MOIS_PAR_AN;
|
this.calendrier.moisRdD = (this.calendrier.moisRdD ?? 0) % RDD_MOIS_PAR_AN;
|
||||||
|
|
||||||
@@ -86,34 +124,117 @@ export class RdDCalendrier extends Application {
|
|||||||
game.settings.set(SYSTEM_RDD, "calendrier", this.calendrier);
|
game.settings.set(SYSTEM_RDD, "calendrier", this.calendrier);
|
||||||
|
|
||||||
this.listeNombreAstral = this.getListeNombreAstral();
|
this.listeNombreAstral = this.getListeNombreAstral();
|
||||||
this.rebuildListeNombreAstral(false); // Ensure always up-to-date
|
this.rebuildListeNombreAstral(HIDE_DICE); // Ensure always up-to-date
|
||||||
}
|
}
|
||||||
console.log(this.calendrier, this.calendrierPos, this.listeNombreAstral);
|
console.log('RdDCalendrier.constructor()', this.calendrier, this.calendrierPos, this.listeNombreAstral);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/** @override */
|
||||||
|
async activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
this.html = html;
|
||||||
|
|
||||||
|
this.updateDisplay();
|
||||||
|
|
||||||
|
this.html.find('.ajout-chronologie').click(ev => DialogChronologie.create());
|
||||||
|
|
||||||
|
this.html.find('.calendar-btn').click(ev => this.onCalendarButton(ev));
|
||||||
|
|
||||||
|
this.html.find('.calendar-btn-edit').click(ev => {
|
||||||
|
ev.preventDefault();
|
||||||
|
this.showCalendarEditor();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.html.find('.astrologie-btn-edit').click(ev => {
|
||||||
|
ev.preventDefault();
|
||||||
|
this.showAstrologieEditor();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.html.find('#calendar-move-handle').mousedown(ev => {
|
||||||
|
ev.preventDefault();
|
||||||
|
ev = ev || window.event;
|
||||||
|
let isRightMB = false;
|
||||||
|
if ("which" in ev) { // Gecko (Firefox), WebKit (Safari/Chrome) & Opera
|
||||||
|
isRightMB = ev.which == 3;
|
||||||
|
} else if ("button" in ev) { // IE, Opera
|
||||||
|
isRightMB = ev.button == 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isRightMB) {
|
||||||
|
dragElement(document.getElementById("calendar-time-container"));
|
||||||
|
let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
|
||||||
|
|
||||||
|
function dragElement(elmnt) {
|
||||||
|
elmnt.onmousedown = dragMouseDown;
|
||||||
|
function dragMouseDown(e) {
|
||||||
|
e = e || window.event;
|
||||||
|
e.preventDefault();
|
||||||
|
pos3 = e.clientX;
|
||||||
|
pos4 = e.clientY;
|
||||||
|
|
||||||
|
document.onmouseup = closeDragElement;
|
||||||
|
document.onmousemove = elementDrag;
|
||||||
|
}
|
||||||
|
|
||||||
|
function elementDrag(e) {
|
||||||
|
e = e || window.event;
|
||||||
|
e.preventDefault();
|
||||||
|
// calculate the new cursor position:
|
||||||
|
pos1 = pos3 - e.clientX;
|
||||||
|
pos2 = pos4 - e.clientY;
|
||||||
|
pos3 = e.clientX;
|
||||||
|
pos4 = e.clientY;
|
||||||
|
// set the element's new position:
|
||||||
|
elmnt.style.bottom = undefined
|
||||||
|
elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
|
||||||
|
elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeDragElement() {
|
||||||
|
// stop moving when mouse button is released:
|
||||||
|
elmnt.onmousedown = undefined;
|
||||||
|
document.onmouseup = undefined;
|
||||||
|
document.onmousemove = undefined;
|
||||||
|
let xPos = (elmnt.offsetLeft - pos1) > window.innerWidth ? window.innerWidth - 200 : (elmnt.offsetLeft - pos1);
|
||||||
|
let yPos = (elmnt.offsetTop - pos2) > window.innerHeight - 20 ? window.innerHeight - 100 : (elmnt.offsetTop - pos2)
|
||||||
|
xPos = xPos < 0 ? 0 : xPos;
|
||||||
|
yPos = yPos < 0 ? 0 : yPos;
|
||||||
|
if (xPos != (elmnt.offsetLeft - pos1) || yPos != (elmnt.offsetTop - pos2)) {
|
||||||
|
elmnt.style.top = (yPos) + "px";
|
||||||
|
elmnt.style.left = (xPos) + "px";
|
||||||
|
}
|
||||||
|
game.system.rdd.calendrier.calendrierPos.top = yPos;
|
||||||
|
game.system.rdd.calendrier.calendrierPos.left = xPos;
|
||||||
|
if (game.user.isGM) {
|
||||||
|
game.settings.set(SYSTEM_RDD, "calendrier-pos", duplicate(game.system.rdd.calendrier.calendrierPos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (isRightMB) {
|
||||||
|
game.system.rdd.calendrier.calendrierPos.top = 200;
|
||||||
|
game.system.rdd.calendrier.calendrierPos.left = 200;
|
||||||
|
if (game.user.isGM) {
|
||||||
|
game.settings.set(SYSTEM_RDD, "calendrier-pos", duplicate(game.system.rdd.calendrier.calendrierPos));
|
||||||
|
}
|
||||||
|
this.setPos(game.system.rdd.calendrier.calendrierPos);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getListeNombreAstral() {
|
getListeNombreAstral() {
|
||||||
return game.settings.get(SYSTEM_RDD, "liste-nombre-astral") ?? [];
|
return game.settings.get(SYSTEM_RDD, "liste-nombre-astral") ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static get defaultOptions() {
|
|
||||||
return mergeObject(super.defaultOptions, {
|
|
||||||
template: "systems/foundryvtt-reve-de-dragon/templates/calendar-template.html",
|
|
||||||
popOut: false,
|
|
||||||
resizable: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getDateFromIndex(index) {
|
getDateFromIndex(index) {
|
||||||
const date = RdDCalendrier.getCalendrier(index ?? this.getCurrentDayIndex());
|
const dateRdD = this.getCalendrier(index);
|
||||||
return (date.jour + 1) + ' ' + RdDCalendrier.getDefSigne(date.moisRdD).label;
|
return (dateRdD.jour + 1) + ' ' + dateRdD.moisLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getNumericDateFromIndex(index = undefined) {
|
getDayMonthFromIndex(index = undefined) {
|
||||||
const dateRdD = RdDCalendrier.getCalendrier(index ?? this.getCurrentDayIndex());
|
const dateRdD = this.getCalendrier(index);
|
||||||
return {
|
return {
|
||||||
day: dateRdD.jour + 1,
|
day: dateRdD.jour + 1,
|
||||||
month: heuresList[dateRdD.moisRdD]
|
month: heuresList[dateRdD.moisRdD]
|
||||||
@@ -180,14 +301,14 @@ export class RdDCalendrier extends Application {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getNombreAstral(indexDate) {
|
getNombreAstral(indexDate) {
|
||||||
let astralData = this.getListeNombreAstral().find((nombreAstral, i) => nombreAstral.index == indexDate);
|
const listNombreAstral = this.getListeNombreAstral();
|
||||||
|
let astralData = listNombreAstral.find((nombreAstral, i) => nombreAstral.index == indexDate);
|
||||||
return astralData?.nombreAstral;
|
return astralData?.nombreAstral;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async rebuildListeNombreAstral(showDice = SHOW_DICE) {
|
async rebuildListeNombreAstral(showDice = HIDE_DICE) {
|
||||||
if (Misc.isUniqueConnectedGM()) {
|
if (Misc.isUniqueConnectedGM()) {
|
||||||
console.log("rebuildListeNombreAstral", showDice);
|
|
||||||
let jourCourant = this.getCurrentDayIndex();
|
let jourCourant = this.getCurrentDayIndex();
|
||||||
let newList = [];
|
let newList = [];
|
||||||
for (let i = 0; i < MAX_NOMBRE_ASTRAL; i++) {
|
for (let i = 0; i < MAX_NOMBRE_ASTRAL; i++) {
|
||||||
@@ -199,9 +320,8 @@ export class RdDCalendrier extends Application {
|
|||||||
newList[i] = await this.ajouterNombreAstral(dayIndex, showDice);
|
newList[i] = await this.ajouterNombreAstral(dayIndex, showDice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//console.log("SAVE list", newList, jourCourant);
|
game.settings.set(SYSTEM_RDD, "liste-nombre-astral", newList);
|
||||||
this.listeNombreAstral = newList;
|
this.listeNombreAstral = newList;
|
||||||
game.settings.set(SYSTEM_RDD, "liste-nombre-astral", this.listeNombreAstral);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,9 +343,9 @@ export class RdDCalendrier extends Application {
|
|||||||
checkMaladie( periode) {
|
checkMaladie( periode) {
|
||||||
for (let actor of game.actors) {
|
for (let actor of game.actors) {
|
||||||
if (actor.type == 'personnage') {
|
if (actor.type == 'personnage') {
|
||||||
let maladies = actor.items.find( item => (item.type == 'maladie' || (item.type == 'poison' && item.system.active) ) && item.system.periodicite.toLowerCase().includes(periode) );
|
let maladies = actor.items.filter( item => (item.type == 'maladie' || (item.type == 'poison' && item.system.active) ) && item.system.periodicite.toLowerCase().includes(periode) );
|
||||||
for (let maladie of maladies) {
|
for (let maladie of maladies) {
|
||||||
if ( maladie.system.identifie) {
|
if ( maladie.system.identifie) {
|
||||||
ChatMessage.create({ content: `${actor.name} souffre de ${maladie.name} (${maladie.type}): vérifiez que les effets ne se sont pas aggravés !` });
|
ChatMessage.create({ content: `${actor.name} souffre de ${maladie.name} (${maladie.type}): vérifiez que les effets ne se sont pas aggravés !` });
|
||||||
} else {
|
} else {
|
||||||
ChatMessage.create({ content: `${actor.name} souffre d'un mal inconnu (${maladie.type}): vérifiez que les effets ne se sont pas aggravés !` });
|
ChatMessage.create({ content: `${actor.name} souffre d'un mal inconnu (${maladie.type}): vérifiez que les effets ne se sont pas aggravés !` });
|
||||||
@@ -264,7 +384,7 @@ export class RdDCalendrier extends Application {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async incrementerJour() {
|
async incrementerJour() {
|
||||||
const index = this.getCurrentDayIndex() + 1;
|
const index = this.getCurrentDayIndex() + 1;
|
||||||
this.calendrier = RdDCalendrier.getCalendrier(index);
|
this.calendrier = this.getCalendrier(index);
|
||||||
await this.rebuildListeNombreAstral();
|
await this.rebuildListeNombreAstral();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,18 +406,15 @@ export class RdDCalendrier extends Application {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
fillCalendrierData(formData = {}) {
|
fillCalendrierData(formData = {}) {
|
||||||
console.log(this.calendrier);
|
const mois = RdDCalendrier.getDefSigne(this.calendrier.moisRdD);
|
||||||
let moisKey = heuresList[this.calendrier.moisRdD];
|
const heure = RdDCalendrier.getDefSigne(this.calendrier.heureRdD);
|
||||||
let heureKey = heuresList[this.calendrier.heureRdD];
|
console.log('fillCalendrierData', this.calendrier, mois, heure);
|
||||||
console.log(moisKey, heureKey);
|
|
||||||
|
|
||||||
const mois = heuresDef[moisKey];
|
formData.heureKey = heure.key;
|
||||||
const heure = heuresDef[heureKey];
|
formData.moisKey = mois.key;
|
||||||
|
|
||||||
formData.heureKey = heureKey;
|
|
||||||
formData.moisKey = moisKey;
|
|
||||||
formData.jourMois = this.calendrier.jour + 1;
|
formData.jourMois = this.calendrier.jour + 1;
|
||||||
formData.nomMois = mois.label; // heures et mois nommés identiques
|
formData.nomMois = mois.label; // heures et mois nommés identiques
|
||||||
|
formData.annee = this.calendrier.annee;
|
||||||
formData.iconMois = dossierIconesHeures + mois.icon;
|
formData.iconMois = dossierIconesHeures + mois.icon;
|
||||||
formData.nomHeure = heure.label;
|
formData.nomHeure = heure.label;
|
||||||
formData.iconHeure = dossierIconesHeures + heure.icon;
|
formData.iconHeure = dossierIconesHeures + heure.icon;
|
||||||
@@ -428,7 +545,7 @@ export class RdDCalendrier extends Application {
|
|||||||
function check() {
|
function check() {
|
||||||
let elmnt = document.getElementById("calendar-time-container");
|
let elmnt = document.getElementById("calendar-time-container");
|
||||||
if (elmnt) {
|
if (elmnt) {
|
||||||
elmnt.style.bottom = null;
|
elmnt.style.bottom = undefined;
|
||||||
let xPos = (pos.left) > window.innerWidth ? window.innerWidth - 200 : pos.left;
|
let xPos = (pos.left) > window.innerWidth ? window.innerWidth - 200 : pos.left;
|
||||||
let yPos = (pos.top) > window.innerHeight - 20 ? window.innerHeight - 100 : pos.top;
|
let yPos = (pos.top) > window.innerHeight - 20 ? window.innerHeight - 100 : pos.top;
|
||||||
elmnt.style.top = (yPos) + "px";
|
elmnt.style.top = (yPos) + "px";
|
||||||
@@ -446,7 +563,7 @@ export class RdDCalendrier extends Application {
|
|||||||
updateDisplay() {
|
updateDisplay() {
|
||||||
let calendrier = this.fillCalendrierData();
|
let calendrier = this.fillCalendrierData();
|
||||||
// Rebuild text du calendrier
|
// Rebuild text du calendrier
|
||||||
let dateHTML = `Jour ${calendrier.jourMois} de ${calendrier.nomMois} (${calendrier.nomSaison})`
|
let dateHTML = `${calendrier.jourMois} ${calendrier.nomMois} ${calendrier.annee} (${calendrier.nomSaison})`
|
||||||
if (game.user.isGM) {
|
if (game.user.isGM) {
|
||||||
dateHTML = dateHTML + " - NA: " + (this.getCurrentNombreAstral() ?? "indéterminé");
|
dateHTML = dateHTML + " - NA: " + (this.getCurrentNombreAstral() ?? "indéterminé");
|
||||||
}
|
}
|
||||||
@@ -469,6 +586,7 @@ export class RdDCalendrier extends Application {
|
|||||||
this.calendrier.minutesRelative = Number(calendrierData.minutesRelative);
|
this.calendrier.minutesRelative = Number(calendrierData.minutesRelative);
|
||||||
this.calendrier.jour = Number(calendrierData.jourMois) - 1;
|
this.calendrier.jour = Number(calendrierData.jourMois) - 1;
|
||||||
this.calendrier.moisRdD = RdDCalendrier.getChiffreFromSigne(calendrierData.moisKey);
|
this.calendrier.moisRdD = RdDCalendrier.getChiffreFromSigne(calendrierData.moisKey);
|
||||||
|
this.calendrier.annee = Number(calendrierData.annee);
|
||||||
this.calendrier.heureRdD = RdDCalendrier.getChiffreFromSigne(calendrierData.heureKey);
|
this.calendrier.heureRdD = RdDCalendrier.getChiffreFromSigne(calendrierData.heureKey);
|
||||||
game.settings.set(SYSTEM_RDD, "calendrier", duplicate(this.calendrier));
|
game.settings.set(SYSTEM_RDD, "calendrier", duplicate(this.calendrier));
|
||||||
|
|
||||||
@@ -528,97 +646,4 @@ export class RdDCalendrier extends Application {
|
|||||||
astrologieEditeur.updateData(calendrierData);
|
astrologieEditeur.updateData(calendrierData);
|
||||||
astrologieEditeur.render(true);
|
astrologieEditeur.render(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
/** @override */
|
|
||||||
async activateListeners(html) {
|
|
||||||
super.activateListeners(html);
|
|
||||||
|
|
||||||
HtmlUtility._showControlWhen($(".gm-only"), game.user.isGM);
|
|
||||||
|
|
||||||
await this.updateDisplay();
|
|
||||||
|
|
||||||
html.find('.calendar-btn').click(ev => this.onCalendarButton(ev));
|
|
||||||
|
|
||||||
html.find('.calendar-btn-edit').click(ev => {
|
|
||||||
ev.preventDefault();
|
|
||||||
this.showCalendarEditor();
|
|
||||||
});
|
|
||||||
|
|
||||||
html.find('.astrologie-btn-edit').click(ev => {
|
|
||||||
ev.preventDefault();
|
|
||||||
this.showAstrologieEditor();
|
|
||||||
});
|
|
||||||
|
|
||||||
html.find('#calendar-move-handle').mousedown(ev => {
|
|
||||||
ev.preventDefault();
|
|
||||||
ev = ev || window.event;
|
|
||||||
let isRightMB = false;
|
|
||||||
if ("which" in ev) { // Gecko (Firefox), WebKit (Safari/Chrome) & Opera
|
|
||||||
isRightMB = ev.which == 3;
|
|
||||||
} else if ("button" in ev) { // IE, Opera
|
|
||||||
isRightMB = ev.button == 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isRightMB) {
|
|
||||||
dragElement(document.getElementById("calendar-time-container"));
|
|
||||||
let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
|
|
||||||
|
|
||||||
function dragElement(elmnt) {
|
|
||||||
elmnt.onmousedown = dragMouseDown;
|
|
||||||
function dragMouseDown(e) {
|
|
||||||
e = e || window.event;
|
|
||||||
e.preventDefault();
|
|
||||||
pos3 = e.clientX;
|
|
||||||
pos4 = e.clientY;
|
|
||||||
|
|
||||||
document.onmouseup = closeDragElement;
|
|
||||||
document.onmousemove = elementDrag;
|
|
||||||
}
|
|
||||||
|
|
||||||
function elementDrag(e) {
|
|
||||||
e = e || window.event;
|
|
||||||
e.preventDefault();
|
|
||||||
// calculate the new cursor position:
|
|
||||||
pos1 = pos3 - e.clientX;
|
|
||||||
pos2 = pos4 - e.clientY;
|
|
||||||
pos3 = e.clientX;
|
|
||||||
pos4 = e.clientY;
|
|
||||||
// set the element's new position:
|
|
||||||
elmnt.style.bottom = null
|
|
||||||
elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
|
|
||||||
elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeDragElement() {
|
|
||||||
// stop moving when mouse button is released:
|
|
||||||
elmnt.onmousedown = null;
|
|
||||||
document.onmouseup = null;
|
|
||||||
document.onmousemove = null;
|
|
||||||
let xPos = (elmnt.offsetLeft - pos1) > window.innerWidth ? window.innerWidth - 200 : (elmnt.offsetLeft - pos1);
|
|
||||||
let yPos = (elmnt.offsetTop - pos2) > window.innerHeight - 20 ? window.innerHeight - 100 : (elmnt.offsetTop - pos2)
|
|
||||||
xPos = xPos < 0 ? 0 : xPos;
|
|
||||||
yPos = yPos < 0 ? 0 : yPos;
|
|
||||||
if (xPos != (elmnt.offsetLeft - pos1) || yPos != (elmnt.offsetTop - pos2)) {
|
|
||||||
elmnt.style.top = (yPos) + "px";
|
|
||||||
elmnt.style.left = (xPos) + "px";
|
|
||||||
}
|
|
||||||
game.system.rdd.calendrier.calendrierPos.top = yPos;
|
|
||||||
game.system.rdd.calendrier.calendrierPos.left = xPos;
|
|
||||||
if (game.user.isGM) {
|
|
||||||
game.settings.set(SYSTEM_RDD, "calendrier-pos", duplicate(game.system.rdd.calendrier.calendrierPos));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (isRightMB) {
|
|
||||||
game.system.rdd.calendrier.calendrierPos.top = 200;
|
|
||||||
game.system.rdd.calendrier.calendrierPos.left = 200;
|
|
||||||
if (game.user.isGM) {
|
|
||||||
game.settings.set(SYSTEM_RDD, "calendrier-pos", duplicate(game.system.rdd.calendrier.calendrierPos));
|
|
||||||
}
|
|
||||||
this.setPos(game.system.rdd.calendrier.calendrierPos);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -52,6 +52,11 @@ export class RdDCarac {
|
|||||||
return selectedCarac?.label?.toLowerCase()?.match(/r(e|ê)ve(( |-)actuel)?/);
|
return selectedCarac?.label?.toLowerCase()?.match(/r(e|ê)ve(( |-)actuel)?/);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static isActionPhysique(selectedCarac) {
|
||||||
|
return !selectedCarac ||
|
||||||
|
selectedCarac?.label.match(/(Apparence|Force|Agilité|Dextérité|Vue|Ouïe|Odorat-Goût|Empathie|Dérobée|Mêlée|Tir|Lancer)/);
|
||||||
|
}
|
||||||
|
|
||||||
static isIgnoreEtatGeneral(rollData) {
|
static isIgnoreEtatGeneral(rollData) {
|
||||||
const selectedCarac = rollData.selectedCarac;
|
const selectedCarac = rollData.selectedCarac;
|
||||||
return !selectedCarac ||
|
return !selectedCarac ||
|
||||||
@@ -62,7 +67,7 @@ export class RdDCarac {
|
|||||||
|
|
||||||
|
|
||||||
static computeTotal(carac, beaute = undefined) {
|
static computeTotal(carac, beaute = undefined) {
|
||||||
const total = Object.values(carac).filter(c => !c.derivee)
|
const total = Object.values(carac ?? {}).filter(c => !c.derivee)
|
||||||
.map(it => parseInt(it.value))
|
.map(it => parseInt(it.value))
|
||||||
.reduce(Misc.sum(), 0);
|
.reduce(Misc.sum(), 0);
|
||||||
const beauteSuperieur10 = Math.max((beaute ?? 10) - 10, 0);
|
const beauteSuperieur10 = Math.max((beaute ?? 10) - 10, 0);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { ChatUtility } from "./chat-utility.js";
|
import { ChatUtility } from "./chat-utility.js";
|
||||||
import { ENTITE_INCARNE, ENTITE_NONINCARNE, HIDE_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE, HIDE_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
||||||
|
import { DialogSelectTarget } from "./dialog-select-target.js";
|
||||||
import { Grammar } from "./grammar.js";
|
import { Grammar } from "./grammar.js";
|
||||||
import { RdDItemArme } from "./item-arme.js";
|
import { RdDItemArme } from "./item-arme.js";
|
||||||
import { RdDItemCompetence } from "./item-competence.js";
|
import { RdDItemCompetence } from "./item-competence.js";
|
||||||
@@ -9,7 +10,9 @@ import { RdDBonus } from "./rdd-bonus.js";
|
|||||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||||
import { RdDRoll } from "./rdd-roll.js";
|
import { RdDRoll } from "./rdd-roll.js";
|
||||||
import { RdDRollTables } from "./rdd-rolltables.js";
|
import { RdDRollTables } from "./rdd-rolltables.js";
|
||||||
import { ReglesOptionelles } from "./regles-optionelles.js";
|
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
||||||
|
import { STATUSES } from "./settings/status-effects.js";
|
||||||
|
import { Targets } from "./targets.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
const premierRoundInit = [
|
const premierRoundInit = [
|
||||||
@@ -81,7 +84,6 @@ export class RdDCombatManager extends Combat {
|
|||||||
console.log(`${game.system.title} | Combat.rollInitiative()`, ids, formula, messageOptions);
|
console.log(`${game.system.title} | Combat.rollInitiative()`, ids, formula, messageOptions);
|
||||||
|
|
||||||
ids = typeof ids === "string" ? [ids] : ids;
|
ids = typeof ids === "string" ? [ids] : ids;
|
||||||
const currentId = this.combatant._id;
|
|
||||||
// calculate initiative
|
// calculate initiative
|
||||||
for (let cId = 0; cId < ids.length; cId++) {
|
for (let cId = 0; cId < ids.length; cId++) {
|
||||||
const combatant = this.combatants.get(ids[cId]);
|
const combatant = this.combatants.get(ids[cId]);
|
||||||
@@ -100,14 +102,14 @@ export class RdDCombatManager extends Combat {
|
|||||||
const carac = combatant.actor.system.carac[competence.system.defaut_carac].value;
|
const carac = combatant.actor.system.carac[competence.system.defaut_carac].value;
|
||||||
const niveau = competence.system.niveau;
|
const niveau = competence.system.niveau;
|
||||||
const bonusEcaille = (armeCombat?.system.magique) ? armeCombat.system.ecaille_efficacite : 0;
|
const bonusEcaille = (armeCombat?.system.magique) ? armeCombat.system.ecaille_efficacite : 0;
|
||||||
rollFormula = RdDCombatManager.formuleInitiative(2, carac, niveau, bonusEcaille);
|
rollFormula = RdDCombatManager.formuleInitiative(2, carac, niveau, bonusEcaille);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//console.log("Combatat", c);
|
//console.log("Combatat", c);
|
||||||
const roll = combatant.getInitiativeRoll(rollFormula);
|
const roll = combatant.getInitiativeRoll(rollFormula);
|
||||||
if ( !roll.total) {
|
if (!roll.total) {
|
||||||
roll.evaluate( {async: false});
|
roll.evaluate({ async: false });
|
||||||
}
|
}
|
||||||
if (roll.total <= 0) roll.total = 0.00;
|
if (roll.total <= 0) roll.total = 0.00;
|
||||||
console.log("Compute init for", rollFormula, roll.total, combatant);
|
console.log("Compute init for", rollFormula, roll.total, combatant);
|
||||||
@@ -120,7 +122,7 @@ export class RdDCombatManager extends Combat {
|
|||||||
{
|
{
|
||||||
speaker: {
|
speaker: {
|
||||||
scene: canvas.scene._id,
|
scene: canvas.scene._id,
|
||||||
actor: combatant.actor ? combatant.actor._id : null,
|
actor: combatant.actor?._id,
|
||||||
token: combatant.token._id,
|
token: combatant.token._id,
|
||||||
alias: combatant.token.name,
|
alias: combatant.token.name,
|
||||||
sound: CONFIG.sounds.dice,
|
sound: CONFIG.sounds.dice,
|
||||||
@@ -150,84 +152,109 @@ export class RdDCombatManager extends Combat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/** Retourne une liste triée d'actions d'armes avec le split arme1 main / arme 2 main */
|
/** Retourne une liste triée d'actions d'armes avec le split arme1 main / arme 2 main / lancer */
|
||||||
static listActionsArmes(armes, competences, carac) {
|
static listActionsArmes(armes, competences, carac) {
|
||||||
// Gestion des armes 1/2 mains
|
let actions = [];
|
||||||
let actionsArme = [];
|
|
||||||
for (const arme of armes) {
|
for (const arme of armes) {
|
||||||
let action = duplicate(arme)
|
if (arme.system.equipe) {
|
||||||
if (action.system.equipe) {
|
const dommages = arme.system.dommages.toString();
|
||||||
let compData = competences.find(c => c.name == action.system.competence)
|
const tableauDommages = dommages.includes("/") ? dommages.split("/") : [dommages, dommages];
|
||||||
|
if (arme.system.unemain && arme.system.deuxmains && !dommages.includes("/")) {
|
||||||
actionsArme.push(action);
|
ui.notifications.info("Les dommages de l'arme à 1/2 mains " + arme.name + " ne sont pas corrects (ie sous la forme X/Y)");
|
||||||
action.action = 'attaque';
|
}
|
||||||
action.system.dommagesReels = Number(action.system.dommages);
|
console.log(">>>>", arme)
|
||||||
action.system.niveau = compData.system.niveau;
|
if ((arme.system.unemain && arme.system.competence) ||
|
||||||
action.system.initiative = RdDCombatManager.calculInitiative(compData.system.niveau, carac[compData.system.defaut_carac].value);
|
(arme.system.competence.toLowerCase().includes("corps à corps"))) {
|
||||||
// Dupliquer les armes pouvant être à 1 main et 2 mains en patchant la compétence
|
actions.push(RdDCombatManager.$prepareAttaqueArme({
|
||||||
if (action.system.unemain && !action.system.deuxmains) {
|
arme: arme,
|
||||||
action.system.mainInfo = "(1m)";
|
infoMain: "(1 main)",
|
||||||
} else if (!action.system.unemain && action.system.deuxmains) {
|
dommagesReel: Number(tableauDommages[0]),
|
||||||
action.system.mainInfo = "(2m)";
|
competence: arme.system.competence,
|
||||||
} else if (action.system.unemain && action.system.deuxmains) {
|
carac: carac,
|
||||||
action.system.mainInfo = "(1m)";
|
competences: competences
|
||||||
|
}));
|
||||||
const comp2m = action.system.competence.replace(" 1 main", " 2 mains"); // Replace !
|
}
|
||||||
const comp = competences.find(c => c.name == comp2m)
|
if (arme.system.deuxmains && arme.system.competence) {
|
||||||
|
actions.push(RdDCombatManager.$prepareAttaqueArme({
|
||||||
const arme2main = duplicate(action);
|
arme: arme,
|
||||||
arme2main.system.mainInfo = "(2m)";
|
infoMain: "(2 mains)",
|
||||||
arme2main.system.niveau = comp.system.niveau;
|
dommagesReel: Number(tableauDommages[1]),
|
||||||
arme2main.system.competence = comp2m;
|
competence: arme.system.competence.replace(" 1 main", " 2 mains"),
|
||||||
arme2main.system.initiative = RdDCombatManager.calculInitiative(arme2main.system.niveau, carac[comp.system.defaut_carac].value);
|
carac: carac,
|
||||||
actionsArme.push(arme2main);
|
competences: competences
|
||||||
const containsSlash = action.system.dommages.includes("/");
|
}));
|
||||||
if (containsSlash) {
|
}
|
||||||
const tableauDegats = action.system.dommages.split("/");
|
if (arme.system.lancer) {
|
||||||
action.system.dommagesReels = Number(tableauDegats[0]);
|
actions.push(RdDCombatManager.$prepareAttaqueArme({
|
||||||
arme2main.system.dommagesReels = Number(tableauDegats[1]);
|
arme: arme,
|
||||||
}
|
infoMain: "(lancer)",
|
||||||
else{
|
dommagesReel: Number(tableauDommages[0]),
|
||||||
ui.notifications.info("Les dommages de l'arme à 1/2 mains " + action.name + " ne sont pas corrects (ie sous la forme X/Y)");
|
competence: arme.system.lancer,
|
||||||
}
|
carac: carac,
|
||||||
|
competences: competences
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
if (arme.system.tir) {
|
||||||
|
actions.push(RdDCombatManager.$prepareAttaqueArme({
|
||||||
|
arme: arme,
|
||||||
|
infoMain: "(tir)",
|
||||||
|
dommagesReel: Number(tableauDommages[0]),
|
||||||
|
competence: arme.system.tir,
|
||||||
|
carac: carac,
|
||||||
|
competences: competences
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return actionsArme.sort(Misc.ascending(armeData => armeData.name + (armeData.system.mainInfo ?? '')));
|
return actions.sort(Misc.ascending(action => action.name + (action.system.infoMain ?? '')));
|
||||||
|
}
|
||||||
|
|
||||||
|
static $prepareAttaqueArme(infoAttaque) {
|
||||||
|
const comp = infoAttaque.competences.find(c => c.name == infoAttaque.competence);
|
||||||
|
const attaque = duplicate(infoAttaque.arme);
|
||||||
|
attaque.action = 'attaque';
|
||||||
|
attaque.system.competence = infoAttaque.competence;
|
||||||
|
attaque.system.dommagesReels = infoAttaque.dommagesReel;
|
||||||
|
attaque.system.infoMain = infoAttaque.infoMain;
|
||||||
|
attaque.system.niveau = comp.system.niveau;
|
||||||
|
attaque.system.initiative = RdDCombatManager.calculInitiative(comp.system.niveau, infoAttaque.carac[comp.system.defaut_carac].value);
|
||||||
|
return attaque;
|
||||||
|
}
|
||||||
|
|
||||||
|
static listActionsCreature(competences) {
|
||||||
|
return competences.filter(it => RdDItemCompetenceCreature.isCompetenceAttaque(it))
|
||||||
|
.map(it => RdDItemCompetenceCreature.armeNaturelle(it));
|
||||||
}
|
}
|
||||||
|
|
||||||
static listActionsPossessions(actor) {
|
static listActionsPossessions(actor) {
|
||||||
return RdDCombatManager._indexActions(actor.getPossessions().map(p =>
|
return RdDCombatManager._indexActions(actor.getPossessions().map(p => {
|
||||||
{
|
return {
|
||||||
return {
|
name: p.name,
|
||||||
name: p.name,
|
action: 'conjurer',
|
||||||
action: 'conjurer',
|
system: {
|
||||||
system: {
|
competence: p.name,
|
||||||
competence: p.name,
|
possessionid: p.system.possessionid,
|
||||||
possessionid: p.system.possessionid,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}));
|
}
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static listActionsCombat(combatant) {
|
static listActionsCombat(combatant) {
|
||||||
const actor = combatant.actor;
|
const actor = combatant.actor;
|
||||||
let actions = RdDCombatManager.listActionsPossessions(actor);
|
let actions = RdDCombatManager.listActionsPossessions(actor);
|
||||||
if (actions.length>0) {
|
if (actions.length > 0) {
|
||||||
return actions;
|
return actions;
|
||||||
}
|
}
|
||||||
let items = actor.items;
|
if (actor.isCreatureEntite()) {
|
||||||
if (actor.isCreature()) {
|
actions = actions.concat(RdDCombatManager.listActionsCreature(actor.itemTypes['competencecreature']));
|
||||||
actions = actions.concat(items.filter(it => RdDItemCompetenceCreature.isCompetenceAttaque(it))
|
|
||||||
.map(competence => RdDItemCompetenceCreature.toActionArme(competence)));
|
|
||||||
} else {
|
} else {
|
||||||
// Recupération des items 'arme'
|
// Recupération des items 'arme'
|
||||||
let armes = items.filter(it => RdDItemArme.isArmeUtilisable(it))
|
const armes = actor.itemTypes['arme'].filter(it => RdDItemArme.isArmeUtilisable(it))
|
||||||
//.concat(RdDItemArme.empoignade())
|
//.concat(RdDItemArme.empoignade())
|
||||||
.concat(RdDItemArme.mainsNues());
|
.concat(RdDItemArme.mainsNues());
|
||||||
|
|
||||||
let competences = items.filter(it => it.type == 'competence');
|
const competences = actor.itemTypes['competence'];
|
||||||
actions = actions.concat(RdDCombatManager.listActionsArmes(armes, competences, actor.system.carac));
|
actions = actions.concat(RdDCombatManager.listActionsArmes(armes, competences, actor.system.carac));
|
||||||
|
|
||||||
if (actor.system.attributs.hautrevant.value) {
|
if (actor.system.attributs.hautrevant.value) {
|
||||||
@@ -327,22 +354,16 @@ export class RdDCombatManager extends Combat {
|
|||||||
initOffset = 9;
|
initOffset = 9;
|
||||||
initInfo = "Draconic"
|
initInfo = "Draconic"
|
||||||
} else {
|
} else {
|
||||||
compData = RdDItemCompetence.findCompetence(combatant.actor.items, arme.system.competence);
|
compData = RdDItemCompetence.findCompetence(combatant.actor.items, action.system.competence);
|
||||||
compNiveau = compData.system.niveau;
|
compNiveau = compData.system.niveau;
|
||||||
initInfo = action.name + " / " + action.system.competence;
|
initInfo = action.name + " / " + action.system.competence;
|
||||||
|
|
||||||
if (combatant.actor.type == 'creature' || combatant.actor.type == 'entite') {
|
if (combatant.actor.type == 'creature' || combatant.actor.type == 'entite') {
|
||||||
caracForInit = compData.system.carac_value;
|
caracForInit = compData.system.carac_value;
|
||||||
if (compData.system.categorie == "lancer") {
|
} else {
|
||||||
initOffset = 7;
|
caracForInit = combatant.actor.system.carac[compData.system.defaut_carac].value;
|
||||||
}
|
|
||||||
else {
|
|
||||||
initOffset = 5;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
caracForInit = combatant.actor.system.carac[compData.system.defaut_carac].value;
|
|
||||||
initOffset = RdDCombatManager._baseInitOffset(compData.system.categorie, action);
|
|
||||||
}
|
}
|
||||||
|
initOffset = RdDCombatManager._baseInitOffset(compData.system.categorie, action);
|
||||||
}
|
}
|
||||||
|
|
||||||
let malus = combatant.actor.getEtatGeneral(); // Prise en compte état général
|
let malus = combatant.actor.getEtatGeneral(); // Prise en compte état général
|
||||||
@@ -353,6 +374,7 @@ export class RdDCombatManager extends Combat {
|
|||||||
game.combat.rollInitiative(combatantId, rollFormula, { initInfo: initInfo });
|
game.combat.rollInitiative(combatantId, rollFormula, { initInfo: initInfo });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
static _baseInitOffset(categorie, arme) {
|
static _baseInitOffset(categorie, arme) {
|
||||||
if (categorie == "tir") { // Offset de principe pour les armes de jet
|
if (categorie == "tir") { // Offset de principe pour les armes de jet
|
||||||
return 8;
|
return 8;
|
||||||
@@ -360,10 +382,12 @@ export class RdDCombatManager extends Combat {
|
|||||||
if (categorie == "lancer") { // Offset de principe pour les armes de jet
|
if (categorie == "lancer") { // Offset de principe pour les armes de jet
|
||||||
return 7;
|
return 7;
|
||||||
}
|
}
|
||||||
// Offset de principe pour les armes de jet
|
|
||||||
switch (arme.system.cac) {
|
switch (arme.system.cac) {
|
||||||
case "empoignade": return 3;
|
case "empoignade":
|
||||||
case "pugilat": return 4;
|
return 3;
|
||||||
|
case "pugilat":
|
||||||
|
case "naturelle":
|
||||||
|
return 4;
|
||||||
}
|
}
|
||||||
return 5;
|
return 5;
|
||||||
}
|
}
|
||||||
@@ -372,7 +396,7 @@ export class RdDCombatManager extends Combat {
|
|||||||
static displayInitiativeMenu(html, combatantId) {
|
static displayInitiativeMenu(html, combatantId) {
|
||||||
console.log("Combatant ; ", combatantId);
|
console.log("Combatant ; ", combatantId);
|
||||||
const combatant = game.combat.combatants.get(combatantId);
|
const combatant = game.combat.combatants.get(combatantId);
|
||||||
if (! (combatant?.actor) ) {
|
if (!(combatant?.actor)) {
|
||||||
ui.notifications.warn(`Le combatant ${combatant.name ?? combatantId} n'est pas associé à un acteur, impossible de déterminer ses actions de combat!`)
|
ui.notifications.warn(`Le combatant ${combatant.name ?? combatantId} n'est pas associé à un acteur, impossible de déterminer ses actions de combat!`)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -447,49 +471,30 @@ export class RdDCombat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static createUsingTarget(attacker) {
|
static rddCombatTarget(target, attacker) {
|
||||||
const target = RdDCombat.getTarget();
|
const defender = target?.actor;
|
||||||
if (target == undefined) {
|
const defenderTokenId = target?.id;
|
||||||
ui.notifications.warn((game.user.targets?.size ?? 0) > 1
|
|
||||||
? "Vous devez choisir <strong>une seule</strong> cible à attaquer!"
|
|
||||||
: "Vous devez choisir une cible à attaquer!");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const defender = target?.actor;
|
|
||||||
const defenderTokenId = target?.id;
|
|
||||||
if ( defender.type == 'entite' && defender.system.definition.typeentite == ENTITE_NONINCARNE) {
|
|
||||||
ui.notifications.warn("Vous ne pouvez pas cibler une entité non incarnée !!!!");
|
|
||||||
} else {
|
|
||||||
return this.create(attacker, defender, defenderTokenId, target)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static getTarget() {
|
|
||||||
if (game.user.targets && game.user.targets.size == 1) {
|
|
||||||
for (let target of game.user.targets) {
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static create(attacker, defender, defenderTokenId, target = undefined) {
|
|
||||||
return new RdDCombat(attacker, defender, defenderTokenId, target)
|
return new RdDCombat(attacker, defender, defenderTokenId, target)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static createForAttackerAndDefender(attackerId, defenderTokenId) {
|
static rddCombatForAttackerAndDefender(attackerId, defenderTokenId) {
|
||||||
const attacker = game.actors.get(attackerId);
|
const attacker = game.actors.get(attackerId);
|
||||||
if (defenderTokenId) {
|
let defender = defenderTokenId ? canvas.tokens.get(defenderTokenId)?.actor : undefined;
|
||||||
const defenderToken = canvas.tokens.get(defenderTokenId);
|
let target = undefined
|
||||||
const defender = defenderToken.actor;
|
if (!defenderTokenId || !defender) {
|
||||||
|
console.warn(`RdDCombat.rddCombatForAttackerAndDefender: appel avec defenderTokenId ${defenderTokenId} incorrect, ou pas de defender correspondant`);
|
||||||
return RdDCombat.create(attacker, defender, defenderTokenId);
|
target = Targets.getTarget()
|
||||||
|
if (!target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
defenderTokenId = target.id;
|
||||||
|
defender = target.actor;
|
||||||
|
if (!defenderTokenId || !defender) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return RdDCombat.createUsingTarget(attacker)
|
return new RdDCombat(attacker, defender, defenderTokenId, target)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -497,10 +502,10 @@ export class RdDCombat {
|
|||||||
let defender = canvas.tokens.get(msg.defenderTokenId).actor;
|
let defender = canvas.tokens.get(msg.defenderTokenId).actor;
|
||||||
if (Misc.isOwnerPlayerOrUniqueConnectedGM()) {
|
if (Misc.isOwnerPlayerOrUniqueConnectedGM()) {
|
||||||
let attackerRoll = msg.attackerRoll;
|
let attackerRoll = msg.attackerRoll;
|
||||||
let attacker = msg.attackerId ? game.actors.get(msg.attackerId) : null;
|
let attacker = msg.attackerId ? game.actors.get(msg.attackerId) : undefined;
|
||||||
|
|
||||||
defender.encaisserDommages(attackerRoll, attacker);
|
defender.encaisserDommages(attackerRoll, attacker);
|
||||||
const rddCombat = RdDCombat.createForAttackerAndDefender(msg.attackerId, msg.defenderTokenId);
|
const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.defenderTokenId);
|
||||||
rddCombat?.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
|
rddCombat?.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -509,7 +514,7 @@ export class RdDCombat {
|
|||||||
static onMsgDefense(msg) {
|
static onMsgDefense(msg) {
|
||||||
let defenderToken = canvas.tokens.get(msg.defenderTokenId);
|
let defenderToken = canvas.tokens.get(msg.defenderTokenId);
|
||||||
if (defenderToken && Misc.isUniqueConnectedGM()) {
|
if (defenderToken && Misc.isUniqueConnectedGM()) {
|
||||||
const rddCombat = RdDCombat.createForAttackerAndDefender(msg.attackerId, msg.defenderTokenId);
|
const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.defenderTokenId);
|
||||||
rddCombat?.removeChatMessageActionsPasseArme(msg.defenderRoll.passeArme);
|
rddCombat?.removeChatMessageActionsPasseArme(msg.defenderRoll.passeArme);
|
||||||
rddCombat?._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll);
|
rddCombat?._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll);
|
||||||
}
|
}
|
||||||
@@ -536,11 +541,10 @@ export class RdDCombat {
|
|||||||
'#echec-total-attaque',
|
'#echec-total-attaque',
|
||||||
]) {
|
]) {
|
||||||
html.on("click", button, event => {
|
html.on("click", button, event => {
|
||||||
const rddCombat = RdDCombat.createForAttackerAndDefender(
|
const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(
|
||||||
event.currentTarget.attributes['data-attackerId']?.value,
|
event.currentTarget.attributes['data-attackerId']?.value,
|
||||||
event.currentTarget.attributes['data-defenderTokenId']?.value);
|
event.currentTarget.attributes['data-defenderTokenId']?.value);
|
||||||
if (rddCombat) {
|
if (rddCombat) {
|
||||||
|
|
||||||
rddCombat.onEvent(button, event);
|
rddCombat.onEvent(button, event);
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
@@ -555,19 +559,19 @@ export class RdDCombat {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
constructor(attacker, defender, defenderTokenId, target) {
|
constructor(attacker, defender, defenderTokenId, target) {
|
||||||
this.attacker = attacker;
|
this.attacker = attacker
|
||||||
this.defender = defender;
|
this.defender = defender
|
||||||
this.target = target;
|
this.target = target
|
||||||
this.attackerId = this.attacker.id;
|
this.attackerId = this.attacker.id
|
||||||
this.defenderId = this.defender.id;
|
this.defenderId = this.defender.id
|
||||||
this.defenderTokenId = defenderTokenId;
|
this.defenderTokenId = defenderTokenId
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async onEvent(button, event) {
|
async onEvent(button, event) {
|
||||||
const chatMessage = ChatUtility.getChatMessage(event);
|
const chatMessage = ChatUtility.getChatMessage(event);
|
||||||
const defenderRoll = ChatUtility.getMessageData(chatMessage, 'defender-roll');
|
const defenderRoll = ChatUtility.getMessageData(chatMessage, 'defender-roll');
|
||||||
const attackerRoll = defenderRoll?.attackerRoll ?? ChatUtility.getMessageData(chatMessage, 'attacker-roll') ;
|
const attackerRoll = defenderRoll?.attackerRoll ?? ChatUtility.getMessageData(chatMessage, 'attacker-roll');
|
||||||
console.log('RdDCombat', attackerRoll, defenderRoll);
|
console.log('RdDCombat', attackerRoll, defenderRoll);
|
||||||
const defenderTokenId = event.currentTarget.attributes['data-defenderTokenId']?.value;
|
const defenderTokenId = event.currentTarget.attributes['data-defenderTokenId']?.value;
|
||||||
|
|
||||||
@@ -686,9 +690,84 @@ export class RdDCombat {
|
|||||||
return rollData.rolled.isSuccess;
|
return rollData.rolled.isSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async proposerAjustementTirLancer(rollData) {
|
||||||
|
if (['tir', 'lancer'].includes(rollData.competence.system.categorie)) {
|
||||||
|
if (this.defender.isEntite([ENTITE_BLURETTE])) {
|
||||||
|
ChatMessage.create({
|
||||||
|
content: `<strong>La cible est une blurette, l'arme à distance sera perdue dans le blurêve`,
|
||||||
|
whisper: ChatMessage.getWhisperRecipients("GM")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const defenderToken = canvas.tokens.get(this.defenderTokenId);
|
||||||
|
const dist = this.distance(_token, defenderToken)
|
||||||
|
const isVisible = this.isVisible(_token, defenderToken)
|
||||||
|
const portee = this._ajustementPortee(dist, rollData.arme)
|
||||||
|
const taille = this._ajustementTaille(this.defender)
|
||||||
|
const activite = this._ajustementMouvement(this.defender)
|
||||||
|
const total = [portee, taille, activite].map(it => it.diff).filter(d => !Number.isNaN(d)).reduce(Misc.sum(), 0)
|
||||||
|
ChatMessage.create({
|
||||||
|
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-info-distance.html', {
|
||||||
|
rollData: rollData,
|
||||||
|
attacker: _token,
|
||||||
|
isVisible: isVisible,
|
||||||
|
defender: defenderToken,
|
||||||
|
distance: dist,
|
||||||
|
portee: portee,
|
||||||
|
taille: taille,
|
||||||
|
activite: activite,
|
||||||
|
total: total
|
||||||
|
}),
|
||||||
|
whisper: ChatMessage.getWhisperRecipients("GM")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isVisible(token, defenderToken) {
|
||||||
|
return canvas.effects.visibility.testVisibility(defenderToken.center, { object: token })
|
||||||
|
}
|
||||||
|
|
||||||
|
distance(token, defenderToken) {
|
||||||
|
return Number(canvas.grid.measureDistances([{ ray: new Ray(token.center, defenderToken.center) }], { gridSpaces: false })).toFixed(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
_ajustementPortee(dist, arme) {
|
||||||
|
if (dist <= arme.system.portee_courte) return { msg: "courte", diff: 0 };
|
||||||
|
if (dist <= arme.system.portee_moyenne) return { msg: "moyenne", diff: -3 };
|
||||||
|
if (dist <= arme.system.portee_extreme) return { msg: "extrême", diff: -5 };
|
||||||
|
return { msg: "inatteignable", diff: -10 };
|
||||||
|
}
|
||||||
|
|
||||||
|
_ajustementTaille(actor) {
|
||||||
|
if (actor.isVehicule()) return { msg: "véhicule", diff: 0 }
|
||||||
|
const taille = actor.getCaracByName('TAILLE')?.value ?? 1;
|
||||||
|
if (taille <= 1) return { msg: "souris", diff: -8 };
|
||||||
|
if (taille <= 3) return { msg: "chat", diff: -4 };
|
||||||
|
if (taille <= 5) return { msg: "chien", diff: -2 };
|
||||||
|
if (taille <= 15) return { msg: "humanoïde", diff: 0 };
|
||||||
|
if (taille <= 20) return { msg: "ogre", diff: 2 };
|
||||||
|
return { msg: "gigantesque", diff: 4 };
|
||||||
|
}
|
||||||
|
_ajustementMouvement(defender) {
|
||||||
|
if (defender.getSurprise(true)) return { msg: "immobile (surprise)", diff: 0 };
|
||||||
|
if (game.combat?.combatants.find(it => it.actorId == defender.id)) return { msg: "en mouvement (combat)", diff: -4 };
|
||||||
|
return { msg: "à déterminer (0 immobile, -3 actif, -4 en mouvement, -5 en zig-zag)", diff: -3 };
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async attaque(competence, arme) {
|
async attaque(competence, arme) {
|
||||||
if (!await this.accorderEntite('avant-attaque')) {
|
// const nonIncarnee = this.defender.isEntite([ENTITE_NONINCARNE])
|
||||||
|
// const blurette = this.defender.isEntite([ENTITE_BLURETTE])
|
||||||
|
// if (nonIncarnee || blurette) {
|
||||||
|
// ChatMessage.create( {
|
||||||
|
// content: `<strong>La cible est ${nonIncarnee ? 'non incarnée' : 'une blurette'}.
|
||||||
|
// Il est impossible de l'atteindre.`,
|
||||||
|
// whisper: ChatMessage.getWhisperRecipients("GM")})
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (!await this.attacker.accorder(this.defender, 'avant-attaque')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (arme.system.cac == 'empoignade' && this.attacker.isCombatTouche()) {
|
if (arme.system.cac == 'empoignade' && this.attacker.isCombatTouche()) {
|
||||||
@@ -708,25 +787,24 @@ export class RdDCombat {
|
|||||||
if (arme) {
|
if (arme) {
|
||||||
this.attacker.verifierForceMin(arme);
|
this.attacker.verifierForceMin(arme);
|
||||||
}
|
}
|
||||||
|
await this.proposerAjustementTirLancer(rollData)
|
||||||
|
|
||||||
const dialog = await RdDRoll.create(this.attacker, rollData,
|
const dialog = await RdDRoll.create(this.attacker, rollData,
|
||||||
|
{ html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' },
|
||||||
{
|
{
|
||||||
html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html',
|
name: 'jet-attaque',
|
||||||
options: { height: 540 }
|
label: 'Attaque: ' + (arme?.name ?? competence.name),
|
||||||
}, {
|
callbacks: [
|
||||||
name: 'jet-attaque',
|
this.attacker.createCallbackExperience(),
|
||||||
label: 'Attaque: ' + (arme?.name ?? competence.name),
|
this.attacker.createCallbackAppelAuMoral(),
|
||||||
callbacks: [
|
{ action: r => this.removeChatMessageActionsPasseArme(r.passeArme) },
|
||||||
this.attacker.createCallbackExperience(),
|
{ condition: r => arme && !RdDCombat.isParticuliere(r), action: r => this.attacker.incDecItemUse(arme._id) },
|
||||||
this.attacker.createCallbackAppelAuMoral(),
|
{ condition: r => (RdDCombat.isReussite(r) && !RdDCombat.isParticuliere(r)), action: r => this._onAttaqueNormale(r) },
|
||||||
{ action: r => this.removeChatMessageActionsPasseArme(r.passeArme) },
|
{ condition: RdDCombat.isParticuliere, action: r => this._onAttaqueParticuliere(r) },
|
||||||
{ condition: r => arme && !RdDCombat.isParticuliere(r), action: r => this.attacker.incDecItemUse(arme._id) },
|
{ condition: RdDCombat.isEchec, action: r => this._onAttaqueEchec(r) },
|
||||||
{ condition: r => (RdDCombat.isReussite(r) && !RdDCombat.isParticuliere(r)), action: r => this._onAttaqueNormale(r) },
|
{ condition: RdDCombat.isEchecTotal, action: r => this._onAttaqueEchecTotal(r) },
|
||||||
{ condition: RdDCombat.isParticuliere, action: r => this._onAttaqueParticuliere(r) },
|
]
|
||||||
{ condition: RdDCombat.isEchec, action: r => this._onAttaqueEchec(r) },
|
});
|
||||||
{ condition: RdDCombat.isEchecTotal, action: r => this._onAttaqueEchecTotal(r) },
|
|
||||||
]
|
|
||||||
});
|
|
||||||
dialog.render(true);
|
dialog.render(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -739,10 +817,11 @@ export class RdDCombat {
|
|||||||
competence: competence,
|
competence: competence,
|
||||||
surprise: this.attacker.getSurprise(true),
|
surprise: this.attacker.getSurprise(true),
|
||||||
surpriseDefenseur: this.defender.getSurprise(true),
|
surpriseDefenseur: this.defender.getSurprise(true),
|
||||||
|
targetToken: Targets.extractTokenData(this.target),
|
||||||
essais: {}
|
essais: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.attacker.isCreature()) {
|
if (this.attacker.isCreatureEntite()) {
|
||||||
RdDItemCompetenceCreature.setRollDataCreature(rollData);
|
RdDItemCompetenceCreature.setRollDataCreature(rollData);
|
||||||
}
|
}
|
||||||
else if (arme) {
|
else if (arme) {
|
||||||
@@ -760,7 +839,7 @@ export class RdDCombat {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async _onAttaqueParticuliere(rollData) {
|
async _onAttaqueParticuliere(rollData) {
|
||||||
|
|
||||||
const isMeleeDiffNegative = (rollData.competence.type == 'competencecreature' || rollData.selectedCarac.label == "Mêlée") && rollData.diffLibre < 0;
|
const isMeleeDiffNegative = (rollData.competence.type == 'competencecreature' || rollData.selectedCarac.label == "Mêlée") && rollData.diffLibre < 0;
|
||||||
// force toujours, sauf empoignade
|
// force toujours, sauf empoignade
|
||||||
// finesse seulement en mélée, pour l'empoignade, ou si la difficulté libre est de -1 minimum
|
// finesse seulement en mélée, pour l'empoignade, ou si la difficulté libre est de -1 minimum
|
||||||
@@ -778,7 +857,7 @@ export class RdDCombat {
|
|||||||
else if (!isForce && !isFinesse && isRapide) {
|
else if (!isForce && !isFinesse && isRapide) {
|
||||||
return await this.choixParticuliere(rollData, "rapidite");
|
return await this.choixParticuliere(rollData, "rapidite");
|
||||||
}
|
}
|
||||||
|
|
||||||
const choixParticuliere = await ChatMessage.create({
|
const choixParticuliere = await ChatMessage.create({
|
||||||
alias: this.attacker.name,
|
alias: this.attacker.name,
|
||||||
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.attacker.name),
|
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.attacker.name),
|
||||||
@@ -802,12 +881,12 @@ export class RdDCombat {
|
|||||||
attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker.getBonusDegat(), this.defender.isEntite());
|
attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker.getBonusDegat(), this.defender.isEntite());
|
||||||
let defenderRoll = { attackerRoll: attackerRoll, passeArme: attackerRoll.passeArme, show: {} }
|
let defenderRoll = { attackerRoll: attackerRoll, passeArme: attackerRoll.passeArme, show: {} }
|
||||||
attackerRoll.show = {
|
attackerRoll.show = {
|
||||||
cible: this.target ? this.defender.system.name : 'la cible',
|
cible: this.target ? this.defender.name : 'la cible',
|
||||||
isRecul: (attackerRoll.particuliere == 'force' || attackerRoll.tactique == 'charge')
|
isRecul: (attackerRoll.particuliere == 'force' || attackerRoll.tactique == 'charge')
|
||||||
}
|
}
|
||||||
await RdDResolutionTable.displayRollData(attackerRoll, this.attacker, 'chat-resultat-attaque.html');
|
await RdDResolutionTable.displayRollData(attackerRoll, this.attacker, 'chat-resultat-attaque.html');
|
||||||
|
|
||||||
if (!await this.accorderEntite('avant-defense')) {
|
if (!await this.attacker.accorder(this.defender, 'avant-defense')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -817,7 +896,7 @@ export class RdDCombat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
isPossession( attackerRoll) {
|
isPossession(attackerRoll) {
|
||||||
return attackerRoll.selectedCarac.label.toLowerCase() == 'possession';
|
return attackerRoll.selectedCarac.label.toLowerCase() == 'possession';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -833,7 +912,7 @@ export class RdDCombat {
|
|||||||
// # utilisation esquive
|
// # utilisation esquive
|
||||||
const corpsACorps = this.defender.getCompetence("Corps à corps", { onMessage: it => console.info(it, this.defender) });
|
const corpsACorps = this.defender.getCompetence("Corps à corps", { onMessage: it => console.info(it, this.defender) });
|
||||||
const esquives = duplicate(this.defender.getCompetences("esquive", { onMessage: it => console.info(it, this.defender) }))
|
const esquives = duplicate(this.defender.getCompetences("esquive", { onMessage: it => console.info(it, this.defender) }))
|
||||||
esquives.forEach(e => e.usages = e?.id ? this.defender.getItemUse(e.id) : 0);
|
esquives.forEach(e => e.system.nbUsage = e?._id ? this.defender.getItemUse(e._id) : 0);
|
||||||
|
|
||||||
const paramChatDefense = {
|
const paramChatDefense = {
|
||||||
passeArme: attackerRoll.passeArme,
|
passeArme: attackerRoll.passeArme,
|
||||||
@@ -960,31 +1039,28 @@ export class RdDCombat {
|
|||||||
const arme = this.defender.getArmeParade(armeParadeId);
|
const arme = this.defender.getArmeParade(armeParadeId);
|
||||||
console.log("RdDCombat.parade >>>", attackerRoll, armeParadeId, arme);
|
console.log("RdDCombat.parade >>>", attackerRoll, armeParadeId, arme);
|
||||||
const competence = arme?.system?.competence;
|
const competence = arme?.system?.competence;
|
||||||
if (competence == undefined)
|
if (competence == undefined) {
|
||||||
{
|
console.error("Pas de compétence de parade associée à ", arme?.name, armeParadeId);
|
||||||
console.error("Pas de compétence de parade associée à ", arme?.name, armeParadeId) ;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let rollData = this._prepareParade(attackerRoll, arme, competence);
|
let rollData = this._prepareParade(attackerRoll, arme, competence);
|
||||||
|
|
||||||
const dialog = await RdDRoll.create(this.defender, rollData,
|
const dialog = await RdDRoll.create(this.defender, rollData,
|
||||||
|
{ html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' },
|
||||||
{
|
{
|
||||||
html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html',
|
name: 'jet-parade',
|
||||||
options: { height: 540 }
|
label: 'Parade: ' + (arme ? arme.name : rollData.competence.name),
|
||||||
}, {
|
callbacks: [
|
||||||
name: 'jet-parade',
|
this.defender.createCallbackExperience(),
|
||||||
label: 'Parade: ' + (arme ? arme.name : rollData.competence.name),
|
this.defender.createCallbackAppelAuMoral(),
|
||||||
callbacks: [
|
{ action: r => this.removeChatMessageActionsPasseArme(r.passeArme) },
|
||||||
this.defender.createCallbackExperience(),
|
{ condition: r => !RdDCombat.isParticuliere(r), action: r => this.defender.incDecItemUse(armeParadeId) },
|
||||||
this.defender.createCallbackAppelAuMoral(),
|
{ condition: RdDCombat.isReussite, action: r => this._onParadeNormale(r) },
|
||||||
{ action: r => this.removeChatMessageActionsPasseArme(r.passeArme) },
|
{ condition: RdDCombat.isParticuliere, action: r => this._onParadeParticuliere(r) },
|
||||||
{ condition: r => !RdDCombat.isParticuliere(r), action: r => this.defender.incDecItemUse(armeParadeId) },
|
{ condition: RdDCombat.isEchec, action: r => this._onParadeEchec(r) },
|
||||||
{ condition: RdDCombat.isReussite, action: r => this._onParadeNormale(r) },
|
]
|
||||||
{ condition: RdDCombat.isParticuliere, action: r => this._onParadeParticuliere(r) },
|
});
|
||||||
{ condition: RdDCombat.isEchec, action: r => this._onParadeEchec(r) },
|
|
||||||
]
|
|
||||||
});
|
|
||||||
dialog.render(true);
|
dialog.render(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1003,7 +1079,7 @@ export class RdDCombat {
|
|||||||
show: {}
|
show: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.defender.isCreature()) {
|
if (this.defender.isCreatureEntite()) {
|
||||||
RdDItemCompetenceCreature.setRollDataCreature(defenderRoll);
|
RdDItemCompetenceCreature.setRollDataCreature(defenderRoll);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1052,19 +1128,20 @@ export class RdDCombat {
|
|||||||
let rollData = this._prepareEsquive(attackerRoll, esquive);
|
let rollData = this._prepareEsquive(attackerRoll, esquive);
|
||||||
|
|
||||||
const dialog = await RdDRoll.create(this.defender, rollData,
|
const dialog = await RdDRoll.create(this.defender, rollData,
|
||||||
{ html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' }, {
|
{ html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' },
|
||||||
name: 'jet-esquive',
|
{
|
||||||
label: 'Esquiver',
|
name: 'jet-esquive',
|
||||||
callbacks: [
|
label: 'Esquiver',
|
||||||
this.defender.createCallbackExperience(),
|
callbacks: [
|
||||||
this.defender.createCallbackAppelAuMoral(),
|
this.defender.createCallbackExperience(),
|
||||||
{ condition: r => !RdDCombat.isParticuliere(r), action: r => this.defender.incDecItemUse(esquive._id) },
|
this.defender.createCallbackAppelAuMoral(),
|
||||||
{ action: r => this.removeChatMessageActionsPasseArme(r.passeArme) },
|
{ condition: r => !RdDCombat.isParticuliere(r), action: r => this.defender.incDecItemUse(esquive._id) },
|
||||||
{ condition: RdDCombat.isReussite, action: r => this._onEsquiveNormale(r) },
|
{ action: r => this.removeChatMessageActionsPasseArme(r.passeArme) },
|
||||||
{ condition: RdDCombat.isParticuliere, action: r => this._onEsquiveParticuliere(r) },
|
{ condition: RdDCombat.isReussite, action: r => this._onEsquiveNormale(r) },
|
||||||
{ condition: RdDCombat.isEchec, action: r => this._onEsquiveEchec(r) },
|
{ condition: RdDCombat.isParticuliere, action: r => this._onEsquiveParticuliere(r) },
|
||||||
]
|
{ condition: RdDCombat.isEchec, action: r => this._onEsquiveEchec(r) },
|
||||||
});
|
]
|
||||||
|
});
|
||||||
dialog.render(true);
|
dialog.render(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1081,7 +1158,7 @@ export class RdDCombat {
|
|||||||
show: {}
|
show: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.defender.isCreature()) {
|
if (this.defender.isCreatureEntite()) {
|
||||||
RdDItemCompetenceCreature.setRollDataCreature(rollData);
|
RdDItemCompetenceCreature.setRollDataCreature(rollData);
|
||||||
}
|
}
|
||||||
return rollData;
|
return rollData;
|
||||||
@@ -1185,7 +1262,7 @@ export class RdDCombat {
|
|||||||
defenderRoll.show.recul = 'encaisse';
|
defenderRoll.show.recul = 'encaisse';
|
||||||
} else if (rollRecul.rolled.isETotal || this._isReculCauseChute(impact)) {
|
} else if (rollRecul.rolled.isETotal || this._isReculCauseChute(impact)) {
|
||||||
defenderRoll.show.recul = 'chute';
|
defenderRoll.show.recul = 'chute';
|
||||||
await this.defender.setStatusEffect("EFFECT.StatusProne", true);
|
await this.defender.setEffect(STATUSES.StatusProne, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
defenderRoll.show.recul = 'recul';
|
defenderRoll.show.recul = 'recul';
|
||||||
@@ -1227,7 +1304,7 @@ export class RdDCombat {
|
|||||||
attackerRoll.defenderTokenId = defenderTokenId;
|
attackerRoll.defenderTokenId = defenderTokenId;
|
||||||
|
|
||||||
await this.computeRecul(defenderRoll);
|
await this.computeRecul(defenderRoll);
|
||||||
this.defender.encaisserDommages(attackerRoll, this.attacker, defenderRoll);
|
this.defender.encaisserDommages(attackerRoll, this.attacker, defenderRoll?.show);
|
||||||
}
|
}
|
||||||
else { // envoi à un GM: les joueurs n'ont pas le droit de modifier les personnages qu'ils ne possèdent pas
|
else { // envoi à un GM: les joueurs n'ont pas le droit de modifier les personnages qu'ils ne possèdent pas
|
||||||
game.socket.emit(SYSTEM_SOCKET_ID, {
|
game.socket.emit(SYSTEM_SOCKET_ID, {
|
||||||
@@ -1242,35 +1319,6 @@ export class RdDCombat {
|
|||||||
this.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
|
this.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
/* retourne true si on peut continuer, false si on ne peut pas continuer */
|
|
||||||
async accorderEntite(when = 'avant-encaissement') {
|
|
||||||
if (when != game.settings.get(SYSTEM_RDD, "accorder-entite-cauchemar")
|
|
||||||
|| this.defender == undefined
|
|
||||||
|| !this.defender.isEntite([ENTITE_INCARNE])
|
|
||||||
|| this.defender.isEntiteAccordee(this.attacker)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
let rolled = await RdDResolutionTable.roll(this.attacker.getReveActuel(), - Number(this.defender.system.carac.niveau.value));
|
|
||||||
|
|
||||||
let message = {
|
|
||||||
content: "Jet de points actuels de rêve à " + rolled.finalLevel + RdDResolutionTable.explain(rolled) + "<br>",
|
|
||||||
whisper: ChatMessage.getWhisperRecipients(this.attacker.name)
|
|
||||||
};
|
|
||||||
|
|
||||||
if (rolled.isSuccess) {
|
|
||||||
await this.defender.setEntiteReveAccordee(this.attacker);
|
|
||||||
message.content += this.attacker.name + " s'est accordé avec " + this.defender.name;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
message.content += this.attacker.name + " n'est pas accordé avec " + this.defender.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
ChatMessage.create(message);
|
|
||||||
return rolled.isSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async displayActorCombatStatus(combat, actor) {
|
static async displayActorCombatStatus(combat, actor) {
|
||||||
let formData = {
|
let formData = {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
|
import { DialogChronologie } from "./dialog-chronologie.js";
|
||||||
import { DialogCreateSigneDraconique } from "./dialog-create-signedraconique.js";
|
import { DialogCreateSigneDraconique } from "./dialog-create-signedraconique.js";
|
||||||
import { DialogStress } from "./dialog-stress.js";
|
import { DialogStress } from "./dialog-stress.js";
|
||||||
import { Grammar } from "./grammar.js";
|
|
||||||
import { RdDItemCompetence } from "./item-competence.js";
|
import { RdDItemCompetence } from "./item-competence.js";
|
||||||
import { Misc } from "./misc.js";
|
import { Misc } from "./misc.js";
|
||||||
import { RdDCarac } from "./rdd-carac.js";
|
import { RdDCarac } from "./rdd-carac.js";
|
||||||
@@ -13,7 +13,7 @@ import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
|||||||
import { RdDRollResolutionTable } from "./rdd-roll-resolution-table.js";
|
import { RdDRollResolutionTable } from "./rdd-roll-resolution-table.js";
|
||||||
import { RdDRollTables } from "./rdd-rolltables.js";
|
import { RdDRollTables } from "./rdd-rolltables.js";
|
||||||
import { RdDUtility } from "./rdd-utility.js";
|
import { RdDUtility } from "./rdd-utility.js";
|
||||||
import { TMRRencontres } from "./tmr-rencontres.js";
|
import { CompendiumTableHelpers } from "./settings/system-compendiums.js";
|
||||||
import { TMRUtility } from "./tmr-utility.js";
|
import { TMRUtility } from "./tmr-utility.js";
|
||||||
|
|
||||||
const rddRollNumeric = /^(\d+)\s*([\+\-]?\d+)?\s*(s)?/;
|
const rddRollNumeric = /^(\d+)\s*([\+\-]?\d+)?\s*(s)?/;
|
||||||
@@ -22,55 +22,100 @@ const rddRollNumeric = /^(\d+)\s*([\+\-]?\d+)?\s*(s)?/;
|
|||||||
export class RdDCommands {
|
export class RdDCommands {
|
||||||
|
|
||||||
static init() {
|
static init() {
|
||||||
if (!game.system.rdd.commands) {
|
const rddCommands = new RdDCommands();
|
||||||
const rddCommands = new RdDCommands();
|
|
||||||
rddCommands.registerCommand({ path: ["/aide"], func: (content, msg, params) => rddCommands.help(msg), descr: "Affiche l'aide pour toutes les commandes" });
|
|
||||||
rddCommands.registerCommand({ path: ["/help"], func: (content, msg, params) => rddCommands.help(msg), descr: "Affiche l'aide pour toutes les commandes" });
|
|
||||||
rddCommands.registerCommand({ path: ["/table", "queues"], func: (content, msg, params) => RdDRollTables.getQueue(true), descr: "Tire une Queue de Dragon" });
|
|
||||||
rddCommands.registerCommand({ path: ["/table", "ideefixe"], func: (content, msg, params) => RdDRollTables.getIdeeFixe(true), descr: "Tire une Idée fixe" });
|
|
||||||
rddCommands.registerCommand({ path: ["/table", "desir"], func: (content, msg, params) => RdDRollTables.getDesirLancinant(true), descr: "Tire un Désir Lancinant" });
|
|
||||||
rddCommands.registerCommand({ path: ["/table", "ombre"], func: (content, msg, params) => RdDRollTables.getOmbre(true), descr: "Tire une Ombre de Dragon" });
|
|
||||||
rddCommands.registerCommand({ path: ["/table", "tetehr"], func: (content, msg, params) => RdDRollTables.getTeteHR(true), descr: "Tire une Tête de Dragon pour Hauts Revants" });
|
|
||||||
rddCommands.registerCommand({ path: ["/table", "tete"], func: (content, msg, params) => RdDRollTables.getTete(true), descr: "Tire une Tête de Dragon" });
|
|
||||||
rddCommands.registerCommand({ path: ["/table", "souffle"], func: (content, msg, params) => RdDRollTables.getSouffle(true), descr: " Tire un Souffle de Dragon" });
|
|
||||||
rddCommands.registerCommand({ path: ["/table", "comp"], func: (content, msg, params) => RdDRollTables.getCompetence(true), descr: "Tire une compétence au hasard" });
|
|
||||||
rddCommands.registerCommand({ path: ["/table", "tarot"], func: (content, msg, params) => RdDRollTables.getTarot(true), descr: "Tire une carte du Tarot Draconique" });
|
|
||||||
rddCommands.registerCommand({ path: ["/meteo"], func: (content, msg, params) => rddCommands.getMeteo(msg, params), descr: "Propose une météo marine" });
|
|
||||||
rddCommands.registerCommand({ path: ["/nom"], func: (content, msg, params) => RdDNameGen.getName(msg, params), descr: "Génère un nom aléatoire" });
|
|
||||||
|
|
||||||
rddCommands.registerCommand({
|
Hooks.on("chatMessage", (html, content, msg) => {
|
||||||
path: ["/tmra"], func: (content, msg, params) => rddCommands.getTMRAleatoire(msg, params),
|
if (content[0] == '/') {
|
||||||
descr: `Tire une case aléatoire des Terres médianes
|
let regExp = /(\S+)/g;
|
||||||
|
let commands = content.match(regExp);
|
||||||
|
if (rddCommands.processChatCommand(commands, content, msg)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
game.system.rdd.commands = rddCommands;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.commandsTable = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
_registerCommands() {
|
||||||
|
this.commandsTable = {}
|
||||||
|
this.registerCommand({ path: ["/aide"], func: (content, msg, params) => this.help(msg), descr: "Affiche l'aide pour toutes les commandes" });
|
||||||
|
this.registerCommand({ path: ["/help"], func: (content, msg, params) => this.help(msg), descr: "Affiche l'aide pour toutes les commandes" });
|
||||||
|
|
||||||
|
this.registerCommand({ path: ["/liste", "comp"], func: (content, msg, params) => RdDRollTables.getCompetence('liste'), descr: "Affiche la liste des compétences" });
|
||||||
|
|
||||||
|
this.registerCommand({ path: ["/table", "queue"], func: (content, msg, params) => RdDRollTables.getQueue('liste'), descr: "Affiche la table des Queues de Dragon" });
|
||||||
|
this.registerCommand({ path: ["/table", "ombre"], func: (content, msg, params) => RdDRollTables.getOmbre('liste'), descr: "Affiche la table des Ombres de Thanatos" });
|
||||||
|
this.registerCommand({ path: ["/table", "tetehr"], func: (content, msg, params) => RdDRollTables.getTeteHR('liste'), descr: "Affiche la table des Têtes de Dragon pour Hauts Revants" });
|
||||||
|
this.registerCommand({ path: ["/table", "tete"], func: (content, msg, params) => RdDRollTables.getTete('liste'), descr: "Affiche la table des Tête de Dragon pour tous" });
|
||||||
|
this.registerCommand({ path: ["/table", "souffle"], func: (content, msg, params) => RdDRollTables.getSouffle('liste'), descr: "Affiche la table des Souffles de Dragon" });
|
||||||
|
this.registerCommand({ path: ["/table", "tarot"], func: (content, msg, params) => RdDRollTables.getTarot('liste'), descr: "Affiche la table les cartes du Tarot Draconique" });
|
||||||
|
this.registerCommand({ path: ["/table", "ideefixe"], func: (content, msg, params) => RdDRollTables.getIdeeFixe('liste'), descr: "Affiche la table des Idées fixes" });
|
||||||
|
this.registerCommand({ path: ["/table", "desir"], func: (content, msg, params) => RdDRollTables.getDesirLancinant('liste'), descr: "Affiche la table des Désirs Lancinants" });
|
||||||
|
this.registerCommand({
|
||||||
|
path: ["/table", "rencontre"], func: (content, msg, params) => this.tableRencontres(msg, params),
|
||||||
|
descr: `Affiche la table des Rencontres
|
||||||
|
<br><strong>/table rencontre deso</strong> affiche la table des rencontres en Désolation
|
||||||
|
<br><strong>/table rencontre mauvaise</strong> affiche la table des mauvaises rencontres`
|
||||||
|
});
|
||||||
|
this.registerCommand({ path: ["/table", "milieu"], func: (content, msg, params) => this.tableMilieu(msg, params, 'liste'), descr: "Affiche la table des ressource naturelles pour un milieu donné" });
|
||||||
|
|
||||||
|
this.registerCommand({ path: ["/tirer", "comp"], func: (content, msg, params) => RdDRollTables.getCompetence('chat'), descr: "Tire une compétence au hasard" });
|
||||||
|
this.registerCommand({ path: ["/tirer", "queue"], func: (content, msg, params) => RdDRollTables.getQueue('chat'), descr: "Tire une Queue de Dragon" });
|
||||||
|
this.registerCommand({ path: ["/tirer", "ombre"], func: (content, msg, params) => RdDRollTables.getOmbre('chat'), descr: "Tire une Ombre de Thanatos" });
|
||||||
|
this.registerCommand({ path: ["/tirer", "tetehr"], func: (content, msg, params) => RdDRollTables.getTeteHR('chat'), descr: "Tire une Tête de Dragon pour Hauts Revants" });
|
||||||
|
this.registerCommand({ path: ["/tirer", "tete"], func: (content, msg, params) => RdDRollTables.getTete('chat'), descr: "Tire une Tête de Dragon" });
|
||||||
|
this.registerCommand({ path: ["/tirer", "souffle"], func: (content, msg, params) => RdDRollTables.getSouffle('chat'), descr: "Tire un Souffle de Dragon" });
|
||||||
|
this.registerCommand({ path: ["/tirer", "tarot"], func: (content, msg, params) => RdDRollTables.getTarot('chat'), descr: "Tire une carte du Tarot Draconique" });
|
||||||
|
this.registerCommand({ path: ["/tirer", "ideefixe"], func: (content, msg, params) => RdDRollTables.getIdeeFixe('chat'), descr: "Tire une Idée fixe" });
|
||||||
|
this.registerCommand({ path: ["/tirer", "desir"], func: (content, msg, params) => RdDRollTables.getDesirLancinant('chat'), descr: "Tire un Désir Lancinant" });
|
||||||
|
this.registerCommand({ path: ["/tirer", "rencontre"], func: (content, msg, params) => this.getRencontreTMR(params), descr: `Détermine une rencontre dans les TMR (synonyme de "/tmrr")` });
|
||||||
|
this.registerCommand({ path: ["/tirer", "milieu"], func: (content, msg, params) => this.tableMilieu(msg, params, 'chat'), descr: "Effectue un tirage dans la table desressource naturelles pour un milieu donné" });
|
||||||
|
|
||||||
|
this.registerCommand({ path: ["/meteo"], func: (content, msg, params) => this.getMeteo(msg, params), descr: "Propose une météo marine" });
|
||||||
|
this.registerCommand({ path: ["/nom"], func: (content, msg, params) => RdDNameGen.getName(msg, params), descr: "Génère un nom aléatoire" });
|
||||||
|
|
||||||
|
this.registerCommand({
|
||||||
|
path: ["/tmr"], func: (content, msg, params) => this.findTMR(msg, params),
|
||||||
|
descr: `Cherche où se trouve une case des Terres médianes
|
||||||
|
<br><strong>/tmr sord</strong> indique que la cité Sordide est en D13
|
||||||
|
<br><strong>/tmr foret</strong> donne la liste des TMR dont le nom contient "foret" (donc, toutes les forêts)`
|
||||||
|
});
|
||||||
|
this.registerCommand({
|
||||||
|
path: ["/tmra"], func: (content, msg, params) => this.getTMRAleatoire(msg, params),
|
||||||
|
descr: `Tire une case aléatoire des Terres médianes
|
||||||
<br><strong>/tmra forêt</strong> détermine une 'forêt' aléatoire
|
<br><strong>/tmra forêt</strong> détermine une 'forêt' aléatoire
|
||||||
<br><strong>/tmra</strong> détermine une case aléatoire dans toutes les TMR` });
|
<br><strong>/tmra</strong> détermine une case aléatoire dans toutes les TMR`
|
||||||
rddCommands.registerCommand({
|
});
|
||||||
path: ["/tmr"], func: (content, msg, params) => rddCommands.findTMR(msg, params),
|
this.registerCommand({
|
||||||
descr: `Cherche où se trouve une case des Terres médianes
|
path: ["/tmrr"], func: (content, msg, params) => this.getRencontreTMR(params),
|
||||||
<br><strong>/tmr? sordide</strong> indique que la cité Sordide est en D13
|
descr: `Détermine une rencontre dans les TMR
|
||||||
<br><strong>/tmr? foret</strong> donne la liste des TMR dont le nom contient "foret" (donc, toutes les forêts)` });
|
<br><strong>/tmrr forêt</strong> détermine une rencontre aléatoire en 'forêt'
|
||||||
rddCommands.registerCommand({
|
<br><strong>/tmrr mauvaise</strong> détermine une mauvaise rencontre aléatoire
|
||||||
path: ["/tmrr"], func: (content, msg, params) => rddCommands.getRencontreTMR(params),
|
<br><strong>/tmrr for 47</strong> détermine la rencontre en 'forêt' pour un jet de dé de 47`
|
||||||
descr: `Détermine une rencontre dans un type de case
|
});
|
||||||
<br><strong>/tmrr foret</strong> lance un d100 et détermine la rencontre correspondante en 'forêt'
|
|
||||||
<br><strong>/tmrr forêt 47</strong> détermine la rencontre en 'forêt' pour un jet de dé de 47`
|
|
||||||
});
|
|
||||||
|
|
||||||
rddCommands.registerCommand({
|
this.registerCommand({
|
||||||
path: ["/xp", "comp"], func: (content, msg, params) => rddCommands.getCoutXpComp(msg, params),
|
path: ["/xp", "comp"], func: (content, msg, params) => this.getCoutXpComp(msg, params),
|
||||||
descr: `Détermine le coût d'expérience pour augmenter une compétence. Exemples:
|
descr: `Détermine le coût d'expérience pour augmenter une compétence. Exemples:
|
||||||
<br>/xp comp -6 1: pour passer de -6 à +1
|
<br>/xp comp -6 1: pour passer de -6 à +1
|
||||||
<br>/xp comp +4: pour atteindre le niveau 4 (depuis +3)`
|
<br>/xp comp +4: pour atteindre le niveau 4 (depuis +3)`
|
||||||
});
|
});
|
||||||
|
|
||||||
rddCommands.registerCommand({
|
this.registerCommand({
|
||||||
path: ["/xp", "carac"], func: (content, msg, params) => rddCommands.getCoutXpCarac(msg, params),
|
path: ["/xp", "carac"], func: (content, msg, params) => this.getCoutXpCarac(msg, params),
|
||||||
descr: `Détermine le coût d'expérience pour augmenter une caractéristique. Exemples:
|
descr: `Détermine le coût d'expérience pour augmenter une caractéristique. Exemples:
|
||||||
<br>/xp carac 15: coût pour atteindre 15 (depuis 14)`
|
<br>/xp carac 15: coût pour atteindre 15 (depuis 14)`
|
||||||
});
|
});
|
||||||
|
|
||||||
rddCommands.registerCommand({
|
this.registerCommand({
|
||||||
path: ["/rdd"], func: (content, msg, params) => rddCommands.rollRdd(msg, params),
|
path: ["/rdd"], func: (content, msg, params) => this.rollRdd(msg, params),
|
||||||
descr: `Effectue un jet de dés dans la table de résolution. Exemples:
|
descr: `Effectue un jet de dés dans la table de résolution. Exemples:
|
||||||
<br><strong>/rdd</strong> ouvre la table de résolution
|
<br><strong>/rdd</strong> ouvre la table de résolution
|
||||||
<br><strong>/rdd 10 3</strong> effectue un jet 10 à +3
|
<br><strong>/rdd 10 3</strong> effectue un jet 10 à +3
|
||||||
<br><strong>/rdd 15 -2</strong> effectue un jet 15 à -2
|
<br><strong>/rdd 15 -2</strong> effectue un jet 15 à -2
|
||||||
@@ -78,47 +123,46 @@ export class RdDCommands {
|
|||||||
<br><strong>/rdd Vue Vigilance -2</strong> effectue un jet de Vue/Vigilance à -2 pour les tokens sélectionnés
|
<br><strong>/rdd Vue Vigilance -2</strong> effectue un jet de Vue/Vigilance à -2 pour les tokens sélectionnés
|
||||||
<br><strong>/rdd vol déser +2</strong> effectue un jet de Volonté/Survie en désert à +2 pour les tokens sélectionnés
|
<br><strong>/rdd vol déser +2</strong> effectue un jet de Volonté/Survie en désert à +2 pour les tokens sélectionnés
|
||||||
`
|
`
|
||||||
});
|
});
|
||||||
rddCommands.registerCommand({ path: ["/ddr"], func: (content, msg, params) => rddCommands.rollDeDraconique(msg), descr: "Lance un Dé Draconique" });
|
this.registerCommand({ path: ["/ddr"], func: (content, msg, params) => this.rollDeDraconique(msg), descr: "Lance un Dé Draconique" });
|
||||||
|
|
||||||
rddCommands.registerCommand({
|
this.registerCommand({
|
||||||
path: ["/payer"], func: (content, msg, params) => RdDUtility.afficherDemandePayer(params[0], params[1]),
|
path: ["/payer"], func: (content, msg, params) => RdDUtility.afficherDemandePayer(params[0], params[1]),
|
||||||
descr: `Permet de payer un montant. Exemples:
|
descr: `Demande aux joueurs de payer un montant. Exemples:
|
||||||
<br><strong>/payer 5s 10d</strong> permet d'envoyer un message pour payer 5 sols et 10 deniers
|
<br><strong>/payer 5s 10d</strong> permet d'envoyer un message pour payer 5 sols et 10 deniers
|
||||||
<br><strong>/payer 10d</strong> permet d'envoyer un message pour payer 10 deniers`
|
<br><strong>/payer 10d</strong> permet d'envoyer un message pour payer 10 deniers`
|
||||||
});
|
});
|
||||||
rddCommands.registerCommand({
|
this.registerCommand({
|
||||||
path: ["/astro"], func: (content, msg, params) => RdDUtility.afficherHeuresChanceMalchance(Misc.join(params, ' ')),
|
path: ["/astro"], func: (content, msg, params) => RdDUtility.afficherHeuresChanceMalchance(Misc.join(params, ' ')),
|
||||||
descr: `Affiche les heures de chance et de malchance selon l'heure de naissance donnée en argument. Exemples pour l'heure de la Lyre:
|
descr: `Affiche les heures de chance et de malchance selon l'heure de naissance donnée en argument. Exemples pour l'heure de la Lyre:
|
||||||
<br><strong>/astro 7</strong>
|
<br><strong>/astro 7</strong>
|
||||||
<br><strong>/astro Lyre</strong>
|
<br><strong>/astro Lyre</strong>
|
||||||
<br><strong>/astro Lyr</strong>`
|
<br><strong>/astro Lyr</strong>`
|
||||||
});
|
});
|
||||||
|
|
||||||
rddCommands.registerCommand({
|
this.registerCommand({
|
||||||
path: ["/signe", "+"], func: (content, msg, params) => rddCommands.creerSignesDraconiques(),
|
path: ["/signe", "+"], func: (content, msg, params) => this.creerSignesDraconiques(),
|
||||||
descr: "Crée un signe draconique et l'ajoute aux haut-rêvants choisis."
|
descr: "Crée un signe draconique et l'ajoute aux haut-rêvants choisis."
|
||||||
});
|
});
|
||||||
|
|
||||||
rddCommands.registerCommand({
|
this.registerCommand({
|
||||||
path: ["/signe", "-"], func: (content, msg, params) => rddCommands.supprimerSignesDraconiquesEphemeres(),
|
path: ["/signe", "-"], func: (content, msg, params) => this.supprimerSignesDraconiquesEphemeres(),
|
||||||
descr: "Supprime les signes draconiques éphémères"
|
descr: "Supprime les signes draconiques éphémères"
|
||||||
});
|
});
|
||||||
|
|
||||||
rddCommands.registerCommand({
|
this.registerCommand({
|
||||||
path: ["/stress"], func: (content, msg, params) => rddCommands.distribuerStress(params),
|
path: ["/stress"], func: (content, msg, params) => this.distribuerStress(params),
|
||||||
descr: `Distribue du stress aux personnages. Exemples:
|
descr: `Distribue du stress aux personnages. Exemples:
|
||||||
<br><strong>/stress</strong> : Ouvre une fenêtre pour donner du stress ou de l'expérience à un ensemble de personnages
|
<br><strong>/stress</strong> : Ouvre une fenêtre pour donner du stress ou de l'expérience à un ensemble de personnages
|
||||||
<br><strong>/stress 6</strong> : Distribue 6 points des Stress à tout les personnages joueurs, sans raison renseignée
|
<br><strong>/stress 6</strong> : Distribue 6 points des Stress à tout les personnages joueurs, sans raison renseignée
|
||||||
<br><strong>/stress 6 Tigre</strong> : Distribue 6 points des Stress à tout les personnages joueurs, à cause d'un Tigre (Vert)
|
<br><strong>/stress 6 Tigre</strong> : Distribue 6 points des Stress à tout les personnages joueurs, à cause d'un Tigre (Vert)
|
||||||
<br><strong>/stress 6 Glou Paulo</strong> : Distribue 6 points de Stress au personnage Paulon ou au personnage joueur Paulo, à cause d'un Glou`
|
<br><strong>/stress 6 Glou Paulo</strong> : Distribue 6 points de Stress au personnage Paulon ou au personnage joueur Paulo, à cause d'un Glou`
|
||||||
});
|
});
|
||||||
|
|
||||||
game.system.rdd.commands = rddCommands;
|
this.registerCommand({
|
||||||
}
|
path: ["/chrono"], func: (content, msg, params) => DialogChronologie.create(),
|
||||||
}
|
descr: `Enregistre une entrée de chronologie dans un article de journal`
|
||||||
constructor() {
|
});
|
||||||
this.commandsTable = {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -160,37 +204,50 @@ export class RdDCommands {
|
|||||||
processChatCommand(commandLine, content = '', msg = {}) {
|
processChatCommand(commandLine, content = '', msg = {}) {
|
||||||
// Setup new message's visibility
|
// Setup new message's visibility
|
||||||
let rollMode = game.settings.get("core", "rollMode");
|
let rollMode = game.settings.get("core", "rollMode");
|
||||||
if (["gmroll", "blindroll"].includes(rollMode)) msg["whisper"] = ChatMessage.getWhisperRecipients("GM");
|
if (["gmroll", "blindroll"].includes(rollMode)) {
|
||||||
if (rollMode === "blindroll") msg["blind"] = true;
|
msg["whisper"] = ChatMessage.getWhisperRecipients("GM");
|
||||||
|
}
|
||||||
|
if (rollMode === "blindroll"){
|
||||||
|
msg["blind"] = true;
|
||||||
|
}
|
||||||
msg["type"] = 0;
|
msg["type"] = 0;
|
||||||
|
|
||||||
|
if (!this.commandsTable) {
|
||||||
|
this._registerCommands();
|
||||||
|
}
|
||||||
|
|
||||||
let command = commandLine[0].toLowerCase();
|
let command = commandLine[0].toLowerCase();
|
||||||
let params = commandLine.slice(1);
|
if (this._isCommandHandled(command)) {
|
||||||
|
let params = commandLine.slice(1);
|
||||||
return this.process(command, params, content, msg);
|
this._processCommand(this.commandsTable, command, params, content, msg);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
process(command, params, content, msg) {
|
_isCommandHandled(command){
|
||||||
return this._processCommand(this.commandsTable, command, params, content, msg);
|
return this.commandsTable[command] != undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
_processCommand(commandsTable, name, params, content = '', msg = {}, path = "") {
|
async _processCommand(commandsTable, name, params, content = '', msg = {}, path = "") {
|
||||||
let command = commandsTable[name];
|
let command = commandsTable[name];
|
||||||
path = path + name + " ";
|
path = path + name + " ";
|
||||||
if (command && command.subTable) {
|
if (command && command.subTable) {
|
||||||
if (params[0]) {
|
if (params[0]) {
|
||||||
return this._processCommand(command.subTable, params[0], params.slice(1), content, msg, path)
|
this._processCommand(command.subTable, params[0], params.slice(1), content, msg, path)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.help(msg, command.subTable);
|
this.help(msg, command.subTable);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (command && command.func) {
|
if (command && command.func) {
|
||||||
const result = command.func(content, msg, params);
|
new Promise(async () => {
|
||||||
if (result == false) {
|
const result = await command.func(content, msg, params);
|
||||||
RdDCommands._chatAnswer(msg, command.descr);
|
if (result == false) {
|
||||||
}
|
RdDCommands._chatAnswer(msg, command.descr);
|
||||||
|
}
|
||||||
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -201,10 +258,10 @@ export class RdDCommands {
|
|||||||
this.help(msg, undefined);
|
this.help(msg, undefined);
|
||||||
}
|
}
|
||||||
async help(msg, table) {
|
async help(msg, table) {
|
||||||
let list = []
|
let commands = []
|
||||||
this._buildSubTableHelp(list, table || this.commandsTable);
|
this._buildSubTableHelp(commands, table ?? this.commandsTable);
|
||||||
|
|
||||||
let html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/settings/dialog-aide-commands.html", { commands: list });
|
let html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/settings/dialog-aide-commands.html", { commands: commands });
|
||||||
let d = new Dialog(
|
let d = new Dialog(
|
||||||
{
|
{
|
||||||
title: "Commandes disponibles dans le tchat",
|
title: "Commandes disponibles dans le tchat",
|
||||||
@@ -212,7 +269,7 @@ export class RdDCommands {
|
|||||||
buttons: {},
|
buttons: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
width: 600, height: 500,
|
width: 600, height: 600,
|
||||||
});
|
});
|
||||||
|
|
||||||
d.render(true);
|
d.render(true);
|
||||||
@@ -242,11 +299,9 @@ export class RdDCommands {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async getRencontreTMR(params) {
|
async getRencontreTMR(params) {
|
||||||
if (params.length == 1 || params.length == 2) {
|
if (params.length == 1 || params.length == 2) {
|
||||||
return TMRRencontres.rollRencontre(params[0], params[1])
|
return game.system.rdd.rencontresTMR.rollRencontre(params[0], params[1])
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -299,20 +354,20 @@ export class RdDCommands {
|
|||||||
show: { title: "Table de résolution" }
|
show: { title: "Table de résolution" }
|
||||||
};
|
};
|
||||||
await RdDResolutionTable.rollData(rollData);
|
await RdDResolutionTable.rollData(rollData);
|
||||||
RdDCommands._chatAnswer(msg, await RdDResolutionTable.buildRollDataHtml(rollData));
|
return RdDCommands._chatAnswer(msg, await RdDResolutionTable.buildRollDataHtml(rollData));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async rollDeDraconique(msg) {
|
async rollDeDraconique(msg) {
|
||||||
let ddr = await RdDDice.rollTotal("1dr + 7");
|
let ddr = await RdDDice.rollTotal("1dr + 7");
|
||||||
RdDCommands._chatAnswer(msg, `Lancer d'un Dé draconique: ${ddr}`);
|
return RdDCommands._chatAnswer(msg, `Lancer d'un Dé draconique: ${ddr}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getTMRAleatoire(msg, params) {
|
async getTMRAleatoire(msg, params) {
|
||||||
if (params.length < 2) {
|
if (params.length < 2) {
|
||||||
let type = params[0];
|
let type = params[0];
|
||||||
const tmr = await TMRUtility.getTMRAleatoire(type ? (it => it.type == type) : (it => true));
|
const tmr = await TMRUtility.getTMRAleatoire(type ? (it => it.type == type) : (it => true));
|
||||||
RdDCommands._chatAnswer(msg, `Case aléatoire: ${tmr.coord} - ${tmr.label}`);
|
return RdDCommands._chatAnswer(msg, `Case aléatoire: ${tmr.coord} - ${tmr.label}`);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return false;
|
return false;
|
||||||
@@ -320,20 +375,61 @@ export class RdDCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async findTMR(msg, params) {
|
async findTMR(msg, params) {
|
||||||
const search = Misc.join(params, ' ');
|
if (params && params.length > 0) {
|
||||||
const found = TMRUtility.findTMR(search);
|
const search = Misc.join(params, ' ');
|
||||||
if (found?.length > 0) {
|
const found = TMRUtility.findTMR(search);
|
||||||
return RdDCommands._chatAnswer(msg, `Les TMRs correspondant à '${search}' sont:` + Misc.join(found.map(it => `<br>${it.coord}: ${it.label}`)));
|
if (found?.length > 0) {
|
||||||
|
return RdDCommands._chatAnswer(msg, `Les TMRs correspondant à '${search}' sont:` + Misc.join(found.map(it => `<br>${it.coord}: ${it.label}`)));
|
||||||
|
}
|
||||||
|
return RdDCommands._chatAnswer(msg, 'Aucune TMR correspondant à ' + search);
|
||||||
}
|
}
|
||||||
return RdDCommands._chatAnswer(msg, 'Aucune TMR correspondant à ' + search);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async tableRencontres(msg, params) {
|
||||||
|
if (params && params.length > 0) {
|
||||||
|
const search = Misc.join(params, ' ');
|
||||||
|
const solvedTerrain = TMRUtility.findTMRLike(search);
|
||||||
|
if (solvedTerrain == undefined) {
|
||||||
|
return RdDCommands._chatAnswer(msg, 'Aucune TMR correspondant à ' + search);
|
||||||
|
}
|
||||||
|
return await game.system.rdd.rencontresTMR.chatTable(solvedTerrain);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async tableMilieu(msg, params, toChat) {
|
||||||
|
if (params && params.length > 0) {
|
||||||
|
const search = Misc.join(params, ' ');
|
||||||
|
const milieux = await game.system.rdd.environnement.findEnvironnementsLike(search);
|
||||||
|
if (milieux.length == 0) {
|
||||||
|
const tous = Object.values(await game.system.rdd.environnement.milieux());
|
||||||
|
return RdDCommands._chatAnswer(msg, `<strong>Aucun milieu correspondant à '${search}'.</strong>
|
||||||
|
<br>Milieux disponibles:
|
||||||
|
<br><ul class="chat-list"><li>${tous.reduce(Misc.joining('</li><li>'))}</li></ul>`);
|
||||||
|
}
|
||||||
|
if (milieux.length > 1) {
|
||||||
|
ui.notifications.warn(`<strong>Plusieurs milieux correspondent à '${search}'</strong>:
|
||||||
|
<br><ul class="chat-list"><li>${milieux.reduce(Misc.joining('</li><li>'))}</li></ul>`);
|
||||||
|
}
|
||||||
|
const tableName = `ressources en ${milieux.reduce(Misc.joining(', '))}`;
|
||||||
|
if (toChat == 'liste') {
|
||||||
|
return await game.system.rdd.environnement.searchToChatMessage(milieux, tableName);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const row = await game.system.rdd.environnement.getRandom(milieux, tableName);
|
||||||
|
await CompendiumTableHelpers.tableRowToChatMessage(row, 'Item');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getCoutXpComp(msg, params) {
|
getCoutXpComp(msg, params) {
|
||||||
if (params && (params.length == 1 || params.length == 2)) {
|
if (params && (params.length == 1 || params.length == 2)) {
|
||||||
let to = params.length == 1 ? Number(params[0]) : Number(params[1]);
|
let to = params.length == 1 ? Number(params[0]) : Number(params[1]);
|
||||||
let from = params.length == 1 ? to - 1 : Number(params[0]);
|
let from = params.length == 1 ? to - 1 : Number(params[0]);
|
||||||
RdDCommands._chatAnswer(msg, `Coût pour passer une compétence de ${from} à ${to}: ${RdDItemCompetence.getDeltaXp(from, to)}`);
|
return RdDCommands._chatAnswer(msg, `Coût pour passer une compétence de ${from} à ${to}: ${RdDItemCompetence.getDeltaXp(from, to)}`);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return false;
|
return false;
|
||||||
@@ -344,7 +440,7 @@ export class RdDCommands {
|
|||||||
getCoutXpCarac(msg, params) {
|
getCoutXpCarac(msg, params) {
|
||||||
if (params && params.length == 1) {
|
if (params && params.length == 1) {
|
||||||
let to = Number(params[0]);
|
let to = Number(params[0]);
|
||||||
RdDCommands._chatAnswer(msg, `Coût pour passer une caractéristique de ${to - 1} à ${to}: ${RdDCarac.getCaracXp(to)}`);
|
return RdDCommands._chatAnswer(msg, `Coût pour passer une caractéristique de ${to - 1} à ${to}: ${RdDCarac.getCaracXp(to)}`);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return false;
|
return false;
|
||||||
@@ -358,10 +454,9 @@ export class RdDCommands {
|
|||||||
|
|
||||||
async supprimerSignesDraconiquesEphemeres() {
|
async supprimerSignesDraconiquesEphemeres() {
|
||||||
game.actors.forEach(actor => {
|
game.actors.forEach(actor => {
|
||||||
const ephemeres = actor.items.find(item => item.type = 'signedraconique' && item.system.ephemere)
|
const ephemeres = actor.items.filter(item => item.type = 'signedraconique' && item.system.ephemere);
|
||||||
.map(item => item.id);
|
|
||||||
if (ephemeres.length > 0) {
|
if (ephemeres.length > 0) {
|
||||||
actor.deleteEmbeddedDocuments("Item", ephemeres);
|
actor.deleteEmbeddedDocuments("Item", ephemeres.map(item => item.id));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
@@ -405,5 +500,6 @@ export class RdDCommands {
|
|||||||
async getMeteo(msg, params) {
|
async getMeteo(msg, params) {
|
||||||
return await RdDMeteo.getMeteo();
|
return await RdDMeteo.getMeteo();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { SYSTEM_RDD } from "./constants.js";
|
import { SYSTEM_RDD } from "./constants.js";
|
||||||
import { Misc } from "./misc.js";
|
|
||||||
|
|
||||||
export class RddCompendiumOrganiser {
|
export class RddCompendiumOrganiser {
|
||||||
static init() {
|
static init() {
|
||||||
@@ -17,7 +16,7 @@ export class RddCompendiumOrganiser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static async setEntityTypeName(pack, element) {
|
static async setEntityTypeName(pack, element) {
|
||||||
const label = Misc.getEntityTypeLabel(await pack.getDocument(element.dataset.documentId));
|
const label = RddCompendiumOrganiser.getEntityTypeLabel(await pack.getDocument(element.dataset.documentId));
|
||||||
RddCompendiumOrganiser.insertEntityType(element, label);
|
RddCompendiumOrganiser.insertEntityType(element, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,4 +26,17 @@ export class RddCompendiumOrganiser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static getEntityTypeLabel(entity) {
|
||||||
|
const documentName = entity?.documentName
|
||||||
|
const type = entity?.type
|
||||||
|
if (documentName === 'Actor' || documentName === 'Item') {
|
||||||
|
const label = CONFIG[documentName]?.typeLabels?.[type] ?? type;
|
||||||
|
if (game.i18n.has(label)) {
|
||||||
|
return game.i18n.localize(label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
56
module/rdd-confirm.js
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import { Grammar } from "./grammar.js";
|
||||||
|
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
||||||
|
|
||||||
|
export class RdDConfirm {
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static confirmer(options, autresActions) {
|
||||||
|
options.bypass = options.bypass || !(options.settingConfirmer == undefined || ReglesOptionelles.isUsing(options.settingConfirmer));
|
||||||
|
if (options.bypass) {
|
||||||
|
options.onAction();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let buttons = {
|
||||||
|
"action": RdDConfirm._createButtonAction(options),
|
||||||
|
"cancel": RdDConfirm._createButtonCancel()
|
||||||
|
};
|
||||||
|
if (options.settingConfirmer) {
|
||||||
|
buttons = mergeObject(RdDConfirm._createButtonActionSave(options), buttons);
|
||||||
|
}
|
||||||
|
if (autresActions) {
|
||||||
|
buttons = mergeObject(autresActions, buttons);
|
||||||
|
}
|
||||||
|
const dialogDetails = {
|
||||||
|
title: options.title,
|
||||||
|
content: options.content,
|
||||||
|
default: "cancel",
|
||||||
|
buttons: buttons
|
||||||
|
};
|
||||||
|
new Dialog(dialogDetails, { width: 150 * Object.keys(buttons).length }).render(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static _createButtonCancel() {
|
||||||
|
return { icon: '<i class="fas fa-times"></i>', label: "Annuler" };
|
||||||
|
}
|
||||||
|
|
||||||
|
static _createButtonAction(options) {
|
||||||
|
return {
|
||||||
|
icon: '<i class="fas fa-check"></i>',
|
||||||
|
label: options.buttonLabel,
|
||||||
|
callback: () => options.onAction()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static _createButtonActionSave(options) {
|
||||||
|
return {
|
||||||
|
"actionSave": {
|
||||||
|
icon: '<i class="fas fa-user-check"></i>',
|
||||||
|
label: options.buttonLabel + "<br>et ne plus demander",
|
||||||
|
callback: () => {
|
||||||
|
ReglesOptionelles.set(options.settingConfirmer, false);
|
||||||
|
options.onAction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -132,21 +132,21 @@ export class RdDDice {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async rollTotal(formula, options = { showDice: HIDE_DICE }) {
|
||||||
|
return (await RdDDice.roll(formula, options)).total;
|
||||||
|
}
|
||||||
|
|
||||||
static async roll(formula, options = { showDice: SHOW_DICE, rollMode: undefined }) {
|
static async roll(formula, options = { showDice: SHOW_DICE, rollMode: undefined }) {
|
||||||
const roll = new Roll(formula);
|
const roll = new Roll(RdDDice._formulaOrFake(formula, options));
|
||||||
await roll.evaluate({ async: true });
|
await roll.evaluate({ async: true });
|
||||||
if (options.showDice != HIDE_DICE) {
|
await this.showDiceSoNice(roll, options);
|
||||||
await this.showDiceSoNice(roll, options.rollMode ?? game.settings.get("core", "rollMode"));
|
|
||||||
}
|
|
||||||
return roll;
|
return roll;
|
||||||
}
|
}
|
||||||
|
|
||||||
static async rollTotal(formula, options = { showDice: HIDE_DICE}) {
|
|
||||||
const roll = await RdDDice.roll(formula, options);
|
|
||||||
return roll.total;
|
|
||||||
}
|
|
||||||
|
|
||||||
static async rollOneOf(array) {
|
static async rollOneOf(array) {
|
||||||
|
if (array == undefined || array.length == 0) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
const roll = await RdDDice.rollTotal(`1d${array.length}`);
|
const roll = await RdDDice.rollTotal(`1d${array.length}`);
|
||||||
return array[roll - 1];
|
return array[roll - 1];
|
||||||
}
|
}
|
||||||
@@ -160,27 +160,106 @@ export class RdDDice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async showDiceSoNice(roll, rollMode) {
|
static async showDiceSoNice(roll, options) {
|
||||||
if (game.modules.get("dice-so-nice")?.active) {
|
if (options.showDice == HIDE_DICE || !game.modules.get("dice-so-nice")?.active || !game.dice3d) {
|
||||||
if (game.dice3d) {
|
return;
|
||||||
let whisper = null;
|
}
|
||||||
let blind = false;
|
|
||||||
rollMode = rollMode ?? game.settings.get("core", "rollMode");
|
let { whisper, blind } = RdDDice._getWhisperBlind(options);
|
||||||
switch (rollMode) {
|
if (options.forceDiceResult?.total) {
|
||||||
case "blindroll": //GM only
|
let terms = await RdDDice._getForcedTerms(options);
|
||||||
blind = true;
|
if (terms) {
|
||||||
case "gmroll": //GM + rolling player
|
await game.dice3d.show({ throws: [{ dice: terms }] })
|
||||||
whisper = ChatUtility.getUsers(user => user.isGM);
|
return;
|
||||||
break;
|
|
||||||
case "roll": //everybody
|
|
||||||
whisper = ChatUtility.getUsers(user => user.active);
|
|
||||||
break;
|
|
||||||
case "selfroll":
|
|
||||||
whisper = [game.user.id];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
await game.dice3d.showForRoll(roll, game.user, true, whisper, blind);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
await game.dice3d.showForRoll(roll, game.user, true, whisper, blind);
|
||||||
|
}
|
||||||
|
|
||||||
|
static _formulaOrFake(formula, options) {
|
||||||
|
if (options?.forceDiceResult?.total) {
|
||||||
|
options.forceDiceResult.formula = formula;
|
||||||
|
return options.forceDiceResult.total.toString()
|
||||||
|
}
|
||||||
|
return formula;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async _getForcedTerms(options) {
|
||||||
|
const total = options.forceDiceResult.total;
|
||||||
|
switch (options.forceDiceResult.formula) {
|
||||||
|
case '1d100':
|
||||||
|
return terms1d100(total);
|
||||||
|
case "2d10":
|
||||||
|
return await terms2d10(total);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
|
||||||
|
function terms1d100(total) {
|
||||||
|
const unites = total % 10;
|
||||||
|
const dizaines = Math.floor(total / 10);
|
||||||
|
return [{
|
||||||
|
resultLabel: dizaines * 10,
|
||||||
|
d100Result: total,
|
||||||
|
result: dizaines,
|
||||||
|
type: "d100",
|
||||||
|
vectors: [],
|
||||||
|
options: {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
resultLabel: unites,
|
||||||
|
d100Result: total,
|
||||||
|
result: unites,
|
||||||
|
type: "d10",
|
||||||
|
vectors: [],
|
||||||
|
options: {}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
async function terms2d10(total) {
|
||||||
|
if (total>20 || total<2) { return undefined }
|
||||||
|
let first = await RdDDice.d10();
|
||||||
|
let second = Math.min(total-first, 10);
|
||||||
|
first = Math.max(first, total-second);
|
||||||
|
return [{
|
||||||
|
resultLabel:first,
|
||||||
|
result: first,
|
||||||
|
type: "d10",
|
||||||
|
vectors: [],
|
||||||
|
options: {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
resultLabel: second,
|
||||||
|
result: second,
|
||||||
|
type: "d10",
|
||||||
|
vectors: [],
|
||||||
|
options: {}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static async d10() {
|
||||||
|
let roll = new Roll('1d10');
|
||||||
|
await roll.evaluate({ async: true });
|
||||||
|
return roll.total;
|
||||||
|
}
|
||||||
|
|
||||||
|
static _getWhisperBlind(options) {
|
||||||
|
let whisper = undefined;
|
||||||
|
let blind = false;
|
||||||
|
let rollMode = options.rollMode ?? game.settings.get("core", "rollMode");
|
||||||
|
switch (rollMode) {
|
||||||
|
case "blindroll": //GM only
|
||||||
|
blind = true;
|
||||||
|
case "gmroll": //GM + rolling player
|
||||||
|
whisper = ChatUtility.getUsers(user => user.isGM);
|
||||||
|
break;
|
||||||
|
case "roll": //everybody
|
||||||
|
whisper = ChatUtility.getUsers(user => user.active);
|
||||||
|
break;
|
||||||
|
case "selfroll":
|
||||||
|
whisper = [game.user.id];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return { whisper, blind };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,76 +1,75 @@
|
|||||||
import { RdDUtility } from "./rdd-utility.js";
|
import { RdDUtility } from "./rdd-utility.js";
|
||||||
import { RdDCalendrier } from "./rdd-calendrier.js";
|
import { RdDCalendrier } from "./rdd-calendrier.js";
|
||||||
|
import { Grammar } from "./grammar.js";
|
||||||
|
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
export class RdDHerbes extends Item {
|
export class RdDHerbes extends Item {
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static isHerbeSoin( botaniqueItem ) {
|
static async initializeHerbes() {
|
||||||
return botaniqueItem.categorie == 'Soin';
|
this.herbesSoins = await RdDHerbes.listCategorieHerbes('Soin');
|
||||||
}
|
this.herbesRepos = await RdDHerbes.listCategorieHerbes('Repos');
|
||||||
/* -------------------------------------------- */
|
|
||||||
static isHerbeRepos( botaniqueItem ) {
|
|
||||||
return botaniqueItem.categorie == 'Repos';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
static async listCategorieHerbes(categorie) {
|
||||||
static async initializeHerbes( ) {
|
const herbes = await SystemCompendiums.getWorldOrCompendiumItems('herbe', 'faune-flore-mineraux');
|
||||||
this.herbesSoins = await RdDUtility.loadCompendium('foundryvtt-reve-de-dragon.botanique', item => this.isHerbeSoin(item));
|
return herbes.filter(it => Grammar.equalsInsensitive(it.system.categorie, categorie));
|
||||||
this.herbesRepos = await RdDUtility.loadCompendium('foundryvtt-reve-de-dragon.botanique', item => this.isHerbeRepos(item));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static buildHerbesList(listeHerbes, max) {
|
static buildHerbesList(listeHerbes, max) {
|
||||||
let list = {}
|
let list = {}
|
||||||
for ( let herbe of listeHerbes) {
|
for (let herbe of listeHerbes) {
|
||||||
let brins = max - herbe.system.niveau;
|
let brins = max - herbe.system.niveau;
|
||||||
list[herbe.system.name] = `${herbe.system.name} (Bonus: ${herbe.system.niveau}, Brins: ${brins})`;
|
list[herbe.name] = `${herbe.name} (Bonus: ${herbe.system.niveau}, Brins: ${brins})`;
|
||||||
}
|
}
|
||||||
list['Autre'] = 'Autre (Bonus: variable, Brins: variable)'
|
list['Autre'] = 'Autre (Bonus: variable, Brins: variable)'
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static updatePotionData( formData ) {
|
static async updatePotionData(formData) {
|
||||||
formData.herbesSoins = this.buildHerbesList(this.herbesSoins, 12);
|
formData.isSoins = formData.system.categorie.includes('Soin');
|
||||||
formData.herbesRepos = this.buildHerbesList(this.herbesRepos, 7);
|
formData.isRepos = formData.system.categorie.includes('Repos');
|
||||||
|
if (formData.isSoins) {
|
||||||
|
RdDHerbes.calculBonusHerbe(formData, this.herbesSoins, 12);
|
||||||
|
}
|
||||||
|
if (formData.isRepos) {
|
||||||
|
RdDHerbes.calculBonusHerbe(formData, this.herbesRepos, 7);
|
||||||
|
}
|
||||||
|
formData.herbesSoins = RdDHerbes.buildHerbesList(this.herbesSoins, 12);
|
||||||
|
formData.herbesRepos = RdDHerbes.buildHerbesList(this.herbesRepos, 7);
|
||||||
formData.jourMoisOptions = RdDCalendrier.buildJoursMois();
|
formData.jourMoisOptions = RdDCalendrier.buildJoursMois();
|
||||||
formData.dateActuelle = game.system.rdd.calendrier.getDateFromIndex();
|
formData.dateActuelle = game.system.rdd.calendrier.getDateFromIndex();
|
||||||
formData.splitDate = game.system.rdd.calendrier.getNumericDateFromIndex(formData.system.prdate);
|
formData.splitDate = game.system.rdd.calendrier.getDayMonthFromIndex(formData.system.prdate);
|
||||||
|
|
||||||
if (formData.system.categorie.includes('Soin') ) {
|
|
||||||
formData.isHerbe = true;
|
|
||||||
this.computeHerbeBonus(formData, this.herbesSoins, 12);
|
|
||||||
} else if (formData.system.categorie.includes('Repos')) {
|
|
||||||
formData.isRepos = true;
|
|
||||||
this.computeHerbeBonus(formData, this.herbesRepos, 7);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static calculePuissancePotion( potion ) {
|
static calculPuissancePotion(potion) {
|
||||||
return potion.system.herbebonus * potion.system.pr;
|
return potion.system.herbebonus * potion.system.pr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static calculePointsRepos( potion ) {
|
static calculPointsRepos(potion) {
|
||||||
return potion.system.herbebonus * potion.system.pr;
|
return potion.system.herbebonus * potion.system.pr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static calculePointsGuerison( potion ){
|
static calculPointsGuerison(potion) {
|
||||||
return potion.system.herbebonus * potion.system.pr;
|
return potion.system.herbebonus * potion.system.pr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static computeHerbeBonus( formData, herbesList, max) {
|
static calculBonusHerbe(formData, herbesList, max) {
|
||||||
if ( Number(formData.system.herbebrins) ) {
|
if (Number(formData.system.herbebrins)) {
|
||||||
let herbe = herbesList.find(item => item.name.toLowerCase() == formData.system.herbe.toLowerCase() );
|
let herbe = herbesList.find(item => item.name.toLowerCase() == formData.system.herbe.toLowerCase());
|
||||||
if( herbe ) {
|
if (herbe) {
|
||||||
let brinsBase = max - herbe.system.niveau;
|
const brinsRequis = max - herbe.system.niveau;
|
||||||
formData.system.herbebonus = Math.max(herbe.system.niveau - Math.max(brinsBase - formData.system.herbebrins, 0), 0);
|
const brinsManquants = Math.max(brinsRequis - formData.system.herbebrins, 0);
|
||||||
|
formData.system.herbebonus = Math.max(herbe.system.niveau - brinsManquants, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2,14 +2,18 @@ import { Misc } from "./misc.js";
|
|||||||
|
|
||||||
export class RdDHotbar {
|
export class RdDHotbar {
|
||||||
|
|
||||||
static async createMacro(item, command) {
|
static async addToHotbar(item, slot) {
|
||||||
let macro = await Macro.create({
|
let command = `game.system.rdd.RdDHotbar.rollMacro("${item.name}", "${item.type}");`;
|
||||||
name: item.name,
|
let macro = game.macros.contents.find(m => (m.name === item.name) && (m.command === command));
|
||||||
type: "script",
|
if (!macro) {
|
||||||
img: item.img,
|
macro = await Macro.create({
|
||||||
command: command
|
name: item.name,
|
||||||
}, { displaySheet: false })
|
type: "script",
|
||||||
return macro
|
img: item.img,
|
||||||
|
command: command
|
||||||
|
}, { displaySheet: false })
|
||||||
|
}
|
||||||
|
await game.user.assignHotbarMacro(macro, slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,69 +36,33 @@ export class RdDHotbar {
|
|||||||
if (!item || (item.type != "arme" && item.type != "competence")) {
|
if (!item || (item.type != "arme" && item.type != "competence")) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
let command = `game.system.rdd.RdDHotbar.rollMacro("${item.name}", "${item.type}");`;
|
this.addToHotbar(item, slot)
|
||||||
let macro = game.macros.contents.find(m => (m.name === item.name) && (m.command === command));
|
|
||||||
if (!macro) {
|
|
||||||
macro = this.createMacro(item, command)
|
|
||||||
}
|
|
||||||
game.user.assignHotbarMacro(macro, slot);
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a macro to open the actor sheet of the actor dropped on the hotbar
|
return true
|
||||||
/*else if (documentData.type == "Actor") {
|
})
|
||||||
let actor = game.actors.get(documentData.id);
|
}
|
||||||
let command = `game.actors.get("${documentData.id}").sheet.render(true)`
|
|
||||||
let macro = game.macros.contents.find(m => (m.name === actor.name) && (m.command === command));
|
|
||||||
if (!macro) {
|
|
||||||
macro = await Macro.create({
|
|
||||||
name: actor.name,
|
|
||||||
type: "script",
|
|
||||||
img: actor.img,
|
|
||||||
command: command
|
|
||||||
}, { displaySheet: false })
|
|
||||||
game.user.assignHotbarMacro(macro, slot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a macro to open the journal sheet of the journal dropped on the hotbar
|
|
||||||
else if (documentData.type == "JournalEntry") {
|
|
||||||
let journal = fromUuidSync(documentData.uuid)
|
|
||||||
let command = `game.journal.get("${documentData.id}").sheet.render(true)`
|
|
||||||
let macro = game.macros.contents.find(m => (m.name === journal.name) && (m.command === command));
|
|
||||||
if (!macro) {
|
|
||||||
macro = await Macro.create({
|
|
||||||
name: journal.name,
|
|
||||||
type: "script",
|
|
||||||
img: "systems/foundryvtt-reve-de-dragon/icons/templates/icone_parchement_vierge.webp",
|
|
||||||
command: command
|
|
||||||
}, { displaySheet: false })
|
|
||||||
game.user.assignHotbarMacro(macro, slot);
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Roll macro */
|
/** Roll macro */
|
||||||
static rollMacro(itemName, itemType, bypassData) {
|
static rollMacro(itemName, itemType, bypassData) {
|
||||||
const speaker = ChatMessage.getSpeaker();
|
const speaker = ChatMessage.getSpeaker();
|
||||||
let actor;
|
let actor;
|
||||||
if (speaker.token) actor = game.actors.tokens[speaker.token];
|
if (speaker.token) actor = game.actors.tokens[speaker.token];
|
||||||
if (!actor) actor = game.actors.get(speaker.actor);
|
if (!actor) actor = game.actors.get(speaker.actor);
|
||||||
|
|
||||||
let item = actor?.items.find(it => it.name === itemName && it.type == itemType) ?? undefined;
|
let item = actor?.items.find(it => it.name === itemName && it.type == itemType) ?? undefined;
|
||||||
if (!item) {
|
if (!item) {
|
||||||
return ui.notifications.warn(`Impossible de trouver l'objet de cette macro`);
|
return ui.notifications.warn(`Impossible de trouver l'objet de cette macro`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trigger the item roll
|
||||||
|
switch (item.type) {
|
||||||
|
case "arme":
|
||||||
|
return actor.rollArme(item);
|
||||||
|
case "competence":
|
||||||
|
return actor.rollCompetence(itemName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trigger the item roll
|
|
||||||
switch (item.type) {
|
|
||||||
case "arme":
|
|
||||||
return actor.rollArme(item);
|
|
||||||
case "competence":
|
|
||||||
return actor.rollCompetence(itemName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,10 +23,9 @@ import { RdDTokenHud } from "./rdd-token-hud.js";
|
|||||||
import { RdDCommands } from "./rdd-commands.js";
|
import { RdDCommands } from "./rdd-commands.js";
|
||||||
import { RdDCombatManager, RdDCombat } from "./rdd-combat.js";
|
import { RdDCombatManager, RdDCombat } from "./rdd-combat.js";
|
||||||
import { ChatUtility } from "./chat-utility.js";
|
import { ChatUtility } from "./chat-utility.js";
|
||||||
import { StatusEffects } from "./status-effects.js";
|
import { StatusEffects } from "./settings/status-effects.js";
|
||||||
import { RddCompendiumOrganiser } from "./rdd-compendium-organiser.js";
|
import { RddCompendiumOrganiser } from "./rdd-compendium-organiser.js";
|
||||||
import { ReglesOptionelles } from "./regles-optionelles.js";
|
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
||||||
import { TMRRencontres } from "./tmr-rencontres.js";
|
|
||||||
import { RdDHotbar } from "./rdd-hotbar-drop.js"
|
import { RdDHotbar } from "./rdd-hotbar-drop.js"
|
||||||
import { EffetsDraconiques } from "./tmr/effets-draconiques.js";
|
import { EffetsDraconiques } from "./tmr/effets-draconiques.js";
|
||||||
import { RdDHerbes } from "./rdd-herbes.js";
|
import { RdDHerbes } from "./rdd-herbes.js";
|
||||||
@@ -35,6 +34,16 @@ import { RdDDice } from "./rdd-dice.js";
|
|||||||
import { RdDPossession } from "./rdd-possession.js";
|
import { RdDPossession } from "./rdd-possession.js";
|
||||||
import { RdDSigneDraconiqueItemSheet } from "./item-signedraconique-sheet.js";
|
import { RdDSigneDraconiqueItemSheet } from "./item-signedraconique-sheet.js";
|
||||||
import { Misc } from "./misc.js";
|
import { Misc } from "./misc.js";
|
||||||
|
import { Migrations } from './migrations.js';
|
||||||
|
import { DialogChronologie } from "./dialog-chronologie.js";
|
||||||
|
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
||||||
|
import { RdDRencontreItemSheet } from "./item-rencontre-sheet.js";
|
||||||
|
import { TMRRencontres } from "./tmr-rencontres.js";
|
||||||
|
import { RdDHerbeItemSheet } from "./item-herbe-sheet.js";
|
||||||
|
import { Environnement } from "./environnement.js";
|
||||||
|
import { RdDIngredientItemSheet } from "./item-ingredient-sheet.js";
|
||||||
|
import { RdDFauneItemSheet } from "./item-faune-sheet.js";
|
||||||
|
import { RdDConteneurItemSheet } from "./item-conteneur-sheet.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/* Foundry VTT Initialization */
|
/* Foundry VTT Initialization */
|
||||||
@@ -76,7 +85,7 @@ Hooks.once("init", async function () {
|
|||||||
name: "calendrier",
|
name: "calendrier",
|
||||||
scope: "world",
|
scope: "world",
|
||||||
config: false,
|
config: false,
|
||||||
default: RdDCalendrier.getCalendrier(0),
|
default: RdDCalendrier.createCalendrierInitial(),
|
||||||
type: Object
|
type: Object
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -106,6 +115,8 @@ Hooks.once("init", async function () {
|
|||||||
default: RdDCalendrier.createCalendrierPos(),
|
default: RdDCalendrier.createCalendrierPos(),
|
||||||
type: Object
|
type: Object
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
game.settings.register(SYSTEM_RDD, "supprimer-dialogues-combat-chat", {
|
game.settings.register(SYSTEM_RDD, "supprimer-dialogues-combat-chat", {
|
||||||
name: "Supprimer les dialogues de combat",
|
name: "Supprimer les dialogues de combat",
|
||||||
@@ -147,13 +158,16 @@ Hooks.once("init", async function () {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
game.socket.on(SYSTEM_SOCKET_ID, sockmsg => {
|
game.socket.on(SYSTEM_SOCKET_ID, async (sockmsg) => {
|
||||||
console.log(">>>>> MSG RECV", sockmsg);
|
console.log(">>>>> MSG RECV", sockmsg);
|
||||||
|
try {
|
||||||
RdDUtility.onSocketMessage(sockmsg);
|
RdDUtility.onSocketMessage(sockmsg);
|
||||||
RdDCombat.onSocketMessage(sockmsg);
|
RdDCombat.onSocketMessage(sockmsg);
|
||||||
ChatUtility.onSocketMessage(sockmsg);
|
ChatUtility.onSocketMessage(sockmsg);
|
||||||
RdDActor.onSocketMessage(sockmsg);
|
RdDActor.onSocketMessage(sockmsg);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('game.socket.on(SYSTEM_SOCKET_ID) Exception: ', sockmsg, ' => ', e)
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -175,19 +189,30 @@ Hooks.once("init", async function () {
|
|||||||
Actors.registerSheet(SYSTEM_RDD, RdDActorVehiculeSheet, { types: ["vehicule"], makeDefault: true });
|
Actors.registerSheet(SYSTEM_RDD, RdDActorVehiculeSheet, { types: ["vehicule"], makeDefault: true });
|
||||||
Actors.registerSheet(SYSTEM_RDD, RdDActorEntiteSheet, { types: ["entite"], makeDefault: true });
|
Actors.registerSheet(SYSTEM_RDD, RdDActorEntiteSheet, { types: ["entite"], makeDefault: true });
|
||||||
Items.unregisterSheet("core", ItemSheet);
|
Items.unregisterSheet("core", ItemSheet);
|
||||||
Items.registerSheet(SYSTEM_RDD, RdDSigneDraconiqueItemSheet, {
|
|
||||||
label: "Signe draconique",
|
RdDItemSheet.register(RdDSigneDraconiqueItemSheet);
|
||||||
types: ["signedraconique"],
|
RdDItemSheet.register(RdDRencontreItemSheet);
|
||||||
makeDefault: true
|
RdDItemSheet.register(RdDConteneurItemSheet);
|
||||||
});
|
RdDItemSheet.register(RdDHerbeItemSheet);
|
||||||
|
RdDItemSheet.register(RdDFauneItemSheet);
|
||||||
|
RdDItemSheet.register(RdDIngredientItemSheet);
|
||||||
|
|
||||||
Items.registerSheet(SYSTEM_RDD, RdDItemSheet, {
|
Items.registerSheet(SYSTEM_RDD, RdDItemSheet, {
|
||||||
types: ["arme", "armure", "objet", "arme", "armure", "conteneur", "competence", "sort", "herbe", "ingredient", "livre", "potion", "munition", "rencontresTMR", "queue", "ombre", "souffle",
|
types: [
|
||||||
"tete", "competencecreature", "tarot", "monnaie", "nombreastral", "tache", "meditation", "casetmr", "recettealchimique", "gemme",
|
"competence", "competencecreature",
|
||||||
"musique", "chant", "danse", "jeu", "recettecuisine", "maladie", "poison", "oeuvre", "nourritureboisson", "possession"], makeDefault: true
|
"recettealchimique", "musique", "chant", "danse", "jeu", "recettecuisine", "oeuvre",
|
||||||
|
"objet", "arme", "armure", "livre", "potion", "munition",
|
||||||
|
"monnaie", "nourritureboisson", "gemme",
|
||||||
|
"meditation", "queue", "ombre", "souffle", "tete", "casetmr", "sort", "sortreserve",
|
||||||
|
"nombreastral", "tache", "maladie", "poison", "possession",
|
||||||
|
"tarot", "extraitpoetique"
|
||||||
|
], makeDefault: true
|
||||||
});
|
});
|
||||||
CONFIG.Combat.documentClass = RdDCombatManager;
|
CONFIG.Combat.documentClass = RdDCombatManager;
|
||||||
|
|
||||||
// préparation des différents modules
|
// préparation des différents modules
|
||||||
|
SystemCompendiums.init();
|
||||||
|
DialogChronologie.init();
|
||||||
ReglesOptionelles.init();
|
ReglesOptionelles.init();
|
||||||
RdDUtility.init();
|
RdDUtility.init();
|
||||||
RdDDice.init();
|
RdDDice.init();
|
||||||
@@ -199,9 +224,10 @@ Hooks.once("init", async function () {
|
|||||||
RddCompendiumOrganiser.init();
|
RddCompendiumOrganiser.init();
|
||||||
EffetsDraconiques.init()
|
EffetsDraconiques.init()
|
||||||
TMRUtility.init();
|
TMRUtility.init();
|
||||||
TMRRencontres.init();
|
|
||||||
RdDHotbar.initDropbar();
|
RdDHotbar.initDropbar();
|
||||||
RdDPossession.init();
|
RdDPossession.init();
|
||||||
|
TMRRencontres.init();
|
||||||
|
Environnement.init();
|
||||||
});
|
});
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -219,8 +245,8 @@ function messageDeBienvenue() {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
// Register world usage statistics
|
// Register world usage statistics
|
||||||
function registerUsageCount( registerKey ) {
|
function registerUsageCount(registerKey) {
|
||||||
if ( game.user.isGM ) {
|
if (game.user.isGM) {
|
||||||
game.settings.register("world", "world-key", {
|
game.settings.register("world", "world-key", {
|
||||||
name: "Unique world key",
|
name: "Unique world key",
|
||||||
scope: "world",
|
scope: "world",
|
||||||
@@ -230,9 +256,9 @@ function registerUsageCount( registerKey ) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let worldKey = game.settings.get("world", "world-key")
|
let worldKey = game.settings.get("world", "world-key")
|
||||||
if ( worldKey == undefined || worldKey == "" ) {
|
if (worldKey == undefined || worldKey == "") {
|
||||||
worldKey = randomID(32)
|
worldKey = randomID(32)
|
||||||
game.settings.set("world", "world-key", worldKey )
|
game.settings.set("world", "world-key", worldKey)
|
||||||
}
|
}
|
||||||
let regURL = `https://www.uberwald.me/fvtt_appcount/count.php?name="${registerKey}"&worldKey="${worldKey}"&version="${game.release.generation}.${game.release.build}"&system="${game.system.id}"&systemversion="${game.system.version}"`
|
let regURL = `https://www.uberwald.me/fvtt_appcount/count.php?name="${registerKey}"&worldKey="${worldKey}"&version="${game.release.generation}.${game.release.build}"&system="${game.system.id}"&systemversion="${game.system.version}"`
|
||||||
$.ajax(regURL)
|
$.ajax(regURL)
|
||||||
@@ -245,6 +271,9 @@ function registerUsageCount( registerKey ) {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
Hooks.once("ready", async function () {
|
Hooks.once("ready", async function () {
|
||||||
await migrationPngWebp_1_5_34()
|
await migrationPngWebp_1_5_34()
|
||||||
|
if (Misc.isUniqueConnectedGM()) {
|
||||||
|
new Migrations().migrate();
|
||||||
|
}
|
||||||
|
|
||||||
StatusEffects.onReady();
|
StatusEffects.onReady();
|
||||||
RdDHerbes.initializeHerbes();
|
RdDHerbes.initializeHerbes();
|
||||||
@@ -269,7 +298,7 @@ Hooks.once("ready", async function () {
|
|||||||
}
|
}
|
||||||
if (Misc.isUniqueConnectedGM()) {
|
if (Misc.isUniqueConnectedGM()) {
|
||||||
messageDeBienvenue();
|
messageDeBienvenue();
|
||||||
registerUsageCount( SYSTEM_RDD );
|
registerUsageCount(SYSTEM_RDD);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -314,17 +343,3 @@ async function migrationPngWebp_1_5_34() {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
Hooks.once('diceSoNiceReady', (dice3d) => RdDDice.diceSoNiceReady(dice3d));
|
Hooks.once('diceSoNiceReady', (dice3d) => RdDDice.diceSoNiceReady(dice3d));
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
/* Foundry VTT chat message */
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
Hooks.on("chatMessage", (html, content, msg) => {
|
|
||||||
if (content[0] == '/') {
|
|
||||||
let regExp = /(\S+)/g;
|
|
||||||
let commands = content.match(regExp);
|
|
||||||
if (game.system.rdd.commands.processChatCommand(commands, content, msg)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { RdDCombat } from "./rdd-combat.js";
|
|||||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||||
import { RdDRoll } from "./rdd-roll.js";
|
import { RdDRoll } from "./rdd-roll.js";
|
||||||
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
||||||
|
import { Targets } from "./targets.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/* On part du principe qu'une entité démarre tjs
|
/* On part du principe qu'une entité démarre tjs
|
||||||
@@ -27,7 +28,139 @@ export class RdDPossession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static updateEtatPossession(possession) {
|
static async onAttaquePossession(target, attacker, competence, suitePossession = undefined) {
|
||||||
|
const defender = target.actor;
|
||||||
|
const fromEntite = RdDPossession.searchPossessionFromEntite(attacker, defender);
|
||||||
|
const isNouvelle = !suitePossession && ! fromEntite;
|
||||||
|
const possession = (suitePossession ?? fromEntite ?? (await RdDPossession.createPossession(attacker, defender)));
|
||||||
|
|
||||||
|
RdDPossession.$updateEtatPossession(possession)
|
||||||
|
|
||||||
|
let rollData = {
|
||||||
|
mode: "possession",
|
||||||
|
isECNIDefender: false,
|
||||||
|
competence: competence,
|
||||||
|
possession: possession,
|
||||||
|
attacker: attacker,
|
||||||
|
defender: defender,
|
||||||
|
targetToken: Targets.extractTokenData(target)
|
||||||
|
};
|
||||||
|
if (attacker.isCreatureEntite()) {
|
||||||
|
RdDItemCompetenceCreature.setRollDataCreature(rollData)
|
||||||
|
}
|
||||||
|
|
||||||
|
await RdDPossession.$rollAttaquePossession(attacker, rollData, isNouvelle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async onConjurerPossession(attacker, competence, possession) {
|
||||||
|
possession = duplicate(possession);
|
||||||
|
RdDPossession.$updateEtatPossession(possession)
|
||||||
|
let rollData = {
|
||||||
|
mode: "possession",
|
||||||
|
isECNIDefender: true,
|
||||||
|
competence: competence,
|
||||||
|
possession: possession,
|
||||||
|
attacker: attacker,
|
||||||
|
defender: game.actors.get(possession.system.possesseurid)
|
||||||
|
};
|
||||||
|
await RdDPossession.$rollAttaquePossession(attacker, rollData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async onDefensePossession(attackerId, defenderId, possessionId) {
|
||||||
|
let attacker = game.actors.get(attackerId)
|
||||||
|
let possession = attacker?.getPossession(possessionId)
|
||||||
|
defenderId = defenderId ?? possession?.system.possesseurid ?? undefined
|
||||||
|
let defender = game.actors.get(defenderId)
|
||||||
|
possession = possession ?? defender?.getPossession(possessionId) ?? undefined;
|
||||||
|
|
||||||
|
if (!possession) {
|
||||||
|
ui.notifications.warn("Une erreur s'est produite : Aucune possession trouvée !!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
possession = duplicate(possession)
|
||||||
|
// Update for draconic roll
|
||||||
|
let rollData = {
|
||||||
|
mode: "conjuration",
|
||||||
|
isECNIDefender: defender.type == "entite",
|
||||||
|
possession: possession,
|
||||||
|
attacker: attacker,
|
||||||
|
defender: defender,
|
||||||
|
competence: defender.getDraconicOuPossession(),
|
||||||
|
selectedCarac: defender.system.carac.reve,
|
||||||
|
forceCarac: { 'reve-actuel': { label: "Rêve Actuel", value: defender.getReveActuel() } }
|
||||||
|
}
|
||||||
|
rollData.competence.system.defaut_carac = 'reve-actuel'
|
||||||
|
|
||||||
|
await RdDPossession.$rollDefensePossession(defender, rollData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async $rollAttaquePossession(attacker, rollData, isNouvelle = false) {
|
||||||
|
const dialog = await RdDRoll.create(attacker, rollData,
|
||||||
|
{ html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' },
|
||||||
|
{
|
||||||
|
name: 'jet-possession',
|
||||||
|
label: rollData.isECNIDefender ? 'Conjurer la possession' : 'Possession',
|
||||||
|
callbacks: [
|
||||||
|
{ condition: r => (r.rolled.isSuccess), action: async (r) => await RdDPossession.$onRollPossession(r, true, isNouvelle) },
|
||||||
|
{ condition: r => (r.rolled.isEchec), action: async (r) => await RdDPossession.$onRollPossession(r, false, isNouvelle) },
|
||||||
|
]
|
||||||
|
});
|
||||||
|
dialog.render(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async $onRollPossession(rollData, isSuccess, isNouvelle = false) {
|
||||||
|
rollData.possession.isSuccess = isSuccess;
|
||||||
|
RdDPossession.$updateEtatPossession(rollData.possession);
|
||||||
|
if (isNouvelle) {
|
||||||
|
// Creer la possession sur le defenseur
|
||||||
|
rollData.defender.createEmbeddedDocuments('Item', [rollData.possession.toObject()])
|
||||||
|
}
|
||||||
|
await RdDResolutionTable.displayRollData(rollData, rollData.attacker, 'chat-resultat-possession.html');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async $rollDefensePossession(defender, rollData) {
|
||||||
|
const dialog = await RdDRoll.create(defender, rollData,
|
||||||
|
{ html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-defense-possession.html' },
|
||||||
|
{
|
||||||
|
name: 'conjurer',
|
||||||
|
label: 'Conjurer une Possession',
|
||||||
|
callbacks: [
|
||||||
|
{ action: async (r) => await RdDPossession.$onRollConjuration(r) }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
);
|
||||||
|
dialog.render(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async $onRollConjuration(rollData) {
|
||||||
|
let actor = game.actors.get(rollData.possession.system.possedeid)
|
||||||
|
if (!rollData.rolled.isSuccess) {
|
||||||
|
if (rollData.isECNIDefender) {
|
||||||
|
rollData.possession.system.compteur--
|
||||||
|
} else {
|
||||||
|
rollData.possession.system.compteur++
|
||||||
|
}
|
||||||
|
let update = { _id: rollData.possession._id, "system.compteur": rollData.possession.system.compteur }
|
||||||
|
await actor.updateEmbeddedDocuments('Item', [update])
|
||||||
|
}
|
||||||
|
|
||||||
|
RdDPossession.$updateEtatPossession(rollData.possession)
|
||||||
|
|
||||||
|
await RdDResolutionTable.displayRollData(rollData,rollData.defender, 'chat-resultat-possession.html')
|
||||||
|
if (rollData.possession.isPosseder || rollData.possession.isConjurer) {
|
||||||
|
// conjuration
|
||||||
|
actor.deleteEmbeddedDocuments("Item", [rollData.possession._id])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static $updateEtatPossession(possession) {
|
||||||
possession.ptsConjuration = 0
|
possession.ptsConjuration = 0
|
||||||
possession.ptsPossession = 0
|
possession.ptsPossession = 0
|
||||||
console.log("Possession", possession)
|
console.log("Possession", possession)
|
||||||
@@ -48,122 +181,15 @@ export class RdDPossession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async resultConjuration(rollData) {
|
static async createPossession(attacker, defender) {
|
||||||
let actor = game.actors.get(rollData.possession.system.possedeid)
|
return await Item.create({
|
||||||
if (!rollData.rolled.isSuccess) {
|
name: "Possession en cours de " + attacker.name, type: 'possession',
|
||||||
if (rollData.isECNIDefender) {
|
img: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp",
|
||||||
rollData.possession.system.compteur--
|
system: { description: "", typepossession: attacker.name, possede: false, possessionid: randomID(16), possesseurid: attacker.id, possedeid: defender.id, date: 0, compteur: 0 }
|
||||||
} else {
|
|
||||||
rollData.possession.system.compteur++
|
|
||||||
}
|
|
||||||
let update = { _id: rollData.possession._id, "system.compteur": rollData.possession.system.compteur }
|
|
||||||
await actor.updateEmbeddedDocuments('Item', [update])
|
|
||||||
}
|
|
||||||
|
|
||||||
this.updateEtatPossession(rollData.possession)
|
|
||||||
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-possession.html')
|
|
||||||
if (rollData.possession.isPosseder || rollData.possession.isConjurer) {
|
|
||||||
actor.deleteEmbeddedDocuments("Item", [rollData.possession._id])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static async onDefensePossession(attackerId, defenderId, possessionId) {
|
|
||||||
let attacker = game.actors.get(attackerId)
|
|
||||||
let defender = game.actors.get(defenderId)
|
|
||||||
let possession = attacker.getPossession(possessionId) ?? defender.getPossession(possessionId) ;
|
|
||||||
if (!possession) {
|
|
||||||
ui.notifications.warn("Une erreur s'est produite : Aucune possession trouvée !!")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Update for draconic roll
|
|
||||||
let rollData = {
|
|
||||||
mode: "conjuration",
|
|
||||||
isECNIDefender: defender.type == "entite",
|
|
||||||
possession: duplicate(possession),
|
|
||||||
attacker: attacker,
|
|
||||||
defender: defender,
|
|
||||||
competence: defender.getDraconicOuPossession(),
|
|
||||||
selectedCarac: defender.system.carac.reve,
|
|
||||||
forceCarac: { 'reve-actuel': { label: "Rêve Actuel", value: defender.getReveActuel() } }
|
|
||||||
}
|
|
||||||
rollData.competence.system.defaut_carac = 'reve-actuel'
|
|
||||||
|
|
||||||
|
|
||||||
const dialog = await RdDRoll.create(defender, rollData,
|
|
||||||
{
|
|
||||||
html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-defense-possession.html',
|
|
||||||
options: { height: 450 }
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'conjurer',
|
temporary: true
|
||||||
label: 'Conjurer une Possession',
|
})
|
||||||
callbacks: [
|
|
||||||
{ action: async r => await this.resultConjuration(r) }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
);
|
|
||||||
dialog.render(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static async onAttaquePossession(attacker, competence, possession = undefined) {
|
|
||||||
const target = RdDCombat.getTarget()
|
|
||||||
if (target == undefined) {
|
|
||||||
ui.notifications.warn((game.user.targets?.size ?? 0) > 1
|
|
||||||
? "Vous devez choisir <strong>une seule</strong> cible à posséder!"
|
|
||||||
: "Vous devez choisir une cible à posséder!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const defender = target.actor;
|
|
||||||
possession = duplicate(possession ?? this.searchPossessionFromEntite(attacker, defender) ??(await this.createPossession(attacker, defender)));
|
|
||||||
|
|
||||||
this.updateEtatPossession(possession)
|
|
||||||
let rollData = {
|
|
||||||
mode: "possession",
|
|
||||||
isECNIDefender: defender.type == "entite",
|
|
||||||
competence: competence,
|
|
||||||
possession: possession,
|
|
||||||
attacker: attacker,
|
|
||||||
defender: defender
|
|
||||||
};
|
|
||||||
if (attacker.isCreature()) {
|
|
||||||
RdDItemCompetenceCreature.setRollDataCreature(rollData)
|
|
||||||
}
|
|
||||||
|
|
||||||
const dialog = await RdDRoll.create(attacker, rollData,
|
|
||||||
{
|
|
||||||
html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html',
|
|
||||||
options: { height: 540 }
|
|
||||||
}, {
|
|
||||||
name: 'jet-possession',
|
|
||||||
label: rollData.isECNIDefender ? 'Conjurer la possession' : 'Possession',
|
|
||||||
callbacks: [
|
|
||||||
{ condition: r => (r.rolled.isSuccess), action: async r => await this._onRollPossession(r, true) },
|
|
||||||
{ condition: r => (r.rolled.isEchec), action: async r => await this._onRollPossession(r, false) },
|
|
||||||
]
|
|
||||||
});
|
|
||||||
dialog.render(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static async _onRollPossession(rollData, isSuccess) {
|
|
||||||
rollData.possession.isSuccess = isSuccess;
|
|
||||||
this.updateEtatPossession(rollData.possession);
|
|
||||||
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-possession.html');
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static async createPossession(attacker, defender) {
|
|
||||||
let possessionData = {
|
|
||||||
name: "Possession en cours de " + attacker.name, type: 'possession',
|
|
||||||
img: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp",
|
|
||||||
system: { description: "", typepossession: attacker.name, possede: false, possessionid: randomID(16), possesseurid: attacker.id, possedeid: defender.id, date: 0, compteur: 0 }
|
|
||||||
}
|
|
||||||
// Creates only the possession on the personnage side
|
|
||||||
let poss = await defender.createEmbeddedDocuments('Item', [possessionData])
|
|
||||||
return duplicate(poss[0])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { ChatUtility } from "./chat-utility.js";
|
import { ChatUtility } from "./chat-utility.js";
|
||||||
import { Misc } from "./misc.js";
|
import { Misc } from "./misc.js";
|
||||||
import { RdDDice } from "./rdd-dice.js";
|
import { RdDDice } from "./rdd-dice.js";
|
||||||
import { ReglesOptionelles } from "./regles-optionelles.js";
|
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* difficultés au delà de -10
|
* difficultés au delà de -10
|
||||||
@@ -14,7 +14,7 @@ const levelDown = [
|
|||||||
{ level: -15, score: 1, norm: 1, sign: 0, part: 0, epart: 2, etotal: 10 },
|
{ level: -15, score: 1, norm: 1, sign: 0, part: 0, epart: 2, etotal: 10 },
|
||||||
{ level: -16, score: 1, norm: 1, sign: 0, part: 0, epart: 0, etotal: 2 }
|
{ level: -16, score: 1, norm: 1, sign: 0, part: 0, epart: 0, etotal: 2 }
|
||||||
];
|
];
|
||||||
const levelImpossible = { score: 0, norm:0, sign: 0, part: 0, epart: 0, etotal: 1 };
|
const levelImpossible = { score: 0, norm: 0, sign: 0, part: 0, epart: 0, etotal: 1 };
|
||||||
|
|
||||||
const reussites = [
|
const reussites = [
|
||||||
{ code: "etotal", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: true, isETotal: true, ptTache: -4, ptQualite: -6, quality: "Echec total", condition: (target, roll) => roll >= target.etotal && roll <= 100 },
|
{ code: "etotal", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: true, isETotal: true, ptTache: -4, ptQualite: -6, quality: "Echec total", condition: (target, roll) => roll >= target.etotal && roll <= 100 },
|
||||||
@@ -42,6 +42,44 @@ export class RdDResolutionTable {
|
|||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static computeChances(carac, level) {
|
||||||
|
if (level < -16) {
|
||||||
|
return levelImpossible;
|
||||||
|
}
|
||||||
|
if (level < -10) {
|
||||||
|
return levelDown.find(it => it.level == level);
|
||||||
|
}
|
||||||
|
const percentage = RdDResolutionTable.computePercentage(carac, level);
|
||||||
|
return this._computeCell(level, percentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static _computeRow(caracValue) {
|
||||||
|
let dataRow = [
|
||||||
|
this._computeCell(-10, Math.max(Math.floor(caracValue / 4), 1)),
|
||||||
|
this._computeCell(-9, Math.max(Math.floor(caracValue / 2), 1))
|
||||||
|
]
|
||||||
|
for (var diff = -8; diff <= 22; diff++) {
|
||||||
|
dataRow[diff + 10] = this._computeCell(diff, RdDResolutionTable.computePercentage(caracValue, diff));
|
||||||
|
}
|
||||||
|
return dataRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static _computeCell(niveau, percentage) {
|
||||||
|
return {
|
||||||
|
niveau: niveau,
|
||||||
|
score: percentage,
|
||||||
|
norm: Math.min(99, percentage),
|
||||||
|
sign: this._reussiteSignificative(percentage),
|
||||||
|
part: this._reussitePart(percentage),
|
||||||
|
epart: this._echecParticulier(percentage),
|
||||||
|
etotal: this._echecTotal(percentage)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getResultat(code) {
|
static getResultat(code) {
|
||||||
let resultat = reussites.find(r => code == r.code);
|
let resultat = reussites.find(r => code == r.code);
|
||||||
@@ -51,17 +89,6 @@ export class RdDResolutionTable {
|
|||||||
return resultat;
|
return resultat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static explain(rolled) {
|
|
||||||
let message = "<br>Jet : <strong>" + rolled.roll + "</strong> sur " + rolled.score + "% ";
|
|
||||||
if (rolled.caracValue != null && rolled.finalLevel != null) {
|
|
||||||
message += (rolled.diviseurSignificative > 1 ? `(1/${rolled.diviseurSignificative} de ` : "(")
|
|
||||||
+ rolled.caracValue + " à " + Misc.toSignedString(rolled.finalLevel) + ") ";
|
|
||||||
}
|
|
||||||
message += '<strong>' + rolled.quality + '</strong>'
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async displayRollData(rollData, actor = undefined, template = 'chat-resultat-general.html') {
|
static async displayRollData(rollData, actor = undefined, template = 'chat-resultat-general.html') {
|
||||||
return await ChatUtility.createChatWithRollMode(actor?.userName ?? game.user.name, {
|
return await ChatUtility.createChatWithRollMode(actor?.userName ?? game.user.name, {
|
||||||
@@ -82,8 +109,8 @@ export class RdDResolutionTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async roll(caracValue, finalLevel, rollData = {}){
|
static async roll(caracValue, finalLevel, rollData = {}) {
|
||||||
let chances = this.computeChances(caracValue, finalLevel);
|
let chances = duplicate(this.computeChances(caracValue, finalLevel));
|
||||||
this._updateChancesWithBonus(chances, rollData.bonus, finalLevel);
|
this._updateChancesWithBonus(chances, rollData.bonus, finalLevel);
|
||||||
this._updateChancesFactor(chances, rollData.diviseurSignificative);
|
this._updateChancesFactor(chances, rollData.diviseurSignificative);
|
||||||
chances.showDice = rollData.showDice;
|
chances.showDice = rollData.showDice;
|
||||||
@@ -95,7 +122,7 @@ export class RdDResolutionTable {
|
|||||||
rolled.bonus = rollData.bonus;
|
rolled.bonus = rollData.bonus;
|
||||||
rolled.factorHtml = Misc.getFractionHtml(rollData.diviseurSignificative);
|
rolled.factorHtml = Misc.getFractionHtml(rollData.diviseurSignificative);
|
||||||
|
|
||||||
if (ReglesOptionelles.isUsing("afficher-colonnes-reussite")){
|
if (ReglesOptionelles.isUsing("afficher-colonnes-reussite")) {
|
||||||
rolled.niveauNecessaire = this.findNiveauNecessaire(caracValue, rolled.roll);
|
rolled.niveauNecessaire = this.findNiveauNecessaire(caracValue, rolled.roll);
|
||||||
rolled.ajustementNecessaire = rolled.niveauNecessaire - finalLevel;
|
rolled.ajustementNecessaire = rolled.niveauNecessaire - finalLevel;
|
||||||
}
|
}
|
||||||
@@ -103,28 +130,39 @@ export class RdDResolutionTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static findNiveauNecessaire(caracValue, rollValue) {
|
static findNiveauNecessaire(carac, rolled) {
|
||||||
for (let cell of this.resolutionTable[caracValue]) {
|
if (carac == 0) {
|
||||||
if ( rollValue <= cell.norm) {
|
return NaN;
|
||||||
return cell.niveau;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 16; // Dummy default
|
if (rolled >= carac){
|
||||||
|
const upper = Math.ceil(rolled/carac);
|
||||||
|
return 2*upper -10
|
||||||
|
}
|
||||||
|
if (rolled > Math.floor(carac/2)) {
|
||||||
|
return -8
|
||||||
|
}
|
||||||
|
if (rolled > Math.floor(carac/4)) {
|
||||||
|
return -9
|
||||||
|
}
|
||||||
|
if (rolled > 1) {
|
||||||
|
return -10
|
||||||
|
}
|
||||||
|
return -11;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static _updateChancesFactor(chances, diviseur) {
|
static _updateChancesFactor(chances, diviseur) {
|
||||||
if (chances.level > -11 && diviseur && diviseur > 1) {
|
if (chances.level > -11 && diviseur && diviseur > 1) {
|
||||||
let newScore = Math.floor(chances.score / diviseur);
|
let newScore = Math.floor(chances.score / diviseur);
|
||||||
mergeObject(chances, this._computeCell(null, newScore), { overwrite: true });
|
mergeObject(chances, this._computeCell(undefined, newScore), { overwrite: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static _updateChancesWithBonus(chances, bonus, finalLevel) {
|
static _updateChancesWithBonus(chances, bonus, finalLevel) {
|
||||||
if (bonus && finalLevel>-11) {
|
if (bonus && finalLevel > -11) {
|
||||||
let newScore = Number(chances.score) + bonus;
|
let newScore = Number(chances.score) + bonus;
|
||||||
mergeObject(chances, this._computeCell(null, newScore), { overwrite: true });
|
mergeObject(chances, this._computeCell(undefined, newScore), { overwrite: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,23 +180,19 @@ export class RdDResolutionTable {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async rollChances(chances, diviseur, forceDiceResult = -1) {
|
static async rollChances(chances, diviseur, forceDiceResult = -1) {
|
||||||
if (forceDiceResult <= 0 || forceDiceResult > 100) {
|
chances.forceDiceResult = forceDiceResult <= 0 || forceDiceResult > 100 ? undefined : { total: forceDiceResult };
|
||||||
forceDiceResult = -1;
|
chances.roll = await RdDDice.rollTotal("1d100", chances);
|
||||||
}
|
|
||||||
chances.roll = await RdDDice.rollTotal((forceDiceResult == -1) ? "1d100" : `${forceDiceResult}`, chances);
|
|
||||||
mergeObject(chances, this.computeReussite(chances, chances.roll, diviseur), { overwrite: true });
|
mergeObject(chances, this.computeReussite(chances, chances.roll, diviseur), { overwrite: true });
|
||||||
return chances;
|
return chances;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static computeChances(caracValue, difficulte) {
|
static computePercentage(carac, diff) {
|
||||||
if (difficulte < -16) {
|
if (diff < -16) return 0
|
||||||
return duplicate(levelImpossible);
|
if (diff < -10) return 1
|
||||||
}
|
if (diff == -10) return Math.max(Math.floor(carac / 4), 1)
|
||||||
if (difficulte < -10) {
|
if (diff == -9) return Math.max(Math.floor(carac / 2), 1)
|
||||||
return duplicate(levelDown.find(levelData => levelData.level == difficulte));
|
return Math.max(Math.floor(carac * (diff + 10) / 2), 1);
|
||||||
}
|
|
||||||
return duplicate(RdDResolutionTable.resolutionTable[caracValue][difficulte + 10]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -215,31 +249,6 @@ export class RdDResolutionTable {
|
|||||||
return reussite;
|
return reussite;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static _computeRow(caracValue) {
|
|
||||||
let dataRow = [
|
|
||||||
this._computeCell(-10, Math.max(Math.floor(caracValue / 4), 1)),
|
|
||||||
this._computeCell(-9, Math.max(Math.floor(caracValue / 2), 1))
|
|
||||||
]
|
|
||||||
for (var diff = -8; diff <= 22; diff++) {
|
|
||||||
dataRow[diff + 10] = this._computeCell(diff, Math.max(Math.floor(caracValue * (diff + 10) / 2), 1));
|
|
||||||
}
|
|
||||||
return dataRow;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static _computeCell(niveau, percentage) {
|
|
||||||
return {
|
|
||||||
niveau: niveau,
|
|
||||||
score: percentage,
|
|
||||||
norm: Math.min(99, percentage),
|
|
||||||
sign: this._reussiteSignificative(percentage),
|
|
||||||
part: this._reussitePart(percentage),
|
|
||||||
epart: this._echecParticulier(percentage),
|
|
||||||
etotal: this._echecTotal(percentage)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static _reussiteSignificative(percentage) {
|
static _reussiteSignificative(percentage) {
|
||||||
return Math.floor(percentage / 2);
|
return Math.floor(percentage / 2);
|
||||||
@@ -263,92 +272,34 @@ export class RdDResolutionTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static buildHTMLResults(caracValue, levelValue) {
|
static subTable(carac, level, delta = { carac: 2, level: 5}) {
|
||||||
if (caracValue == undefined || isNaN(caracValue)) caracValue = 10;
|
return {
|
||||||
if (levelValue == undefined || isNaN(levelValue)) levelValue = 0;
|
carac,
|
||||||
|
level,
|
||||||
let cell = this.computeChances(caracValue, levelValue);
|
minCarac: carac - (delta?.carac ?? 2),
|
||||||
cell.epart = cell.epart > 99 ? 'N/A' : cell.epart;
|
maxCarac: carac + (delta?.carac ?? 2),
|
||||||
cell.etotal = cell.etotal > 100 ? 'N/A' : cell.etotal;
|
minLevel: level - (delta?.level ?? 5),
|
||||||
cell.score = Math.min(cell.score, 99);
|
maxLevel: level + (delta?.level ?? 5)
|
||||||
|
};
|
||||||
return `
|
|
||||||
<span class="table-proba-reussite competence-label">
|
|
||||||
Particulière: <span class="rdd-roll-part">${cell.part}</span>
|
|
||||||
- Significative: <span class="rdd-roll-sign">${cell.sign}</span>
|
|
||||||
- Réussite: <span class="rdd-roll-norm">${cell.score}</span>
|
|
||||||
- Echec Particulier: <span class="rdd-roll-epart">${cell.epart}</span>
|
|
||||||
- Echec Total: <span class="rdd-roll-etotal">${cell.etotal}</span>
|
|
||||||
</span>
|
|
||||||
`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static buildHTMLTableExtract(caracValue, levelValue) {
|
static async buildHTMLTable({ carac: carac, level: level, minCarac = 1, maxCarac = 21, minLevel = -10, maxLevel = 11 }) {
|
||||||
return this.buildHTMLTable(caracValue, levelValue, caracValue - 2, caracValue + 2, levelValue - 5, levelValue + 5)
|
let colonnes = maxLevel - minLevel;
|
||||||
}
|
|
||||||
|
|
||||||
static buildHTMLTable(caracValue, levelValue, minCarac = 1, maxCarac = 21, minLevel = -10, maxLevel = 11) {
|
|
||||||
return this._buildHTMLTable(caracValue, levelValue, minCarac, maxCarac, minLevel, maxLevel)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static _buildHTMLTable(caracValue, levelValue, minCarac, maxCarac, minLevel, maxLevel) {
|
|
||||||
let countColonnes = maxLevel - minLevel;
|
|
||||||
minCarac = Math.max(minCarac, 1);
|
minCarac = Math.max(minCarac, 1);
|
||||||
maxCarac = Math.min(maxCarac, caracMaximumResolution);
|
maxCarac = Math.min(maxCarac, minCarac + 20);
|
||||||
minLevel = Math.max(minLevel, -10);
|
minLevel = Math.max(minLevel, -10);
|
||||||
maxLevel = Math.max(Math.min(maxLevel, 22), minLevel + countColonnes);
|
maxLevel = Math.max(Math.min(maxLevel, 30), minLevel + colonnes);
|
||||||
|
return await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/resolution-table.html', {
|
||||||
let table = $("<table class='table-resolution'/>")
|
carac: carac,
|
||||||
.append(this._buildHTMLHeader(RdDResolutionTable.resolutionTable[0], minLevel, maxLevel));
|
difficulte: level,
|
||||||
|
min: minLevel,
|
||||||
for (var rowIndex = minCarac; rowIndex <= maxCarac; rowIndex++) {
|
rows: RdDResolutionTable.incrementalArray(minCarac, maxCarac),
|
||||||
table.append(this._buildHTMLRow(RdDResolutionTable.resolutionTable[rowIndex], rowIndex, caracValue, levelValue, minLevel, maxLevel));
|
cols: RdDResolutionTable.incrementalArray(minLevel, maxLevel)
|
||||||
}
|
});
|
||||||
table.append("</table>");
|
|
||||||
return table;
|
|
||||||
}
|
}
|
||||||
|
static incrementalArray(min, max) {
|
||||||
/* -------------------------------------------- */
|
return Array.from(Array(max-min+1).keys()).map(i=>i+min)
|
||||||
static _buildHTMLHeader(dataRow, minLevel, maxLevel) {
|
|
||||||
let tr = $("<tr/>");
|
|
||||||
|
|
||||||
if (minLevel > -8) {
|
|
||||||
tr.append($("<th class='table-resolution-level'/>").text("-8"))
|
|
||||||
}
|
|
||||||
if (minLevel > -7) {
|
|
||||||
tr.append($("<th class='table-resolution-level'/>").text("..."));
|
|
||||||
}
|
|
||||||
for (let difficulte = minLevel; difficulte <= maxLevel; difficulte++) {
|
|
||||||
tr.append($("<th class='table-resolution-level'/>").text(Misc.toSignedString(difficulte)));
|
|
||||||
}
|
|
||||||
return tr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static _buildHTMLRow(dataRow, rowIndex, caracValue, levelValue, minLevel, maxLevel) {
|
|
||||||
let tr = $("<tr/>");
|
|
||||||
let max = maxLevel;
|
|
||||||
|
|
||||||
if (minLevel > -8) {
|
|
||||||
let score = dataRow[-8 + 10].score;
|
|
||||||
tr.append($("<td class='table-resolution-carac'/>").text(score))
|
|
||||||
}
|
|
||||||
if (minLevel > -7) {
|
|
||||||
tr.append($("<td/>"))
|
|
||||||
}
|
|
||||||
for (let difficulte = minLevel; difficulte <= max; difficulte++) {
|
|
||||||
let td = $("<td/>");
|
|
||||||
let score = dataRow[difficulte + 10].score;
|
|
||||||
if (rowIndex == caracValue && levelValue == difficulte) {
|
|
||||||
td.addClass('table-resolution-target');
|
|
||||||
} else if (difficulte == -8) {
|
|
||||||
td.addClass('table-resolution-carac');
|
|
||||||
}
|
|
||||||
tr.append(td.text(score));
|
|
||||||
}
|
|
||||||
return tr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE } from "./constants.js";
|
import { ENTITE_BLURETTE, ENTITE_INCARNE } from "./constants.js";
|
||||||
|
import { RdDUtility } from "./rdd-utility.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extend the base Dialog entity by defining a custom window to perform roll.
|
* Extend the base Dialog entity by defining a custom window to perform roll.
|
||||||
@@ -6,34 +7,39 @@ import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE } from "./constants.
|
|||||||
*/
|
*/
|
||||||
export class RdDEncaisser extends Dialog {
|
export class RdDEncaisser extends Dialog {
|
||||||
|
|
||||||
|
static async encaisser(actor) {
|
||||||
|
let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-roll-encaisser.html',
|
||||||
|
{ ajustementsEncaissement: RdDUtility.getAjustementsEncaissement() }
|
||||||
|
);
|
||||||
|
new RdDEncaisser(html, actor).render(true);
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
constructor(html, actor) {
|
constructor(html, actor) {
|
||||||
// Common conf
|
let dialogConf = {
|
||||||
let buttons = {};
|
title: "Jet d'Encaissement",
|
||||||
if (!actor.isEntite()){
|
content: html,
|
||||||
buttons = {
|
}
|
||||||
|
|
||||||
|
if (!actor.isEntite()) {
|
||||||
|
dialogConf.default = "mortel";
|
||||||
|
dialogConf.buttons = {
|
||||||
"mortel": { label: "Mortel", callback: html => this.performEncaisser("mortel") },
|
"mortel": { label: "Mortel", callback: html => this.performEncaisser("mortel") },
|
||||||
"non-mortel": { label: "Non-mortel", callback: html => this.performEncaisser("non-mortel") },
|
"non-mortel": { label: "Non-mortel", callback: html => this.performEncaisser("non-mortel") },
|
||||||
"sonne": { label: "Sonné", callback: html => this.actor.setSonne() },
|
"sonne": { label: "Sonné", callback: html => this.actor.setSonne() },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else if (actor.isEntite([ENTITE_BLURETTE, ENTITE_INCARNE])){
|
else if (actor.isEntite([ENTITE_BLURETTE, ENTITE_INCARNE])) {
|
||||||
buttons = {
|
dialogConf.default = "cauchemar"
|
||||||
"cauchemar": { label: "cauchemar", callback: html => this.performEncaisser("cauchemar") }
|
dialogConf.buttons = {
|
||||||
|
"cauchemar": { label: "Cauchemar", callback: html => this.performEncaisser("cauchemar") }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let dialogConf = {
|
|
||||||
title: "Jet d'Encaissement",
|
|
||||||
content: html,
|
|
||||||
buttons: buttons,
|
|
||||||
default: "mortel"
|
|
||||||
}
|
|
||||||
|
|
||||||
let dialogOptions = {
|
let dialogOptions = {
|
||||||
classes: ["rdddialog"],
|
classes: ["rdd-roll-dialog"],
|
||||||
width: 320,
|
width: 320,
|
||||||
height: 240
|
height: 'fit-content'
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select proper roll dialog template and stuff
|
// Select proper roll dialog template and stuff
|
||||||
@@ -44,35 +50,29 @@ export class RdDEncaisser extends Dialog {
|
|||||||
this.encaisserSpecial = "aucun";
|
this.encaisserSpecial = "aucun";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
this.html = html;
|
||||||
|
|
||||||
|
this.html.find('[name="modificateurDegats"]').val("0");
|
||||||
|
this.html.find('[name="modificateurDegats"]').change((event) => {
|
||||||
|
this.modifier = event.currentTarget.value; // Update the selected bonus/malus
|
||||||
|
});
|
||||||
|
this.html.find('[name="encaisserSpecial"]').change((event) => {
|
||||||
|
this.encaisserSpecial = event.currentTarget.value; // Update the selected bonus/malus
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
performEncaisser(mortalite) {
|
performEncaisser(mortalite) {
|
||||||
this.actor.encaisserDommages({
|
this.actor.encaisserDommages({
|
||||||
dmg: {
|
dmg: {
|
||||||
total: Number(this.modifier),
|
total: Number(this.modifier),
|
||||||
|
ajustement: Number(this.modifier),
|
||||||
encaisserSpecial: this.encaisserSpecial,
|
encaisserSpecial: this.encaisserSpecial,
|
||||||
loc: { result: 0, label: "" },
|
loc: { result: 0, label: "" },
|
||||||
mortalite: mortalite
|
mortalite: mortalite
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
activateListeners(html) {
|
|
||||||
super.activateListeners(html);
|
|
||||||
|
|
||||||
// Setup everything onload
|
|
||||||
$(function () {
|
|
||||||
$("#modificateurDegats").val("0");
|
|
||||||
});
|
|
||||||
|
|
||||||
html.find('#modificateurDegats').change((event) => {
|
|
||||||
this.modifier = event.currentTarget.value; // Update the selected bonus/malus
|
|
||||||
});
|
|
||||||
html.find('#encaisserSpecial').change((event) => {
|
|
||||||
this.encaisserSpecial = event.currentTarget.value; // Update the selected bonus/malus
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,47 +13,33 @@ export class RdDRollDialogEthylisme extends Dialog {
|
|||||||
title: "Test d'éthylisme",
|
title: "Test d'éthylisme",
|
||||||
content: html,
|
content: html,
|
||||||
default: "rollButton",
|
default: "rollButton",
|
||||||
buttons: { "rollButton": { label: "Test d'éthylisme", callback: html => this.onButton(html) } }
|
buttons: { "rollButton": { label: "Test d'éthylisme", callback: html => onRoll(this.rollData) } }
|
||||||
};
|
};
|
||||||
let dialogOptions = { classes: ["rdddialog"], width: 400, height: 270, 'z-index': 99999 }
|
let dialogOptions = { classes: ["rdd-roll-dialog"], width: 400, height: 'fit-content', 'z-index': 99999 }
|
||||||
super(dialogConf, dialogOptions)
|
super(dialogConf, dialogOptions)
|
||||||
|
|
||||||
//console.log("ETH", rollData);
|
|
||||||
this.onRoll = onRoll;
|
|
||||||
this.rollData = rollData;
|
this.rollData = rollData;
|
||||||
this.actor = actor;
|
this.actor = actor;
|
||||||
}
|
}
|
||||||
|
|
||||||
async onButton(html) {
|
activateListeners(html) {
|
||||||
this.onRoll(this.rollData);
|
super.activateListeners(html);
|
||||||
|
this.html = html;
|
||||||
|
this.bringToTop();
|
||||||
|
|
||||||
|
this.html.find(".force-alcool").change((event) => {
|
||||||
|
this.rollData.forceAlcool = Misc.toInt(event.currentTarget.value);
|
||||||
|
this.updateRollResult();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.html.find(".force-alcool").val(Misc.toInt(this.rollData.forceAlcool));
|
||||||
|
this.updateRollResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
activateListeners(html) {
|
|
||||||
super.activateListeners(html);
|
|
||||||
|
|
||||||
this.bringToTop(); // Ensure top level
|
|
||||||
// Get the rollData stuff
|
|
||||||
var rollData = this.rollData;
|
|
||||||
var dialog = this;
|
|
||||||
|
|
||||||
// Setup everything onload
|
|
||||||
$(function () {
|
|
||||||
$("#forceAlcool").val(Misc.toInt(rollData.forceAlcool));
|
|
||||||
dialog.updateRollResult();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update !
|
|
||||||
html.find('#forceAlcool').change((event) => {
|
|
||||||
rollData.forceAlcool = Misc.toInt(event.currentTarget.value); // Update the selected bonus/malus
|
|
||||||
dialog.updateRollResult();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
async updateRollResult() {
|
async updateRollResult() {
|
||||||
|
this.html.find(".roll-ethylisme").text(this.rollData.vie + " / " + Misc.toSignedString(Number(this.rollData.etat) + Number(this.rollData.forceAlcool) + this.rollData.diffNbDoses));
|
||||||
// Mise à jour valeurs
|
this.html.find(".table-resolution").remove();
|
||||||
$("#roll-param").text(this.rollData.vie + " / " + Misc.toSignedString(Number(this.rollData.etat) + Number(this.rollData.forceAlcool) + this.rollData.diffNbDoses));
|
|
||||||
$(".table-resolution").remove();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,12 +9,19 @@ const titleTableDeResolution = 'Table de résolution';
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
export class RdDRollResolutionTable extends Dialog {
|
export class RdDRollResolutionTable extends Dialog {
|
||||||
|
|
||||||
|
static resolutionTable = undefined;
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async open(rollData = {}) {
|
static async open() {
|
||||||
RdDRollResolutionTable._setDefaultOptions(rollData);
|
if (RdDRollResolutionTable.resolutionTable == undefined) {
|
||||||
let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-roll-resolution.html', rollData);
|
const rollData = {}
|
||||||
const dialog = new RdDRollResolutionTable(rollData, html);
|
RdDRollResolutionTable._setDefaultOptions(rollData);
|
||||||
dialog.render(true);
|
let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-roll-resolution.html', rollData);
|
||||||
|
RdDRollResolutionTable.resolutionTable = new RdDRollResolutionTable(rollData, html);
|
||||||
|
RdDRollResolutionTable.resolutionTable.render(true);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
RdDRollResolutionTable.resolutionTable.bringToTop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -53,11 +60,40 @@ export class RdDRollResolutionTable extends Dialog {
|
|||||||
'lancer-fermer': { label: 'Lancer les dés et fermer', callback: html => this.onLancerFermer() }
|
'lancer-fermer': { label: 'Lancer les dés et fermer', callback: html => this.onLancerFermer() }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
super(conf, { classes: ["rdddialog"], width: 800, height: 800, 'z-index': 99999 });
|
super(conf, { classes: ["rdd-roll-dialog"], top: 50, width: 'fit-content', height: 'fit-content', 'z-index': 99999 });
|
||||||
|
|
||||||
this.rollData = rollData;
|
this.rollData = rollData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
this.html = html;
|
||||||
|
this.bringToTop();
|
||||||
|
|
||||||
|
|
||||||
|
this.html.find("[name='diffLibre']").val(Misc.toInt(this.rollData.diffLibre));
|
||||||
|
this.html.find("[name='diffConditions']").val(Misc.toInt(this.rollData.diffConditions));
|
||||||
|
this.updateRollResult();
|
||||||
|
|
||||||
|
this.html.find('.lancer-table-resolution').click((event) => {
|
||||||
|
this.onLancer();
|
||||||
|
});
|
||||||
|
// Update !
|
||||||
|
this.html.find("[name='diffLibre']").change((event) => {
|
||||||
|
this.rollData.diffLibre = Misc.toInt(event.currentTarget.value);
|
||||||
|
this.updateRollResult();
|
||||||
|
});
|
||||||
|
this.html.find("[name='diffConditions']").change((event) => {
|
||||||
|
this.rollData.diffConditions = Misc.toInt(event.currentTarget.value);
|
||||||
|
this.updateRollResult();
|
||||||
|
});
|
||||||
|
this.html.find("[name='carac']").change((event) => {
|
||||||
|
let caracKey = event.currentTarget.value;
|
||||||
|
this.rollData.selectedCarac = this.rollData.carac[caracKey];
|
||||||
|
this.updateRollResult();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async onLancer() {
|
async onLancer() {
|
||||||
await RdDResolutionTable.rollData(this.rollData);
|
await RdDResolutionTable.rollData(this.rollData);
|
||||||
@@ -72,65 +108,37 @@ export class RdDRollResolutionTable extends Dialog {
|
|||||||
await RdDResolutionTable.displayRollData(this.rollData);
|
await RdDResolutionTable.displayRollData(this.rollData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
activateListeners(html) {
|
|
||||||
super.activateListeners(html);
|
|
||||||
|
|
||||||
this.bringToTop();
|
|
||||||
|
|
||||||
var dialog = this;
|
|
||||||
|
|
||||||
// Setup everything onload
|
|
||||||
function onLoad(){
|
|
||||||
$("#diffLibre").val(Misc.toInt(dialog.rollData.diffLibre));
|
|
||||||
$("#diffConditions").val(Misc.toInt(dialog.rollData.diffConditions));
|
|
||||||
dialog.updateRollResult();
|
|
||||||
}
|
|
||||||
$(function () { onLoad();});
|
|
||||||
html.find('#lancer').click((event) => {
|
|
||||||
this.onLancer();
|
|
||||||
});
|
|
||||||
// Update !
|
|
||||||
html.find('#diffLibre').change((event) => {
|
|
||||||
this.rollData.diffLibre = Misc.toInt(event.currentTarget.value);
|
|
||||||
this.updateRollResult();
|
|
||||||
});
|
|
||||||
html.find('#diffConditions').change((event) => {
|
|
||||||
this.rollData.diffConditions = Misc.toInt(event.currentTarget.value);
|
|
||||||
this.updateRollResult();
|
|
||||||
});
|
|
||||||
html.find('#carac').change((event) => {
|
|
||||||
let caracKey = event.currentTarget.value;
|
|
||||||
this.rollData.selectedCarac = this.rollData.carac[caracKey];
|
|
||||||
this.updateRollResult();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async updateRollResult() {
|
async updateRollResult() {
|
||||||
let rollData = this.rollData;
|
let rollData = this.rollData;
|
||||||
rollData.caracValue = parseInt(rollData.selectedCarac.value)
|
rollData.caracValue = parseInt(rollData.selectedCarac.value)
|
||||||
rollData.finalLevel = this._computeFinalLevel(rollData);
|
rollData.finalLevel = this._computeFinalLevel(rollData);
|
||||||
|
|
||||||
|
const htmlTable = await RdDResolutionTable.buildHTMLTable({
|
||||||
|
carac:rollData.caracValue,
|
||||||
|
level: rollData.finalLevel
|
||||||
|
});
|
||||||
|
|
||||||
// Mise à jour valeurs
|
// Mise à jour valeurs
|
||||||
$("#carac").val(rollData.caracValue);
|
this.html.find("[name='carac']").val(rollData.caracValue);
|
||||||
$("#roll-param").text(rollData.selectedCarac.value + " / " + Misc.toSignedString(rollData.finalLevel));
|
this.html.find(".roll-param-resolution").text(rollData.selectedCarac.value + " / " + Misc.toSignedString(rollData.finalLevel));
|
||||||
$(".table-resolution").remove();
|
this.html.find(".table-resolution").remove();
|
||||||
$(".table-proba-reussite").remove();
|
this.html.find(".table-proba-reussite").remove();
|
||||||
$("#tableResolution").append(RdDResolutionTable.buildHTMLTable(rollData.caracValue, rollData.finalLevel));
|
|
||||||
$("#tableProbaReussite").append(RdDResolutionTable.buildHTMLResults(rollData.caracValue, rollData.finalLevel));
|
this.html.find("div.placeholder-resolution").append(htmlTable)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_computeFinalLevel(rollData) {
|
_computeFinalLevel(rollData) {
|
||||||
const diffConditions = Misc.toInt(rollData.diffConditions);
|
const diffConditions = Misc.toInt(rollData.diffConditions);
|
||||||
const diffLibre = this._computeDiffLibre(rollData);
|
const diffLibre = Misc.toInt(rollData.diffLibre);
|
||||||
|
|
||||||
return diffLibre + diffConditions;
|
return diffLibre + diffConditions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
async close() {
|
||||||
_computeDiffLibre(rollData) {
|
await super.close();
|
||||||
return Misc.toInt(rollData.diffLibre);
|
RdDRollResolutionTable.resolutionTable = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { Misc } from "./misc.js";
|
|||||||
import { RdDBonus } from "./rdd-bonus.js";
|
import { RdDBonus } from "./rdd-bonus.js";
|
||||||
import { RdDCarac } from "./rdd-carac.js";
|
import { RdDCarac } from "./rdd-carac.js";
|
||||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||||
import { ReglesOptionelles } from "./regles-optionelles.js";
|
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extend the base Dialog entity to select roll parameters
|
* Extend the base Dialog entity to select roll parameters
|
||||||
@@ -16,48 +16,42 @@ import { ReglesOptionelles } from "./regles-optionelles.js";
|
|||||||
export class RdDRoll extends Dialog {
|
export class RdDRoll extends Dialog {
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async create(actor, rollData, dialogConfig, ...actions) {
|
static async create(actor, rollData, dialogConfig, action) {
|
||||||
|
RdDRoll._ensureCorrectAction(action);
|
||||||
if (actor.isRollWindowsOpened()) {
|
|
||||||
ui.notifications.warn("Vous avez déja une fenêtre de Test ouverte, il faut la fermer avant d'en ouvrir une autre.")
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
actor.setRollWindowsOpened(true);
|
|
||||||
|
|
||||||
RdDRoll._ensureCorrectActions(actions);
|
|
||||||
RdDRoll._setDefaultOptions(actor, rollData);
|
RdDRoll._setDefaultOptions(actor, rollData);
|
||||||
|
|
||||||
const html = await renderTemplate(dialogConfig.html, rollData);
|
const html = await renderTemplate(dialogConfig.html, rollData);
|
||||||
|
|
||||||
let options = { classes: ["rdddialog"], width: 600, height: 500, 'z-index': 99999 };
|
let options = { classes: ["rdd-roll-dialog"], width: 600, height: 'fit-content', 'z-index': 99999, close: html => {} };
|
||||||
if (dialogConfig.options) {
|
if (dialogConfig.close) {
|
||||||
mergeObject(options, dialogConfig.options, { overwrite: true })
|
options.close = dialogConfig.close;
|
||||||
}
|
}
|
||||||
return new RdDRoll(actor, rollData, html, options, actions, dialogConfig.close);
|
return new RdDRoll(actor, rollData, html, options, action);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static _setDefaultOptions(actor, rollData) {
|
static _setDefaultOptions(actor, rollData) {
|
||||||
const actorData = actor.system
|
|
||||||
let defaultRollData = {
|
let defaultRollData = {
|
||||||
alias: actor.name,
|
alias: actor.name,
|
||||||
ajustementsConditions: CONFIG.RDD.ajustementsConditions,
|
ajustementsConditions: CONFIG.RDD.ajustementsConditions,
|
||||||
difficultesLibres: CONFIG.RDD.difficultesLibres,
|
difficultesLibres: CONFIG.RDD.difficultesLibres,
|
||||||
etat: actor.getEtatGeneral(),
|
etat: actor.getEtatGeneral(),
|
||||||
moral: actor.getMoralTotal(), /* La valeur du moral pour les jets de volonté */
|
moral: actor.getMoralTotal(), /* La valeur du moral pour les jets de volonté */
|
||||||
carac: actorData.carac,
|
carac: actor.system.carac,
|
||||||
finalLevel: 0,
|
finalLevel: 0,
|
||||||
diffConditions: 0,
|
diffConditions: 0,
|
||||||
diffLibre: rollData.competence?.system.default_diffLibre ?? 0,
|
diffLibre: rollData.competence?.system.default_diffLibre ?? 0,
|
||||||
malusArmureValue: actor.getMalusArmure(),
|
|
||||||
surencMalusFlag: actor.isPersonnage() ? (actorData.compteurs.surenc.value < 0) : false,
|
|
||||||
surencMalusValue: actor.computeMalusSurEncombrement(),
|
|
||||||
useMalusSurenc: false,
|
|
||||||
useMoral: false, /* Est-ce que le joueur demande d'utiliser le moral ? Utile si le joueur change plusieurs fois de carac associée. */
|
|
||||||
perteMoralEchec: false, /* Pour l'affichage dans le chat */
|
perteMoralEchec: false, /* Pour l'affichage dans le chat */
|
||||||
use: { libre: true, conditions: true, surenc: false, encTotal: false },
|
use: {
|
||||||
isMalusEncombrementTotal: rollData.competence ? RdDItemCompetence.isMalusEncombrementTotal(rollData.competence) : 0,
|
moral: false, /* Est-ce que le joueur demande d'utiliser le moral ? Utile si le joueur change plusieurs fois de carac associée. */
|
||||||
useMalusEncTotal: false,
|
libre: true,
|
||||||
|
conditions: true,
|
||||||
|
surenc: actor.isSurenc(),
|
||||||
|
encTotal: true
|
||||||
|
},
|
||||||
|
isMalusEncombrementTotal: RdDItemCompetence.isMalusEncombrementTotal(rollData.competence),
|
||||||
|
malusArmureValue: actor.getMalusArmure(),
|
||||||
|
surencMalusValue: actor.computeMalusSurEncombrement(),
|
||||||
encTotal: actor.getEncTotal(),
|
encTotal: actor.getEncTotal(),
|
||||||
ajustementAstrologique: actor.ajustementAstrologique(),
|
ajustementAstrologique: actor.ajustementAstrologique(),
|
||||||
surprise: actor.getSurprise(false),
|
surprise: actor.getSurprise(false),
|
||||||
@@ -66,8 +60,8 @@ export class RdDRoll extends Dialog {
|
|||||||
forceDiceResult: -1
|
forceDiceResult: -1
|
||||||
}
|
}
|
||||||
// Mini patch :Ajout du rêve actuel
|
// Mini patch :Ajout du rêve actuel
|
||||||
if ( actorData.type == "personnage") {
|
if (actor.system.type == "personnage") {
|
||||||
defaultRollData.carac["reve-actuel"] = actorData.reve.reve
|
defaultRollData.carac["reve-actuel"] = actor.system.reve.reve
|
||||||
}
|
}
|
||||||
|
|
||||||
mergeObject(rollData, defaultRollData, { recursive: true, overwrite: false });
|
mergeObject(rollData, defaultRollData, { recursive: true, overwrite: false });
|
||||||
@@ -78,6 +72,7 @@ export class RdDRoll extends Dialog {
|
|||||||
|
|
||||||
RollDataAjustements.calcul(rollData, actor);
|
RollDataAjustements.calcul(rollData, actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getDiviseurSignificative(rollData) {
|
static getDiviseurSignificative(rollData) {
|
||||||
let facteurSign = 1;
|
let facteurSign = 1;
|
||||||
@@ -96,158 +91,133 @@ export class RdDRoll extends Dialog {
|
|||||||
return facteurSign;
|
return facteurSign;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static _ensureCorrectActions(actions) {
|
static _ensureCorrectAction(action) {
|
||||||
if (actions.length == 0) {
|
if (action.callbacks == undefined) {
|
||||||
throw 'No action defined';
|
console.warn('No callback defined for ', action.name);
|
||||||
|
action.callbacks = [{ action: r => console.warn(action.name, r) }];
|
||||||
}
|
}
|
||||||
actions.forEach(action => {
|
|
||||||
if (action.callbacks == undefined) {
|
|
||||||
action.callbacks = [{ action: r => console.log(action.name, r) }];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
constructor(actor, rollData, html, options, actions, close = undefined) {
|
constructor(actor, rollData, html, options, action) {
|
||||||
let conf = {
|
let conf = {
|
||||||
title: actions[0].label,
|
title: action.label,
|
||||||
content: html,
|
content: html,
|
||||||
buttons: {},
|
buttons: {
|
||||||
default: actions[0].name,
|
"onAction": {
|
||||||
close: close
|
label: action.label, callback: html => {
|
||||||
};
|
this.rollData.canClose = true;
|
||||||
for (let action of actions) {
|
this.onAction(action)
|
||||||
conf.buttons[action.name] = {
|
}
|
||||||
label: action.label, callback: html => {
|
|
||||||
this.rollData.canClose = true;
|
|
||||||
this.onAction(action, html)
|
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
}
|
default: "onAction",
|
||||||
|
close: options.close
|
||||||
|
};
|
||||||
super(conf, options);
|
super(conf, options);
|
||||||
|
|
||||||
this.actor = actor;
|
this.actor = actor;
|
||||||
this.rollData = rollData;
|
this.rollData = rollData;
|
||||||
}
|
}
|
||||||
|
|
||||||
close() {
|
|
||||||
if (this.rollData.canClose) {
|
|
||||||
this.actor.setRollWindowsOpened(false);
|
|
||||||
return super.close();
|
|
||||||
}
|
|
||||||
ui.notifications.info("Vous devez faire ce jet de dés!");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async onAction(action, html) {
|
|
||||||
await RdDResolutionTable.rollData(this.rollData);
|
|
||||||
console.log("RdDRoll -=>", this.rollData, this.rollData.rolled);
|
|
||||||
this.actor.setRollWindowsOpened(false);
|
|
||||||
if (action.callbacks)
|
|
||||||
for (let callback of action.callbacks) {
|
|
||||||
if (callback.condition == undefined || callback.condition(this.rollData)) {
|
|
||||||
await callback.action(this.rollData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
activateListeners(html) {
|
activateListeners(html) {
|
||||||
super.activateListeners(html);
|
super.activateListeners(html);
|
||||||
|
this.html = html;
|
||||||
this.bringToTop();
|
this.bringToTop();
|
||||||
|
|
||||||
var dialog = this;
|
console.log('RdDRoll.activateListeners', this.rollData);
|
||||||
|
|
||||||
function onLoad() {
|
// Update html, according to rollData
|
||||||
let rollData = dialog.rollData;
|
if (this.rollData.competence) {
|
||||||
console.log('Ouverture RdDRoll', rollData);
|
const defaut_carac = this.rollData.competence.system.defaut_carac
|
||||||
// Update html, according to rollData
|
// Set the default carac from the competence item
|
||||||
if (rollData.competence) {
|
this.rollData.selectedCarac = this.rollData.carac[defaut_carac];
|
||||||
const defaut_carac = rollData.competence.system.defaut_carac
|
this.html.find("[name='carac']").val(defaut_carac);
|
||||||
// Set the default carac from the competence item
|
|
||||||
rollData.selectedCarac = rollData.carac[defaut_carac];
|
|
||||||
$("#carac").val(defaut_carac);
|
|
||||||
}
|
|
||||||
if (rollData.selectedSort) {
|
|
||||||
dialog.setSelectedSort(rollData.selectedSort);
|
|
||||||
$(".draconic").val(rollData.selectedSort.system.listIndex); // Uniquement a la selection du sort, pour permettre de changer
|
|
||||||
}
|
|
||||||
RdDItemSort.setCoutReveReel(rollData.selectedSort);
|
|
||||||
$("#diffLibre").val(Misc.toInt(rollData.diffLibre));
|
|
||||||
$("#diffConditions").val(Misc.toInt(rollData.diffConditions));
|
|
||||||
dialog.updateRollResult();
|
|
||||||
}
|
}
|
||||||
|
if (this.rollData.selectedSort) {
|
||||||
|
this.setSelectedSort(this.rollData.selectedSort);
|
||||||
|
this.html.find(".draconic").val(this.rollData.selectedSort.system.listIndex); // Uniquement a la selection du sort, pour permettre de changer
|
||||||
|
}
|
||||||
|
RdDItemSort.setCoutReveReel(this.rollData.selectedSort);
|
||||||
|
this.html.find("[name='diffLibre']").val(Misc.toInt(this.rollData.diffLibre));
|
||||||
|
this.html.find("[name='diffConditions']").val(Misc.toInt(this.rollData.diffConditions));
|
||||||
|
this.updateRollResult(html);
|
||||||
|
|
||||||
// Setup everything onload
|
this.html.find("[name='diffLibre']").change((event) => {
|
||||||
$(function () { onLoad(); });
|
|
||||||
|
|
||||||
// Update !
|
|
||||||
html.find('#diffLibre').change((event) => {
|
|
||||||
this.rollData.diffLibre = Misc.toInt(event.currentTarget.value); // Update the selected bonus/malus
|
this.rollData.diffLibre = Misc.toInt(event.currentTarget.value); // Update the selected bonus/malus
|
||||||
this.updateRollResult();
|
this.updateRollResult(html);
|
||||||
});
|
});
|
||||||
html.find('#diffConditions').change((event) => {
|
this.html.find("[name='diffConditions']").change((event) => {
|
||||||
this.rollData.diffConditions = Misc.toInt(event.currentTarget.value); // Update the selected bonus/malus
|
this.rollData.diffConditions = Misc.toInt(event.currentTarget.value); // Update the selected bonus/malus
|
||||||
this.updateRollResult();
|
this.updateRollResult(html);
|
||||||
});
|
});
|
||||||
html.find('#force-dice-result').change((event) => {
|
this.html.find("[name='force-dice-result']").change((event) => {
|
||||||
this.rollData.forceDiceResult = Misc.toInt(event.currentTarget.value);
|
this.rollData.forceDiceResult = Misc.toInt(event.currentTarget.value);
|
||||||
});
|
});
|
||||||
html.find('#carac').change((event) => {
|
this.html.find("[name='carac']").change((event) => {
|
||||||
let caracKey = event.currentTarget.value;
|
let caracKey = event.currentTarget.value;
|
||||||
this.rollData.selectedCarac = this.rollData.carac[caracKey]; // Update the selectedCarac
|
this.rollData.selectedCarac = this.rollData.carac[caracKey]; // Update the selectedCarac
|
||||||
this.updateRollResult();
|
this.updateRollResult(html);
|
||||||
});
|
});
|
||||||
html.find('.roll-draconic').change((event) => {
|
this.html.find('.roll-draconic').change((event) => {
|
||||||
let draconicKey = Misc.toInt(event.currentTarget.value);
|
let draconicKey = Misc.toInt(event.currentTarget.value);
|
||||||
this.rollData.competence = this.rollData.draconicList[draconicKey]; // Update the selectedCarac
|
this.rollData.competence = this.rollData.draconicList[draconicKey]; // Update the selectedCarac
|
||||||
this.updateRollResult();
|
this.updateRollResult(html);
|
||||||
});
|
});
|
||||||
html.find('.roll-sort').change((event) => {
|
this.html.find('.roll-sort').change((event) => {
|
||||||
let sortKey = Misc.toInt(event.currentTarget.value);
|
let sortKey = Misc.toInt(event.currentTarget.value);
|
||||||
this.setSelectedSort(this.rollData.sortList[sortKey]);
|
this.setSelectedSort(this.rollData.sortList[sortKey]);
|
||||||
this.updateRollResult();
|
this.updateRollResult(html);
|
||||||
$("#diffLibre").val(this.rollData.diffLibre);
|
this.html.find("[name='diffLibre']").val(this.rollData.diffLibre);
|
||||||
});
|
});
|
||||||
html.find('.roll-signedraconique').change((event) => {
|
this.html.find('.roll-carac-competence').change((event) => {
|
||||||
|
const competence = event.currentTarget.value;
|
||||||
|
this.rollData.competence = this.rollData.competences.find(it => it.name == competence);
|
||||||
|
this.updateRollResult(html);
|
||||||
|
});
|
||||||
|
this.html.find('.roll-signedraconique').change((event) => {
|
||||||
let sortKey = Misc.toInt(event.currentTarget.value);
|
let sortKey = Misc.toInt(event.currentTarget.value);
|
||||||
this.setSelectedSigneDraconique(this.rollData.signes[sortKey]);
|
this.setSelectedSigneDraconique(this.rollData.signes[sortKey]);
|
||||||
this.updateRollResult();
|
this.updateRollResult(html);
|
||||||
});
|
});
|
||||||
html.find('#ptreve-variable').change((event) => {
|
this.html.find("[name='ptreve-variable']").change((event) => {
|
||||||
let ptreve = Misc.toInt(event.currentTarget.value);
|
let ptreve = Misc.toInt(event.currentTarget.value);
|
||||||
this.rollData.selectedSort.system.ptreve_reel = ptreve;
|
this.rollData.selectedSort.system.ptreve_reel = ptreve;
|
||||||
console.log("RdDRollSelectDialog - Cout reve", ptreve);
|
console.log("RdDRollSelectDialog - Cout reve", ptreve);
|
||||||
this.updateRollResult();
|
this.updateRollResult(html);
|
||||||
});
|
});
|
||||||
html.find("[name='coupsNonMortels']").change((event) => {
|
this.html.find("[name='coupsNonMortels']").change((event) => {
|
||||||
this.rollData.dmg.mortalite = event.currentTarget.checked ? "non-mortel" : "mortel";
|
this.rollData.dmg.mortalite = event.currentTarget.checked ? "non-mortel" : "mortel";
|
||||||
this.updateRollResult();
|
this.updateRollResult(html);
|
||||||
});
|
});
|
||||||
html.find('.cuisine-proportions').change((event) => {
|
this.html.find('.cuisine-proportions').change((event) => {
|
||||||
this.rollData.proportions = Number(event.currentTarget.value);
|
this.rollData.proportions = Number(event.currentTarget.value);
|
||||||
this.updateRollResult();
|
this.updateRollResult(html);
|
||||||
});
|
});
|
||||||
html.find('.select-by-name').change((event) => {
|
this.html.find('.select-by-name').change((event) => {
|
||||||
const attribute = event.currentTarget.attributes['name'].value;
|
const attribute = event.currentTarget.attributes['name'].value;
|
||||||
this.rollData[attribute] = event.currentTarget.value;
|
this.rollData[attribute] = event.currentTarget.value;
|
||||||
this.updateRollResult();
|
this.updateRollResult(html);
|
||||||
});
|
});
|
||||||
html.find('.checkbox-by-name').change((event) => {
|
this.html.find('.checkbox-by-name').change((event) => {
|
||||||
const attribute = event.currentTarget.attributes['name'].value;
|
const attribute = event.currentTarget.attributes['name'].value;
|
||||||
this.rollData[attribute] = event.currentTarget.checked;
|
this.rollData[attribute] = event.currentTarget.checked;
|
||||||
this.updateRollResult();
|
this.updateRollResult(html);
|
||||||
});
|
});
|
||||||
html.find('.appel-moral').click((event) => { /* l'appel au moral, qui donne un bonus de +1 */
|
this.html.find('input.use-encTotal').change((event) => {
|
||||||
this.rollData.useMoral = !this.rollData.useMoral;
|
this.rollData.use.encTotal = event.currentTarget.checked;
|
||||||
const appelMoral = html.find('.icon-appel-moral')[0];
|
this.updateRollResult(html);
|
||||||
const tooltip = html.find('.tooltipAppelAuMoralText')[0];
|
});
|
||||||
if (this.rollData.useMoral) {
|
this.html.find('input.use-surenc').change((event) => {
|
||||||
|
this.rollData.use.surenc = event.currentTarget.checked;
|
||||||
|
this.updateRollResult(html);
|
||||||
|
});
|
||||||
|
this.html.find('.appel-moral').click((event) => { /* l'appel au moral, qui donne un bonus de +1 */
|
||||||
|
this.rollData.use.moral = !this.rollData.use.moral;
|
||||||
|
const appelMoral = this.html.find('.icon-appel-moral')[0];
|
||||||
|
const tooltip = this.html.find('.tooltipAppelAuMoralText')[0];
|
||||||
|
if (this.rollData.use.moral) {
|
||||||
if (this.rollData.moral > 0) {
|
if (this.rollData.moral > 0) {
|
||||||
tooltip.innerHTML = "Appel au moral";
|
tooltip.innerHTML = "Appel au moral";
|
||||||
appelMoral.src = "/systems/foundryvtt-reve-de-dragon/icons/moral-heureux.svg";
|
appelMoral.src = "/systems/foundryvtt-reve-de-dragon/icons/moral-heureux.svg";
|
||||||
@@ -259,16 +229,36 @@ export class RdDRoll extends Dialog {
|
|||||||
tooltip.innerHTML = "Sans appel au moral";
|
tooltip.innerHTML = "Sans appel au moral";
|
||||||
appelMoral.src = "/systems/foundryvtt-reve-de-dragon/icons/moral-neutre.svg";
|
appelMoral.src = "/systems/foundryvtt-reve-de-dragon/icons/moral-neutre.svg";
|
||||||
}
|
}
|
||||||
this.updateRollResult();
|
this.updateRollResult(html);
|
||||||
});
|
});
|
||||||
// Section Méditation
|
// Section Méditation
|
||||||
html.find('.conditionMeditation').change((event) => {
|
this.html.find('.conditionMeditation').change((event) => {
|
||||||
let condition = event.currentTarget.attributes['id'].value;
|
let condition = event.currentTarget.attributes['name'].value;
|
||||||
this.rollData.conditionMeditation[condition] = event.currentTarget.checked;
|
this.rollData.conditionMeditation[condition] = event.currentTarget.checked;
|
||||||
this.updateRollResult();
|
this.updateRollResult(html);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
close() {
|
||||||
|
if (this.rollData.canClose) {
|
||||||
|
return super.close();
|
||||||
|
}
|
||||||
|
ui.notifications.info("Vous devez faire ce jet de dés!");
|
||||||
|
}
|
||||||
|
|
||||||
|
async onAction(action) {
|
||||||
|
this.rollData.forceDiceResult = Number.parseInt(this.html.find("[name='force-dice-result']").val()) ?? -1;
|
||||||
|
await RdDResolutionTable.rollData(this.rollData);
|
||||||
|
console.log("RdDRoll -=>", this.rollData, this.rollData.rolled);
|
||||||
|
if (action.callbacks)
|
||||||
|
for (let callback of action.callbacks) {
|
||||||
|
if (callback.condition == undefined || callback.condition(this.rollData)) {
|
||||||
|
await callback.action(this.rollData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async setSelectedSort(sort) {
|
async setSelectedSort(sort) {
|
||||||
this.rollData.selectedSort = sort; // Update the selectedCarac
|
this.rollData.selectedSort = sort; // Update the selectedCarac
|
||||||
this.rollData.competence = RdDItemCompetence.getVoieDraconic(this.rollData.draconicList, sort.system.draconic);
|
this.rollData.competence = RdDItemCompetence.getVoieDraconic(this.rollData.draconicList, sort.system.draconic);
|
||||||
@@ -276,30 +266,31 @@ export class RdDRoll extends Dialog {
|
|||||||
this.rollData.diffLibre = RdDItemSort.getDifficulte(sort, -7);
|
this.rollData.diffLibre = RdDItemSort.getDifficulte(sort, -7);
|
||||||
RdDItemSort.setCoutReveReel(sort);
|
RdDItemSort.setCoutReveReel(sort);
|
||||||
const htmlSortDescription = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/partial-description-sort.html", { sort: sort });
|
const htmlSortDescription = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/partial-description-sort.html", { sort: sort });
|
||||||
$(".sort-ou-rituel").text(sort.system.isrituel ? "rituel" : "sort");
|
this.html.find(".sort-ou-rituel").text(sort.system.isrituel ? "rituel" : "sort");
|
||||||
$(".bonus-case").text(`${this.rollData.bonus}%`);
|
this.html.find(".bonus-case").text(`${this.rollData.bonus}%`);
|
||||||
$(".details-sort").remove();
|
this.html.find(".placeholder-description-sort").children().remove();
|
||||||
$(".description-sort").append(htmlSortDescription);
|
this.html.find(".placeholder-description-sort").append(htmlSortDescription);
|
||||||
$(".roll-draconic").val(sort.system.listIndex);
|
this.html.find(".roll-draconic").val(sort.system.listIndex);
|
||||||
$(".div-sort-difficulte-fixe").text(Misc.toSignedString(sort.system.difficulte));
|
this.html.find(".div-sort-difficulte-fixe").text(Misc.toSignedString(sort.system.difficulte));
|
||||||
$(".div-sort-ptreve-fixe").text(sort.system.ptreve);
|
this.html.find(".div-sort-ptreve-fixe").text(sort.system.ptreve);
|
||||||
const diffVariable = RdDItemSort.isDifficulteVariable(sort);
|
const diffVariable = RdDItemSort.isDifficulteVariable(sort);
|
||||||
const coutVariable = RdDItemSort.isCoutVariable(sort);
|
const coutVariable = RdDItemSort.isCoutVariable(sort);
|
||||||
HtmlUtility._showControlWhen($(".div-sort-non-rituel"), !sort.system.isrituel);
|
|
||||||
HtmlUtility._showControlWhen($(".div-sort-difficulte-var"), diffVariable);
|
HtmlUtility._showControlWhen(this.html.find(".div-sort-non-rituel"), !sort.system.isrituel);
|
||||||
HtmlUtility._showControlWhen($(".div-sort-difficulte-fixe"), !diffVariable);
|
HtmlUtility._showControlWhen(this.html.find(".div-sort-difficulte-var"), diffVariable);
|
||||||
HtmlUtility._showControlWhen($(".div-sort-ptreve-var"), coutVariable);
|
HtmlUtility._showControlWhen(this.html.find(".div-sort-difficulte-fixe"), !diffVariable);
|
||||||
HtmlUtility._showControlWhen($(".div-sort-ptreve-fixe"), !coutVariable);
|
HtmlUtility._showControlWhen(this.html.find(".div-sort-ptreve-var"), coutVariable);
|
||||||
|
HtmlUtility._showControlWhen(this.html.find(".div-sort-ptreve-fixe"), !coutVariable);
|
||||||
}
|
}
|
||||||
|
|
||||||
async setSelectedSigneDraconique(signe){
|
async setSelectedSigneDraconique(signe) {
|
||||||
this.rollData.signe = signe;
|
this.rollData.signe = signe;
|
||||||
this.rollData.diffLibre = signe.system.difficulte,
|
this.rollData.diffLibre = signe.system.difficulte,
|
||||||
$(".signe-difficulte").text(Misc.toSignedString(this.rollData.diffLibre));
|
$(".signe-difficulte").text(Misc.toSignedString(this.rollData.diffLibre));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async updateRollResult() {
|
async updateRollResult(html) {
|
||||||
let rollData = this.rollData;
|
let rollData = this.rollData;
|
||||||
|
|
||||||
rollData.dmg = rollData.attackerRoll?.dmg ?? RdDBonus.dmg(rollData, this.actor.getBonusDegat())
|
rollData.dmg = rollData.attackerRoll?.dmg ?? RdDBonus.dmg(rollData, this.actor.getBonusDegat())
|
||||||
@@ -309,36 +300,35 @@ export class RdDRoll extends Dialog {
|
|||||||
rollData.use.appelAuMoral = this.actor.isPersonnage() && RdDCarac.isActionPhysique(rollData.selectedCarac);
|
rollData.use.appelAuMoral = this.actor.isPersonnage() && RdDCarac.isActionPhysique(rollData.selectedCarac);
|
||||||
let dmgText = Misc.toSignedString(rollData.dmg.total);
|
let dmgText = Misc.toSignedString(rollData.dmg.total);
|
||||||
|
|
||||||
switch (rollData.mortalite){
|
switch (rollData.mortalite) {
|
||||||
case 'non-mortel': dmgText = `(${dmgText}) non-mortel`; break;
|
case 'non-mortel': dmgText = `(${dmgText}) non-mortel`; break;
|
||||||
case 'empoignade': dmgText = `empoignade`; break;
|
case 'empoignade': dmgText = `empoignade`; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
RollDataAjustements.calcul(rollData, this.actor);
|
RollDataAjustements.calcul(rollData, this.actor);
|
||||||
rollData.finalLevel = this._computeFinalLevel(rollData);
|
rollData.finalLevel = this._computeFinalLevel(rollData);
|
||||||
|
|
||||||
HtmlUtility._showControlWhen($(".diffMoral"), rollData.ajustements.moralTotal.used);
|
const resolutionTable = await RdDResolutionTable.buildHTMLTable(RdDResolutionTable.subTable(rollData.caracValue, rollData.finalLevel))
|
||||||
HtmlUtility._showControlWhen($(".divAppelAuMoral"), rollData.use.appelAuMoral);
|
const adjustements = await this.buildAjustements(rollData);
|
||||||
HtmlUtility._showControlWhen($("#etat-general"), !RdDCarac.isIgnoreEtatGeneral(rollData));
|
|
||||||
HtmlUtility._showControlWhen($("#ajust-astrologique"), RdDResolutionTable.isAjustementAstrologique(rollData));
|
HtmlUtility._showControlWhen(this.html.find(".use-encTotal"), rollData.ajustements.encTotal.visible && RdDCarac.isAgiliteOuDerivee(rollData.selectedCarac));
|
||||||
|
HtmlUtility._showControlWhen(this.html.find(".use-surenc"), rollData.ajustements.surenc.visible && RdDCarac.isActionPhysique(rollData.selectedCarac));
|
||||||
|
HtmlUtility._showControlWhen(this.html.find(".utilisation-moral"), rollData.use.appelAuMoral);
|
||||||
|
HtmlUtility._showControlWhen(this.html.find(".diffMoral"), rollData.ajustements.moralTotal.used);
|
||||||
|
HtmlUtility._showControlWhen(this.html.find(".divAppelAuMoral"), rollData.use.appelAuMoral);
|
||||||
|
|
||||||
// Mise à jour valeurs
|
// Mise à jour valeurs
|
||||||
$(".dialog-roll-title").text(this._getTitle(rollData));
|
this.html.find(".dialog-roll-title").text(this._getTitle(rollData));
|
||||||
$("[name='coupsNonMortels']").prop('checked', rollData.mortalite == 'non-mortel');
|
this.html.find("[name='coupsNonMortels']").prop('checked', rollData.mortalite == 'non-mortel');
|
||||||
$(".dmg-arme-actor").text(dmgText);
|
this.html.find(".dmg-arme-actor").text(dmgText);
|
||||||
$('.table-ajustement').remove();
|
this.html.find("div.placeholder-ajustements").empty().append(adjustements);
|
||||||
$(".table-resolution").remove();
|
this.html.find("div.placeholder-resolution").empty().append(resolutionTable)
|
||||||
$(".table-proba-reussite").remove();
|
|
||||||
$("#tableAjustements").append(await this.buildAjustements(rollData));
|
|
||||||
$("#tableResolution").append(RdDResolutionTable.buildHTMLTableExtract(rollData.caracValue, rollData.finalLevel));
|
|
||||||
$("#tableProbaReussite").append(RdDResolutionTable.buildHTMLResults(rollData.caracValue, rollData.finalLevel));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async buildAjustements(rollData) {
|
async buildAjustements(rollData) {
|
||||||
const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/partial-roll-ajustements.html`, rollData);
|
return await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/partial-roll-ajustements.html`, rollData);
|
||||||
return html;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -356,23 +346,11 @@ export class RdDRoll extends Dialog {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
_computeDiffLibre(rollData) {
|
|
||||||
let diffLibre = Misc.toInt(rollData.diffLibre);
|
|
||||||
if (rollData.draconicList && rollData.selectedSort) {
|
|
||||||
return RdDItemSort.getDifficulte(rollData.selectedSort, diffLibre);
|
|
||||||
}
|
|
||||||
return diffLibre;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_computeMalusArmure(rollData) {
|
_computeMalusArmure(rollData) {
|
||||||
let malusArmureValue = 0;
|
let malusArmureValue = 0;
|
||||||
if (rollData.malusArmureValue && (rollData.selectedCarac.label == "Agilité" || rollData.selectedCarac.label == "Dérobée")) {
|
if (rollData.malusArmureValue && (rollData.selectedCarac.label == "Agilité" || rollData.selectedCarac.label == "Dérobée")) {
|
||||||
$("#addon-message").text("Malus armure appliqué : " + rollData.malusArmureValue);
|
|
||||||
malusArmureValue = rollData.malusArmureValue;
|
malusArmureValue = rollData.malusArmureValue;
|
||||||
} else {
|
|
||||||
$("#addon-message").text("");
|
|
||||||
}
|
}
|
||||||
return malusArmureValue;
|
return malusArmureValue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,87 +1,109 @@
|
|||||||
|
import { Grammar } from "./grammar.js";
|
||||||
|
import { CompendiumTable, CompendiumTableHelpers, SystemCompendiums } from "./settings/system-compendiums.js";
|
||||||
|
|
||||||
export class RdDRollTables {
|
export class RdDRollTables {
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async genericGetTableResult(tableName, toChat) {
|
static async genericGetTableResult(tableName, toChat) {
|
||||||
let table = game.tables.find(table => table.name.toLowerCase() == tableName.toLowerCase())
|
let table = RdDRollTables.getWorldTable(tableName) ?? (await RdDRollTables.getSystemTable(tableName));
|
||||||
if ( !table) {
|
const draw = await table.draw({ displayChat: toChat, rollMode: "gmroll" });
|
||||||
const pack = game.packs.get("foundryvtt-reve-de-dragon.tables-diverses");
|
|
||||||
const index = await pack.getIndex();
|
|
||||||
const entry = index.find(e => e.name === tableName);
|
|
||||||
table = await pack.getDocument(entry._id);
|
|
||||||
}
|
|
||||||
const draw = await table.draw({ displayChat: toChat, rollMode: "gmroll"});
|
|
||||||
//console.log("RdDRollTables", tableName, toChat, ":", draw);
|
|
||||||
return draw.results.length > 0 ? draw.results[0] : undefined;
|
return draw.results.length > 0 ? draw.results[0] : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getWorldTable(tableName) {
|
||||||
|
return game.tables.find(table => table.name.toLowerCase() == tableName.toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
static async getSystemTable(tableName) {
|
||||||
|
const pack = SystemCompendiums.getPack("tables-diverses");
|
||||||
|
const index = await pack.getIndex();
|
||||||
|
const entry = index.find(e => e.name === tableName);
|
||||||
|
return await pack.getDocument(entry._id);
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async drawItemFromRollTable(tableName, toChat = false) {
|
static async drawItemFromRollTable(tableName, toChat = false) {
|
||||||
const drawResult = await RdDRollTables.genericGetTableResult(tableName, toChat);
|
const drawResult = await RdDRollTables.genericGetTableResult(tableName, toChat);
|
||||||
const pack = game.packs.get(drawResult.documentCollection)
|
const pack = game.packs.get(drawResult.documentCollection)
|
||||||
let doc = await pack.getDocument(drawResult.documentId)
|
return await pack.getDocument(drawResult.documentId)
|
||||||
return doc
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async drawTextFromRollTable(tableName, toChat) {
|
static async drawTextFromRollTable(tableName, toChat) {
|
||||||
const drawResult = await RdDRollTables.genericGetTableResult(tableName, toChat);
|
const drawResult = await RdDRollTables.genericGetTableResult(tableName, toChat);
|
||||||
return drawResult.system.text;
|
return drawResult.text;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async getCompetence(toChat = false) {
|
static async getCompetence(toChat = false) {
|
||||||
return await RdDRollTables.drawItemFromRollTable("Détermination aléatoire de compétence", toChat);
|
if (toChat == 'liste') {
|
||||||
|
return await RdDRollTables.listOrRoll('competences', 'Item', ['competence'], toChat, it => 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return await RdDRollTables.drawItemFromRollTable("Détermination aléatoire de compétence", toChat);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async getSouffle(toChat = false) {
|
static async getSouffle(toChat = false) {
|
||||||
return await RdDRollTables.drawItemFromRollTable("Souffles de Dragon", toChat);
|
return await RdDRollTables.listOrRoll('souffles-de-dragon', 'Item', ['souffle'], toChat);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async getQueue(toChat = false) {
|
static async getQueue(toChat = false) {
|
||||||
let queue = await RdDRollTables.drawItemFromRollTable("Queues de dragon", toChat);
|
return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', ['queue'], toChat);
|
||||||
if (queue.name.toLowerCase().includes('lancinant') ) {
|
|
||||||
return await RdDRollTables.getDesirLancinant(toChat);
|
|
||||||
}
|
|
||||||
if (queue.name.toLowerCase().includes('fixe') ) {
|
|
||||||
return await RdDRollTables.getIdeeFixe(toChat);
|
|
||||||
}
|
|
||||||
return queue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static async getDesirLancinant(toChat = false) {
|
static async getDesirLancinant(toChat = false) {
|
||||||
return await RdDRollTables.drawItemFromRollTable("Désirs lancinants", toChat);
|
return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', ['queue'], toChat,
|
||||||
|
it => it.system.frequence,
|
||||||
|
it => it.system.categorie == 'lancinant');
|
||||||
}
|
}
|
||||||
|
|
||||||
static async getIdeeFixe(toChat = false) {
|
static async getIdeeFixe(toChat = false) {
|
||||||
return await RdDRollTables.drawItemFromRollTable("Idées fixes", toChat);
|
return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', ['queue'], toChat,
|
||||||
|
it => it.system.frequence,
|
||||||
|
it => it.system.categorie == 'ideefixe');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async getTeteHR(toChat = false) {
|
static async getTeteHR(toChat = false) {
|
||||||
return await RdDRollTables.drawItemFromRollTable("Têtes de Dragon pour haut-rêvants", toChat);
|
return await RdDRollTables.listOrRoll('tetes-de-dragon-pour-haut-revants', 'Item', ['tete'], toChat);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async getTete(toChat = false) {
|
static async getTete(toChat = false) {
|
||||||
return await RdDRollTables.drawItemFromRollTable("Têtes de Dragon pour tous personnages", toChat);
|
return await RdDRollTables.listOrRoll('tetes-de-dragon-pour-tous-personnages', 'Item', ['tete'], toChat);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async getOmbre(toChat = false) {
|
static async getOmbre(toChat = false) {
|
||||||
return await RdDRollTables.drawItemFromRollTable("Ombre de Thanatos", toChat);
|
return await RdDRollTables.listOrRoll('ombres-de-thanatos', 'Item', ['ombre'], toChat);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async getTarot(toChat = true) {
|
static async getTarot(toChat = true) {
|
||||||
return await RdDRollTables.drawItemFromRollTable("Tarot Draconique", toChat);
|
return await RdDRollTables.listOrRoll('tarot-draconique', 'Item', ['tarot'], toChat);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async getMaladresse(options = {toChat: false, arme: false}) {
|
static async listOrRoll(compendium, type, subTypes, toChat, itemFrequence = it => it.system.frequence, filter = it => true) {
|
||||||
|
const table = new CompendiumTable(compendium, type, subTypes);
|
||||||
|
if (toChat == 'liste') {
|
||||||
|
return await table.toChatMessage(itemFrequence, filter);
|
||||||
|
}
|
||||||
|
const row = await table.getRandom(itemFrequence, filter);
|
||||||
|
if (row) {
|
||||||
|
await CompendiumTableHelpers.tableRowToChatMessage(row, type);
|
||||||
|
}
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async getMaladresse(options = { toChat: false, arme: false }) {
|
||||||
return await RdDRollTables.drawTextFromRollTable(
|
return await RdDRollTables.drawTextFromRollTable(
|
||||||
options.arme ? "Maladresse armé" : "Maladresses non armé",
|
options.arme ? "Maladresse armé" : "Maladresses non armé",
|
||||||
options.toChat);
|
options.toChat);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { DialogSplitItem } from "./dialog-split-item.js";
|
import { DialogSplitItem } from "./dialog-split-item.js";
|
||||||
import { Misc } from "./misc.js";
|
|
||||||
|
|
||||||
export class RdDSheetUtility {
|
export class RdDSheetUtility {
|
||||||
|
|
||||||
@@ -20,17 +19,23 @@ export class RdDSheetUtility {
|
|||||||
return $(event.currentTarget)?.parents(".item");
|
return $(event.currentTarget)?.parents(".item");
|
||||||
}
|
}
|
||||||
|
|
||||||
static prepareItemDropParameters(destItemId, actorId, dragData, objetVersConteneur) {
|
static prepareItemDropParameters(destItemId, actor, dragData, objetVersConteneur) {
|
||||||
const item = fromUuidSync(dragData.uuid)
|
const item = fromUuidSync(dragData.uuid)
|
||||||
return {
|
if (actor.canReceive(item)) {
|
||||||
destId: destItemId,
|
return {
|
||||||
targetActorId: actorId,
|
destId: destItemId,
|
||||||
itemId: item.id,
|
targetActorId: actor.id,
|
||||||
sourceActorId: item.actor?.id,
|
itemId: item.id,
|
||||||
srcId: objetVersConteneur[item.id],
|
sourceActorId: item.actor?.id,
|
||||||
onEnleverConteneur: () => { delete objetVersConteneur[item.id]; },
|
srcId: objetVersConteneur[item.id],
|
||||||
onAjouterDansConteneur: (itemId, conteneurId) => { objetVersConteneur[itemId] = conteneurId; }
|
onEnleverConteneur: () => { delete objetVersConteneur[item.id]; },
|
||||||
|
onAjouterDansConteneur: (itemId, conteneurId) => { objetVersConteneur[itemId] = conteneurId; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
ui.notifications.warn(`Impossible de donner ${item.name} à ${actor.name}: ${item.type} / ${actor.type}`);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
static async splitItem(item, actor, onSplit = () => { }) {
|
static async splitItem(item, actor, onSplit = () => { }) {
|
||||||
|
|||||||
@@ -1,26 +1,29 @@
|
|||||||
import { SYSTEM_SOCKET_ID } from "./constants.js";
|
import { SHOW_DICE } from "./constants.js";
|
||||||
import { RollDataAjustements } from "./rolldata-ajustements.js";
|
import { RollDataAjustements } from "./rolldata-ajustements.js";
|
||||||
import { RdDUtility } from "./rdd-utility.js";
|
import { RdDUtility } from "./rdd-utility.js";
|
||||||
import { TMRUtility } from "./tmr-utility.js";
|
import { TMRUtility } from "./tmr-utility.js";
|
||||||
import { tmrConstants } from "./tmr-constants.js";
|
import { tmrConstants } from "./tmr-constants.js";
|
||||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||||
import { RdDTMRRencontreDialog } from "./rdd-tmr-rencontre-dialog.js";
|
import { RdDTMRRencontreDialog } from "./rdd-tmr-rencontre-dialog.js";
|
||||||
import { TMRRencontres } from "./tmr-rencontres.js";
|
|
||||||
import { ChatUtility } from "./chat-utility.js";
|
import { ChatUtility } from "./chat-utility.js";
|
||||||
import { RdDRoll } from "./rdd-roll.js";
|
import { RdDRoll } from "./rdd-roll.js";
|
||||||
import { Poetique } from "./poetique.js";
|
import { Poetique } from "./poetique.js";
|
||||||
import { EffetsDraconiques } from "./tmr/effets-draconiques.js";
|
import { EffetsDraconiques } from "./tmr/effets-draconiques.js";
|
||||||
import { PixiTMR } from "./tmr/pixi-tmr.js";
|
import { PixiTMR } from "./tmr/pixi-tmr.js";
|
||||||
import { Draconique } from "./tmr/draconique.js";
|
import { Draconique } from "./tmr/draconique.js";
|
||||||
import { Misc } from "./misc.js";
|
|
||||||
import { HtmlUtility } from "./html-utility.js";
|
import { HtmlUtility } from "./html-utility.js";
|
||||||
import { ReglesOptionelles } from "./regles-optionelles.js";
|
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
||||||
import { RdDDice } from "./rdd-dice.js";
|
import { RdDDice } from "./rdd-dice.js";
|
||||||
|
import { STATUSES } from "./settings/status-effects.js";
|
||||||
|
import { RdDRencontre } from "./item-rencontre.js";
|
||||||
|
import { RdDCalendrier } from "./rdd-calendrier.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
export class RdDTMRDialog extends Dialog {
|
export class RdDTMRDialog extends Dialog {
|
||||||
|
|
||||||
static async create(html, actor, tmrData) {
|
static async create(actor, tmrData) {
|
||||||
|
let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-tmr.html', tmrData);
|
||||||
|
|
||||||
if (tmrData.mode != 'visu') {
|
if (tmrData.mode != 'visu') {
|
||||||
// Notification au MJ
|
// Notification au MJ
|
||||||
@@ -55,7 +58,6 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
this.fatigueParCase = this.viewOnly || !ReglesOptionelles.isUsing("appliquer-fatigue") ? 0 : this.actor.getTMRFatigue();
|
this.fatigueParCase = this.viewOnly || !ReglesOptionelles.isUsing("appliquer-fatigue") ? 0 : this.actor.getTMRFatigue();
|
||||||
this.cumulFatigue = 0;
|
this.cumulFatigue = 0;
|
||||||
this.loadRencontres();
|
this.loadRencontres();
|
||||||
this.loadSortsReserve();
|
|
||||||
this.loadCasesSpeciales();
|
this.loadCasesSpeciales();
|
||||||
this.allTokens = [];
|
this.allTokens = [];
|
||||||
this.rencontreState = 'aucune';
|
this.rencontreState = 'aucune';
|
||||||
@@ -81,9 +83,16 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
this.casesSpeciales = this.actor.items.filter(item => Draconique.isCaseTMR(item));
|
this.casesSpeciales = this.actor.items.filter(item => Draconique.isCaseTMR(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
get sortsReserve() {
|
||||||
loadSortsReserve() {
|
return this.actor.itemTypes['sortreserve'];
|
||||||
this.sortsReserves = this.actor.system.reve.reserve.list;
|
}
|
||||||
|
|
||||||
|
getSortsReserve(coord) {
|
||||||
|
return this.actor.itemTypes['sortreserve'].filter(// Reserve sur une case fleuve ou normale
|
||||||
|
TMRUtility.getTMR(coord).type == 'fleuve'
|
||||||
|
? it => TMRUtility.getTMR(it.system.coord).type == 'fleuve'
|
||||||
|
: it => it.system.coord == coord
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -97,10 +106,10 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
this.updateTokens();
|
this.updateTokens();
|
||||||
this.forceDemiRevePositionView();
|
this.forceDemiRevePositionView();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_createTokens() {
|
_createTokens() {
|
||||||
if (!this.isDemiReveCache()){
|
if (!this.isDemiReveCache()) {
|
||||||
this.demiReve = this._tokenDemiReve();
|
this.demiReve = this._tokenDemiReve();
|
||||||
this._trackToken(this.demiReve);
|
this._trackToken(this.demiReve);
|
||||||
}
|
}
|
||||||
@@ -117,7 +126,6 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
updateTokens() {
|
updateTokens() {
|
||||||
this._removeTokens(t => true);
|
this._removeTokens(t => true);
|
||||||
this.loadRencontres();
|
this.loadRencontres();
|
||||||
this.loadSortsReserve();
|
|
||||||
this.loadCasesSpeciales();
|
this.loadCasesSpeciales();
|
||||||
this._createTokens();
|
this._createTokens();
|
||||||
}
|
}
|
||||||
@@ -136,24 +144,24 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
return this.rencontresExistantes.map(it => this._tokenRencontre(it));
|
return this.rencontresExistantes.map(it => this._tokenRencontre(it));
|
||||||
}
|
}
|
||||||
_getTokensSortsReserve() {
|
_getTokensSortsReserve() {
|
||||||
return this.sortsReserves.map(it => this._tokenSortEnReserve(it));
|
return this.actor.itemTypes['sortreserve'].map(it => this._tokenSortEnReserve(it));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_tokenRencontre(rencontre) {
|
_tokenRencontre(rencontre) {
|
||||||
return EffetsDraconiques.rencontre.token(this.pixiTMR, rencontre, () => rencontre.coord);
|
return EffetsDraconiques.rencontre.token(this.pixiTMR, rencontre, () => rencontre.system.coord);
|
||||||
}
|
}
|
||||||
_tokenCaseSpeciale(casetmr) {
|
_tokenCaseSpeciale(casetmr) {
|
||||||
const caseData = casetmr;
|
const caseData = casetmr;
|
||||||
const draconique = Draconique.get(caseData.system.specific);
|
const draconique = Draconique.get(caseData.system.specific);
|
||||||
return draconique?.token(this.pixiTMR, caseData, () => caseData.system.coord);
|
return draconique?.token(this.pixiTMR, caseData, () => caseData.system.coord);
|
||||||
}
|
}
|
||||||
_tokenSortEnReserve(sortEnReserve) {
|
_tokenSortEnReserve(sortReserve) {
|
||||||
return EffetsDraconiques.sortReserve.token(this.pixiTMR, sortEnReserve.sort, () => sortEnReserve.coord);
|
return EffetsDraconiques.sortReserve.token(this.pixiTMR, sortReserve, () => sortReserve.system.coord);
|
||||||
}
|
}
|
||||||
|
|
||||||
_tokenDemiReve() {
|
_tokenDemiReve() {
|
||||||
return EffetsDraconiques.demiReve.token(this.pixiTMR, this.actor.system, () => this.actor.system.reve.tmrpos.coord);
|
return EffetsDraconiques.demiReve.token(this.pixiTMR, this.actor, () => this.actor.system.reve.tmrpos.coord);
|
||||||
}
|
}
|
||||||
|
|
||||||
forceDemiRevePositionView() {
|
forceDemiRevePositionView() {
|
||||||
@@ -189,44 +197,33 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async activateListeners(html) {
|
async activateListeners(html) {
|
||||||
super.activateListeners(html);
|
super.activateListeners(html);
|
||||||
|
this.html = html;
|
||||||
|
|
||||||
document.getElementById("tmrrow1").insertCell(0).append(this.pixiApp.view);
|
document.getElementById("tmrrow1").insertCell(0).append(this.pixiApp.view);
|
||||||
|
|
||||||
if (this.viewOnly) {
|
if (this.viewOnly) {
|
||||||
html.find('.lancer-sort').remove();
|
this.html.find('.lancer-sort').remove();
|
||||||
html.find('.lire-signe-draconique').remove();
|
this.html.find('.lire-signe-draconique').remove();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
HtmlUtility._showControlWhen($(".appliquerFatigue"), ReglesOptionelles.isUsing("appliquer-fatigue"));
|
HtmlUtility._showControlWhen(this.html.find(".appliquerFatigue"), ReglesOptionelles.isUsing("appliquer-fatigue"));
|
||||||
HtmlUtility._showControlWhen($(".lire-signe-draconique"), this.actor.isResonanceSigneDraconique(this._getActorCoord()));
|
HtmlUtility._showControlWhen(this.html.find(".lire-signe-draconique"), this.actor.isResonanceSigneDraconique(this._getActorCoord()));
|
||||||
|
|
||||||
// Roll Sort
|
// Roll Sort
|
||||||
html.find('.lancer-sort').click((event) => {
|
this.html.find('.lancer-sort').click((event) => {
|
||||||
this.actor.rollUnSort(this._getActorCoord());
|
this.actor.rollUnSort(this._getActorCoord());
|
||||||
});
|
});
|
||||||
html.find('.lire-signe-draconique').click((event) => {
|
this.html.find('.lire-signe-draconique').click((event) => {
|
||||||
this.actor.rollLireSigneDraconique(this._getActorCoord());
|
this.actor.rollLireSigneDraconique(this._getActorCoord());
|
||||||
});
|
});
|
||||||
|
|
||||||
html.find('#dir-top').click((event) => {
|
this.html.find('#dir-top').click((event) => this.moveFromKey("top"));
|
||||||
this.moveFromKey("top");
|
this.html.find('#dir-top-left').click((event) => this.moveFromKey("top-left"));
|
||||||
});
|
this.html.find('#dir-top-right').click((event) => this.moveFromKey("top-right"));
|
||||||
html.find('#dir-top-left').click((event) => {
|
this.html.find('#dir-bottom-left').click((event) => this.moveFromKey("bottom-left"));
|
||||||
this.moveFromKey("top-left");
|
this.html.find('#dir-bottom-right').click((event) => this.moveFromKey("bottom-right"));
|
||||||
});
|
this.html.find('#dir-bottom').click((event) => this.moveFromKey("bottom"));
|
||||||
html.find('#dir-top-right').click((event) => {
|
|
||||||
this.moveFromKey("top-right");
|
|
||||||
});
|
|
||||||
html.find('#dir-bottom-left').click((event) => {
|
|
||||||
this.moveFromKey("bottom-left");
|
|
||||||
});
|
|
||||||
html.find('#dir-bottom-right').click((event) => {
|
|
||||||
this.moveFromKey("bottom-right");
|
|
||||||
});
|
|
||||||
html.find('#dir-bottom').click((event) => {
|
|
||||||
this.moveFromKey("bottom");
|
|
||||||
});
|
|
||||||
|
|
||||||
// Gestion du cout de montée en points de rêve
|
// Gestion du cout de montée en points de rêve
|
||||||
let reveCout = ((this.tmrdata.isRapide && !EffetsDraconiques.isDeplacementAccelere(this.actor)) ? -2 : -1) - this.actor.countMonteeLaborieuse();
|
let reveCout = ((this.tmrdata.isRapide && !EffetsDraconiques.isDeplacementAccelere(this.actor)) ? -2 : -1) - this.actor.countMonteeLaborieuse();
|
||||||
@@ -238,25 +235,26 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
// Le reste...
|
// Le reste...
|
||||||
this.updateValuesDisplay();
|
this.updateValuesDisplay();
|
||||||
let tmr = TMRUtility.getTMR(this._getActorCoord());
|
let tmr = TMRUtility.getTMR(this._getActorCoord());
|
||||||
await this.manageRencontre(tmr, () => {
|
await this.manageRencontre(tmr);
|
||||||
this.postRencontre(tmr);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async updateValuesDisplay() {
|
async updateValuesDisplay() {
|
||||||
|
if (!this.rendered) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const coord = this._getActorCoord();
|
const coord = this._getActorCoord();
|
||||||
|
|
||||||
HtmlUtility._showControlWhen($(".lire-signe-draconique"), this.actor.isResonanceSigneDraconique(coord));
|
HtmlUtility._showControlWhen(this.html.find(".lire-signe-draconique"), this.actor.isResonanceSigneDraconique(coord));
|
||||||
|
|
||||||
let ptsreve = document.getElementById("tmr-pointsreve-value");
|
let ptsreve = document.getElementById("tmr-pointsreve-value");
|
||||||
ptsreve.innerHTML = this.actor.system.reve.reve.value;
|
ptsreve.innerHTML = this.actor.system.reve.reve.value;
|
||||||
|
|
||||||
let tmrpos = document.getElementById("tmr-pos");
|
let tmrpos = document.getElementById("tmr-pos");
|
||||||
if (this.isDemiReveCache()) {
|
if (this.isDemiReveCache()) {
|
||||||
tmrpos.innerHTML = '?? (' + TMRUtility.getTMRType(coord) + ')';
|
tmrpos.innerHTML = `?? ( ${TMRUtility.getTMRType(coord)})`;
|
||||||
} else {
|
} else {
|
||||||
tmrpos.innerHTML = coord + " (" + TMRUtility.getTMRLabel(coord) + ")";
|
tmrpos.innerHTML = `${coord} ( ${TMRUtility.getTMRLabel(coord)})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
let etat = document.getElementById("tmr-etatgeneral-value");
|
let etat = document.getElementById("tmr-etatgeneral-value");
|
||||||
@@ -272,39 +270,59 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
close() {
|
async close() {
|
||||||
if ( this.actor.tmrApp ) {
|
this.descenteTMR = true;
|
||||||
|
if (this.actor.tmrApp) {
|
||||||
this.actor.tmrApp = undefined; // Cleanup reference
|
this.actor.tmrApp = undefined; // Cleanup reference
|
||||||
if ( !this.viewOnly ) {
|
if (!this.viewOnly) {
|
||||||
this.actor.setStatusEffect("EFFECT.StatusDemiReve", false);
|
await this.actor.setEffect(STATUSES.StatusDemiReve, false)
|
||||||
this._tellToGM(this.actor.name + " a quitté les terres médianes");
|
this._tellToGM(this.actor.name + " a quitté les terres médianes");
|
||||||
}
|
}
|
||||||
this.actor.santeIncDec("fatigue", this.cumulFatigue).then(super.close()); // moving 1 cell costs 1 fatigue
|
await this.actor.santeIncDec("fatigue", this.cumulFatigue)
|
||||||
}
|
}
|
||||||
|
await super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
async onActionRencontre(action, tmr) {
|
||||||
|
switch (action) {
|
||||||
|
case 'derober':
|
||||||
|
await this.derober();
|
||||||
|
return;
|
||||||
|
case 'refouler':
|
||||||
|
await this.refouler();
|
||||||
|
break;
|
||||||
|
case 'maitriser':
|
||||||
|
await this.maitriserRencontre();
|
||||||
|
break;
|
||||||
|
case 'ignorer':
|
||||||
|
await this.ignorerRencontre();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
await this.postRencontre(tmr);
|
||||||
|
}
|
||||||
|
|
||||||
async derober() {
|
async derober() {
|
||||||
await this.actor.addTMRRencontre(this.currentRencontre);
|
|
||||||
console.log("-> derober", this.currentRencontre);
|
console.log("-> derober", this.currentRencontre);
|
||||||
|
await this.actor.addTMRRencontre(this.currentRencontre);
|
||||||
this._tellToGM(this.actor.name + " s'est dérobé et quitte les TMR.");
|
this._tellToGM(this.actor.name + " s'est dérobé et quitte les TMR.");
|
||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async refouler() {
|
async refouler() {
|
||||||
this._tellToGM(this.actor.name + " a refoulé : " + this.currentRencontre.name);
|
console.log("-> refouler", this.currentRencontre);
|
||||||
|
await this.actor.ajouterRefoulement(this.currentRencontre.system.refoulement, `${this.currentRencontre.system.genre == 'f' ? 'une' : 'un'} ${this.currentRencontre.name}`);
|
||||||
await this.actor.deleteTMRRencontreAtPosition(); // Remove the stored rencontre if necessary
|
await this.actor.deleteTMRRencontreAtPosition(); // Remove the stored rencontre if necessary
|
||||||
await this.actor.ajouterRefoulement(this.currentRencontre.refoulement ?? 1);
|
|
||||||
this.updateTokens();
|
this.updateTokens();
|
||||||
console.log("-> refouler", this.currentRencontre)
|
|
||||||
this.updateValuesDisplay();
|
this.updateValuesDisplay();
|
||||||
this.nettoyerRencontre();
|
this.nettoyerRencontre();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async ignorerRencontre() {
|
async ignorerRencontre() {
|
||||||
this._tellToGM(this.actor.name + " a ignoré : " + this.currentRencontre.name);
|
console.log("-> ignorer", this.currentRencontre);
|
||||||
|
this._tellToGM(this.actor.name + " a ignoré: " + this.currentRencontre.name);
|
||||||
await this.actor.deleteTMRRencontreAtPosition(); // Remove the stored rencontre if necessary
|
await this.actor.deleteTMRRencontreAtPosition(); // Remove the stored rencontre if necessary
|
||||||
this.updateTokens();
|
this.updateTokens();
|
||||||
this.updateValuesDisplay();
|
this.updateValuesDisplay();
|
||||||
@@ -312,15 +330,22 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
colorierZoneRencontre(listCoordTMR) {
|
// garder la trace de l'état en cours
|
||||||
|
setRencontreState(state, listCoordTMR) {
|
||||||
|
this.rencontreState = state;
|
||||||
|
this.$marquerCasesTMR(listCoordTMR ?? []);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
$marquerCasesTMR(listCoordTMR) {
|
||||||
this.currentRencontre.graphics = []; // Keep track of rectangles to delete it
|
this.currentRencontre.graphics = []; // Keep track of rectangles to delete it
|
||||||
this.currentRencontre.locList = duplicate(listCoordTMR); // And track of allowed location
|
this.currentRencontre.locList = duplicate(listCoordTMR); // And track of allowed location
|
||||||
for (let coordTMR of listCoordTMR) {
|
for (let coordTMR of listCoordTMR) {
|
||||||
let rect = this._getCaseRectangleCoord(coordTMR);
|
const rect = this._getCaseRectangleCoord(coordTMR);
|
||||||
var rectDraw = new PIXI.Graphics();
|
const rectDraw = new PIXI.Graphics();
|
||||||
rectDraw.beginFill(0xFFFF00, 0.3);
|
rectDraw.beginFill(0xffff00, 0.3);
|
||||||
// set the line style to have a width of 5 and set the color to red
|
// set the line style to have a width of 5 and set the color to red
|
||||||
rectDraw.lineStyle(5, 0xFF0000);
|
rectDraw.lineStyle(5, 0xff0000);
|
||||||
// draw a rectangle
|
// draw a rectangle
|
||||||
rectDraw.drawRect(rect.x, rect.y, rect.w, rect.h);
|
rectDraw.drawRect(rect.x, rect.y, rect.w, rect.h);
|
||||||
this.pixiApp.stage.addChild(rectDraw);
|
this.pixiApp.stage.addChild(rectDraw);
|
||||||
@@ -328,29 +353,6 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
// garder la trace de l'état en cours
|
|
||||||
setStateRencontre(state) {
|
|
||||||
this.rencontreState = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async choisirCasePortee(coord, portee) {
|
|
||||||
if (this.actor.isTMRCache())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Récupère la liste des cases à portées
|
|
||||||
let locList = TMRUtility.getTMRPortee(coord, portee);
|
|
||||||
this.colorierZoneRencontre(locList);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async choisirCaseType(type) {
|
|
||||||
const locList = TMRUtility.filterTMR(it => it.type == type).map(it => it.coord);
|
|
||||||
this.colorierZoneRencontre(locList);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
checkQuitterTMR() {
|
checkQuitterTMR() {
|
||||||
|
|
||||||
@@ -375,15 +377,15 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async quitterLesTMRInconscient() {
|
async quitterLesTMRInconscient() {
|
||||||
if (this.currentRencontre?.isPersistant) {
|
await this.refouler();
|
||||||
await this.refouler();
|
|
||||||
}
|
|
||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async maitriserRencontre() {
|
async maitriserRencontre() {
|
||||||
this.actor.deleteTMRRencontreAtPosition();
|
console.log("-> maitriser", this.currentRencontre);
|
||||||
|
|
||||||
|
await this.actor.deleteTMRRencontreAtPosition();
|
||||||
this.updateTokens();
|
this.updateTokens();
|
||||||
|
|
||||||
let rencontreData = {
|
let rencontreData = {
|
||||||
@@ -394,7 +396,7 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
rencontre: this.currentRencontre,
|
rencontre: this.currentRencontre,
|
||||||
nbRounds: 1,
|
nbRounds: 1,
|
||||||
canClose: false,
|
canClose: false,
|
||||||
selectedCarac: {label: "reve-actuel"},
|
selectedCarac: { label: "reve-actuel" },
|
||||||
tmr: TMRUtility.getTMR(this._getActorCoord())
|
tmr: TMRUtility.getTMR(this._getActorCoord())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,8 +405,6 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async _tentativeMaitrise(rencData) {
|
async _tentativeMaitrise(rencData) {
|
||||||
console.log("-> matriser", rencData);
|
|
||||||
|
|
||||||
rencData.reve = this.actor.getReveActuel();
|
rencData.reve = this.actor.getReveActuel();
|
||||||
rencData.etat = this.actor.getEtatGeneral();
|
rencData.etat = this.actor.getEtatGeneral();
|
||||||
|
|
||||||
@@ -414,41 +414,67 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
? this._rollPresentCite(rencData)
|
? this._rollPresentCite(rencData)
|
||||||
: await RdDResolutionTable.roll(rencData.reve, RollDataAjustements.sum(rencData.ajustements));
|
: await RdDResolutionTable.roll(rencData.reve, RollDataAjustements.sum(rencData.ajustements));
|
||||||
|
|
||||||
let postProcess = await TMRRencontres.gererRencontre(this, rencData);
|
const result = rencData.rolled.isSuccess
|
||||||
|
? rencData.rencontre.system.succes
|
||||||
|
: rencData.rencontre.system.echec;
|
||||||
|
|
||||||
|
await RdDRencontre.appliquer(result.effets, this, rencData);
|
||||||
|
|
||||||
|
rencData.poesie = { extrait: result.poesie, reference: result.reference };
|
||||||
|
rencData.message = this.formatMessageRencontre(rencData, result.message);
|
||||||
|
|
||||||
ChatMessage.create({
|
ChatMessage.create({
|
||||||
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
|
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
|
||||||
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-rencontre-tmr.html`, rencData)
|
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-rencontre-tmr.html`, rencData)
|
||||||
});
|
});
|
||||||
|
|
||||||
if (postProcess) {
|
|
||||||
/** Gère les rencontres avec du post-processing (passeur, messagers, tourbillons, ...) */
|
|
||||||
await postProcess(this, rencData);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.currentRencontre = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.updateValuesDisplay();
|
this.updateValuesDisplay();
|
||||||
if (this.checkQuitterTMR()) {
|
if (this.checkQuitterTMR()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (rencData.rolled.isEchec && rencData.rencontre.isPersistant) {
|
if (this.rencontreState == 'persistant') {
|
||||||
setTimeout(() => {
|
this._nouvelleTentativeMaitrise(rencData);
|
||||||
rencData.nbRounds++;
|
}
|
||||||
if (ReglesOptionelles.isUsing("appliquer-fatigue")) {
|
else if (!this.isRencontreDeplacement()) {
|
||||||
this.cumulFatigue += this.fatigueParCase;
|
this.nettoyerRencontre();
|
||||||
}
|
}
|
||||||
this._tentativeMaitrise(rencData);
|
}
|
||||||
this._deleteTmrMessages(rencData.actor, rencData.nbRounds);
|
|
||||||
}, 2000);
|
_nouvelleTentativeMaitrise(rencData) {
|
||||||
|
setTimeout(() => {
|
||||||
|
// TODO: remplacer par une boucle while(this.currentRencontre) ?
|
||||||
|
rencData.nbRounds++;
|
||||||
|
if (ReglesOptionelles.isUsing("appliquer-fatigue")) {
|
||||||
|
this.cumulFatigue += this.fatigueParCase;
|
||||||
|
}
|
||||||
|
this._tentativeMaitrise(rencData);
|
||||||
|
this._deleteTmrMessages(rencData.actor, rencData.nbRounds);
|
||||||
|
}, 2000);
|
||||||
|
this.rencontreState == 'normal';
|
||||||
|
}
|
||||||
|
|
||||||
|
formatMessageRencontre(rencData, template) {
|
||||||
|
let messageDuree = ''
|
||||||
|
if (rencData.nbRounds > 1) {
|
||||||
|
if (rencData.rolled.isSuccess) {
|
||||||
|
messageDuree = ` Au total, vous avez passé ${rencData.nbRounds} rounds à vous battre!`;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
messageDuree = ` Vous avez passé ${rencData.nbRounds} rounds à lutter!`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const compiled = Handlebars.compile(template);
|
||||||
|
return compiled(rencData) + messageDuree ;
|
||||||
|
} catch (error) {
|
||||||
|
return template + messageDuree ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_rollPresentCite(rencontreData) {
|
_rollPresentCite(rencData) {
|
||||||
let rolled = RdDResolutionTable.computeChances(rencontreData.reve, 0);
|
let rolled = RdDResolutionTable.computeChances(rencData.reve, 0);
|
||||||
mergeObject(rolled, { caracValue: rencontreData.reve, finalLevel: 0, roll: rolled.score });
|
mergeObject(rolled, { caracValue: rencData.reve, finalLevel: 0, roll: rolled.score });
|
||||||
RdDResolutionTable.succesRequis(rolled);
|
RdDResolutionTable.succesRequis(rolled);
|
||||||
return rolled;
|
return rolled;
|
||||||
}
|
}
|
||||||
@@ -483,44 +509,49 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async manageRencontre(tmr, postRencontre) {
|
async manageRencontre(tmr) {
|
||||||
if (this.viewOnly) {
|
if (this.viewOnly) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this.descenteTMR = false;
|
||||||
this.currentRencontre = undefined;
|
this.currentRencontre = undefined;
|
||||||
if (this._presentCite(tmr, postRencontre)) {
|
if (this._presentCite(tmr)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let rencontre = await this._jetDeRencontre(tmr);
|
this.currentRencontre = await this._jetDeRencontre(tmr);
|
||||||
|
if (this.currentRencontre) {
|
||||||
if (rencontre) { // Manages it
|
if (this.rencontresExistantes.find(it => it.id == this.currentRencontre.id)){
|
||||||
if (rencontre.rencontre) rencontre = rencontre.rencontre; // Manage stored rencontres
|
// rencontre en attente suite à dérobade
|
||||||
console.log("manageRencontre", rencontre);
|
await this.maitriserRencontre();
|
||||||
this.currentRencontre = duplicate(rencontre);
|
}
|
||||||
|
else {
|
||||||
let dialog = new RdDTMRRencontreDialog("", this, this.currentRencontre, postRencontre);
|
let dialog = new RdDTMRRencontreDialog(this, this.currentRencontre, tmr);
|
||||||
dialog.render(true);
|
dialog.render(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
postRencontre();
|
this.postRencontre(tmr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_presentCite(tmr, postRencontre) {
|
_presentCite(tmr) {
|
||||||
const presentCite = this.casesSpeciales.find(c => EffetsDraconiques.presentCites.isCase(c, tmr.coord));
|
const presentCite = this.casesSpeciales.find(c => EffetsDraconiques.presentCites.isCase(c, tmr.coord));
|
||||||
if (presentCite) {
|
if (presentCite) {
|
||||||
this.minimize();
|
this.minimize();
|
||||||
const caseData = presentCite;
|
const caseData = presentCite;
|
||||||
EffetsDraconiques.presentCites.choisirUnPresent(caseData, (type => this._utiliserPresentCite(presentCite, type, tmr, postRencontre)));
|
EffetsDraconiques.presentCites.choisirUnPresent(caseData, (present => this._utiliserPresentCite(presentCite, present, tmr)));
|
||||||
}
|
}
|
||||||
return presentCite;
|
return presentCite;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async _utiliserPresentCite(presentCite, typeRencontre, tmr, postRencontre) {
|
async _utiliserPresentCite(presentCite, present, tmr) {
|
||||||
this.currentRencontre = TMRRencontres.getRencontre(typeRencontre);
|
this.currentRencontre = present.clone({
|
||||||
await TMRRencontres.evaluerForceRencontre(this.currentRencontre);
|
'system.force': await RdDDice.rollTotal(present.system.formule),
|
||||||
|
'system.coord': tmr.coord
|
||||||
|
}, {save: false});
|
||||||
|
|
||||||
await EffetsDraconiques.presentCites.ouvrirLePresent(this.actor, presentCite);
|
await EffetsDraconiques.presentCites.ouvrirLePresent(this.actor, presentCite);
|
||||||
this.removeToken(tmr, presentCite);
|
this.removeToken(tmr, presentCite);
|
||||||
|
|
||||||
@@ -537,42 +568,38 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
await this._tentativeMaitrise(rencontreData);
|
await this._tentativeMaitrise(rencontreData);
|
||||||
|
|
||||||
this.maximize();
|
this.maximize();
|
||||||
postRencontre();
|
this.postRencontre(tmr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async _jetDeRencontre(tmr) {
|
async _jetDeRencontre(tmr) {
|
||||||
let rencontre = this.rencontresExistantes.find(prev => prev.coord == tmr.coord);
|
let rencontre = this.lookupRencontreExistente(tmr);
|
||||||
if (rencontre) {
|
if (rencontre) {
|
||||||
return rencontre;
|
return game.system.rdd.rencontresTMR.calculRencontre(rencontre, tmr);
|
||||||
}
|
}
|
||||||
let locTMR = (this.isDemiReveCache()
|
let locTMR = (this.isDemiReveCache()
|
||||||
? Misc.upperFirst(tmr.type) + " ??"
|
? TMRUtility.getTMRType(tmr.coord) + " ??"
|
||||||
: tmr.label + " (" + tmr.coord + ")");
|
: tmr.label + " (" + tmr.coord + ")");
|
||||||
|
|
||||||
let myRoll = await RdDDice.rollTotal("1dt");
|
let myRoll = await RdDDice.rollTotal("1dt", { showDice: SHOW_DICE });
|
||||||
if (TMRUtility.isForceRencontre() || myRoll == 7) {
|
if (myRoll == 7) {
|
||||||
this._tellToUser(myRoll + ": Rencontre en " + locTMR);
|
this._tellToUser(myRoll + ": Rencontre en " + locTMR);
|
||||||
return await this.rencontreTMRRoll(tmr, this.actor.isRencontreSpeciale());
|
return await game.system.rdd.rencontresTMR.getRencontreAleatoire(tmr, this.actor.isMauvaiseRencontre())
|
||||||
} else {
|
} else {
|
||||||
this._tellToUser(myRoll + ": Pas de rencontre en " + locTMR);
|
this._tellToUser(myRoll + ": Pas de rencontre en " + locTMR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
lookupRencontreExistente(tmr) {
|
||||||
async rencontreTMRRoll(tmr, isMauvaise = false) {
|
return this.rencontresExistantes.find(it => it.system.coord == tmr.coord)
|
||||||
let rencontre = TMRUtility.utiliseForceRencontre() ??
|
?? this.rencontresExistantes.find(it => it.system.coord == "");
|
||||||
(isMauvaise
|
|
||||||
? await TMRRencontres.getMauvaiseRencontre()
|
|
||||||
: await TMRRencontres.getRencontreAleatoire(tmr.type));
|
|
||||||
rencontre.coord = tmr.coord;
|
|
||||||
rencontre.date = game.system.rdd.calendrier.getDateFromIndex();
|
|
||||||
rencontre.heure = game.system.rdd.calendrier.getCurrentHeure();
|
|
||||||
return rencontre;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async manageTmrInnaccessible(tmr) {
|
async manageTmrInnaccessible(tmr) {
|
||||||
|
if (!tmr) {
|
||||||
|
return await this.actor.reinsertionAleatoire('Sortie de carte');
|
||||||
|
}
|
||||||
const caseTmrInnaccessible = this.casesSpeciales.find(c => EffetsDraconiques.isInnaccessible(c, tmr.coord));
|
const caseTmrInnaccessible = this.casesSpeciales.find(c => EffetsDraconiques.isInnaccessible(c, tmr.coord));
|
||||||
if (caseTmrInnaccessible) {
|
if (caseTmrInnaccessible) {
|
||||||
return await this.actor.reinsertionAleatoire(caseTmrInnaccessible.name);
|
return await this.actor.reinsertionAleatoire(caseTmrInnaccessible.name);
|
||||||
@@ -593,7 +620,7 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
maitrise: { verbe: 'maîtriser', action: 'Maîtriser le fleuve' }
|
maitrise: { verbe: 'maîtriser', action: 'Maîtriser le fleuve' }
|
||||||
}
|
}
|
||||||
rollData.double = EffetsDraconiques.isDoubleResistanceFleuve(this.actor) ? true : undefined,
|
rollData.double = EffetsDraconiques.isDoubleResistanceFleuve(this.actor) ? true : undefined,
|
||||||
rollData.competence.system.defaut_carac = 'reve-actuel';
|
rollData.competence.system.defaut_carac = 'reve-actuel';
|
||||||
await this._rollMaitriseCaseHumide(rollData);
|
await this._rollMaitriseCaseHumide(rollData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -605,7 +632,6 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
|
|
||||||
async _resultatMaitriseCaseHumide(rollData) {
|
async _resultatMaitriseCaseHumide(rollData) {
|
||||||
await this.souffleSiEchecTotal(rollData);
|
await this.souffleSiEchecTotal(rollData);
|
||||||
this.toclose = rollData.rolled.isEchec;
|
|
||||||
if (rollData.rolled.isSuccess && rollData.double) {
|
if (rollData.rolled.isSuccess && rollData.double) {
|
||||||
rollData.previous = { rolled: rollData.rolled, ajustements: rollData.ajustements };
|
rollData.previous = { rolled: rollData.rolled, ajustements: rollData.ajustements };
|
||||||
rollData.double = undefined;
|
rollData.double = undefined;
|
||||||
@@ -618,7 +644,7 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-maitrise-tmr.html`, rollData)
|
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-maitrise-tmr.html`, rollData)
|
||||||
});
|
});
|
||||||
if (rollData.rolled.isEchec) {
|
if (rollData.rolled.isEchec) {
|
||||||
this.close();
|
await this.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -632,16 +658,16 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
isCaseHumide(tmr) {
|
isCaseHumide(tmr) {
|
||||||
if (!(TMRUtility.isCaseHumide(tmr) || this.isCaseHumideAdditionelle(tmr))) {
|
if (!(TMRUtility.isCaseHumide(tmr) || this.isCaseHumideAdditionelle(tmr))) {
|
||||||
return undefined;
|
return false;
|
||||||
}
|
}
|
||||||
if (this.isCaseMaitrisee(tmr.coord)) {
|
if (this.isCaseMaitrisee(tmr.coord)) {
|
||||||
ChatMessage.create({
|
ChatMessage.create({
|
||||||
content: tmr.label + ": cette case humide est déja maitrisée grâce à votre Tête <strong>Quête des Eaux</strong>",
|
content: tmr.label + ": cette case humide est déja maitrisée grâce à votre Tête <strong>Quête des Eaux</strong>",
|
||||||
whisper: ChatMessage.getWhisperRecipients(game.user.name)
|
whisper: ChatMessage.getWhisperRecipients(game.user.name)
|
||||||
});
|
});
|
||||||
return undefined;
|
return false;
|
||||||
}
|
}
|
||||||
return -7;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -728,8 +754,6 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
if (rollData.rolled.isETotal) {
|
if (rollData.rolled.isETotal) {
|
||||||
rollData.souffle = await this.actor.ajouterSouffle({ chat: false });
|
rollData.souffle = await this.actor.ajouterSouffle({ chat: false });
|
||||||
}
|
}
|
||||||
this.toclose = rollData.rolled.isEchec;
|
|
||||||
|
|
||||||
rollData.poesie = await Poetique.getExtrait();
|
rollData.poesie = await Poetique.getExtrait();
|
||||||
ChatMessage.create({
|
ChatMessage.create({
|
||||||
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
|
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
|
||||||
@@ -751,7 +775,6 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
const dialog = await RdDRoll.create(this.actor, rollData,
|
const dialog = await RdDRoll.create(this.actor, rollData,
|
||||||
{
|
{
|
||||||
html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-maitrise-tmr.html',
|
html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-maitrise-tmr.html',
|
||||||
options: { height: 420 },
|
|
||||||
close: html => { this.maximize(); } // Re-display TMR
|
close: html => { this.maximize(); } // Re-display TMR
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -774,9 +797,8 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async declencheSortEnReserve(coord) {
|
async declencheSortEnReserve(coord) {
|
||||||
|
let sorts = this.getSortsReserve(coord);
|
||||||
let sortsEnCoord = TMRUtility.getSortsReserve(this.sortsReserves, coord);
|
if (sorts.length > 0) {
|
||||||
if (sortsEnCoord.length > 0) {
|
|
||||||
if (EffetsDraconiques.isSortReserveImpossible(this.actor)) {
|
if (EffetsDraconiques.isSortReserveImpossible(this.actor)) {
|
||||||
ui.notifications.error("Une queue ou un souffle vous empèche de déclencher de sort!");
|
ui.notifications.error("Une queue ou un souffle vous empèche de déclencher de sort!");
|
||||||
return;
|
return;
|
||||||
@@ -784,8 +806,8 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
if (!EffetsDraconiques.isUrgenceDraconique(this.actor) &&
|
if (!EffetsDraconiques.isUrgenceDraconique(this.actor) &&
|
||||||
(EffetsDraconiques.isReserveEnSecurite(this.actor) || this.isReserveExtensible(coord))) {
|
(EffetsDraconiques.isReserveEnSecurite(this.actor) || this.isReserveExtensible(coord))) {
|
||||||
let msg = "Vous êtes sur une case avec un Sort en Réserve. Grâce à votre Tête <strong>Reserve en Sécurité</strong> ou <strong>Réserve Exensible</strong>, vous pouvez contrôler le déclenchement. Cliquez si vous souhaitez le déclencher : <ul>";
|
let msg = "Vous êtes sur une case avec un Sort en Réserve. Grâce à votre Tête <strong>Reserve en Sécurité</strong> ou <strong>Réserve Exensible</strong>, vous pouvez contrôler le déclenchement. Cliquez si vous souhaitez le déclencher : <ul>";
|
||||||
for (let sortReserve of sortsEnCoord) {
|
for (let sort of sorts) {
|
||||||
msg += "<li><a class='chat-card-button' id='sort-reserve' data-actor-id='" + this.actor._id + "' data-tmr-coord='" + coord + "' data-sort-id='" + sortReserve.sort._id + "'>" + sortReserve.sort.name + "</a></li>";
|
msg += `<li><a class="chat-card-button declencher-sort-reserve" data-actor-id="${this.actor.id}" data-tmr-coord="${coord}" data-sort-id='${sort.id}">${sort.name}</a></li>`;
|
||||||
}
|
}
|
||||||
msg += "</ol>";
|
msg += "</ol>";
|
||||||
ChatMessage.create({
|
ChatMessage.create({
|
||||||
@@ -794,33 +816,36 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await this.processSortReserve(sortsEnCoord[0]);
|
await this.processSortReserve(sorts[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
lancerSortEnReserve(coord, sortId) {
|
lancerSortEnReserve(coord, sortId) {
|
||||||
let sortEnCoord = TMRUtility.getSortsReserve(this.sortsReserves, coord);
|
let sorts = this.getSortsReserve(coord);
|
||||||
let sortReserve = sortEnCoord.find(sortReserve => sortReserve.sort._id == sortId);
|
let sort = sorts.find(it => it.id == sortId);
|
||||||
if (sortReserve) {
|
if (sort) {
|
||||||
this.processSortReserve(sortReserve);
|
this.processSortReserve(sort);
|
||||||
} else {
|
} else {
|
||||||
ChatMessage.create({
|
ChatMessage.create({
|
||||||
content: "Une erreur est survenue : impossible de récupérer le sort en réserve demandé.",
|
content:
|
||||||
whisper: ChatMessage.getWhisperRecipients(game.user.name)
|
"Une erreur est survenue : impossible de récupérer le sort en réserve demandé.",
|
||||||
|
whisper: ChatMessage.getWhisperRecipients(game.user.name),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async processSortReserve(sortReserve) {
|
async processSortReserve(sortReserve) {
|
||||||
await this.actor.deleteSortReserve(sortReserve);
|
await this.actor.deleteEmbeddedDocuments('Item', [sortReserve.id]);
|
||||||
//this.updateSortReserve();
|
console.log("declencheSortEnReserve", sortReserve);
|
||||||
console.log("declencheSortEnReserve", sortReserve)
|
const heureCible = RdDCalendrier.getSigneAs('label', sortReserve.system.heurecible);
|
||||||
this._tellToUserAndGM(`Vous avez déclenché le sort en réserve <strong> ${sortReserve.sort.name}</strong>
|
this._tellToUserAndGM(`Vous avez déclenché
|
||||||
avec ${sortReserve.sort.data.ptreve_reel} points de Rêve
|
${sortReserve.system.echectotal ? "<strong>l'échec total!</strong>" : "le sort"}
|
||||||
en ${sortReserve.coord} (${TMRUtility.getTMRLabel(sortReserve.coord)})
|
en réserve <strong>${sortReserve.name}</strong>
|
||||||
`);
|
avec ${sortReserve.system.ptreve} points de Rêve
|
||||||
|
en ${sortReserve.system.coord} (${TMRUtility.getTMRLabel(sortReserve.system.coord)}).
|
||||||
|
L'heure ciblée est ${heureCible}`);
|
||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -886,14 +911,14 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
|
|
||||||
if (this.isDemiReveCache()) {
|
if (this.isDemiReveCache()) {
|
||||||
if (this.isTerreAttache(targetCoord)
|
if (this.isTerreAttache(targetCoord)
|
||||||
|| (this.isCaseHumide(currentCoord) && this.isCaseHumide(targetCoord))
|
|| this.isConnaissanceFleuve(currentCoord, targetCoord)
|
||||||
|| deplacementType == 'changeur')
|
|| deplacementType == 'changeur') {
|
||||||
{
|
|
||||||
// déplacement possible
|
// déplacement possible
|
||||||
await this.actor.montreTMR();
|
await this.actor.setTMRVisible(true);
|
||||||
|
this.demiReve = this._tokenDemiReve();
|
||||||
|
this._trackToken(this.demiReve);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
ui.notifications.error(`Vous ne connaissez plus votre position dans les TMR.
|
ui.notifications.error(`Vous ne connaissez plus votre position dans les TMR.
|
||||||
Vous devez utiliser les boutons de direction pour vous déplacer.
|
Vous devez utiliser les boutons de direction pour vous déplacer.
|
||||||
Une fois que vous aurez retrouvé votre demi-rêve, demandez au gardien de vérifier et rendre les TMR visibles.
|
Une fois que vous aurez retrouvé votre demi-rêve, demandez au gardien de vérifier et rendre les TMR visibles.
|
||||||
@@ -902,20 +927,18 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (deplacementType){
|
switch (deplacementType) {
|
||||||
case 'normal':
|
case 'normal':
|
||||||
|
case 'changeur':
|
||||||
|
case 'passeur':
|
||||||
await this._deplacerDemiReve(targetCoord, deplacementType);
|
await this._deplacerDemiReve(targetCoord, deplacementType);
|
||||||
break;
|
break;
|
||||||
case 'messager':
|
case 'messager':
|
||||||
await this._messagerDemiReve(targetCoord);
|
await this._messagerDemiReve(targetCoord);
|
||||||
break;
|
break;
|
||||||
case 'changeur':
|
|
||||||
case 'passeur':
|
|
||||||
await this._deplacerDemiReve(targetCoord, deplacementType);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
ui.notifications.error("Vous ne pouvez pas vous déplacer que sur des cases adjacentes à votre position ou valides dans le cas d'une rencontre");
|
ui.notifications.error("Vous ne pouvez pas vous déplacer que sur des cases adjacentes à votre position ou valides dans le cas d'une rencontre");
|
||||||
console.log("STATUS :", this.rencontreState, this.currentRencontre);
|
console.log("STATUS :", this.rencontreState, this.currentRencontre);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.checkQuitterTMR();
|
this.checkQuitterTMR();
|
||||||
@@ -923,19 +946,23 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_calculDeplacement(targetCoord, currentCoord, fromOddq, toOddq) {
|
_calculDeplacement(targetCoord, currentCoord, fromOddq, toOddq) {
|
||||||
|
if (this.isRencontreDeplacement()) {
|
||||||
const isInArea = this.rencontreState == 'aucune'
|
if (this.currentRencontre?.locList?.find(coord => coord == targetCoord)) {
|
||||||
? (this.isTerreAttache(targetCoord) || this.isConnaissanceFleuve(currentCoord, targetCoord) || TMRUtility.distanceOddq(fromOddq, toOddq) <= 1)
|
return this.rencontreState;
|
||||||
: this.currentRencontre?.locList.find(coord => coord == targetCoord) ?? false
|
}
|
||||||
if (isInArea) {
|
}
|
||||||
switch (this.rencontreState) {
|
else {
|
||||||
case 'aucune': return 'normal';
|
if (this.isTerreAttache(targetCoord) || this.isConnaissanceFleuve(currentCoord, targetCoord) || TMRUtility.distanceOddq(fromOddq, toOddq) <= 1) {
|
||||||
case 'passeur': case 'changeur': case 'messager': return this.rencontreState;
|
return 'normal'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 'erreur';
|
return 'erreur';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isRencontreDeplacement() {
|
||||||
|
return ['passeur', 'changeur', 'messager'].includes(this.rencontreState);
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async _messagerDemiReve(targetCoord) {
|
async _messagerDemiReve(targetCoord) {
|
||||||
/*
|
/*
|
||||||
@@ -975,7 +1002,7 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
this.actor.notifyRefreshTMR();
|
this.actor.notifyRefreshTMR();
|
||||||
|
|
||||||
if (deplacementType == 'normal') { // Pas de rencontres après un saut de type passeur/changeur/...
|
if (deplacementType == 'normal') { // Pas de rencontres après un saut de type passeur/changeur/...
|
||||||
await this.manageRencontre(tmr, () => this.postRencontre(tmr));
|
await this.manageRencontre(tmr);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
await this.postRencontre(tmr);
|
await this.postRencontre(tmr);
|
||||||
@@ -994,13 +1021,14 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async postRencontre(tmr) {
|
async postRencontre(tmr) {
|
||||||
if (!(this.viewOnly || this.currentRencontre)) {
|
if (!(this.viewOnly || this.currentRencontre)) {
|
||||||
await this.manageCaseHumide(tmr);
|
// TODO: vérifier que la méthode s'arrête en cas de non-maîtrise
|
||||||
await this.conquerirCiteFermee(tmr);
|
if (!this.descenteTMR) await this.manageCaseHumide(tmr);
|
||||||
await this.purifierPeriple(tmr);
|
if (!this.descenteTMR) await this.conquerirCiteFermee(tmr);
|
||||||
await this.conquerirTMR(tmr);
|
if (!this.descenteTMR) await this.purifierPeriple(tmr);
|
||||||
await this.validerVisite(tmr);
|
if (!this.descenteTMR) await this.conquerirTMR(tmr);
|
||||||
await this.declencheSortEnReserve(tmr.coord);
|
if (!this.descenteTMR) await this.validerVisite(tmr);
|
||||||
await this.actor.checkSoufflePeage(tmr);
|
if (!this.descenteTMR) await this.declencheSortEnReserve(tmr.coord);
|
||||||
|
if (!this.descenteTMR) await this.actor.checkSoufflePeage(tmr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1019,7 +1047,7 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
let x = origEvent.clientX - canvasRect.left;
|
let x = origEvent.clientX - canvasRect.left;
|
||||||
let y = origEvent.clientY - canvasRect.top;
|
let y = origEvent.clientY - canvasRect.top;
|
||||||
let col = Math.floor(x / tmrConstants.cellw); // [From 0 -> 12]
|
let col = Math.floor(x / tmrConstants.cellw); // [From 0 -> 12]
|
||||||
y -= (col % 2 == 0) ? tmrConstants.col1_y : tmrConstants.col2_y;
|
y -= col % 2 == 0 ? tmrConstants.col1_y : tmrConstants.col2_y;
|
||||||
let row = Math.floor(y / tmrConstants.cellh); // [From 0 -> 14]
|
let row = Math.floor(y / tmrConstants.cellh); // [From 0 -> 14]
|
||||||
return { col: col, row: row };
|
return { col: col, row: row };
|
||||||
}
|
}
|
||||||
@@ -1029,7 +1057,7 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
_getCaseRectangleCoord(coord) {
|
_getCaseRectangleCoord(coord) {
|
||||||
return this.pixiTMR.getCaseRectangle(TMRUtility.coordTMRToOddq(coord));
|
return this.pixiTMR.getCaseRectangle(TMRUtility.coordTMRToOddq(coord));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_removeTokens(filter) {
|
_removeTokens(filter) {
|
||||||
const tokensToRemove = this.allTokens.filter(filter);
|
const tokensToRemove = this.allTokens.filter(filter);
|
||||||
@@ -1037,7 +1065,7 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
this.pixiApp.stage.removeChild(token.sprite);
|
this.pixiApp.stage.removeChild(token.sprite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_trackToken(token) {
|
_trackToken(token) {
|
||||||
if (this.demiReve === token && this.isDemiReveCache()) {
|
if (this.demiReve === token && this.isDemiReveCache()) {
|
||||||
|
|||||||
@@ -2,46 +2,41 @@
|
|||||||
export class RdDTMRRencontreDialog extends Dialog {
|
export class RdDTMRRencontreDialog extends Dialog {
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
constructor(html, tmrApp, rencontre, postRencontre) {
|
constructor(tmrApp, rencontre, tmr) {
|
||||||
const dialogConf = {
|
const dialogConf = {
|
||||||
title: "Rencontre en TMR!",
|
title: "Rencontre en TMR!",
|
||||||
content: "Vous rencontrez un " + rencontre.name + " de force " + rencontre.force + "<br>",
|
content: "Vous rencontrez un " + rencontre.name + " de force " + rencontre.system.force + "<br>",
|
||||||
buttons: {
|
buttons: {
|
||||||
derober: { icon: '<i class="fas fa-check"></i>', label: "Se dérober", callback: () => { this.onButtonFuir(() => tmrApp.derober()); } },
|
derober: { icon: '<i class="fas fa-check"></i>', label: "Se dérober", callback: () => this.onButtonAction('derober') },
|
||||||
refouler: { icon: '<i class="fas fa-check"></i>', label: "Refouler", callback: () => this.onButtonAction(() => tmrApp.refouler()) },
|
maitiser: { icon: '<i class="fas fa-check"></i>', label: "Maîtriser", callback: () => this.onButtonAction('maitriser') }
|
||||||
maitiser: { icon: '<i class="fas fa-check"></i>', label: "Maîtriser", callback: () => this.onButtonAction(() => tmrApp.maitriserRencontre()) }
|
|
||||||
},
|
},
|
||||||
default: "derober"
|
default: "derober"
|
||||||
};
|
}
|
||||||
if (rencontre.ignorer) {
|
if ((rencontre.system.refoulement ?? 0) == 0) {
|
||||||
dialogConf.buttons.ignorer = { icon: '<i class="fas fa-check"></i>', label: "Ignorer", callback: () => this.onButtonAction(() => tmrApp.ignorerRencontre()) }
|
dialogConf.buttons.ignorer = { icon: '<i class="fas fa-check"></i>', label: "Ignorer", callback: () => this.onButtonAction('ignorer') }
|
||||||
};
|
}
|
||||||
|
else {
|
||||||
|
dialogConf.buttons.refouler = { icon: '<i class="fas fa-check"></i>', label: "Refouler", callback: () => this.onButtonAction('refouler') }
|
||||||
|
}
|
||||||
|
|
||||||
const dialogOptions = {
|
const dialogOptions = {
|
||||||
classes: ["tmrrencdialog"],
|
classes: ["tmrrencdialog"],
|
||||||
width: 320, height: 240,
|
width: 320, height: 'fit-content',
|
||||||
'z-index': 50
|
'z-index': 50
|
||||||
}
|
}
|
||||||
super(dialogConf, dialogOptions);
|
super(dialogConf, dialogOptions);
|
||||||
|
|
||||||
this.toClose = false;
|
this.toClose = false;
|
||||||
this.rencontreData = duplicate(rencontre);
|
this.tmr = tmr;
|
||||||
this.postRencontre = postRencontre;
|
|
||||||
this.tmrApp = tmrApp;
|
this.tmrApp = tmrApp;
|
||||||
this.tmrApp.minimize();
|
this.tmrApp.minimize();
|
||||||
}
|
}
|
||||||
|
|
||||||
async onButtonAction(action) {
|
async onButtonAction(action) {
|
||||||
this.toClose = true;
|
this.toClose = true;
|
||||||
await action();
|
this.tmrApp.onActionRencontre(action, this.tmr)
|
||||||
this.postRencontre();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async onButtonFuir(action) {
|
|
||||||
this.toClose = true;
|
|
||||||
await action();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
close() {
|
close() {
|
||||||
if (this.toClose) {
|
if (this.toClose) {
|
||||||
|
|||||||
@@ -1,17 +1,21 @@
|
|||||||
/* Common useful functions shared between objects */
|
/* Common useful functions shared between objects */
|
||||||
|
|
||||||
import { ChatUtility } from "./chat-utility.js";
|
import { ChatUtility } from "./chat-utility.js";
|
||||||
import { RdDCombat } from "./rdd-combat.js";
|
import { RdDCombat } from "./rdd-combat.js";
|
||||||
import { Misc } from "./misc.js";
|
import { Misc } from "./misc.js";
|
||||||
import { Grammar } from "./grammar.js";
|
import { Grammar } from "./grammar.js";
|
||||||
import { TMRUtility } from "./tmr-utility.js";
|
import { TMRUtility } from "./tmr-utility.js";
|
||||||
import { DialogItemAchat } from "./dialog-item-achat.js";
|
import { DialogItemAchat } from "./dialog-item-achat.js";
|
||||||
import { ReglesOptionelles } from "./regles-optionelles.js";
|
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
||||||
import { RdDDice } from "./rdd-dice.js";
|
import { RdDDice } from "./rdd-dice.js";
|
||||||
import { RdDItem } from "./item.js";
|
import { RdDItem } from "./item.js";
|
||||||
import { Monnaie } from "./item-monnaie.js";
|
import { Monnaie } from "./item-monnaie.js";
|
||||||
import { RdDPossession } from "./rdd-possession.js";
|
import { RdDPossession } from "./rdd-possession.js";
|
||||||
import { RdDNameGen } from "./rdd-namegen.js";
|
import { RdDNameGen } from "./rdd-namegen.js";
|
||||||
|
import { RdDConfirm } from "./rdd-confirm.js";
|
||||||
|
import { RdDCalendrier } from "./rdd-calendrier.js";
|
||||||
|
import { Environnement } from "./environnement.js";
|
||||||
|
import { RdDItemCompetence } from "./item-competence.js";
|
||||||
|
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
// This table starts at 0 -> niveau -10
|
// This table starts at 0 -> niveau -10
|
||||||
@@ -115,23 +119,63 @@ export class RdDUtility {
|
|||||||
'systems/foundryvtt-reve-de-dragon/templates/actor-creature-sheet.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor-creature-sheet.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor-entite-sheet.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor-entite-sheet.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor-vehicule-sheet.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor-vehicule-sheet.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-competence-partial.html',
|
// sous-parties de feuilles de personnages
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-categorie-competences-partial.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/header-buttons.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-effects-partial.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/header-etat.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-oeuvre-partial.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/header-compteurs.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor-liste-blessures-partial.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/header-compteurs-creature.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor-blessure-partial.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/header-compteurs-entitee.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-queues.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/header-effects.html',
|
||||||
// Conteneur/item in Actor sheet
|
'systems/foundryvtt-reve-de-dragon/templates/actor/vue-detaillee.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-inventaire.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/carac-main.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-item-queue.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/carac-derivee.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-inventaire-item.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/carac-creature.html',
|
||||||
"systems/foundryvtt-reve-de-dragon/templates/actor-sheet-inventaire-monnaie.html",
|
'systems/foundryvtt-reve-de-dragon/templates/actor/carac-entitee.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-liens-animaux.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/comp-creature.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-liens-suivants.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/comp-possession.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-liens-vehicules.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/carac-total.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-editor-notes-mj.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/competence.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html',
|
||||||
|
'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/maladies-poisons.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/possessions.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/taches.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/taches.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/oeuvres.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/oeuvre.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/jeux.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/alchimie.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/astrologie.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/non-haut-revant.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/haut-revant.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-queues.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-queue.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-souffles.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-tetes.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/hr-signes-draconiques.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/hr-rencontres.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/hr-sorts.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/hr-sorts-reserve.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/hr-meditations.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/hr-casestmr.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/xp-journal.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/editor-notes-mj.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/inventaire.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-item.html',
|
||||||
|
"systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-monnaie.html",
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/liens-animaux.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/liens-suivants.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/liens-vehicules.html',
|
||||||
//Items
|
//Items
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete-script.hbs',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete.hbs',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/item/boutons-comestible.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/item/partial-inventaire.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/item/partial-environnement.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/item/partial-tab-environnement.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/header-item.html',
|
'systems/foundryvtt-reve-de-dragon/templates/header-item.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-competence-sheet.html',
|
'systems/foundryvtt-reve-de-dragon/templates/item-competence-sheet.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-competencecreature-sheet.html',
|
'systems/foundryvtt-reve-de-dragon/templates/item-competencecreature-sheet.html',
|
||||||
@@ -142,10 +186,11 @@ export class RdDUtility {
|
|||||||
'systems/foundryvtt-reve-de-dragon/templates/item-sort-sheet.html',
|
'systems/foundryvtt-reve-de-dragon/templates/item-sort-sheet.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-herbe-sheet.html',
|
'systems/foundryvtt-reve-de-dragon/templates/item-herbe-sheet.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-ingredient-sheet.html',
|
'systems/foundryvtt-reve-de-dragon/templates/item-ingredient-sheet.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/item-faune-sheet.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-livre-sheet.html',
|
'systems/foundryvtt-reve-de-dragon/templates/item-livre-sheet.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-tache-sheet.html',
|
'systems/foundryvtt-reve-de-dragon/templates/item-tache-sheet.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-potion-sheet.html',
|
'systems/foundryvtt-reve-de-dragon/templates/item-potion-sheet.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-rencontresTMR-sheet.html',
|
'systems/foundryvtt-reve-de-dragon/templates/item-rencontre-sheet.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-queue-sheet.html',
|
'systems/foundryvtt-reve-de-dragon/templates/item-queue-sheet.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-souffle-sheet.html',
|
'systems/foundryvtt-reve-de-dragon/templates/item-souffle-sheet.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-tarot-sheet.html',
|
'systems/foundryvtt-reve-de-dragon/templates/item-tarot-sheet.html',
|
||||||
@@ -156,33 +201,28 @@ export class RdDUtility {
|
|||||||
'systems/foundryvtt-reve-de-dragon/templates/item-nourritureboisson-sheet.html',
|
'systems/foundryvtt-reve-de-dragon/templates/item-nourritureboisson-sheet.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-signedraconique-sheet.html',
|
'systems/foundryvtt-reve-de-dragon/templates/item-signedraconique-sheet.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-possession-sheet.html',
|
'systems/foundryvtt-reve-de-dragon/templates/item-possession-sheet.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/competence-carac-defaut.html',
|
'systems/foundryvtt-reve-de-dragon/templates/item-extraitpoetique-sheet.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/competence-base.html',
|
// partial enums
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/enum-caracteristiques.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/enum-base-competence.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-aspect-tarot.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-aspect-tarot.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-competence.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-competence.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-ingredient.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-ingredient.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-parade.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-parade.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-potion.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-vehicule.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-vehicule.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-competence.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-competence.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-herbesoin-ingredient.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-herbesoin-ingredient.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-potion.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-heures.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-initpremierround.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-initpremierround.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/enum-niveau-ethylisme.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-rarete.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-rarete.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/sort-draconic.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-queue.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/sort-tmr.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-draconic.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/niveau-ethylisme.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-tmr-type.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/casetmr-specific-list.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-tmr-effet.html',
|
||||||
// Dialogs
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-resolution.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-sort.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-encaisser.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-meditation.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/dialog-tmr.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-alchimie.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/dialog-astrologie-joueur.html',
|
|
||||||
// Partials
|
// Partials
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/common/compendium-link.hbs',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/partial-description-overflow.html',
|
'systems/foundryvtt-reve-de-dragon/templates/partial-description-overflow.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/partial-description-sort.html',
|
'systems/foundryvtt-reve-de-dragon/templates/partial-description-sort.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/partial-roll-ajustements.html',
|
'systems/foundryvtt-reve-de-dragon/templates/partial-roll-ajustements.html',
|
||||||
@@ -193,12 +233,27 @@ export class RdDUtility {
|
|||||||
'systems/foundryvtt-reve-de-dragon/templates/partial-roll-enctotal.html',
|
'systems/foundryvtt-reve-de-dragon/templates/partial-roll-enctotal.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/partial-roll-moral.html',
|
'systems/foundryvtt-reve-de-dragon/templates/partial-roll-moral.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/partial-roll-forcer.html',
|
'systems/foundryvtt-reve-de-dragon/templates/partial-roll-forcer.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/partial-roll-competences.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/partial-select-carac.html',
|
'systems/foundryvtt-reve-de-dragon/templates/partial-select-carac.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/partial-item-hautrevant.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/partial-item-frequence.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/partial-item-description.html',
|
'systems/foundryvtt-reve-de-dragon/templates/partial-item-description.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/roll/explain.hbs',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/resolution-table.html',
|
||||||
|
// Dialogs
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-resolution.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-sort.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-encaisser.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/dialog-validation-encaissement.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-meditation.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/dialog-tmr.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-alchimie.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/dialog-astrologie-joueur.html',
|
||||||
// Calendrier
|
// Calendrier
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/calendar-template.html',
|
'systems/foundryvtt-reve-de-dragon/templates/calendar-template.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/calendar-editor-template.html',
|
'systems/foundryvtt-reve-de-dragon/templates/calendar-editor-template.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/heures-select-option.html',
|
|
||||||
// HUD
|
// HUD
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/hud-actor-init.html',
|
'systems/foundryvtt-reve-de-dragon/templates/hud-actor-init.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.html',
|
'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.html',
|
||||||
@@ -206,6 +261,7 @@ export class RdDUtility {
|
|||||||
'systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html',
|
'systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/chat-description.html',
|
'systems/foundryvtt-reve-de-dragon/templates/chat-description.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html',
|
'systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/chat-info-distance.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.html',
|
'systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-particuliere.html',
|
'systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-particuliere.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-etotal.html',
|
'systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-etotal.html',
|
||||||
@@ -228,6 +284,9 @@ export class RdDUtility {
|
|||||||
'systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-actor.html'
|
'systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-actor.html'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
Handlebars.registerHelper('either', (a, b) => a ?? b);
|
||||||
|
Handlebars.registerHelper('computeResolutionScore', (row, col) => RdDResolutionTable.computePercentage(row, col));
|
||||||
|
Handlebars.registerHelper('computeResolutionChances', (row, col) => RdDResolutionTable.computeChances(row, col));
|
||||||
Handlebars.registerHelper('upperFirst', str => Misc.upperFirst(str ?? 'Null'));
|
Handlebars.registerHelper('upperFirst', str => Misc.upperFirst(str ?? 'Null'));
|
||||||
Handlebars.registerHelper('lowerFirst', str => Misc.lowerFirst(str ?? 'Null'));
|
Handlebars.registerHelper('lowerFirst', str => Misc.lowerFirst(str ?? 'Null'));
|
||||||
Handlebars.registerHelper('upper', str => str?.toUpperCase() ?? 'NULL');
|
Handlebars.registerHelper('upper', str => str?.toUpperCase() ?? 'NULL');
|
||||||
@@ -239,45 +298,28 @@ export class RdDUtility {
|
|||||||
Handlebars.registerHelper('buildContenu', (objet) => { return new Handlebars.SafeString(RdDUtility.buildContenu(objet, 1, true)); });
|
Handlebars.registerHelper('buildContenu', (objet) => { return new Handlebars.SafeString(RdDUtility.buildContenu(objet, 1, true)); });
|
||||||
Handlebars.registerHelper('caseTmr-label', coord => TMRUtility.getTMRLabel(coord));
|
Handlebars.registerHelper('caseTmr-label', coord => TMRUtility.getTMRLabel(coord));
|
||||||
Handlebars.registerHelper('caseTmr-type', coord => TMRUtility.getTMRType(coord));
|
Handlebars.registerHelper('caseTmr-type', coord => TMRUtility.getTMRType(coord));
|
||||||
Handlebars.registerHelper('typeTmr-name', coord => TMRUtility.typeTmrName(coord));
|
Handlebars.registerHelper('typeTmr-name', type => TMRUtility.typeTmrName(type));
|
||||||
|
Handlebars.registerHelper('effetRencontre-name', coord => TMRUtility.typeTmrName(coord));
|
||||||
|
Handlebars.registerHelper('signeHeure', (key, heure) => RdDCalendrier.getSigneAs(key, heure));
|
||||||
Handlebars.registerHelper('min', (...args) => Math.min(...args.slice(0, -1)));
|
Handlebars.registerHelper('min', (...args) => Math.min(...args.slice(0, -1)));
|
||||||
|
Handlebars.registerHelper('regle-optionnelle', (option) => ReglesOptionelles.isUsing(option));
|
||||||
Handlebars.registerHelper('filtreTriCompetences', competences => competences.filter(it => it.system.isVisible)
|
Handlebars.registerHelper('trier', list => list.sort((a, b) => a.name.localeCompare(b.name)));
|
||||||
.sort((a, b) => {
|
Handlebars.registerHelper('filtreTriCompetences', competences => RdDItemCompetence.triVisible(competences));
|
||||||
if (a.name.startsWith("Survie") && b.name.startsWith("Survie")) {
|
Handlebars.registerHelper('linkCompendium', (pack, id, name) => RdDUtility.linkCompendium(pack, id, name));
|
||||||
if (a.name.includes("Cité")) return -1;
|
Handlebars.registerHelper('uniteQuantite', (itemId, actorId) => RdDUtility.getItem(itemId, actorId)?.getUniteQuantite());
|
||||||
if (b.name.includes("Cité")) return 1;
|
Handlebars.registerHelper('isFieldInventaireModifiable', (type, field) => RdDItem.isFieldInventaireModifiable(type, field));
|
||||||
if (a.name.includes("Extérieur")) return -1;
|
Handlebars.registerHelper('getFrequenceRarete', (rarete, field) => Environnement.getFrequenceRarete(rarete, field));
|
||||||
if (b.name.includes("Extérieur")) return 1;
|
|
||||||
return a.name.localeCompare(b.name);
|
|
||||||
}
|
|
||||||
if (a.system.categorie.startsWith("melee") && b.system.categorie.startsWith("melee")) {
|
|
||||||
if (a.name.includes("Corps")) return -1;
|
|
||||||
if (b.name.includes("Corps")) return 1;
|
|
||||||
if (a.name.includes("Dague")) return -1;
|
|
||||||
if (b.name.includes("Dague")) return 1;
|
|
||||||
if (a.name.includes("Esquive")) return -1;
|
|
||||||
if (b.name.includes("Esquive")) return 1;
|
|
||||||
return a.name.localeCompare(b.name);
|
|
||||||
}
|
|
||||||
if (a.name.startsWith("Voie") && b.name.startsWith("Voie")) {
|
|
||||||
if (a.name.includes("Oniros")) return -1;
|
|
||||||
if (b.name.includes("Oniros")) return 1;
|
|
||||||
if (a.name.includes("Hypnos")) return -1;
|
|
||||||
if (b.name.includes("Hypnos")) return 1;
|
|
||||||
if (a.name.includes("Narcos")) return -1;
|
|
||||||
if (b.name.includes("Narcos")) return 1;
|
|
||||||
if (a.name.includes("Thanatos")) return -1;
|
|
||||||
if (b.name.includes("Thanatos")) return 1;
|
|
||||||
return a.name.localeCompare(b.name);
|
|
||||||
}
|
|
||||||
return a.name.localeCompare(b.name);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
return loadTemplates(templatePaths);
|
return loadTemplates(templatePaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getItem(itemId, actorId = undefined) {
|
||||||
|
return actorId ? game.actors.get(actorId)?.getObjet(itemId) : game.items.get(itemId);
|
||||||
|
}
|
||||||
|
|
||||||
|
static linkCompendium(pack, id, name) {
|
||||||
|
return `@Compendium[${pack}.${id}]{${name}}`;
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async creerObjet(actorSheet) {
|
static async creerObjet(actorSheet) {
|
||||||
let itemType = $(".item-type").val();
|
let itemType = $(".item-type").val();
|
||||||
@@ -286,7 +328,7 @@ export class RdDUtility {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async selectObjetType(actorSheet) {
|
static async selectObjetType(actorSheet) {
|
||||||
let typeObjets = RdDItem.getTypeObjetsEquipement();
|
let typeObjets = RdDItem.getItemTypesInventaire();
|
||||||
let options = `<span class="competence-label">Selectionnez le type d'équipement</span><select class="item-type">`;
|
let options = `<span class="competence-label">Selectionnez le type d'équipement</span><select class="item-type">`;
|
||||||
for (let typeName of typeObjets) {
|
for (let typeName of typeObjets) {
|
||||||
options += `<option value="${typeName}">${typeName}</option>`
|
options += `<option value="${typeName}">${typeName}</option>`
|
||||||
@@ -368,48 +410,51 @@ export class RdDUtility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static filterItemsPerTypeForSheet(formData) {
|
static filterItemsPerTypeForSheet(formData, itemTypes) {
|
||||||
|
|
||||||
RdDUtility.filterEquipementParType(formData);
|
RdDUtility.filterEquipementParType(formData, itemTypes);
|
||||||
|
|
||||||
formData.sorts = this.arrayOrEmpty(formData.itemsByType['sort']);
|
formData.sorts = this.arrayOrEmpty(itemTypes['sort']);
|
||||||
formData.signesdraconiques = this.arrayOrEmpty(formData.itemsByType['signedraconique']);
|
formData.rencontres = this.arrayOrEmpty(itemTypes['rencontre']);
|
||||||
formData.queues = this.arrayOrEmpty(formData.itemsByType['queue']);
|
formData.casestmr = this.arrayOrEmpty(itemTypes['casetmr']);
|
||||||
formData.souffles = this.arrayOrEmpty(formData.itemsByType['souffle']);
|
formData.signesdraconiques = this.arrayOrEmpty(itemTypes['signedraconique']);
|
||||||
formData.ombres = this.arrayOrEmpty(formData.itemsByType['ombre']);
|
formData.queues = this.arrayOrEmpty(itemTypes['queue']);
|
||||||
formData.tetes = this.arrayOrEmpty(formData.itemsByType['tete']);
|
formData.souffles = this.arrayOrEmpty(itemTypes['souffle']);
|
||||||
formData.taches = this.arrayOrEmpty(formData.itemsByType['tache']);
|
formData.ombres = this.arrayOrEmpty(itemTypes['ombre']);
|
||||||
formData.meditations = this.arrayOrEmpty(formData.itemsByType['meditation']);
|
formData.tetes = this.arrayOrEmpty(itemTypes['tete']);
|
||||||
formData.chants = this.arrayOrEmpty(formData.itemsByType['chant']);
|
formData.taches = this.arrayOrEmpty(itemTypes['tache']);
|
||||||
formData.danses = this.arrayOrEmpty(formData.itemsByType['danse']);
|
formData.meditations = this.arrayOrEmpty(itemTypes['meditation']);
|
||||||
formData.musiques = this.arrayOrEmpty(formData.itemsByType['musique']);
|
formData.chants = this.arrayOrEmpty(itemTypes['chant']);
|
||||||
formData.oeuvres = this.arrayOrEmpty(formData.itemsByType['oeuvre']);
|
formData.danses = this.arrayOrEmpty(itemTypes['danse']);
|
||||||
formData.jeux = this.arrayOrEmpty(formData.itemsByType['jeu']);
|
formData.musiques = this.arrayOrEmpty(itemTypes['musique']);
|
||||||
|
formData.oeuvres = this.arrayOrEmpty(itemTypes['oeuvre']);
|
||||||
|
formData.jeux = this.arrayOrEmpty(itemTypes['jeu']);
|
||||||
|
|
||||||
formData.recettescuisine = this.arrayOrEmpty(formData.itemsByType['recettecuisine']);
|
formData.recettescuisine = this.arrayOrEmpty(itemTypes['recettecuisine']);
|
||||||
formData.recettesAlchimiques = this.arrayOrEmpty(formData.itemsByType['recettealchimique']);
|
formData.recettesAlchimiques = this.arrayOrEmpty(itemTypes['recettealchimique']);
|
||||||
formData.maladies = this.arrayOrEmpty(formData.itemsByType['maladie']);
|
formData.maladies = this.arrayOrEmpty(itemTypes['maladie']);
|
||||||
formData.poisons = this.arrayOrEmpty(formData.itemsByType['poison']);
|
formData.poisons = this.arrayOrEmpty(itemTypes['poison']);
|
||||||
formData.possessions = this.arrayOrEmpty(formData.itemsByType['possession']);
|
formData.possessions = this.arrayOrEmpty(itemTypes['possession']);
|
||||||
formData.maladiesPoisons = formData.maladies.concat(formData.poisons);
|
formData.maladiesPoisons = formData.maladies.concat(formData.poisons);
|
||||||
formData.competences = (formData.itemsByType.competence ?? []).concat(formData.itemsByType.competencecreature ?? []);
|
formData.competences = (itemTypes['competence'] ?? []).concat(itemTypes['competencecreature'] ?? []);
|
||||||
|
formData.sortsReserve = this.arrayOrEmpty(itemTypes['sortreserve']);
|
||||||
}
|
}
|
||||||
|
|
||||||
static filterEquipementParType(formData) {
|
static filterEquipementParType(formData, itemTypes) {
|
||||||
formData.conteneurs = this.arrayOrEmpty(formData.itemsByType['conteneur']);
|
formData.conteneurs = this.arrayOrEmpty(itemTypes['conteneur']);
|
||||||
|
|
||||||
formData.materiel = this.arrayOrEmpty(formData.itemsByType['objet']);
|
formData.materiel = this.arrayOrEmpty(itemTypes['objet']);
|
||||||
formData.armes = this.arrayOrEmpty(formData.itemsByType['arme']);
|
formData.armes = this.arrayOrEmpty(itemTypes['arme']);
|
||||||
formData.armures = this.arrayOrEmpty(formData.itemsByType['armure']);
|
formData.armures = this.arrayOrEmpty(itemTypes['armure']);
|
||||||
formData.munitions = this.arrayOrEmpty(formData.itemsByType['munition']);
|
formData.munitions = this.arrayOrEmpty(itemTypes['munition']);
|
||||||
formData.livres = this.arrayOrEmpty(formData.itemsByType['livre']);
|
formData.livres = this.arrayOrEmpty(itemTypes['livre']);
|
||||||
formData.potions = this.arrayOrEmpty(formData.itemsByType['potion']);
|
formData.potions = this.arrayOrEmpty(itemTypes['potion']);
|
||||||
formData.ingredients = this.arrayOrEmpty(formData.itemsByType['ingredient']);
|
formData.ingredients = this.arrayOrEmpty(itemTypes['ingredient']);
|
||||||
formData.herbes = this.arrayOrEmpty(formData.itemsByType['herbe']);
|
formData.faunes = this.arrayOrEmpty(itemTypes['faune']);
|
||||||
formData.monnaie = this.arrayOrEmpty(formData.itemsByType['monnaie']);
|
formData.herbes = this.arrayOrEmpty(itemTypes['herbe']);
|
||||||
formData.monnaie.sort(Monnaie.triValeurDenier());
|
formData.monnaie = this.arrayOrEmpty(itemTypes['monnaie']).sort(Monnaie.triValeurEntiere());
|
||||||
formData.nourritureboissons = this.arrayOrEmpty(formData.itemsByType['nourritureboisson']);
|
formData.nourritureboissons = this.arrayOrEmpty(itemTypes['nourritureboisson']);
|
||||||
formData.gemmes = this.arrayOrEmpty(formData.itemsByType['gemme']);
|
formData.gemmes = this.arrayOrEmpty(itemTypes['gemme']);
|
||||||
|
|
||||||
formData.objets = formData.conteneurs
|
formData.objets = formData.conteneurs
|
||||||
.concat(formData.materiel)
|
.concat(formData.materiel)
|
||||||
@@ -420,6 +465,7 @@ export class RdDUtility {
|
|||||||
.concat(formData.potions)
|
.concat(formData.potions)
|
||||||
.concat(formData.ingredients)
|
.concat(formData.ingredients)
|
||||||
.concat(formData.herbes)
|
.concat(formData.herbes)
|
||||||
|
.concat(formData.faunes)
|
||||||
.concat(formData.monnaie)
|
.concat(formData.monnaie)
|
||||||
.concat(formData.nourritureboissons)
|
.concat(formData.nourritureboissons)
|
||||||
.concat(formData.gemmes);
|
.concat(formData.gemmes);
|
||||||
@@ -479,7 +525,7 @@ export class RdDUtility {
|
|||||||
const isConteneur = objet.type == 'conteneur';
|
const isConteneur = objet.type == 'conteneur';
|
||||||
const isOuvert = isConteneur && this.getAfficheContenu(objet._id);
|
const isOuvert = isConteneur && this.getAfficheContenu(objet._id);
|
||||||
const isVide = isConteneur && objet.system.contenu.length == 0;
|
const isVide = isConteneur && objet.system.contenu.length == 0;
|
||||||
const conteneur = Handlebars.partials['systems/foundryvtt-reve-de-dragon/templates/actor-sheet-inventaire-item.html']({
|
const conteneur = Handlebars.partials['systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-item.html']({
|
||||||
item: objet,
|
item: objet,
|
||||||
vide: isVide,
|
vide: isVide,
|
||||||
ouvert: isOuvert
|
ouvert: isOuvert
|
||||||
@@ -493,8 +539,7 @@ export class RdDUtility {
|
|||||||
if (!profondeur) profondeur = 1;
|
if (!profondeur) profondeur = 1;
|
||||||
objet.niveau = profondeur;
|
objet.niveau = profondeur;
|
||||||
const display = afficherContenu ? 'item-display-show' : 'item-display-hide';
|
const display = afficherContenu ? 'item-display-show' : 'item-display-hide';
|
||||||
//console.log("ITEM DISPLAYED", objet );
|
let strContenu = `<ul class='item-list alterne-list ${display} list-item-margin${Math.min(profondeur,6)}'>`;
|
||||||
let strContenu = `<ul class='item-list alterne-list ${display} list-item-margin${profondeur}'>`;
|
|
||||||
for (let subItem of objet.subItems) {
|
for (let subItem of objet.subItems) {
|
||||||
strContenu += this.buildConteneur(subItem, profondeur + 1);
|
strContenu += this.buildConteneur(subItem, profondeur + 1);
|
||||||
}
|
}
|
||||||
@@ -613,7 +658,68 @@ export class RdDUtility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static selectEncaissement(degats, mortalite) {
|
static async jetEncaissement(rollData, armure, options = { showDice: HIDE_DICE }) {
|
||||||
|
let formula = "2d10";
|
||||||
|
|
||||||
|
// Chaque dé fait au minmum la difficulté libre
|
||||||
|
if (ReglesOptionelles.isUsing('degat-minimum-malus-libre')) {
|
||||||
|
if (rollData.diffLibre < 0) {
|
||||||
|
let valeurMin = Math.abs(rollData.diffLibre);
|
||||||
|
formula += "min" + valeurMin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Chaque dé fait au minmum la difficulté libre
|
||||||
|
if (ReglesOptionelles.isUsing('degat-ajout-malus-libre')) {
|
||||||
|
if (rollData.diffLibre < 0) {
|
||||||
|
let valeurMin = Math.abs(rollData.diffLibre);
|
||||||
|
formula += "+" + valeurMin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let roll = await RdDDice.roll(formula, options);
|
||||||
|
|
||||||
|
// 1 dé fait au minmum la difficulté libre
|
||||||
|
if (ReglesOptionelles.isUsing('degat-minimum-malus-libre-simple')) {
|
||||||
|
if (rollData.diffLibre < 0) {
|
||||||
|
let valeurMin = Math.abs(rollData.diffLibre);
|
||||||
|
if (roll.terms[0].results[0].result < valeurMin) {
|
||||||
|
roll.terms[0].results[0].result = valeurMin;
|
||||||
|
} else if (roll.terms[0].results[1].result < valeurMin) {
|
||||||
|
roll.terms[0].results[1].result = valeurMin;
|
||||||
|
}
|
||||||
|
roll._total = roll.terms[0].results[0].result + roll.terms[0].results[1].result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return await RdDUtility.prepareEncaissement(rollData, roll, armure);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async prepareEncaissement(rollData, roll, armure) {
|
||||||
|
const jetTotal = roll.total + rollData.dmg.total - armure;
|
||||||
|
let encaissement = RdDUtility._selectEncaissement(jetTotal, rollData.dmg.mortalite);
|
||||||
|
let over20 = Math.max(jetTotal - 20, 0);
|
||||||
|
encaissement.dmg = rollData.dmg;
|
||||||
|
encaissement.dmg.loc = rollData.dmg.loc ?? await RdDUtility.getLocalisation(this.type);
|
||||||
|
encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;';
|
||||||
|
encaissement.roll = roll;
|
||||||
|
encaissement.armure = armure;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static _selectEncaissement(degats, mortalite) {
|
||||||
const table = definitionsEncaissement[mortalite] === undefined ? definitionsEncaissement["mortel"] : definitionsEncaissement[mortalite];
|
const table = definitionsEncaissement[mortalite] === undefined ? definitionsEncaissement["mortel"] : definitionsEncaissement[mortalite];
|
||||||
for (let encaissement of table) {
|
for (let encaissement of table) {
|
||||||
if ((encaissement.minimum === undefined || encaissement.minimum <= degats)
|
if ((encaissement.minimum === undefined || encaissement.minimum <= degats)
|
||||||
@@ -624,6 +730,13 @@ export class RdDUtility {
|
|||||||
return duplicate(table[0]);
|
return duplicate(table[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async _evaluatePerte(formula, over20) {
|
||||||
|
let perte = new Roll(formula, { over20: over20 });
|
||||||
|
await perte.evaluate({ async: true });
|
||||||
|
return perte.total;
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static currentFatigueMalus(value, max) {
|
static currentFatigueMalus(value, max) {
|
||||||
if (ReglesOptionelles.isUsing("appliquer-fatigue")) {
|
if (ReglesOptionelles.isUsing("appliquer-fatigue")) {
|
||||||
@@ -643,18 +756,6 @@ export class RdDUtility {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static async loadCompendiumData(compendium) {
|
|
||||||
const pack = game.packs.get(compendium);
|
|
||||||
return await pack?.getDocuments() ?? [];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static async loadCompendium(compendium, filter = item => true) {
|
|
||||||
let compendiumData = await RdDUtility.loadCompendiumData(compendium);
|
|
||||||
return compendiumData.filter(filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async responseNombreAstral(callData) {
|
static async responseNombreAstral(callData) {
|
||||||
let actor = game.actors.get(callData.id);
|
let actor = game.actors.get(callData.id);
|
||||||
@@ -693,12 +794,13 @@ export class RdDUtility {
|
|||||||
actor.tmrApp.positionnerDemiReve(coord);
|
actor.tmrApp.positionnerDemiReve(coord);
|
||||||
});
|
});
|
||||||
// Gestion spécifique des sorts en réserve multiples (ie têtes)
|
// Gestion spécifique des sorts en réserve multiples (ie têtes)
|
||||||
html.on("click", '#sort-reserve', event => {
|
html.on("click", '.declencher-sort-reserve', event => {
|
||||||
let coord = event.currentTarget.attributes['data-tmr-coord'].value;
|
let coord = event.currentTarget.attributes['data-tmr-coord'].value;
|
||||||
let sortId = event.currentTarget.attributes['data-sort-id'].value;
|
let sortId = event.currentTarget.attributes['data-sort-id'].value;
|
||||||
let actorId = event.currentTarget.attributes['data-actor-id'].value;
|
let actorId = event.currentTarget.attributes['data-actor-id'].value;
|
||||||
let actor = game.actors.get(actorId);
|
let actor = game.actors.get(actorId);
|
||||||
actor.tmrApp.lancerSortEnReserve(coord, sortId);
|
actor.tmrApp.lancerSortEnReserve(coord, sortId);
|
||||||
|
// TODO: supprimer le message?
|
||||||
});
|
});
|
||||||
|
|
||||||
// gestion bouton tchat Possession
|
// gestion bouton tchat Possession
|
||||||
@@ -710,22 +812,20 @@ export class RdDUtility {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// gestion bouton tchat Acheter
|
// gestion bouton tchat Acheter
|
||||||
html.on("click", '.button-acheter', event => DialogItemAchat.onButtonAcheter(event));
|
html.on("click", '.button-acheter', event => {
|
||||||
|
const venteData = DialogItemAchat.venteData(event.currentTarget);
|
||||||
|
if (venteData) {
|
||||||
|
DialogItemAchat.onAcheter(venteData);
|
||||||
|
}
|
||||||
|
});
|
||||||
html.on("click", '.button-creer-acteur', event => RdDNameGen.onCreerActeur(event));
|
html.on("click", '.button-creer-acteur', event => RdDNameGen.onCreerActeur(event));
|
||||||
|
|
||||||
// Gestion du bouton payer
|
// Gestion du bouton payer
|
||||||
html.on("click", '.payer-button', event => {
|
html.on("click", '.payer-button', event => {
|
||||||
let sumdenier = event.currentTarget.attributes['data-somme-denier']?.value ?? 0;
|
let sommeAPayer = Number(event.currentTarget.attributes['data-somme-a-payer']?.value ?? 0);
|
||||||
let quantite = event.currentTarget.attributes['data-quantite']?.value ?? 1;
|
|
||||||
let fromActorId = event.currentTarget.attributes['data-actor-id']?.value;
|
|
||||||
let jsondata = event.currentTarget.attributes['data-jsondata']
|
|
||||||
let objData
|
|
||||||
if (jsondata) {
|
|
||||||
objData = JSON.parse(jsondata.value)
|
|
||||||
}
|
|
||||||
let actor = RdDUtility.getSelectedActor("Pour effectuer le paiement:");
|
let actor = RdDUtility.getSelectedActor("Pour effectuer le paiement:");
|
||||||
if (actor) {
|
if (actor) {
|
||||||
actor.depenserDeniers(sumdenier, objData, quantite, fromActorId);
|
actor.payerSols(sommeAPayer);
|
||||||
ChatUtility.removeChatMessageId(RdDUtility.findChatMessageId(event.currentTarget));
|
ChatUtility.removeChatMessageId(RdDUtility.findChatMessageId(event.currentTarget));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -776,12 +876,12 @@ export class RdDUtility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static createMonnaie(name, valeur_deniers, img = "", enc = 0.01) {
|
static createMonnaie(name, cout, img = "", enc = 0.01) {
|
||||||
let piece = {
|
let piece = {
|
||||||
name: name, type: 'monnaie', img: img, _id: randomID(16),
|
name: name, type: 'monnaie', img: img, _id: randomID(16),
|
||||||
dasystemta: {
|
dasystemta: {
|
||||||
quantite: 0,
|
quantite: 0,
|
||||||
valeur_deniers: valeur_deniers,
|
cout: cout,
|
||||||
encombrement: enc,
|
encombrement: enc,
|
||||||
description: ""
|
description: ""
|
||||||
}
|
}
|
||||||
@@ -793,20 +893,20 @@ export class RdDUtility {
|
|||||||
static afficherDemandePayer(som1, som2) {
|
static afficherDemandePayer(som1, som2) {
|
||||||
som1 = (som1) ? som1.toLowerCase() : "0d";
|
som1 = (som1) ? som1.toLowerCase() : "0d";
|
||||||
som2 = (som2) ? som2.toLowerCase() : "0d";
|
som2 = (som2) ? som2.toLowerCase() : "0d";
|
||||||
let regExp = /(\d+)(\w+)/g;
|
let regExp1 = /(\d+)(\w+)/g;
|
||||||
let p1 = regExp.exec(som1);
|
let p1 = regExp1.exec(som1);
|
||||||
regExp = /(\d+)(\w+)/g;
|
let regExp2 = /(\d+)(\w+)/g;
|
||||||
let p2 = regExp.exec(som2);
|
let p2 = regExp2.exec(som2);
|
||||||
let sumd = 0;
|
let deniers = 0;
|
||||||
let sums = 0;
|
let sols = 0;
|
||||||
if (p1[2] == 'd') sumd += Number(p1[1]);
|
if (p1[2] == 'd') deniers += Number(p1[1]);
|
||||||
if (p1[2] == 's') sums += Number(p1[1]);
|
if (p1[2] == 's') sols += Number(p1[1]);
|
||||||
if (p2[2] == 'd') sumd += Number(p2[1]);
|
if (p2[2] == 'd') deniers += Number(p2[1]);
|
||||||
if (p2[2] == 's') sums += Number(p2[1]);
|
if (p2[2] == 's') sols += Number(p2[1]);
|
||||||
|
|
||||||
let sumtotald = sumd + (sums * 100);
|
let sommeAPayer = sols + deniers/100;
|
||||||
let msgPayer = "La somme de " + sums + " Sols et " + sumd + " Deniers est à payer, cliquer sur le lien ci-dessous si besoin.<br>";
|
let msgPayer = `La somme de ${sols} Sols et ${deniers} Deniers est à payer<br>
|
||||||
msgPayer += "<a class='payer-button chat-card-button' data-somme-denier='" + sumtotald + "'>Payer</a>"
|
<a class='payer-button chat-card-button' data-somme-a-payer='${sommeAPayer}'>Payer</a>`
|
||||||
ChatMessage.create({ content: msgPayer });
|
ChatMessage.create({ content: msgPayer });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -830,38 +930,17 @@ export class RdDUtility {
|
|||||||
return chatData;
|
return chatData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static confirmerSuppression(sheet, htmlToDelete, options) {
|
|
||||||
const d = new Dialog({
|
|
||||||
title: options.title ?? 'Confirmer la suppression',
|
|
||||||
content: `<p>Etes vous certain de vouloir supprimer ${options.supprimer ?? 'cet objet'} ?</p>`,
|
|
||||||
buttons: {
|
|
||||||
delete: {
|
|
||||||
icon: '<i class="fas fa-check"></i>',
|
|
||||||
label: options.deleteLabel ?? 'Supprimer',
|
|
||||||
callback: () => {
|
|
||||||
options.onDelete();
|
|
||||||
RdDUtility.slideOnDelete(sheet, htmlToDelete);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
cancel: {
|
|
||||||
icon: '<i class="fas fa-times"></i>',
|
|
||||||
label: "Annuler"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
default: "cancel"
|
|
||||||
});
|
|
||||||
d.render(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static confirmerSuppressionSubacteur(sheet, subActor, htmlToDelete) {
|
static confirmerSuppressionSubacteur(sheet, subActor, htmlToDelete) {
|
||||||
RdDUtility.confirmerSuppression(sheet, htmlToDelete,{
|
RdDConfirm.confirmer({
|
||||||
supprimer: "le lien vers le véhicule/monture/suivant : " + subActor.name,
|
settingConfirmer: "confirmation-supprimer-lien-acteur",
|
||||||
deleteLabel: "Supprimer le lien",
|
content: `<p>Etes vous certain de vouloir supprimer le lien vers ${subActor.name} ?</p>`,
|
||||||
onDelete: () => {
|
title: 'Confirmer la suppression',
|
||||||
console.log("Delete : ", subActor.id);
|
buttonLabel: 'Supprimer le lien',
|
||||||
|
onAction: () => {
|
||||||
|
console.log('Delete : ', subActor.id);
|
||||||
sheet.actor.removeSubacteur(subActor.id);
|
sheet.actor.removeSubacteur(subActor.id);
|
||||||
|
RdDUtility.slideOnDelete(sheet, htmlToDelete);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -869,51 +948,40 @@ export class RdDUtility {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async confirmerSuppressionItem(sheet, item, htmlToDelete) {
|
static async confirmerSuppressionItem(sheet, item, htmlToDelete) {
|
||||||
const itemId = item.id;
|
const itemId = item.id;
|
||||||
if (Monnaie.isSystemMonnaie(item, sheet.actor.items)) {
|
const confirmationSuppression = {
|
||||||
ui.notifications.warn("Suppression des monnaies de base impossible");
|
settingConfirmer: "confirmation-supprimer-" + item.getItemGroup(),
|
||||||
return;
|
content: `<p>Etes vous certain de vouloir supprimer: ${item.name}?</p>`,
|
||||||
}
|
title: `Supprimer ${item.name}`,
|
||||||
|
buttonLabel: "Supprimer",
|
||||||
let msgTxt = "<p>Etes vous certain de vouloir supprimer cet objet ?";
|
onAction: () => {
|
||||||
let buttons = {
|
console.log('Delete : ', itemId);
|
||||||
delete: {
|
sheet.actor.deleteEmbeddedDocuments('Item', [itemId], { renderSheet: false });
|
||||||
icon: '<i class="fas fa-check"></i>',
|
RdDUtility.slideOnDelete(sheet, htmlToDelete);
|
||||||
label: "Supprimer l'objet",
|
|
||||||
callback: () => {
|
|
||||||
console.log("Delete : ", itemId);
|
|
||||||
sheet.actor.deleteEmbeddedDocuments('Item', [itemId]);
|
|
||||||
RdDUtility.slideOnDelete(sheet, htmlToDelete);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
cancel: {
|
|
||||||
icon: '<i class="fas fa-times"></i>',
|
|
||||||
label: "Annuler"
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
if (item.isConteneurNonVide()) {
|
||||||
|
confirmationSuppression.content += `<p>Ce conteneur n'est pas vide. Que voulez vous supprimer?</p>`;
|
||||||
|
confirmationSuppression.settingConfirmer = undefined;
|
||||||
|
RdDConfirm.confirmer(confirmationSuppression,
|
||||||
|
{
|
||||||
|
'deleteall': {
|
||||||
|
icon: '<i class="fas fa-check"></i>',
|
||||||
|
label: "Supprimer conteneur et contenu",
|
||||||
|
callback: () => {
|
||||||
|
console.log("Delete : ", itemId);
|
||||||
|
sheet.actor.deleteAllConteneur(itemId, { renderSheet: false });
|
||||||
|
RdDUtility.slideOnDelete(sheet, htmlToDelete);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (item.type == 'conteneur' && item.system.contenu.length > 0) {
|
else {
|
||||||
msgTxt += "<br>Ce conteneur n'est pas vide. Choisissez l'option de suppression";
|
RdDConfirm.confirmer(confirmationSuppression)
|
||||||
buttons['deleteall'] = {
|
|
||||||
icon: '<i class="fas fa-check"></i>',
|
|
||||||
label: "Supprimer le conteneur et tout son contenu",
|
|
||||||
callback: () => {
|
|
||||||
console.log("Delete : ", itemId);
|
|
||||||
sheet.actor.deleteAllConteneur(itemId);
|
|
||||||
RdDUtility.slideOnDelete(sheet, htmlToDelete);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
msgTxt += "</p>";
|
|
||||||
let d = new Dialog({
|
|
||||||
title: "Confirmer la suppression",
|
|
||||||
content: msgTxt,
|
|
||||||
buttons: buttons,
|
|
||||||
default: "cancel"
|
|
||||||
});
|
|
||||||
d.render(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static slideOnDelete(sheet, htmlToDelete) {
|
static slideOnDelete(sheet, htmlToDelete) {
|
||||||
return htmlToDelete.slideUp(200, () => sheet.render(false));
|
return htmlToDelete?.slideUp(200, () => sheet.render(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|||||||
@@ -1,91 +0,0 @@
|
|||||||
import { SYSTEM_RDD } from "./constants.js";
|
|
||||||
import { Misc } from "./misc.js";
|
|
||||||
|
|
||||||
const listeReglesOptionelles = [
|
|
||||||
{ name: 'recul', group: 'Règles de combat', descr: "Appliquer le recul en cas de particulière en force ou de charge" },
|
|
||||||
{ name: 'resistanceArmeParade', group: 'Règles de combat', descr: "Faire le jet de résistance des armes lors de parades pouvant les endommager" },
|
|
||||||
{ name: 'deteriorationArmure', group: 'Règles de combat', descr: "Tenir compte de la détérioration des armures" },
|
|
||||||
{ name: 'defenseurDesarme', group: 'Règles de combat', descr: "Le défenseur peut être désarmé en parant une particulière en force ou une charge avec une arme autre qu'un bouclier" },
|
|
||||||
{ name: 'categorieParade', group: 'Règles de combat', descr: "Le défenseur doit obtenir une significative en cas de parade avec des armes de catégories différentes" },
|
|
||||||
{ name: 'tripleSignificative', group: 'Règles de combat', descr: "En cas de demi-surprise, d'attaque particulière en finesse, et de catégories d'armes différentes, le défenseur doit obtenir 1/8 des chances de succès" },
|
|
||||||
{ name: 'degat-minimum-malus-libre-simple', group: 'Règles de combat', descr: "Le malus libre d'attaque remplace une des valeurs de dés d'encaissement si elle est plus petite. Exemple : la difficulté libre de l'attaquant est de -4. Sur le jet d'encaissement, si 1 résultat est inférieur à 4, alors il devient 4.", default: false },
|
|
||||||
{ name: 'degat-minimum-malus-libre', group: 'Règles de combat', descr: "Le malus libre d'attaque remplace une valeur de dés d'encaissement si elle est plus petite. Exemple : la difficulté libre de l'attaquant est de -4. Sur le jet d'encaissement, tout résultat inférieur à 4 devient 4.", default: false },
|
|
||||||
{ name: 'degat-ajout-malus-libre', group: 'Règles de combat', descr: "Le malus libre d'attaque s'ajoute au jet d'encaissement et aux autres bonus. Exemple : la difficulté libre de l'attaquant est de -4. Le jet d'encaissement est effectué à 2d10+4, plus les bonus de situation et d'armes.", default: false },
|
|
||||||
{ name: 'astrologie', group: 'Règles générales', descr: "Appliquer les ajustements astrologiques aux jets de chance et aux rituels", default: true },
|
|
||||||
{ name: 'afficher-prix-joueurs', group: 'Règles générales', descr: "Afficher le prix de l'équipement des joueurs", default: true },
|
|
||||||
{ name: 'appliquer-fatigue', group: 'Règles générales', descr: "Appliquer les règles de fatigue", default: true },
|
|
||||||
{ name: 'afficher-colonnes-reussite', group: 'Règles générales', descr: "Afficher le nombre de colonnes de réussite ou d'échec", default: false },
|
|
||||||
];
|
|
||||||
|
|
||||||
export class ReglesOptionelles extends FormApplication {
|
|
||||||
static init() {
|
|
||||||
for (const regle of listeReglesOptionelles) {
|
|
||||||
const name = regle.name;
|
|
||||||
const id = ReglesOptionelles._getIdRegle(name);
|
|
||||||
game.settings.register(SYSTEM_RDD, id, { name: id, scope: "world", config: false, default: regle.default == undefined ? true : regle.default, type: Boolean });
|
|
||||||
}
|
|
||||||
|
|
||||||
game.settings.registerMenu(SYSTEM_RDD, "rdd-options-regles", {
|
|
||||||
name: "Choisir les règles optionelles",
|
|
||||||
label: "Choix des règles optionelles",
|
|
||||||
hint: "Ouvre la fenêtre de sélection des règles optionelles",
|
|
||||||
icon: "fas fa-bars",
|
|
||||||
type: ReglesOptionelles,
|
|
||||||
restricted: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(...args) {
|
|
||||||
super(...args);
|
|
||||||
}
|
|
||||||
|
|
||||||
static _getIdRegle(name) {
|
|
||||||
return `rdd-option-${name}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
static get defaultOptions() {
|
|
||||||
const options = super.defaultOptions;
|
|
||||||
mergeObject(options, {
|
|
||||||
id: "optional-settings",
|
|
||||||
template: "systems/foundryvtt-reve-de-dragon/templates/regles-optionelles.html",
|
|
||||||
height: 600,
|
|
||||||
width: 350,
|
|
||||||
minimizable: false,
|
|
||||||
closeOnSubmit: true,
|
|
||||||
title: "Règles optionnelles"
|
|
||||||
});
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
||||||
getData() {
|
|
||||||
let formData = super.getData();
|
|
||||||
const regles = listeReglesOptionelles.map(it => {
|
|
||||||
it = duplicate(it);
|
|
||||||
it.id = ReglesOptionelles._getIdRegle(it.name);
|
|
||||||
it.active = ReglesOptionelles.isUsing(it.name);
|
|
||||||
return it;
|
|
||||||
});
|
|
||||||
formData.regles = regles;
|
|
||||||
formData.groups = Misc.classify(regles, it => it.group);
|
|
||||||
return formData;
|
|
||||||
}
|
|
||||||
|
|
||||||
static isUsing(name) {
|
|
||||||
return game.settings.get(SYSTEM_RDD, ReglesOptionelles._getIdRegle(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
activateListeners(html) {
|
|
||||||
html.find(".select-option").click((event) => {
|
|
||||||
if (event.currentTarget.attributes.name) {
|
|
||||||
let id = event.currentTarget.attributes.name.value;
|
|
||||||
let isChecked = event.currentTarget.checked;
|
|
||||||
game.settings.set(SYSTEM_RDD, id, isChecked);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async _updateObject(event, formData) {
|
|
||||||
this.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -6,7 +6,7 @@ import { Misc } from "./misc.js";
|
|||||||
import { RdDBonus } from "./rdd-bonus.js";
|
import { RdDBonus } from "./rdd-bonus.js";
|
||||||
import { RdDCarac } from "./rdd-carac.js";
|
import { RdDCarac } from "./rdd-carac.js";
|
||||||
import { RdDUtility } from "./rdd-utility.js";
|
import { RdDUtility } from "./rdd-utility.js";
|
||||||
import { ReglesOptionelles } from "./regles-optionelles.js";
|
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tous les ajustements pouvant s'appliquer.
|
* tous les ajustements pouvant s'appliquer.
|
||||||
@@ -62,20 +62,20 @@ export const referenceAjustements = {
|
|||||||
getValue: (rollData, actor) => actor.getMalusArmure()
|
getValue: (rollData, actor) => actor.getMalusArmure()
|
||||||
},
|
},
|
||||||
encTotal: {
|
encTotal: {
|
||||||
isVisible: (rollData, actor) => RdDItemCompetence.isMalusEncombrementTotal(rollData.competence),
|
isVisible: (rollData, actor) => RdDCarac.isAgiliteOuDerivee(rollData.selectedCarac) && RdDItemCompetence.isMalusEncombrementTotal(rollData.competence),
|
||||||
isUsed: (rollData, actor) => rollData.useMalusEncTotal,
|
isUsed: (rollData, actor) => !rollData.oeuvre && RdDCarac.isAgiliteOuDerivee(rollData.selectedCarac) && RdDItemCompetence.isMalusEncombrementTotal(rollData.competence) && rollData.use.encTotal,
|
||||||
getLabel: (rollData, actor) => 'Encombrement total',
|
getLabel: (rollData, actor) => 'Encombrement total',
|
||||||
getValue: (rollData, actor) => -actor.getEncTotal()
|
getValue: (rollData, actor) => -actor.getEncTotal()
|
||||||
},
|
},
|
||||||
surenc: {
|
surenc: {
|
||||||
isVisible: (rollData, actor) => rollData.useMalusSurenc,
|
isVisible: (rollData, actor) => actor.isSurenc(),
|
||||||
isUsed: (rollData, actor) => rollData.useMalusSurenc,
|
isUsed: (rollData, actor) => rollData.use?.surenc,
|
||||||
getLabel: (rollData, actor) => 'Sur-encombrement',
|
getLabel: (rollData, actor) => 'Sur-encombrement',
|
||||||
getValue: (rollData, actor) => actor.computeMalusSurEncombrement()
|
getValue: (rollData, actor) => actor.computeMalusSurEncombrement()
|
||||||
},
|
},
|
||||||
moral: {
|
moral: {
|
||||||
isVisible: (rollData, actor) => actor.isPersonnage() && RdDCarac.isActionPhysique(rollData.selectedCarac) && rollData.useMoral,
|
isVisible: (rollData, actor) => actor.isPersonnage() && RdDCarac.isActionPhysique(rollData.selectedCarac) && rollData.use?.moral,
|
||||||
isUsed: (rollData, actor) => rollData.useMoral,
|
isUsed: (rollData, actor) => rollData.use?.moral,
|
||||||
getLabel: (rollData, actor) => 'Appel au moral',
|
getLabel: (rollData, actor) => 'Appel au moral',
|
||||||
getValue: (rollData, actor) => 1
|
getValue: (rollData, actor) => 1
|
||||||
},
|
},
|
||||||
@@ -120,7 +120,7 @@ export const referenceAjustements = {
|
|||||||
isVisible: (rollData, actor) => rollData.tmr && rollData.rencontre?.name,
|
isVisible: (rollData, actor) => rollData.tmr && rollData.rencontre?.name,
|
||||||
isUsed: (rollData, actor) => rollData.tmr && rollData.rencontre?.name,
|
isUsed: (rollData, actor) => rollData.tmr && rollData.rencontre?.name,
|
||||||
getLabel: (rollData, actor) => rollData.rencontre?.name,
|
getLabel: (rollData, actor) => rollData.rencontre?.name,
|
||||||
getValue: (rollData, actor) => - (rollData.rencontre?.force ?? 0)
|
getValue: (rollData, actor) => - (rollData.rencontre?.system.force ?? 0)
|
||||||
},
|
},
|
||||||
ethylismeAlcool: {
|
ethylismeAlcool: {
|
||||||
isVisible: (rollData, actor) => rollData.nbDoses != undefined,
|
isVisible: (rollData, actor) => rollData.nbDoses != undefined,
|
||||||
|
|||||||
118
module/settings/regles-optionelles.js
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
import { SYSTEM_RDD } from "../constants.js";
|
||||||
|
import { Misc } from "../misc.js";
|
||||||
|
|
||||||
|
const listeReglesOptionelles = [
|
||||||
|
{ group: 'Règles de combat', name: 'recul', descr: "Appliquer le recul en cas de particulière en force ou de charge" },
|
||||||
|
{ group: 'Règles de combat', name: 'resistanceArmeParade', descr: "Faire le jet de résistance des armes lors de parades pouvant les endommager" },
|
||||||
|
{ group: 'Règles de combat', name: 'deteriorationArmure', descr: "Tenir compte de la détérioration des armures" },
|
||||||
|
{ group: 'Règles de combat', name: 'defenseurDesarme', descr: "Le défenseur peut être désarmé en parant une particulière en force ou une charge avec une arme autre qu'un bouclier" },
|
||||||
|
{ group: 'Règles de combat', name: 'categorieParade', descr: "Le défenseur doit obtenir une significative en cas de parade avec des armes de catégories différentes" },
|
||||||
|
{ group: 'Règles de combat', name: 'tripleSignificative', descr: "En cas de demi-surprise, d'attaque particulière en finesse, et de catégories d'armes différentes, le défenseur doit obtenir 1/8 des chances de succès" },
|
||||||
|
{ group: 'Règles de combat', name: 'degat-minimum-malus-libre-simple', descr: "Le malus libre d'attaque remplace une des valeurs de dés d'encaissement si elle est plus petite. Exemple : la difficulté libre de l'attaquant est de -4. Sur le jet d'encaissement, si le plus petit dé est inférieur à 4, alors il devient 4.", default: false },
|
||||||
|
{ group: 'Règles de combat', name: 'degat-minimum-malus-libre', descr: "Le malus libre d'attaque remplace une valeur de dés d'encaissement si elle est plus petite. Exemple : la difficulté libre de l'attaquant est de -4. Sur le jet d'encaissement, tout résultat inférieur à 4 devient 4.", default: false },
|
||||||
|
{ group: 'Règles de combat', name: 'degat-ajout-malus-libre', descr: "Le malus libre d'attaque s'ajoute au jet d'encaissement et aux autres bonus. Exemple : la difficulté libre de l'attaquant est de -4. Le jet d'encaissement est effectué à 2d10+4, plus les bonus de situation et d'armes.", default: false },
|
||||||
|
{ group: 'Règles de combat', name: 'validation-encaissement-gr', descr: "Le Gardien des Rêves doit valider les jets d'encaissement et peut les changer.", default: false },
|
||||||
|
|
||||||
|
{ group: 'Règles générales', name: 'astrologie', descr: "Appliquer les ajustements astrologiques aux jets de chance et aux rituels"},
|
||||||
|
{ group: 'Règles générales', name: 'afficher-prix-joueurs', descr: "Afficher le prix de l'équipement des joueurs", uniquementJoueur: true},
|
||||||
|
{ group: 'Règles générales', name: 'appliquer-fatigue', descr: "Appliquer les règles de fatigue"},
|
||||||
|
{ group: 'Règles générales', name: 'afficher-colonnes-reussite', descr: "Afficher le nombre de colonnes de réussite ou d'échec", default: false },
|
||||||
|
|
||||||
|
{ group: 'Confirmations', name: 'confirmer-combat-sans-cible', descr: "Confirmer avant une attaque sans cible", scope: "client"},
|
||||||
|
{ group: 'Confirmations', name: 'confirmation-tmr', descr: "Confirmer pour monter dans les TMR", scope: "client"},
|
||||||
|
{ group: 'Confirmations', name: 'confirmation-refouler', descr: "Confirmer avant de refouler", scope: "client"},
|
||||||
|
{ group: 'Confirmations', name: 'confirmation-vider', descr: "Confirmer pour vider l'équipement", scope: "client"},
|
||||||
|
{ group: 'Confirmations', name: 'confirmation-supprimer-lien-acteur', descr: "Confirmer pour détacher un animal/suivant/véhicule", scope: "client"},
|
||||||
|
{ group: 'Confirmations', name: 'confirmation-supprimer-equipement', descr: "Confirmer la suppression des équipements", scope: "client"},
|
||||||
|
{ group: 'Confirmations', name: 'confirmation-supprimer-oeuvre', descr: "Confirmer la suppression des oeuvres", scope: "client"},
|
||||||
|
{ group: 'Confirmations', name: 'confirmation-supprimer-connaissance', descr: "Confirmer la suppression des connaissances", scope: "client"},
|
||||||
|
{ group: 'Confirmations', name: 'confirmation-supprimer-draconique', descr: "Confirmer la suppression des queues, souffles, têtes", scope: "client"},
|
||||||
|
{ group: 'Confirmations', name: 'confirmation-supprimer-effet', descr: "Confirmer la suppression des effets", scope: "client"},
|
||||||
|
{ group: 'Confirmations', name: 'confirmation-supprimer-competence', descr: "Confirmer la suppression des compétences", scope: "client"},
|
||||||
|
{ group: 'Confirmations', name: 'confirmation-supprimer-autres', descr: "Confirmer la suppression des autres types d'Objets", scope: "client"},
|
||||||
|
];
|
||||||
|
|
||||||
|
const uniquementJoueur = listeReglesOptionelles.filter(it => it.uniquementJoueur).map(it=>it.name);
|
||||||
|
|
||||||
|
export class ReglesOptionelles extends FormApplication {
|
||||||
|
static init() {
|
||||||
|
for (const regle of listeReglesOptionelles) {
|
||||||
|
const name = regle.name;
|
||||||
|
const id = ReglesOptionelles._getIdRegle(name);
|
||||||
|
game.settings.register(SYSTEM_RDD, id, { name: id, scope: regle.scope ?? "world", config: false, default: regle.default == undefined ? true : regle.default, type: Boolean });
|
||||||
|
}
|
||||||
|
|
||||||
|
game.settings.registerMenu(SYSTEM_RDD, "rdd-options-regles", {
|
||||||
|
name: "Choisir les règles optionelles",
|
||||||
|
label: "Règles optionelles",
|
||||||
|
hint: "Ouvre la fenêtre de sélection des règles optionelles",
|
||||||
|
icon: "fas fa-bars",
|
||||||
|
type: ReglesOptionelles
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(...args) {
|
||||||
|
super(...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
static _getIdRegle(name) {
|
||||||
|
return `rdd-option-${name}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get defaultOptions() {
|
||||||
|
const options = super.defaultOptions;
|
||||||
|
mergeObject(options, {
|
||||||
|
id: "regles-optionelles",
|
||||||
|
template: "systems/foundryvtt-reve-de-dragon/templates/settings/regles-optionelles.html",
|
||||||
|
height: 600,
|
||||||
|
width: 450,
|
||||||
|
minimizable: false,
|
||||||
|
closeOnSubmit: true,
|
||||||
|
title: "Règles optionnelles"
|
||||||
|
});
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
getData() {
|
||||||
|
let formData = super.getData();
|
||||||
|
const regles = listeReglesOptionelles.filter(it => game.user.isGM || it.scope == "client").map(it => {
|
||||||
|
it = duplicate(it);
|
||||||
|
it.id = ReglesOptionelles._getIdRegle(it.name);
|
||||||
|
it.active = ReglesOptionelles.isSet(it.name);
|
||||||
|
return it;
|
||||||
|
});
|
||||||
|
formData.regles = regles;
|
||||||
|
formData.groups = Misc.classify(regles, it => it.group);
|
||||||
|
return formData;
|
||||||
|
}
|
||||||
|
|
||||||
|
static isUsing(name) {
|
||||||
|
if (game.user.isGM && uniquementJoueur.includes(name)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return ReglesOptionelles.isSet(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static isSet(name) {
|
||||||
|
return game.settings.get(SYSTEM_RDD, ReglesOptionelles._getIdRegle(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
static set(name, value) {
|
||||||
|
return game.settings.set(SYSTEM_RDD, ReglesOptionelles._getIdRegle(name), value ? true: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
activateListeners(html) {
|
||||||
|
html.find(".select-option").click((event) => {
|
||||||
|
if (event.currentTarget.attributes.name) {
|
||||||
|
let id = event.currentTarget.attributes.name.value;
|
||||||
|
let isChecked = event.currentTarget.checked;
|
||||||
|
game.settings.set(SYSTEM_RDD, id, isChecked);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async _updateObject(event, formData) {
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
141
module/settings/status-effects.js
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
import { SYSTEM_RDD } from "../constants.js";
|
||||||
|
|
||||||
|
export const STATUSES = {
|
||||||
|
StatusStunned : 'stun',
|
||||||
|
StatusBleeding: 'bleeding',
|
||||||
|
StatusProne: 'prone',
|
||||||
|
StatusGrappling: 'grappling',
|
||||||
|
StatusGrappled: 'grappled',
|
||||||
|
StatusRestrained: 'restrain',
|
||||||
|
StatusUnconscious: 'unconscious',
|
||||||
|
StatusBlind: 'blind',
|
||||||
|
StatusComma: 'comma',
|
||||||
|
StatusDead: 'dead',
|
||||||
|
StatusDemiReve: 'demi-reve',
|
||||||
|
}
|
||||||
|
|
||||||
|
const rddStatusEffects = [
|
||||||
|
{ rdd: true, id: STATUSES.StatusStunned, label: 'EFFECT.StatusStunned', icon: 'icons/svg/stoned.svg', "duration.rounds": 1 },
|
||||||
|
{ rdd: true, id: STATUSES.StatusBleeding, label: 'EFFECT.StatusBleeding', icon: 'icons/svg/blood.svg' },
|
||||||
|
{ rdd: true, id: STATUSES.StatusProne, label: 'EFFECT.StatusProne', icon: 'icons/svg/falling.svg' },
|
||||||
|
{ rdd: true, id: STATUSES.StatusGrappling, tint: '#33cc33', label: 'EFFECT.StatusGrappling', icon: 'systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp' },
|
||||||
|
{ rdd: true, id: STATUSES.StatusGrappled, tint: '#ff9900', label: 'EFFECT.StatusGrappled', icon: 'systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp' },
|
||||||
|
{ rdd: true, id: STATUSES.StatusRestrained, label: 'EFFECT.StatusRestrained', icon: 'icons/svg/net.svg' },
|
||||||
|
{ rdd: true, id: STATUSES.StatusUnconscious, label: 'EFFECT.StatusUnconscious', icon: 'icons/svg/unconscious.svg' },
|
||||||
|
{ rdd: true, id: STATUSES.StatusBlind, label: 'EFFECT.StatusBlind', icon: 'icons/svg/blind.svg' },
|
||||||
|
{ rdd: true, id: STATUSES.StatusComma, label: 'EFFECT.StatusComma', icon: 'icons/svg/skull.svg' },
|
||||||
|
{ rdd: true, id: STATUSES.StatusDead, label: 'EFFECT.StatusDead', icon: 'icons/svg/skull.svg' },
|
||||||
|
{ rdd: true, id: STATUSES.StatusDemiReve, label: 'EFFECT.StatusDemiReve', icon: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd12.svg' }
|
||||||
|
];
|
||||||
|
const demiReveStatusEffect = rddStatusEffects.find(it => it.id == STATUSES.StatusDemiReve);
|
||||||
|
|
||||||
|
const statusDemiSurprise = [STATUSES.StatusStunned, STATUSES.StatusProne, STATUSES.StatusRestrained];
|
||||||
|
const statusSurpriseTotale = [STATUSES.StatusUnconscious, STATUSES.StatusBlind, STATUSES.StatusComma];
|
||||||
|
|
||||||
|
export class StatusEffects extends FormApplication {
|
||||||
|
static onReady() {
|
||||||
|
const rddStatusIds = rddStatusEffects.map(it => it.id);
|
||||||
|
rddStatusEffects.forEach(it => it.flags = { core: { statusId: it.id } });
|
||||||
|
const defaultStatusEffectIds = CONFIG.statusEffects.map(it => it.id);
|
||||||
|
game.settings.register(SYSTEM_RDD, "use-status-effects", {
|
||||||
|
name: "use-status-effects",
|
||||||
|
scope: "world",
|
||||||
|
config: false,
|
||||||
|
default: defaultStatusEffectIds.join(),
|
||||||
|
type: String
|
||||||
|
});
|
||||||
|
|
||||||
|
game.settings.registerMenu(SYSTEM_RDD, "select-status-effect", {
|
||||||
|
name: "Choisir les effets disponibles",
|
||||||
|
label: "Choix des effets",
|
||||||
|
hint: "Ouvre la fenêtre de sélection des effets/status appliqués aux acteurs",
|
||||||
|
icon: "fas fa-bars",
|
||||||
|
type: StatusEffects,
|
||||||
|
restricted: true
|
||||||
|
});
|
||||||
|
|
||||||
|
CONFIG.RDD.allEffects = rddStatusEffects.concat(CONFIG.statusEffects.filter(it => !rddStatusIds.includes(it.id)));
|
||||||
|
|
||||||
|
StatusEffects._setUseStatusEffects(StatusEffects._getUseStatusEffects());
|
||||||
|
console.log('statusEffects', CONFIG.statusEffects);
|
||||||
|
}
|
||||||
|
|
||||||
|
static valeurSurprise(effect, isCombat) {
|
||||||
|
// const id = StatusEffects.statusId(effect);
|
||||||
|
if (statusSurpriseTotale.includes(effect.flags?.core?.statusId)) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
return statusDemiSurprise.includes(effect.flags?.core?.statusId) || (isCombat && effect.flags?.core?.statusId == STATUSES.StatusDemiReve) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static _getUseStatusEffects() {
|
||||||
|
return game.settings.get(SYSTEM_RDD, "use-status-effects")?.split(',') ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
static _setUseStatusEffects(statusIds) {
|
||||||
|
if (game.user.isGM) {
|
||||||
|
game.settings.set(SYSTEM_RDD, "use-status-effects", statusIds.join());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let effect of CONFIG.RDD.allEffects) {
|
||||||
|
effect.active = effect.rdd || statusIds.includes(effect.flags?.core?.statusId);
|
||||||
|
}
|
||||||
|
CONFIG.statusEffects = CONFIG.RDD.allEffects.filter(it => it.active);
|
||||||
|
}
|
||||||
|
|
||||||
|
static status(statusId) {
|
||||||
|
return rddStatusEffects.find(it => it.flags?.core?.statusId == statusId);
|
||||||
|
}
|
||||||
|
|
||||||
|
static demiReve() {
|
||||||
|
return demiReveStatusEffect;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(...args) {
|
||||||
|
super(...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
static get defaultOptions() {
|
||||||
|
const options = super.defaultOptions;
|
||||||
|
mergeObject(options, {
|
||||||
|
id: "status-effects",
|
||||||
|
template: "systems/foundryvtt-reve-de-dragon/templates/settings/status-effects.html",
|
||||||
|
height: 800,
|
||||||
|
width: 350,
|
||||||
|
minimizable: false,
|
||||||
|
closeOnSubmit: true,
|
||||||
|
title: "Choix des status/effets"
|
||||||
|
});
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
getData() {
|
||||||
|
const used = StatusEffects._getUseStatusEffects();
|
||||||
|
let formData = super.getData();
|
||||||
|
formData.effects = duplicate(CONFIG.RDD.allEffects);
|
||||||
|
formData.effects.forEach(it => it.active = used.includes(it.id))
|
||||||
|
return formData;
|
||||||
|
}
|
||||||
|
|
||||||
|
activateListeners(html) {
|
||||||
|
html.find(".select-effect").click((event) => {
|
||||||
|
let id = event.currentTarget.attributes.name?.value;
|
||||||
|
if (id) {
|
||||||
|
let selected = StatusEffects._getUseStatusEffects();
|
||||||
|
let isChecked = event.currentTarget.checked;
|
||||||
|
if (isChecked) {
|
||||||
|
selected.push(id);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
selected = selected.filter(it => it != id)
|
||||||
|
}
|
||||||
|
StatusEffects._setUseStatusEffects(selected);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async _updateObject(event, formData) {
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
287
module/settings/system-compendiums.js
Normal file
@@ -0,0 +1,287 @@
|
|||||||
|
import { HIDE_DICE, SYSTEM_RDD } from "../constants.js";
|
||||||
|
import { RdDItem } from "../item.js";
|
||||||
|
import { Misc } from "../misc.js";
|
||||||
|
import { RdDDice } from "../rdd-dice.js";
|
||||||
|
|
||||||
|
const COMPENDIUM_SETTING_PREFIX = 'compendium-';
|
||||||
|
|
||||||
|
const CONFIGURABLE_COMPENDIUMS = {
|
||||||
|
'tables-diverses': { label: "Tables aléatoires", type: "RollTable" },
|
||||||
|
'competences': { label: "Compétences", type: "Item" },
|
||||||
|
'extrait-poetique': { label: "Extraits poetiques", type: "Item" },
|
||||||
|
'queues-de-dragon': { label: "Queues de dragon", type: "Item" },
|
||||||
|
'ombres-de-thanatos': { label: "Ombres de Thanatos", type: "Item" },
|
||||||
|
'souffles-de-dragon': { label: "Souffles de Dragon", type: "Item" },
|
||||||
|
'tarot-draconique': { label: "Tarots draconiques", type: "Item" },
|
||||||
|
'rencontres': { label: "Rencontres dans les TMR", type: "Item" },
|
||||||
|
'tetes-de-dragon-pour-haut-revants': { label: "Têtes de dragons (haut-rêvant)", type: "Item" },
|
||||||
|
'tetes-de-dragon-pour-tous-personnages': { label: "Têtes de dragons (tous)", type: "Item" },
|
||||||
|
'faune-flore-mineraux': { label: "Herbes & plantes", type: "Item" },
|
||||||
|
'equipement': { label: "Equipements", type: "Item" },
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ======= Gestion des accès aux compendiums systèmes (ou surchargés) =======
|
||||||
|
*/
|
||||||
|
export class SystemCompendiums extends FormApplication {
|
||||||
|
static init() {
|
||||||
|
Object.keys(CONFIGURABLE_COMPENDIUMS).forEach(compendium => {
|
||||||
|
const definition = CONFIGURABLE_COMPENDIUMS[compendium];
|
||||||
|
mergeObject(definition, {
|
||||||
|
compendium: compendium,
|
||||||
|
default: SystemCompendiums._getDefaultCompendium(compendium),
|
||||||
|
setting: SystemCompendiums._getSettingCompendium(compendium)
|
||||||
|
});
|
||||||
|
|
||||||
|
game.settings.register(SYSTEM_RDD, definition.setting, {
|
||||||
|
name: definition.label,
|
||||||
|
default: definition.default,
|
||||||
|
scope: "world",
|
||||||
|
config: false,
|
||||||
|
type: String
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
game.settings.registerMenu(SYSTEM_RDD, "compendium-settings", {
|
||||||
|
name: "Choisir les compendiums système",
|
||||||
|
label: "Compendiums système",
|
||||||
|
hint: "Ouvre la fenêtre de sélection des compendiums système",
|
||||||
|
icon: "fas fa-bars",
|
||||||
|
type: SystemCompendiums
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
static getPack(compendium) {
|
||||||
|
return game.packs.get(SystemCompendiums.getCompendium(compendium)) ?? game.packs.get(SystemCompendiums._getDefaultCompendium(compendium));
|
||||||
|
}
|
||||||
|
|
||||||
|
static async getPackContent(compendium, docType) {
|
||||||
|
const pack = SystemCompendiums.getPack(compendium);
|
||||||
|
if (pack.metadata.type == docType) {
|
||||||
|
return await pack.getDocuments();
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
static async getCompetences(actorType) {
|
||||||
|
switch (actorType ?? 'personnage') {
|
||||||
|
case 'personnage': return await SystemCompendiums.getWorldOrCompendiumItems('competence', 'competences');
|
||||||
|
case 'creature': return await SystemCompendiums.getWorldOrCompendiumItems('competencecreature', 'competences-creatures');
|
||||||
|
case 'entite': return await SystemCompendiums.getWorldOrCompendiumItems('competencecreature', 'competences-entites');
|
||||||
|
case 'vehicule': return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async getWorldOrCompendiumItems(itemType, compendium) {
|
||||||
|
let items = game.items.filter(it => it.type == itemType);
|
||||||
|
if (compendium) {
|
||||||
|
const ids = items.map(it => it.id);
|
||||||
|
const names = items.map(it => it.name.toLowerCase());
|
||||||
|
const compendiumItems = await SystemCompendiums.getItems(compendium);
|
||||||
|
items = items.concat(compendiumItems
|
||||||
|
.filter(it => it.type == itemType)
|
||||||
|
.filter(it => !ids.includes(it.id))
|
||||||
|
.filter(it => !names.includes(it.name.toLowerCase())));
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async getItems(compendium, itemType = undefined) {
|
||||||
|
const items = await SystemCompendiums.getPackContent(compendium, 'Item');
|
||||||
|
return (itemType ? items.filter(it => it.type == itemType) : items);
|
||||||
|
}
|
||||||
|
|
||||||
|
static async getContent(compendium, type, filter, itemFrequence, sorting) {
|
||||||
|
let elements = await SystemCompendiums.getPackContent(compendium, type);
|
||||||
|
elements = elements.filter(filter).filter(it => itemFrequence(it) > 0);
|
||||||
|
if (sorting) {
|
||||||
|
elements = elements.sort(sorting);
|
||||||
|
}
|
||||||
|
return elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async getDefaultItems(compendium) {
|
||||||
|
const pack = game.packs.get(SystemCompendiums._getDefaultCompendium(compendium));
|
||||||
|
if (pack.metadata.type == 'Item') {
|
||||||
|
return await pack.getDocuments();
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
static getCompendium(compendium) {
|
||||||
|
const setting = CONFIGURABLE_COMPENDIUMS[compendium]?.setting;
|
||||||
|
return setting ? game.settings.get(SYSTEM_RDD, setting) : SystemCompendiums._getDefaultCompendium(compendium);
|
||||||
|
}
|
||||||
|
|
||||||
|
static _getSettingCompendium(compendium) {
|
||||||
|
return COMPENDIUM_SETTING_PREFIX + compendium;
|
||||||
|
}
|
||||||
|
|
||||||
|
static _getDefaultCompendium(compendium) {
|
||||||
|
return `${SYSTEM_RDD}.${compendium}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(...args) {
|
||||||
|
super(...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
static get defaultOptions() {
|
||||||
|
const options = super.defaultOptions;
|
||||||
|
mergeObject(options, {
|
||||||
|
id: "system-compendiums",
|
||||||
|
template: "systems/foundryvtt-reve-de-dragon/templates/settings/system-compendiums.html",
|
||||||
|
height: 'fit-content',
|
||||||
|
width: 600,
|
||||||
|
minimizable: false,
|
||||||
|
closeOnSubmit: true,
|
||||||
|
title: "Compendiums système"
|
||||||
|
});
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
getData() {
|
||||||
|
const systemCompendiums = Object.values(CONFIGURABLE_COMPENDIUMS)
|
||||||
|
.map(it => mergeObject(it, { value: SystemCompendiums.getCompendium(it.compendium) }));
|
||||||
|
const availableCompendiums = game.packs.map(pack => {
|
||||||
|
return {
|
||||||
|
name: pack.collection,
|
||||||
|
path: pack.collection.replace('.', " / "),
|
||||||
|
type: pack.metadata.type
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return mergeObject(super.getData(), {
|
||||||
|
systemCompendiums: systemCompendiums,
|
||||||
|
availableCompendiums: availableCompendiums
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
activateListeners(html) {
|
||||||
|
html.find("select.system-compendium-setting").change((event) => {
|
||||||
|
const compendium = $(event.currentTarget).data('compendium')
|
||||||
|
const value = $(event.currentTarget).val();
|
||||||
|
const systemCompendium = CONFIGURABLE_COMPENDIUMS[compendium];
|
||||||
|
|
||||||
|
game.settings.set(SYSTEM_RDD, systemCompendium.setting, value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ======= Gestion de jets dans une table correspondant à un compendium =======
|
||||||
|
*/
|
||||||
|
export class CompendiumTable {
|
||||||
|
|
||||||
|
constructor(compendium, type, subTypes, sorting = undefined) {
|
||||||
|
this.compendium = compendium;
|
||||||
|
this.type = type;
|
||||||
|
this.subTypes = subTypes;
|
||||||
|
this.sorting = sorting ?? Misc.ascending(it => it.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getContent(itemFrequence = it => it.system.frequence, filter = it => true) {
|
||||||
|
return await SystemCompendiums.getContent(this.compendium,
|
||||||
|
this.type,
|
||||||
|
it => this.subTypes.includes(it.type) && filter(it),
|
||||||
|
itemFrequence,
|
||||||
|
this.sorting);
|
||||||
|
}
|
||||||
|
|
||||||
|
async buildTable(itemFrequence = it => it.system.frequence, filter = it => true) {
|
||||||
|
const elements = await this.getContent(filter, itemFrequence);
|
||||||
|
return CompendiumTableHelpers.buildTable(elements, itemFrequence);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getRandom(itemFrequence = it => it.system.frequence, filter = it => true, forcedRoll = undefined) {
|
||||||
|
const table = await this.buildTable(itemFrequence, filter);
|
||||||
|
return await CompendiumTableHelpers.getRandom(table, this.type, this.subTypes, forcedRoll, SystemCompendiums.getCompendium(compendium));
|
||||||
|
}
|
||||||
|
|
||||||
|
async toChatMessage(itemFrequence = it => it.system.frequence, filter = it => true, typeName = undefined) {
|
||||||
|
const table = await this.buildTable(itemFrequence, filter);
|
||||||
|
await CompendiumTableHelpers.tableToChatMessage(table, this.type, this.subTypes, typeName);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ======= Gestion de tables correspondant à un compendium =======
|
||||||
|
*/
|
||||||
|
export class CompendiumTableHelpers {
|
||||||
|
|
||||||
|
static buildTable(elements, itemFrequence) {
|
||||||
|
let max = 0;
|
||||||
|
const total = elements.map(it => itemFrequence(it)).reduce(Misc.sum(), 0);
|
||||||
|
return elements.map(it => {
|
||||||
|
const frequence = itemFrequence(it);
|
||||||
|
let row = { document: it, frequence: frequence, min: max + 1, max: max + frequence, total: total };
|
||||||
|
max += frequence;
|
||||||
|
return row;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static async getRandom(table, type, subTypes, forcedRoll = undefined, localisation = undefined) {
|
||||||
|
if (table.length == 0) {
|
||||||
|
ui.notifications.warn(`Aucun ${Misc.typeName(type, subTypes[0])} trouvé dans ${localisation ?? ' les compendiums'}`);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return await CompendiumTableHelpers.selectRow(table, forcedRoll);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async selectRow(table, forcedRoll = undefined) {
|
||||||
|
if (table.length == 0) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
const total = table[0].total;
|
||||||
|
const formula = `1d${total}`;
|
||||||
|
if (forcedRoll == undefined && (forcedRoll > total || forcedRoll <= 0)) {
|
||||||
|
ui.notifications.warn(`Jet de rencontre ${forcedRoll} en dehors de la table [1..${total}], le jet est relancé`);
|
||||||
|
forcedRoll = undefined;
|
||||||
|
}
|
||||||
|
const roll = forcedRoll ? { total: forcedRoll, formula } : await RdDDice.roll(formula, { showDice: HIDE_DICE });
|
||||||
|
const row = table.find(it => it.min <= roll.total && roll.total <= it.max);
|
||||||
|
row.roll = roll;
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async tableRowToChatMessage(row, type = 'Item') {
|
||||||
|
if (!row) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const percentages = (row.total == 100) ? '%' : ''
|
||||||
|
const flavorContent = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-compendium-table-roll.html', {
|
||||||
|
roll: row.roll,
|
||||||
|
document: row.document,
|
||||||
|
percentages,
|
||||||
|
typeName: Misc.typeName(type, row.document.type),
|
||||||
|
isGM: game.user.isGM,
|
||||||
|
});
|
||||||
|
const messageData = {
|
||||||
|
// flavor: flavorContent,
|
||||||
|
user: game.user.id,
|
||||||
|
type: CONST.CHAT_MESSAGE_TYPES.ROLL,
|
||||||
|
roll: row.roll,
|
||||||
|
sound: CONFIG.sounds.dice,
|
||||||
|
content: flavorContent
|
||||||
|
};
|
||||||
|
ChatMessage.create(messageData, { rollMode: "gmroll" });
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async tableToChatMessage(table, type, subTypes, typeName = undefined) {
|
||||||
|
const flavorContent = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-compendium-table.html', {
|
||||||
|
img: RdDItem.getDefaultImg(subTypes[0]),
|
||||||
|
typeName: typeName ?? Misc.typeName(type, subTypes[0]),
|
||||||
|
table,
|
||||||
|
isGM: game.user.isGM,
|
||||||
|
});
|
||||||
|
ChatMessage.create({
|
||||||
|
user: game.user.id,
|
||||||
|
whisper: game.user.id,
|
||||||
|
content: flavorContent
|
||||||
|
}, { rollMode: "gmroll" });
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,135 +0,0 @@
|
|||||||
import { SYSTEM_RDD } from "./constants.js";
|
|
||||||
|
|
||||||
const rddStatusEffects = [
|
|
||||||
{ rdd: true, id: 'stun', label: 'EFFECT.StatusStunned', icon: 'icons/svg/stoned.svg', "duration.rounds": 1 },
|
|
||||||
{ rdd: true, id: 'bleeding', label: 'EFFECT.StatusBleeding', icon: 'icons/svg/blood.svg' },
|
|
||||||
{ rdd: true, id: 'prone', label: 'EFFECT.StatusProne', icon: 'icons/svg/falling.svg' },
|
|
||||||
{ rdd: true, id: 'grappling', tint: '#33cc33', label: 'EFFECT.StatusGrappling', icon: 'systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp' },
|
|
||||||
{ rdd: true, id: 'grappled', tint: '#ff9900', label: 'EFFECT.StatusGrappled', icon: 'systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp' },
|
|
||||||
{ rdd: true, id: 'restrain', label: 'EFFECT.StatusRestrained', icon: 'icons/svg/net.svg' },
|
|
||||||
{ rdd: true, id: 'unconscious', label: 'EFFECT.StatusUnconscious', icon: 'icons/svg/unconscious.svg' },
|
|
||||||
{ rdd: true, id: 'blind', label: 'EFFECT.StatusBlind', icon: 'icons/svg/blind.svg' },
|
|
||||||
{ rdd: true, id: 'comma', label: 'EFFECT.StatusComma', icon: 'icons/svg/skull.svg' },
|
|
||||||
{ rdd: true, id: 'dead', label: 'EFFECT.StatusDead', icon: 'icons/svg/skull.svg' },
|
|
||||||
{ rdd: true, id: 'demi-reve', label: 'EFFECT.StatusDemiReve', icon: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd12.svg' }
|
|
||||||
];
|
|
||||||
const demiReveStatusEffect = rddStatusEffects.find(it => it.label == 'EFFECT.StatusDemiReve');
|
|
||||||
|
|
||||||
const statusDemiSurprise = new Set(['EFFECT.StatusStunned', 'EFFECT.StatusProne', 'EFFECT.StatusRestrain']);
|
|
||||||
const statusSurpriseTotale = new Set(['EFFECT.StatusUnconscious', 'EFFECT.StatusBlind', 'EFFECT.StatusComma']);
|
|
||||||
|
|
||||||
export class StatusEffects {
|
|
||||||
static onReady() {
|
|
||||||
const rddStatusIds = rddStatusEffects.map(it => it.id);
|
|
||||||
const defaultStatusEffectIds = CONFIG.statusEffects.map(it => it.id);
|
|
||||||
game.settings.register(SYSTEM_RDD, "use-status-effects", {
|
|
||||||
name: "use-status-effects",
|
|
||||||
scope: "world",
|
|
||||||
config: false,
|
|
||||||
default: defaultStatusEffectIds.join(),
|
|
||||||
type: String
|
|
||||||
});
|
|
||||||
|
|
||||||
game.settings.registerMenu(SYSTEM_RDD, "select-status-effect", {
|
|
||||||
name: "Choisir les effets disponibles",
|
|
||||||
label: "Choix des effets",
|
|
||||||
hint: "Ouvre la fenêtre de sélection des effets/status appliqués aux acteurs",
|
|
||||||
icon: "fas fa-bars",
|
|
||||||
type: StatusEffectsSettings,
|
|
||||||
restricted: true
|
|
||||||
});
|
|
||||||
|
|
||||||
CONFIG.RDD.allEffects = rddStatusEffects.concat(CONFIG.statusEffects.filter(it => !rddStatusIds.includes(it.id)));
|
|
||||||
|
|
||||||
StatusEffects._setUseStatusEffects(StatusEffects._getUseStatusEffects());
|
|
||||||
console.log('statusEffects', CONFIG.statusEffects);
|
|
||||||
}
|
|
||||||
|
|
||||||
static valeurSurprise(effect, isCombat) {
|
|
||||||
// const id = StatusEffects.statusId(effect);
|
|
||||||
if (statusSurpriseTotale.has(effect.label)) {
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
return statusDemiSurprise.has(effect.label) || (isCombat && effect.label == demiReveStatusEffect.label) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static setMandatoryRdd() {
|
|
||||||
CONFIG.statusEffects.filter(it => statusDemiSurprise.has(it.id) || statusSurpriseTotale.has(it.id))
|
|
||||||
.forEach(it => it.rdd = true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static _getUseStatusEffects() {
|
|
||||||
const setting = game.settings.get(SYSTEM_RDD, "use-status-effects");
|
|
||||||
return setting ? new Set(setting.split(',')) : new Set();
|
|
||||||
}
|
|
||||||
|
|
||||||
static _setUseStatusEffects(useStatusEffects) {
|
|
||||||
if (game.user.isGM) {
|
|
||||||
game.settings.set(SYSTEM_RDD, "use-status-effects", StatusEffects._toSetting(useStatusEffects));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let effect of CONFIG.RDD.allEffects) {
|
|
||||||
effect.active = effect.rdd || useStatusEffects.has(effect.id);
|
|
||||||
}
|
|
||||||
CONFIG.statusEffects = CONFIG.RDD.allEffects.filter(it => it.active);
|
|
||||||
}
|
|
||||||
|
|
||||||
static _toSetting(useStatusEffects) {
|
|
||||||
return Array.from(useStatusEffects).join();
|
|
||||||
}
|
|
||||||
|
|
||||||
static status(label) {
|
|
||||||
return rddStatusEffects.find(it => it.label == label) ?? { label: label };
|
|
||||||
}
|
|
||||||
static demiReve() {
|
|
||||||
return demiReveStatusEffect;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class StatusEffectsSettings extends FormApplication {
|
|
||||||
constructor(...args) {
|
|
||||||
super(...args);
|
|
||||||
}
|
|
||||||
|
|
||||||
static get defaultOptions() {
|
|
||||||
const options = super.defaultOptions;
|
|
||||||
mergeObject(options, {
|
|
||||||
id: "status-effects-settings",
|
|
||||||
template: "systems/foundryvtt-reve-de-dragon/templates/status-effects-settings.html",
|
|
||||||
height: "800",
|
|
||||||
width: 350,
|
|
||||||
minimizable: false,
|
|
||||||
closeOnSubmit: true,
|
|
||||||
title: "Choix des status/effets"
|
|
||||||
});
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
||||||
getData() {
|
|
||||||
let formData = super.getData();
|
|
||||||
formData.effects = CONFIG.RDD.allEffects;
|
|
||||||
return formData;
|
|
||||||
}
|
|
||||||
|
|
||||||
activateListeners(html) {
|
|
||||||
html.find(".select-effect").click((event) => {
|
|
||||||
let id = event.currentTarget.attributes.name?.value;
|
|
||||||
if (id) {
|
|
||||||
let selected = StatusEffects._getUseStatusEffects();
|
|
||||||
let isChecked = event.currentTarget.checked;
|
|
||||||
if (isChecked) {
|
|
||||||
selected.add(id);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
selected.delete(id);
|
|
||||||
}
|
|
||||||
StatusEffects._setUseStatusEffects(selected);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async _updateObject(event, formData) {
|
|
||||||
this.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
56
module/targets.js
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import { ENTITE_NONINCARNE } from "./constants.js";
|
||||||
|
import { DialogSelectTarget } from "./dialog-select-target.js";
|
||||||
|
|
||||||
|
export class Targets {
|
||||||
|
static listTargets() {
|
||||||
|
return Array.from(game.user.targets);
|
||||||
|
}
|
||||||
|
|
||||||
|
static hasTargets() {
|
||||||
|
return Targets.listTargets().length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static extractTokenData(target) {
|
||||||
|
if (!target) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
return { id: target.id, name: target.document.name, img: target.document.texture.src ?? target.actor.img ?? 'icons/svg/mystery-man.svg' };
|
||||||
|
}
|
||||||
|
|
||||||
|
static isTargetEntite(target) {
|
||||||
|
return target?.actor.type == 'entite' && target?.actor.system.definition.typeentite == ENTITE_NONINCARNE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async selectOneToken(onSelectTarget = target => { }) {
|
||||||
|
const targets = Targets.listTargets();
|
||||||
|
switch (targets.length) {
|
||||||
|
case 0: return;
|
||||||
|
case 1:
|
||||||
|
onSelectTarget(targets[0]);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
const tokens = targets.map(it => Targets.extractTokenData(it))
|
||||||
|
const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-select-target.html", {
|
||||||
|
tokens: tokens
|
||||||
|
});
|
||||||
|
new DialogSelectTarget(html, onSelectTarget, targets).render(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static getTarget() {
|
||||||
|
const targets = Targets.listTargets();
|
||||||
|
switch (targets.length) {
|
||||||
|
case 1:
|
||||||
|
return targets[0];
|
||||||
|
case 0:
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,500 +1,132 @@
|
|||||||
import { Grammar } from "./grammar.js";
|
import { Grammar } from "./grammar.js";
|
||||||
import { Misc } from "./misc.js";
|
import { Misc } from "./misc.js";
|
||||||
import { RdDDice } from "./rdd-dice.js";
|
import { RdDDice } from "./rdd-dice.js";
|
||||||
|
import { RdDUtility } from "./rdd-utility.js";
|
||||||
|
import { SystemCompendiums, CompendiumTable, CompendiumTableHelpers } from "./settings/system-compendiums.js";
|
||||||
import { TMRUtility } from "./tmr-utility.js";
|
import { TMRUtility } from "./tmr-utility.js";
|
||||||
import { TMRType } from "./tmr-utility.js";
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
const typeRencontres = {
|
|
||||||
|
|
||||||
messager: {
|
|
||||||
msgSucces: async (rencData) => {
|
|
||||||
if (rencData.actor.isTMRCache()){
|
|
||||||
return `Le ${rencData.rencontre.name} vous propose d'emmener le message de votre un sort, mais vous ne savez pas où vous êtes.`;
|
|
||||||
}
|
|
||||||
return `Le ${rencData.rencontre.name} vous propose d'emmener le message de votre un sort à ${rencData.rencontre.force} cases ${rencData.tmr.label}.`;
|
|
||||||
},
|
|
||||||
msgEchec: async (rencData)=> `Le ${rencData.rencontre.name} est pressé et continue son chemin d'une traite sans vous accorder un regard.`,
|
|
||||||
postSucces: async (tmrDialog, rencData) => {
|
|
||||||
tmrDialog.setStateRencontre(rencData.rencontre.type);
|
|
||||||
tmrDialog.choisirCasePortee(rencData.tmr.coord, rencData.rencontre.force);
|
|
||||||
},
|
|
||||||
poesieSucces: {
|
|
||||||
reference: "La chevelure, Charles Baudelaire",
|
|
||||||
extrait: `J'irai là-bas où l'arbre et l'homme, pleins de sève,
|
|
||||||
<br>Se pâment longuement sous l'ardeur des climats ;
|
|
||||||
<br>Fortes tresses, soyez la houle qui m'enlève !`
|
|
||||||
},
|
|
||||||
poesieEchec: {
|
|
||||||
reference: "Rêve de Dragon, Denis Gerfaud",
|
|
||||||
extrait: `En réalité, tous les éléments du rêve des Dragons expriment
|
|
||||||
le Draconic : chaque pierre, chaque fleur, chaque goutte d'eau,
|
|
||||||
chaque nuage est porteur d'un message dans la langue des Dragons`}
|
|
||||||
},
|
|
||||||
|
|
||||||
passeur: {
|
|
||||||
msgSucces: async (rencData) => {
|
|
||||||
if (rencData.actor.isTMRCache()){
|
|
||||||
return `Le ${rencData.rencontre.name} vous propose de vous transporter, mais vous ne savez pas où vous êtes.`;
|
|
||||||
}
|
|
||||||
return `Le ${rencData.rencontre.name} vous propose de vous transporter à ${rencData.rencontre.force} cases des ${rencData.tmr.label}.`;
|
|
||||||
},
|
|
||||||
msgEchec: async (rencData)=> `Le prix que demande le ${rencData.rencontre.name} est trop élevé, vous êtes réduit à poursuivre votre chemin par vos propres moyens.`,
|
|
||||||
postSucces: async (tmrDialog, rencData) => {
|
|
||||||
tmrDialog.setStateRencontre(rencData.rencontre.type);
|
|
||||||
tmrDialog.choisirCasePortee(rencData.tmr.coord, rencData.rencontre.force);
|
|
||||||
},
|
|
||||||
poesieSucces: {
|
|
||||||
reference: "Femmes damnées (2), Charles Baudelaire",
|
|
||||||
extrait: `Comme je descendais des Fleuves impassibles,
|
|
||||||
<br>Je ne me sentis plus guidé par les haleurs :
|
|
||||||
<br>Des Peaux-Rouges criards les avaient pris pour cibles,
|
|
||||||
<br>Les ayant cloués nus aux poteaux de couleurs.`},
|
|
||||||
poesieEchec: {
|
|
||||||
reference: "Le bateau ivre, Arthur Rimbaud",
|
|
||||||
extrait: `Loin des peuples vivants, errantes, condamnées,
|
|
||||||
<br>A travers les déserts courez comme les loups ;
|
|
||||||
<br>Faites votre destin, âmes désordonnées,
|
|
||||||
<br>Et fuyez l'infini que vous portez en vous !`}
|
|
||||||
},
|
|
||||||
|
|
||||||
fleur: {
|
|
||||||
msgSucces: async (rencData) => `Vous cueillez la ${rencData.rencontre.name}, son parfum vous apporte ${rencData.rencontre.force} points de Rêve.`,
|
|
||||||
msgEchec: async (rencData)=> `La ${rencData.rencontre.name} se fâne et disparaît entre vos doigts.`,
|
|
||||||
postSucces: async (tmrDialog, rencData) => tmrDialog.actor.reveActuelIncDec(rencData.rencontre.force),
|
|
||||||
poesieSucces: {
|
|
||||||
reference: "L'Ennemi, Charles Baudelaire",
|
|
||||||
extrait: `Et qui sait si les fleurs nouvelles que je rêve
|
|
||||||
<br>Trouveront dans ce sol lavé comme une grève
|
|
||||||
<br>Le mystique aliment qui ferait leur vigueur ?`},
|
|
||||||
poesieEchec: {
|
|
||||||
reference: "Une charogne, Charles Baudelaire",
|
|
||||||
extrait: `Et le ciel regardait la carcasse superbe
|
|
||||||
<br>Comme une fleur s'épanouir.
|
|
||||||
<br>La puanteur était si forte, que sur l'herbe
|
|
||||||
<br>Vous crûtes vous évanouir.`},
|
|
||||||
},
|
|
||||||
|
|
||||||
mangeur: {
|
|
||||||
msgSucces: async (rencData) => `Le ${rencData.rencontre.name} claque de sa machoire dans le vide avant de fuir.`,
|
|
||||||
msgEchec: async (rencData)=> `Le ${rencData.rencontre.name} croque votre Rêve ! Il emporte ${rencData.rencontre.force} de vos points de rêve actuels`,
|
|
||||||
postEchec: async (tmrDialog, rencData) => tmrDialog.actor.reveActuelIncDec(-rencData.rencontre.force),
|
|
||||||
poesieSucces: {
|
|
||||||
reference: "Conseil, Victor Hugo",
|
|
||||||
extrait: `Rois ! la bure est souvent jalouse du velours.
|
|
||||||
<br>Le peuple a froid l'hiver, le peuple a faim toujours.
|
|
||||||
<br>Rendez-lui son sort plus facile.
|
|
||||||
<br>Le peuple souvent porte un bien rude collier.
|
|
||||||
<br>Ouvrez l'école aux fils, aux pères l'atelier,
|
|
||||||
<br>À tous vos bras, auguste asile !`},
|
|
||||||
poesieEchec: {
|
|
||||||
reference: "El Desdichado, Gérard de Nerval",
|
|
||||||
extrait: `Suis-je Amour ou Phébus ?... Lusignan ou Biron ?
|
|
||||||
<br>Mon front est rouge encor du baiser de la Reine ;
|
|
||||||
<br>J'ai rêvé dans la Grotte où nage la sirène...`}
|
|
||||||
},
|
|
||||||
|
|
||||||
changeur: {
|
|
||||||
msgSucces: async (rencData) => `Le ${rencData.rencontre.name} vaincu accepte de vous déplacer sur une autre ${TMRType[rencData.tmr.type].name} de votre choix en échange de sa liberté.`,
|
|
||||||
msgEchec: async (rencData) => `Le ${rencData.rencontre.name} vous embobine avec des promesses, et vous transporte sur une autre ${TMRType[rencData.tmr.type].name} sans attendre votre avis.`,
|
|
||||||
postSucces: async (tmrDialog, rencData) => {
|
|
||||||
tmrDialog.setStateRencontre(rencData.rencontre.type);
|
|
||||||
tmrDialog.choisirCaseType(rencData.tmr.type);
|
|
||||||
},
|
|
||||||
postEchec: async (tmrDialog, rencData) => {
|
|
||||||
const newTMR = await TMRUtility.getTMRAleatoire(it => it.type == rencData.tmr.type && it.coord != rencData.tmr.coord);
|
|
||||||
await tmrDialog.actor.forcerPositionTMRInconnue(newTMR);
|
|
||||||
tmrDialog.positionnerDemiReve(newTMR.coord);
|
|
||||||
},
|
|
||||||
poesieSucces: {
|
|
||||||
reference: "Caligula - IIIème chant, Gérard de Nerval",
|
|
||||||
extrait: `Allez, que le caprice emporte
|
|
||||||
<br>Chaque âme selon son désir,
|
|
||||||
<br>Et que, close après vous, la porte
|
|
||||||
<br>Ne se rouvre plus qu'au plaisir.`},
|
|
||||||
poesieEchec: {
|
|
||||||
reference: "Rêve de Dragon, Denis Gerfaud",
|
|
||||||
extrait: `Les sages ont encore coutume de dire :
|
|
||||||
<br>« Mais comment les Dragons peuvent-ils
|
|
||||||
être influencés par une créature qui, tout
|
|
||||||
bien considéré, n'existe pas vraiment pour eux,
|
|
||||||
qui n'est que le fantasme de leur activité nocturne ? »`}
|
|
||||||
},
|
|
||||||
|
|
||||||
briseur: {
|
|
||||||
msgSucces: async (rencData) => `Le ${rencData.rencontre.name} tente vainement de vous déconcentrer, avant de fuir sans demander son reste.`,
|
|
||||||
msgEchec: async (rencData)=> `Le ${rencData.rencontre.name} vous déconcentre au point de briser votre demi-rêve.`,
|
|
||||||
postEchec: async (tmrDialog, rencData) => tmrDialog.close(),
|
|
||||||
poesieSucces: {
|
|
||||||
reference: "Rêve de Dragon, Denis Gerfaud",
|
|
||||||
extrait: `La légende affirme que ce sont les Gnomes qui furent
|
|
||||||
les premiers haut-rêvants. En observant les pierres précieuses,
|
|
||||||
les gemmes qui sont les larmes de joie des Dragons, ils parvinrent à
|
|
||||||
en comprendre la langue. Et l'ayant comprise, ils purent s'en servir
|
|
||||||
pour influencer le cours du rêve`},
|
|
||||||
poesieEchec: {
|
|
||||||
reference: "Quand le rêve se brise, Cypora Sebagh",
|
|
||||||
extrait: `Quand le rêve se brise,
|
|
||||||
<br>Dans la plainte du jour,
|
|
||||||
<br>Ma mémoire devient grise
|
|
||||||
<br>Et sombre, tour à tour,
|
|
||||||
<br>Dans le puits du silence
|
|
||||||
<br>Et de la solitude ;
|
|
||||||
<br>Elle reprend son errance
|
|
||||||
<br>Parmi la multitude.`}
|
|
||||||
},
|
|
||||||
|
|
||||||
reflet: {
|
|
||||||
msgSucces: async (rencData) => `Le ${rencData.rencontre.name} s'estompe dans l'oubli.`,
|
|
||||||
msgEchec: async (rencData)=> `Vous êtes submergé par un ${rencData.rencontre.name}, les souvenirs vous retiennent tant qu'il ne sera pas vaincu!`,
|
|
||||||
poesieSucces: {
|
|
||||||
reference: "Une charogne, Charles Baudelaire",
|
|
||||||
extrait: `Les formes s'effaçaient et n'étaient plus qu'un rêve,
|
|
||||||
<br>Une ébauche lente à venir
|
|
||||||
<br>Sur la toile oubliée, et que l'artiste achève
|
|
||||||
<br>Seulement par le souvenir.`},
|
|
||||||
poesieEchec: {
|
|
||||||
reference: "La chevelure, Charles Baudelaire",
|
|
||||||
extrait: `Longtemps ! toujours ! ma main dans ta crinière lourde
|
|
||||||
<br>Sèmera le rubis, la perle et le saphir,
|
|
||||||
<br>Afin qu'à mon désir tu ne sois jamais sourde !
|
|
||||||
<br>N'es-tu pas l'oasis où je rêve, et la gourde
|
|
||||||
<br>Où je hume à longs traits le vin du souvenir`}
|
|
||||||
},
|
|
||||||
|
|
||||||
passeurfou: {
|
|
||||||
msgSucces: async (rencData) => `Le ${rencData.rencontre.name} tente vainement de découvrir où vous avez caché vos réserves. Vous le chassez, et en déroute il part harceler un autre voyageur du rêve.`,
|
|
||||||
msgEchec: async (rencData)=> TMRRencontres.msgEchecPasseurFou(rencData),
|
|
||||||
postEchec: async (tmrDialog, rencData) => TMRRencontres.postEchecPasseurFou(tmrDialog, rencData),
|
|
||||||
poesieSucces: {
|
|
||||||
reference: "Un Fou et un Sage, Jean de La Fontaine",
|
|
||||||
extrait: `Certain Fou poursuivait à coups de pierre un Sage.
|
|
||||||
<br>Le Sage se retourne et lui dit : Mon ami,
|
|
||||||
<br>C'est fort bien fait à toi ; reçois cet écu-ci :
|
|
||||||
<br>Tu fatigues assez pour gagner davantage.`},
|
|
||||||
poesieEchec: {
|
|
||||||
reference: "Guitare, Victor Hugo",
|
|
||||||
extrait: `Je la voyais passer de ma demeure,
|
|
||||||
<br>Et c'était tout.
|
|
||||||
<br>Mais à présent je m'ennuie à toute heure,
|
|
||||||
<br>Plein de dégoût,
|
|
||||||
<br>Rêveur oisif, l'âme dans la campagne,
|
|
||||||
<br>La dague au clou ... –
|
|
||||||
<br>Le vent qui vient à travers la montagne
|
|
||||||
<br>M'a rendu fou !`}
|
|
||||||
},
|
|
||||||
|
|
||||||
tbblanc: {
|
|
||||||
msgSucces: async (rencData) => `Le ${rencData.rencontre.name} souleve une poussière blanche, vous tenez bon, et il tourbillonne en s'éloignant.`,
|
|
||||||
msgEchec: async (rencData)=> `Le souffle du ${rencData.rencontre.name} vous déstabilise et vous emmène dans un nuage de poussière.`,
|
|
||||||
postEchec: async (tmrDialog, rencData) => TMRRencontres.onPostEchecTourbillon(tmrDialog, rencData, 1),
|
|
||||||
poesieSucces: {
|
|
||||||
reference: "Rêve de Dragon, Denis Gerfaud",
|
|
||||||
extrait: `Le Premier Âge fut appelé l'Âge des Dragons. Ce fut le commencement
|
|
||||||
des temps, le commencement des rêves. Durant cette période plus mythique
|
|
||||||
que réellement historique, les Dragons aimaient à se rêver eux-mêmes.`},
|
|
||||||
poesieEchec: {
|
|
||||||
reference: "Les Djinns, Victor Hugo",
|
|
||||||
extrait: `C'est l'essaim des Djinns qui passe,
|
|
||||||
<br>Et tourbillonne en sifflant !
|
|
||||||
<br>Les ifs, que leur vol fracasse,
|
|
||||||
<br>Craquent comme un pin brûlant.`},
|
|
||||||
},
|
|
||||||
|
|
||||||
tbnoir: {
|
|
||||||
msgSucces: async (rencData) => `Le ${rencData.rencontre.name} orageux vous enveloppe de fureur et d'éclairs, vous tenez bon face à la tempête qui s'éloigne sans vous éloigner de votre chemin.`,
|
|
||||||
msgEchec: async (rencData)=> `Le ${rencData.rencontre.name} furieux vous secoue tel un fichu de paille malmené par les vents, et vous emporte dans la tourmente.`,
|
|
||||||
postEchec: async (tmrDialog, rencData) => TMRRencontres.onPostEchecTourbillon(tmrDialog, rencData, 2),
|
|
||||||
poesieSucces: {
|
|
||||||
reference: "Rêve de Dragon, Denis Gerfaud",
|
|
||||||
extrait: `Car le Second Âge fut bel et bien celui des Magiciens. Durant cette période, les
|
|
||||||
Gnomes s'enfoncèrent profondément sous les montagnes et la magie passa aux
|
|
||||||
mains des Humains qui en usèrent et abusèrent, se croyant devenus les maîtres du monde`},
|
|
||||||
poesieEchec: {
|
|
||||||
reference: "Lily, Pierre Perret",
|
|
||||||
extrait: `Elle aurait pas cru sans le voir
|
|
||||||
<br>Que la couleur du désespoir
|
|
||||||
<br>Là-bas aussi ce fût le noir.`},
|
|
||||||
},
|
|
||||||
|
|
||||||
tbrouge: {
|
|
||||||
msgSucces: async (rencData) => `Le ${rencData.rencontre.name} s'abat avec violence mais vous êtes plus rapide et parvenez à lui échapper.`,
|
|
||||||
msgEchec: async (rencData)=> `Le ${rencData.rencontre.name} vous frappe de milliers de morsure et vous malmène à travers les terres médianes.`,
|
|
||||||
postEchec: async (tmrDialog, rencData) => TMRRencontres.onPostEchecTourbillonRouge(tmrDialog, rencData),
|
|
||||||
poesieSucces: {
|
|
||||||
reference: "Qu'est-ce de votre vie ? une bouteille molle, Jean-Baptiste Chassignet",
|
|
||||||
extrait: `Qu'est-ce de votre vie ? un tourbillon rouant
|
|
||||||
<br>De fumière à flot gris, parmi l'air se jouant,
|
|
||||||
<br>Qui passe plus soudain que foudre meurtrière.`},
|
|
||||||
poesieEchec: {
|
|
||||||
reference: "Les Djinns, poème Victor Hugo",
|
|
||||||
extrait: `Cris de l'enfer! voix qui hurle et qui pleure !
|
|
||||||
<br>L'horrible essaim, poussé par l'aquilon,
|
|
||||||
<br>Sans doute, ô ciel ! s'abat sur ma demeure.
|
|
||||||
<br>Le mur fléchit sous le noir bataillon.
|
|
||||||
<br>La maison crie et chancelle penchée,
|
|
||||||
<br>Et l'on dirait que, du sol arrachée,
|
|
||||||
<br>Ainsi qu'il chasse une feuille séchée,
|
|
||||||
<br>Le vent la roule avec leur tourbillon !`},
|
|
||||||
},
|
|
||||||
|
|
||||||
rdd: {
|
|
||||||
msgSucces: async (rencData) => `A tout seigneur, tout honneur, vous faites face à un ${rencData.rencontre.name}. Vous le maîtrisez et récupérez ses rêves. Vous gagnez ses ${rencData.rencontre.force} points de rêve`,
|
|
||||||
msgEchec: async (rencData)=> `A tout seigneur, tout honneur, vous faites face à un ${rencData.rencontre.name}. La rencontre tourne au cauchemar, dans la lutte épique, vous subissez ${rencData.rolled.isETotal ? 'deux queues' : 'une queue'} de dragon!`,
|
|
||||||
postSucces: async (tmrDialog, rencData) => TMRRencontres.onPostSuccessReveDeDragon(tmrDialog, rencData),
|
|
||||||
postEchec: async (tmrDialog, rencData) => TMRRencontres.onPostEchecReveDeDragon(tmrDialog, rencData),
|
|
||||||
poesieSucces: {
|
|
||||||
reference: "Rêve de Dragon, Denis Gerfaud",
|
|
||||||
extrait: `Le monde est Rêve de Dragons, mais nous ne savons
|
|
||||||
<br>ni leur apparence ni qui sont les dragons.
|
|
||||||
<br>En dépit de l'iconographie qui les clame
|
|
||||||
<br>immenses créatures ailées crachant des flammes`},
|
|
||||||
poesieEchec: {
|
|
||||||
reference: "El Desdichado, Gérard de Nerval",
|
|
||||||
extrait: `Je suis le Ténébreux, – le Veuf, – l'Inconsolé,
|
|
||||||
<br>Le Prince d'Aquitaine à la Tour abolie :
|
|
||||||
<br>Ma seule Etoile est morte, – et mon luth constellé
|
|
||||||
<br>Porte le Soleil noir de la Mélancolie.`}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
const mauvaisesRencontres = [
|
|
||||||
{ code: "mangeur", name: "Mangeur de Rêve", type: "mangeur", genre: "m", force: "1d6", refoulement: 2, isMauvaise: true },
|
|
||||||
{ code: "mangeur2d6", name: "Mangeur de Rêve", type: "mangeur", genre: "m", force: "2d6", refoulement: 2, isMauvaise: true },
|
|
||||||
{ code: "reflet+4", name: "Reflet d'ancien Rêve", type: "reflet", genre: "m", force: "2d6+4", refoulement: 2, isPersistant: true, isMauvaise: true },
|
|
||||||
{ code: "tbblanc+4", name: "Tourbillon blanc", type: "tbblanc", genre: "m", force: "2d6+4", refoulement: 2, isPersistant: true, isMauvaise: true },
|
|
||||||
{ code: "tbnoir+4", name: "Tourbillon noir", type: "tbnoir", genre: "m", force: "2d8+4", refoulement: 2, isPersistant: true, isMauvaise: true },
|
|
||||||
{ code: "passfou", name: "Passeur fou", type: "passeurfou", genre: "m", force: "2d8", refoulement: 2, isMauvaise: true },
|
|
||||||
{ code: "tbrouge", name: "Tourbillon rouge", type: "tbrouge", genre: "m", force: "2d8", refoulement: 3, isPersistant: true, isMauvaise: true }
|
|
||||||
]
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
const rencontresStandard = [
|
|
||||||
{ code: "messager", name: "Messager des Rêves", type: "messager", genre: "m", force: "2d4", ignorer: true },
|
|
||||||
{ code: "passeur", name: "Passeur des Rêves", type: "passeur", genre: "m", force: "2d4", ignorer: true },
|
|
||||||
{ code: "fleur", name: "Fleur des Rêves", type: "fleur", genre: "f", force: "1d6", ignorer: true },
|
|
||||||
{ code: "mangeur", name: "Mangeur de Rêve", type: "mangeur", genre: "m", force: "1d6" },
|
|
||||||
{ code: "changeur", name: "Changeur de Rêve", type: "changeur", genre: "m", force: "2d6" },
|
|
||||||
{ code: "briseur", name: "Briseur de Rêve", type: "briseur", genre: "m", force: "2d6", quitterTMR: true },
|
|
||||||
{ code: "reflet", name: "Reflet d'ancien Rêve", type: "reflet", genre: "m", force: "2d6", isPersistant: true },
|
|
||||||
{ code: "tbblanc", name: "Tourbillon blanc", type: "tbblanc", genre: "m", force: "2d6", isPersistant: true },
|
|
||||||
{ code: "tbnoir", name: "Tourbillon noir", type: "tbnoir", genre: "m", force: "2d8", isPersistant: true },
|
|
||||||
{ code: "rdd", name: "Rêve de Dragon", type: "rdd", genre: "m", force: "1dr + 7", refoulement: 2, quitterTMR: true }
|
|
||||||
];
|
|
||||||
|
|
||||||
const rencontresPresentCite = [
|
|
||||||
{ code: "messager2d6", name: "Messager des Rêves", type: "messager", genre: "m", force: "2d6", ignorer: true },
|
|
||||||
{ code: "passeur2d6", name: "Passeur des Rêves", type: "passeur", genre: "m", force: "2d6", ignorer: true },
|
|
||||||
{ code: "fleur2d6", name: "Fleur des Rêves", type: "fleur", genre: "f", force: "2d6", ignorer: true }
|
|
||||||
]
|
|
||||||
const rencontresAll = [].concat(rencontresStandard).concat(mauvaisesRencontres).concat(rencontresPresentCite);
|
|
||||||
|
|
||||||
const tableRencontres = {
|
|
||||||
cite: [{ code: 'messager', range: [1, 25] }, { code: 'passeur', range: [26, 50] }, { code: 'fleur', range: [51, 65] }, { code: 'mangeur', range: [66, 70] }, { code: 'changeur', range: [71, 80] }, { code: 'briseur', range: [81, 85] }, { code: 'reflet', range: [86, 90] }, { code: 'tbblanc', range: [91, 94] }, { code: 'tbnoir', range: [95, 97] }, { code: 'rdd', range: [98, 100] }],
|
|
||||||
sanctuaire: [{ code: 'messager', range: [1, 25] }, { code: 'passeur', range: [26, 50] }, { code: 'fleur', range: [51, 65] }, { code: 'mangeur', range: [66, 70] }, { code: 'changeur', range: [71, 80] }, { code: 'briseur', range: [81, 85] }, { code: 'reflet', range: [86, 90] }, { code: 'tbblanc', range: [91, 94] }, { code: 'tbnoir', range: [95, 97] }, { code: 'rdd', range: [98, 100] }],
|
|
||||||
plaines: [{ code: 'messager', range: [1, 20] }, { code: 'passeur', range: [21, 40] }, { code: 'fleur', range: [41, 55] }, { code: 'mangeur', range: [56, 60] }, { code: 'changeur', range: [61, 75] }, { code: 'briseur', range: [76, 82] }, { code: 'reflet', range: [83, 88] }, { code: 'tbblanc', range: [89, 93] }, { code: 'tbnoir', range: [94, 97] }, { code: 'rdd', range: [98, 100] }],
|
|
||||||
pont: [{ code: 'messager', range: [1, 20] }, { code: 'passeur', range: [21, 40] }, { code: 'fleur', range: [41, 55] }, { code: 'mangeur', range: [56, 60] }, { code: 'changeur', range: [61, 75] }, { code: 'briseur', range: [76, 82] }, { code: 'reflet', range: [83, 88] }, { code: 'tbblanc', range: [89, 93] }, { code: 'tbnoir', range: [94, 97] }, { code: 'rdd', range: [98, 100] }],
|
|
||||||
collines: [{ code: 'messager', range: [1, 15] }, { code: 'passeur', range: [16, 30] }, { code: 'fleur', range: [31, 42] }, { code: 'mangeur', range: [43, 54] }, { code: 'changeur', range: [55, 69] }, { code: 'briseur', range: [70, 82] }, { code: 'reflet', range: [83, 88] }, { code: 'tbblanc', range: [89, 93] }, { code: 'tbnoir', range: [94, 97] }, { code: 'rdd', range: [98, 100] }],
|
|
||||||
foret: [{ code: 'messager', range: [1, 15] }, { code: 'passeur', range: [16, 30] }, { code: 'fleur', range: [31, 42] }, { code: 'mangeur', range: [43, 54] }, { code: 'changeur', range: [55, 69] }, { code: 'briseur', range: [70, 82] }, { code: 'reflet', range: [83, 88] }, { code: 'tbblanc', range: [89, 93] }, { code: 'tbnoir', range: [94, 97] }, { code: 'rdd', range: [98, 100] }],
|
|
||||||
monts: [{ code: 'messager', range: [1, 10] }, { code: 'passeur', range: [11, 20] }, { code: 'fleur', range: [21, 26] }, { code: 'mangeur', range: [27, 44] }, { code: 'changeur', range: [45, 59] }, { code: 'briseur', range: [60, 75] }, { code: 'reflet', range: [76, 85] }, { code: 'tbblanc', range: [86, 92] }, { code: 'tbnoir', range: [93, 97] }, { code: 'rdd', range: [98, 100] }],
|
|
||||||
desert: [{ code: 'messager', range: [1, 10] }, { code: 'passeur', range: [11, 20] }, { code: 'fleur', range: [21, 26] }, { code: 'mangeur', range: [27, 44] }, { code: 'changeur', range: [45, 59] }, { code: 'briseur', range: [60, 75] }, { code: 'reflet', range: [76, 85] }, { code: 'tbblanc', range: [86, 92] }, { code: 'tbnoir', range: [93, 97] }, { code: 'rdd', range: [98, 100] }],
|
|
||||||
fleuve: [{ code: 'messager', range: [1, 5] }, { code: 'passeur', range: [6, 10] }, { code: 'fleur', range: [11, 13] }, { code: 'mangeur', range: [14, 37] }, { code: 'changeur', range: [38, 49] }, { code: 'briseur', range: [50, 65] }, { code: 'reflet', range: [66, 79] }, { code: 'tbblanc', range: [80, 89] }, { code: 'tbnoir', range: [90, 97] }, { code: 'rdd', range: [98, 100] }],
|
|
||||||
lac: [{ code: 'messager', range: [1, 5] }, { code: 'passeur', range: [6, 10] }, { code: 'fleur', range: [11, 13] }, { code: 'mangeur', range: [14, 37] }, { code: 'changeur', range: [38, 49] }, { code: 'briseur', range: [50, 65] }, { code: 'reflet', range: [66, 79] }, { code: 'tbblanc', range: [80, 89] }, { code: 'tbnoir', range: [90, 97] }, { code: 'rdd', range: [98, 100] }],
|
|
||||||
marais: [{ code: 'messager', range: [1, 2] }, { code: 'passeur', range: [3, 4] }, { code: 'fleur', range: [5, 5] }, { code: 'mangeur', range: [6, 29] }, { code: 'changeur', range: [30, 39] }, { code: 'briseur', range: [40, 60] }, { code: 'reflet', range: [61, 75] }, { code: 'tbblanc', range: [76, 86] }, { code: 'tbnoir', range: [87, 97] }, { code: 'rdd', range: [98, 100] }],
|
|
||||||
gouffre: [{ code: 'messager', range: [1, 2] }, { code: 'passeur', range: [3, 4] }, { code: 'fleur', range: [5, 5] }, { code: 'mangeur', range: [6, 29] }, { code: 'changeur', range: [30, 39] }, { code: 'briseur', range: [40, 60] }, { code: 'reflet', range: [61, 75] }, { code: 'tbblanc', range: [76, 86] }, { code: 'tbnoir', range: [87, 97] }, { code: 'rdd', range: [98, 100] }],
|
|
||||||
necropole: [{ code: 'mangeur', range: [1, 20] }, { code: 'changeur', range: [21, 30] }, { code: 'briseur', range: [31, 50] }, { code: 'reflet', range: [51, 65] }, { code: 'tbblanc', range: [66, 80] }, { code: 'tbnoir', range: [81, 97] }, { code: 'rdd', range: [98, 100] }],
|
|
||||||
desolation: [{ code: 'mangeur', range: [1, 20] }, { code: 'changeur', range: [21, 30] }, { code: 'briseur', range: [31, 50] }, { code: 'reflet', range: [51, 65] }, { code: 'tbblanc', range: [66, 80] }, { code: 'tbnoir', range: [81, 97] }, { code: 'rdd', range: [98, 100] }]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
export class TMRRencontres {
|
export class TMRRencontres {
|
||||||
static gestionRencontre = {}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static init() {
|
static init() {
|
||||||
for (let type in typeRencontres) {
|
const tmrRencontre = new TMRRencontres();
|
||||||
TMRRencontres.register(type, typeRencontres[type]);
|
game.system.rdd.rencontresTMR = tmrRencontre;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
constructor(){
|
||||||
static register(type, rencontre) {
|
this.table = new CompendiumTable('rencontres', 'Item', 'rencontre', Misc.ascending(it => it.system.ordreTri));
|
||||||
TMRRencontres.gestionRencontre[type] = rencontre;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/**
|
/**
|
||||||
* Retourne une recontre en fonction de la case et du tirage
|
* Retourne une recontre en fonction de la case et du tirage
|
||||||
* @param {*} terrain
|
* @param {*} terrain
|
||||||
* @param {*} roll
|
* @param {*} forcedRoll
|
||||||
*/
|
*/
|
||||||
static async rollRencontre(terrain, roll = undefined) {
|
async rollRencontre(terrain, forcedRoll) {
|
||||||
if (!terrain) {
|
terrain = TMRUtility.findTMRLike(terrain);
|
||||||
ChatMessage.create({ content: "Un type de case doit être indiqué (par exemple sanctuaire, desert ou cité)" });
|
if (terrain == undefined) {
|
||||||
return false;
|
return undefined;
|
||||||
}
|
}
|
||||||
if (!roll || roll <= 0 || roll > 100) {
|
|
||||||
roll = await RdDDice.rollTotal("1d100");
|
if (forcedRoll && (forcedRoll <= 0 || forcedRoll > 100)) {
|
||||||
|
forcedRoll = undefined;
|
||||||
}
|
}
|
||||||
let rencontre = await TMRRencontres.getRencontreAleatoire(terrain, roll);
|
const codeTerrain = Grammar.toLowerCaseNoAccent(terrain)
|
||||||
ChatMessage.create({
|
const filtreMauvaise = codeTerrain == 'mauvaise' ? it => it.system.mauvaiseRencontre : it => !it.system.mauvaiseRencontre;
|
||||||
user: game.user.id,
|
const frequence = it => it.system.frequence[codeTerrain];
|
||||||
whisper: [game.user.id],
|
const row = await this.table.getRandom(frequence, filtreMauvaise, forcedRoll);
|
||||||
content: `Rencontre en ${terrain} (jet : ${roll}%)<br>Vous rencontrez un ${rencontre.name} de ${rencontre.force} Points de Rêve`
|
if (row) {
|
||||||
});
|
await CompendiumTableHelpers.tableRowToChatMessage(row);
|
||||||
return false;
|
}
|
||||||
|
|
||||||
|
return row?.document;
|
||||||
|
}
|
||||||
|
|
||||||
|
async chatTable(terrain) {
|
||||||
|
const codeTerrain = Grammar.toLowerCaseNoAccent(terrain)
|
||||||
|
const isMauvaise = codeTerrain == 'mauvaise';
|
||||||
|
const filtreMauvaise = isMauvaise ? it => it.system.mauvaiseRencontre : it => !it.system.mauvaiseRencontre;
|
||||||
|
const frequence = it => it.system.frequence[codeTerrain];
|
||||||
|
const typeName = isMauvaise ? 'Mauvaises rencontres' : `Rencontres en ${Misc.upperFirst(terrain)}`;
|
||||||
|
return await this.table.toChatMessage(frequence, filtreMauvaise, typeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getRencontre(index) {
|
async createRencontre(rencontre, tmr = undefined) {
|
||||||
let rencontre;
|
return rencontre.clone({
|
||||||
if (isNaN(index)) {
|
'system.force': await RdDDice.rollTotal(rencontre.system.formule),
|
||||||
rencontre = rencontresAll.find(r => r.type == index) ?? rencontresAll.find(r => r.code == index)
|
'system.coord': tmr?.coord,
|
||||||
|
'system.date': game.system.rdd.calendrier.getDateFromIndex(),
|
||||||
|
'system.heure': game.system.rdd.calendrier.getCurrentHeure()
|
||||||
|
}, { save: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
async calculRencontre(rencontre, tmr = undefined) {
|
||||||
|
if (rencontre.system.coord == "") {
|
||||||
|
rencontre.system.coord = tmr?.coord;
|
||||||
}
|
}
|
||||||
else if (0 <= index && index < rencontresAll.length) {
|
if (rencontre.system.force == 0) {
|
||||||
rencontre = rencontresAll[index];
|
rencontre.system.force = await RdDDice.rollTotal(rencontre.system.formule);
|
||||||
}
|
}
|
||||||
if (rencontre) {
|
if (rencontre.system.date == "") {
|
||||||
return duplicate(rencontre);
|
rencontre.system.date = game.system.rdd.calendrier.getDateFromIndex();
|
||||||
}
|
}
|
||||||
else {
|
if (rencontre.system.heure == "") {
|
||||||
ui.notifications.info(`Pas de rencontre pour ${index}, seulement ${rencontresAll.length} rencontres sont connues.<br>Vous pouvez aussi essayer par type (ie: mangeur, fleur, fleur2d6, ...)`)
|
rencontre.system.heure = game.system.rdd.calendrier.getCurrentHeure();
|
||||||
|
}
|
||||||
|
return rencontre;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async getPresentsCite() {
|
||||||
|
const rencontres = await SystemCompendiums.getDefaultItems('rencontres');
|
||||||
|
return rencontres.filter(it => !it.system.mauvaiseRencontre && it.system.presentCite).map(it =>
|
||||||
|
it.clone({ 'system.formule': "2d6" }, { save: false }));
|
||||||
|
}
|
||||||
|
|
||||||
|
async getReveDeDragon(force) {
|
||||||
|
const rencontres = await SystemCompendiums.getDefaultItems('rencontres');
|
||||||
|
const reveDeDragon = rencontres.find(it => Grammar.equalsInsensitive(it.name, 'Rêve de Dragon'));
|
||||||
|
return reveDeDragon?.clone({ 'system.force': force }, { save: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async getRencontreAleatoire(tmr, mauvaise) {
|
||||||
|
const codeTerrain = mauvaise ? 'mauvaise' : tmr.type;
|
||||||
|
const filtreMauvaise = codeTerrain == 'mauvaise' ? it => it.system.mauvaiseRencontre : it => !it.system.mauvaiseRencontre;
|
||||||
|
const frequence = it => it.system.frequence[codeTerrain];
|
||||||
|
|
||||||
|
const row = await this.table.getRandom(frequence, filtreMauvaise);
|
||||||
|
if (row) {
|
||||||
|
const rencontre = await this.createRencontre(row.document, tmr);
|
||||||
|
await this.$chatRolledRencontre(row, rencontre, tmr);
|
||||||
|
return rencontre;
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static async getRencontreAleatoire(terrain, roll = undefined) {
|
|
||||||
if (!roll || roll <= 0 || roll > 100) {
|
|
||||||
roll = await RdDDice.rollTotal("1d100");
|
|
||||||
}
|
|
||||||
terrain = Grammar.toLowerCaseNoAccent(terrain);
|
|
||||||
const code = tableRencontres[terrain].find(it => it.range[0] <= roll && roll <= it.range[1]).code;
|
|
||||||
const rencontre = duplicate(rencontresStandard.find(it => it.code == code));
|
|
||||||
rencontre.roll = roll;
|
|
||||||
await TMRRencontres.evaluerForceRencontre(rencontre);
|
|
||||||
return rencontre;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async getMauvaiseRencontre(index = undefined) {
|
async $chatRolledRencontre(row, rencontre,tmr) {
|
||||||
const rencontre = duplicate(
|
const flavorContent = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-compendium-table-roll-rencontre.html',
|
||||||
(index && index >= 0 && index < mauvaisesRencontres.length)
|
{
|
||||||
? mauvaisesRencontres[index]
|
roll: row.roll,
|
||||||
: await RdDDice.rollOneOf(mauvaisesRencontres));
|
rencontre,
|
||||||
await TMRRencontres.evaluerForceRencontre(rencontre);
|
row,
|
||||||
return rencontre;
|
percentages: (row.total == 100) ? '%' : '',
|
||||||
}
|
tmr,
|
||||||
|
isGM: game.user.isGM,
|
||||||
/* -------------------------------------------- */
|
});
|
||||||
static async evaluerForceRencontre(rencontre) {
|
const messageData = {
|
||||||
const rollForce = new Roll(rencontre.force);
|
user: game.user.id,
|
||||||
await rollForce.evaluate();
|
type: CONST.CHAT_MESSAGE_TYPES.ROLL,
|
||||||
rencontre.force = rollForce.total;
|
roll: row.roll,
|
||||||
return rencontre.force;
|
sound: CONFIG.sounds.dice,
|
||||||
}
|
content: flavorContent
|
||||||
|
};
|
||||||
/* -------------------------------------------- */
|
ChatMessage.create(messageData, { rollMode: "gmroll" });
|
||||||
static isReveDeDragon(rencontre) {
|
|
||||||
return rencontre.type == "rdd";
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static getGestionRencontre(name) {
|
|
||||||
let gestion = TMRRencontres.gestionRencontre[name];
|
|
||||||
if (!gestion) {
|
|
||||||
ui.notifications.error(`La rencontre ${name} est inconnue, pas de méthode de gestion associée`)
|
|
||||||
gestion = TMRRencontres.gestionRencontre['messager'];
|
|
||||||
}
|
|
||||||
return gestion;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static async gererRencontre(tmrDialog, rencData) {
|
|
||||||
let gestion = TMRRencontres.getGestionRencontre(rencData.rencontre.type);
|
|
||||||
if (rencData.rolled.isSuccess) {
|
|
||||||
rencData.message = await gestion.msgSucces(rencData);
|
|
||||||
if (rencData.nbRounds > 1) {
|
|
||||||
rencData.message += ` Au total, vous avez passé ${rencData.nbRounds} rounds à vous battre!`;
|
|
||||||
}
|
|
||||||
rencData.poesie = gestion.poesieSucces;
|
|
||||||
return gestion.postSucces;
|
|
||||||
}
|
|
||||||
|
|
||||||
rencData.message = await gestion.msgEchec(rencData);
|
|
||||||
if (rencData.nbRounds > 1) {
|
|
||||||
rencData.message += ` Vous avez passé ${rencData.nbRounds} rounds à lutter!`;
|
|
||||||
}
|
|
||||||
rencData.poesie = gestion.poesieEchec;
|
|
||||||
return gestion.postEchec;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static async msgEchecPasseurFou(tmrData) {
|
|
||||||
tmrData.sortReserve = tmrData.actor.system.reve.reserve.list[0];
|
|
||||||
if (tmrData.sortReserve) {
|
|
||||||
// Passeur fou positionne sur la case d'un ort en réserve // TODO : Choisir le sort le plus loin ou au hasard
|
|
||||||
tmrData.newTMR = TMRUtility.getTMR(tmrData.sortReserve.coord);
|
|
||||||
} else {
|
|
||||||
// Déplacement aléatoire de la force du Passeur Fou
|
|
||||||
const newCoord = await RdDDice.rollOneOf(TMRUtility.getTMRPortee(tmrData.tmr.coord, tmrData.rencontre.force));
|
|
||||||
tmrData.newTMR = TMRUtility.getTMR(newCoord);
|
|
||||||
}
|
|
||||||
if (tmrData.sortReserve) {
|
|
||||||
return `Le ${tmrData.rencontre.name} vous dérobe la clé de vos sorts. Vous vous saisissez de lui, mais dans un nuage violet, il vous emporte en ${tmrData.newTMR.label} déclencher votre sort en réserve de ${tmrData.sortReserve.name}.`;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return `Le ${tmrData.rencontre.name} tente de vous dérober la clé de vos sorts. Ne la trouvant pas, il déclenche un nuage violet et vous emporte en ${tmrData.newTMR.label}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static async postEchecPasseurFou(tmrDialog, tmrData) {
|
|
||||||
if (tmrData.sortReserve) {
|
|
||||||
await tmrDialog.processSortReserve(tmrData.sortReserve);
|
|
||||||
}
|
|
||||||
await tmrDialog.positionnerDemiReve(tmrData.newTMR.coord);
|
|
||||||
if (tmrData.sortReserve) {
|
|
||||||
tmrDialog.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static async onPostEchecTourbillon(tmrDialog, tmrData, cases) {
|
|
||||||
await tmrData.actor.reveActuelIncDec(-cases);
|
|
||||||
await TMRRencontres._toubillonner(tmrDialog, tmrData.actor, cases);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static async onPostEchecTourbillonRouge(tmrDialog, rencontre) {
|
|
||||||
await rencontre.actor.reveActuelIncDec(-2); // -2 pts de Reve a chaque itération
|
|
||||||
TMRRencontres._toubillonner(tmrDialog, rencontre.actor, 4);
|
|
||||||
await rencontre.actor.santeIncDec("vie", -1); // Et -1 PV
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static async _toubillonner(tmrDialog, actor, cases) {
|
|
||||||
let coord = actor.system.reve.tmrpos.coord;
|
|
||||||
for (let i = 0; i < cases; i++) {
|
|
||||||
coord = await TMRUtility.deplaceTMRAleatoire(actor, coord).coord;
|
|
||||||
}
|
|
||||||
await tmrDialog.positionnerDemiReve(coord)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static async onPostSuccessReveDeDragon(tmrDialog, tmrData) {
|
|
||||||
if (tmrData.rolled.isPart) {
|
|
||||||
await tmrData.actor.appliquerAjoutExperience(tmrData);
|
|
||||||
}
|
|
||||||
await tmrData.actor.resultCombatReveDeDragon(tmrData);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static async onPostEchecReveDeDragon(tmrDialog, tmrData) {
|
|
||||||
await tmrData.actor.resultCombatReveDeDragon(tmrData);
|
|
||||||
tmrDialog.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { TMRRencontres } from "./tmr-rencontres.js";
|
|
||||||
import { Misc } from "./misc.js";
|
import { Misc } from "./misc.js";
|
||||||
import { Grammar } from "./grammar.js";
|
import { Grammar } from "./grammar.js";
|
||||||
import { RdDDice } from "./rdd-dice.js";
|
import { RdDDice } from "./rdd-dice.js";
|
||||||
@@ -287,49 +286,43 @@ export class TMRUtility {
|
|||||||
const tmr = TMRMapping[coord];
|
const tmr = TMRMapping[coord];
|
||||||
return Grammar.articleDetermine(tmr.type) + ' ' + tmr.label;
|
return Grammar.articleDetermine(tmr.type) + ' ' + tmr.label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static findTMRLike(type, options = {inclusMauvaise:true}) {
|
||||||
|
const choix = [...Object.values(TMRType)]
|
||||||
|
if (options.inclusMauvaise){
|
||||||
|
choix.push({name: 'Mauvaise'});
|
||||||
|
}
|
||||||
|
const selection = Misc.findAllLike(type, choix).map(it => it.name);
|
||||||
|
if (selection.length == 0) {
|
||||||
|
ui.notifications.warn(`Un type de TMR doit être indiqué, '${type}' n'est pas trouvé dans ${choix}`);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (selection.length > 1) {
|
||||||
|
ui.notifications.warn(`Plusieurs types de TMR pourraient correspondre à '${type}': ${selection}`);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return selection[0];
|
||||||
|
}
|
||||||
|
|
||||||
static typeTmrName(type) {
|
static typeTmrName(type) {
|
||||||
return Misc.upperFirst(TMRType[Grammar.toLowerCaseNoAccent(type)].name);
|
return Misc.upperFirst(TMRType[Grammar.toLowerCaseNoAccent(type)].name);
|
||||||
}
|
}
|
||||||
static listSelectedTMR(typesTMR) {
|
|
||||||
|
static buildSelectionTypesTMR(typesTMR) {
|
||||||
|
typesTMR = typesTMR?? [];
|
||||||
return Object.values(TMRType).map(value => Misc.upperFirst(value.name))
|
return Object.values(TMRType).map(value => Misc.upperFirst(value.name))
|
||||||
.sort()
|
.sort()
|
||||||
.map(name => { return { name: name, selected: typesTMR.includes(name) } });
|
.map(name => { return { name: name, selected: typesTMR.includes(name) } });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static buildListTypesTMRSelection(selectionTMRs) {
|
||||||
|
return selectionTMRs.filter(it => it.selected).map(it => it.name).join(" ");
|
||||||
|
}
|
||||||
|
|
||||||
static isCaseHumide(tmr) {
|
static isCaseHumide(tmr) {
|
||||||
return tmr.type == 'fleuve' || tmr.type == 'lac' || tmr.type == 'marais';
|
return tmr.type == 'fleuve' || tmr.type == 'lac' || tmr.type == 'marais';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
/** Some debug functions */
|
|
||||||
static async setForceRencontre(index, force = undefined) {
|
|
||||||
this.prochaineRencontre = TMRRencontres.getRencontre(index);
|
|
||||||
if (this.prochaineRencontre) {
|
|
||||||
if (force) {
|
|
||||||
this.prochaineRencontre.force = force;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
await TMRRencontres.evaluerForceRencontre(this.prochaineRencontre);
|
|
||||||
}
|
|
||||||
console.log("La prochaine rencontre sera:", this.prochaineRencontre.name, " force:", this.prochaineRencontre.force);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ui.notifications.warn("Pas de prochaine rencontre valide pour " + index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static isForceRencontre() {
|
|
||||||
return this.prochaineRencontre;
|
|
||||||
}
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static utiliseForceRencontre() {
|
|
||||||
const rencontre = this.prochaineRencontre;
|
|
||||||
this.prochaineRencontre = undefined;
|
|
||||||
return rencontre;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async getDirectionPattern() {
|
static async getDirectionPattern() {
|
||||||
return await RdDDice.rollOneOf(tmrRandomMovePatten);
|
return await RdDDice.rollOneOf(tmrRandomMovePatten);
|
||||||
@@ -337,24 +330,15 @@ export class TMRUtility {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async deplaceTMRAleatoire(actor, coord) {
|
static async deplaceTMRAleatoire(actor, coord) {
|
||||||
return TMRUtility.deplaceTMRSelonPattern(actor, coord, await TMRUtility.getDirectionPattern(), 1);
|
const currentOddq = TMRUtility.coordTMRToOddq(coord);
|
||||||
}
|
const direction = await TMRUtility.getDirectionPattern();
|
||||||
|
currentOddq.col = currentOddq.col + direction.col;
|
||||||
/* -------------------------------------------- */
|
currentOddq.row = currentOddq.row + direction.row;
|
||||||
static async deplaceTMRSelonPattern(actor, coordTMR, direction, nTime) {
|
if (this.isOddqInTMR(currentOddq)) { // Sortie de carte ! Ré-insertion aléatoire
|
||||||
let coord;
|
return TMRUtility.getTMR(TMRUtility.oddqToCoordTMR(currentOddq));
|
||||||
for (let i = 0; i < nTime; i++) {
|
} else {
|
||||||
let currentOddq = TMRUtility.coordTMRToOddq(coordTMR);
|
return await actor.reinsertionAleatoire('Sortie de carte');
|
||||||
currentOddq.col = currentOddq.col + direction.col;
|
|
||||||
currentOddq.row = currentOddq.row + direction.row;
|
|
||||||
if (this.isOddqInTMR(currentOddq)) { // Sortie de carte ! Ré-insertion aléatoire
|
|
||||||
coord = TMRUtility.getTMR(TMRUtility.oddqToCoordTMR(currentOddq));
|
|
||||||
} else {
|
|
||||||
coord = await actor.reinsertionAleatoire('Sortie de carte');
|
|
||||||
}
|
|
||||||
console.log("Nouvelle case iteration !!!", i, coord);
|
|
||||||
}
|
}
|
||||||
return coord;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -366,9 +350,12 @@ export class TMRUtility {
|
|||||||
return Object.values(TMRMapping).filter(filter);
|
return Object.values(TMRMapping).filter(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getCasesType(type) {
|
||||||
|
return TMRUtility.filterTMR(it => it.type == type).map(it => it.coord);
|
||||||
|
}
|
||||||
|
|
||||||
static findTMR(search) {
|
static findTMR(search) {
|
||||||
const labelSearch = Grammar.toLowerCaseNoAccent(search)
|
return TMRUtility.filterTMR(it => Grammar.includesLowerCaseNoAccent(it.label, search) || it.coord == search);
|
||||||
return TMRUtility.filterTMR(it => Grammar.toLowerCaseNoAccent(it.label).match(labelSearch) || it.coord == search);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static filterTMRCoord(filter) {
|
static filterTMRCoord(filter) {
|
||||||
@@ -379,18 +366,6 @@ export class TMRUtility {
|
|||||||
return await RdDDice.rollOneOf(TMRUtility.filterTMR(filter))
|
return await RdDDice.rollOneOf(TMRUtility.filterTMR(filter))
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static getSortsReserve(reserveList, coord) {
|
|
||||||
// TODO : Gérer les têtes spéciales réserve!
|
|
||||||
let tmrDescr = this.getTMR(coord);
|
|
||||||
//console.log("Sort réserve : ", tmrDescr);
|
|
||||||
if (tmrDescr.type == 'fleuve') { // Gestion de la reserve en Fleuve
|
|
||||||
return reserveList.filter(it => TMRUtility.getTMR(it.coord).type == 'fleuve');
|
|
||||||
}
|
|
||||||
// Reserve sur un case "normale"
|
|
||||||
return reserveList.filter(it => it.coord == coord);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/** Returns a list of case inside a given distance
|
/** Returns a list of case inside a given distance
|
||||||
*
|
*
|
||||||
|
|||||||
18
module/tmr/augmentation-seuil.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { Grammar } from "../grammar.js";
|
||||||
|
import { Draconique } from "./draconique.js";
|
||||||
|
import { Misc } from "../misc.js";
|
||||||
|
|
||||||
|
export class AugmentationSeuil extends Draconique {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
type() { return 'tete' }
|
||||||
|
match(item) { return Draconique.isTeteDragon(item) && Grammar.toLowerCaseNoAccent(item.name).includes('augmentation du seuil de reve'); }
|
||||||
|
manualMessage() { return false }
|
||||||
|
async onActorCreateOwned(actor, tete) {
|
||||||
|
const seuil = Misc.toInt(actor.system.reve.seuil.value) + 2;
|
||||||
|
await actor.update({ "system.reve.seuil.value": seuil })
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import { Grammar } from "../grammar.js";
|
import { Grammar } from "../grammar.js";
|
||||||
import { Misc } from "../misc.js";
|
|
||||||
import { RdDDice } from "../rdd-dice.js";
|
import { RdDDice } from "../rdd-dice.js";
|
||||||
import { TMRUtility } from "../tmr-utility.js";
|
import { TMRUtility } from "../tmr-utility.js";
|
||||||
import { tmrConstants, tmrColors, tmrTokenZIndex } from "../tmr-constants.js";
|
import { tmrConstants, tmrColors, tmrTokenZIndex } from "../tmr-constants.js";
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import { Pelerinage } from "./pelerinage.js";
|
|||||||
import { Periple } from "./periple.js";
|
import { Periple } from "./periple.js";
|
||||||
import { UrgenceDraconique } from "./urgence-draconique.js";
|
import { UrgenceDraconique } from "./urgence-draconique.js";
|
||||||
import { Grammar } from "../grammar.js";
|
import { Grammar } from "../grammar.js";
|
||||||
|
import { AugmentationSeuil } from "./augmentation-seuil.js";
|
||||||
|
|
||||||
|
|
||||||
export class EffetsDraconiques {
|
export class EffetsDraconiques {
|
||||||
@@ -37,6 +38,7 @@ export class EffetsDraconiques {
|
|||||||
static pelerinage = new Pelerinage();
|
static pelerinage = new Pelerinage();
|
||||||
static periple = new Periple();
|
static periple = new Periple();
|
||||||
static urgenceDraconique = new UrgenceDraconique();
|
static urgenceDraconique = new UrgenceDraconique();
|
||||||
|
static augmentationSeuil = new AugmentationSeuil();
|
||||||
|
|
||||||
static init() {
|
static init() {
|
||||||
Draconique.register(EffetsDraconiques.carteTmr);
|
Draconique.register(EffetsDraconiques.carteTmr);
|
||||||
@@ -56,6 +58,7 @@ export class EffetsDraconiques {
|
|||||||
Draconique.register(EffetsDraconiques.pelerinage);
|
Draconique.register(EffetsDraconiques.pelerinage);
|
||||||
Draconique.register(EffetsDraconiques.periple);
|
Draconique.register(EffetsDraconiques.periple);
|
||||||
Draconique.register(EffetsDraconiques.urgenceDraconique);
|
Draconique.register(EffetsDraconiques.urgenceDraconique);
|
||||||
|
Draconique.register(EffetsDraconiques.augmentationSeuil)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -116,6 +119,10 @@ export class EffetsDraconiques {
|
|||||||
.filter(it => Grammar.includesLowerCaseNoAccent(it.name, name));
|
.filter(it => Grammar.includesLowerCaseNoAccent(it.name, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static countAugmentationSeuil(actor) {
|
||||||
|
return EffetsDraconiques.filterItems(actor, Draconique.isTeteDragon, 'Augmentation du seuil de rêve').length;
|
||||||
|
}
|
||||||
|
|
||||||
static isDonDoubleReve(actor) {
|
static isDonDoubleReve(actor) {
|
||||||
return EffetsDraconiques.filterItems(actor, Draconique.isTeteDragon, 'Don de double-rêve').length>0;
|
return EffetsDraconiques.filterItems(actor, Draconique.isTeteDragon, 'Don de double-rêve').length>0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,15 +46,13 @@ export class PresentCites extends Draconique {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async choisirUnPresent(casetmr, onChoixPresent) {
|
async choisirUnPresent(casetmr, onChoixPresent) {
|
||||||
|
const presents = await game.system.rdd.rencontresTMR.getPresentsCite()
|
||||||
|
const buttons = {};
|
||||||
|
presents.forEach(r => buttons['present'+r.id] = { icon: '<i class="fas fa-check"></i>', label: r.name, callback: async () => onChoixPresent(r) });
|
||||||
let d = new Dialog({
|
let d = new Dialog({
|
||||||
title: "Présent des cités",
|
title: "Présent des cités",
|
||||||
content: `La ${this.tmrLabel(casetmr)} vous offre un présent, faite votre choix`,
|
content: `La ${this.tmrLabel(casetmr)} vous offre un présent, faites votre choix`,
|
||||||
buttons: {
|
buttons: buttons
|
||||||
messager: { icon: '<i class="fas fa-check"></i>', label: "Un Messager des rêves", callback: () => onChoixPresent('messager2d6') },
|
|
||||||
passeur: { icon: '<i class="fas fa-check"></i>', label: "Un Passeur des rêves", callback: () => onChoixPresent('passeur2d6') },
|
|
||||||
fleur: { icon: '<i class="fas fa-check"></i>', label: "Une Fleur des rêves", callback: () => onChoixPresent('fleur2d6') },
|
|
||||||
},
|
|
||||||
default: "fleur"
|
|
||||||
});
|
});
|
||||||
d.render(true);
|
d.render(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export class Rencontre extends Draconique {
|
|||||||
async onActorCreateOwned(actor, item) { }
|
async onActorCreateOwned(actor, item) { }
|
||||||
|
|
||||||
code() { return 'rencontre' }
|
code() { return 'rencontre' }
|
||||||
tooltip(rencontre) { return `${rencontre.name} de force ${rencontre.force}` }
|
tooltip(rencontre) { return `${rencontre.name} de force ${rencontre.system.force}` }
|
||||||
img() { return 'systems/foundryvtt-reve-de-dragon/icons/heures/hd06.webp' }
|
img() { return 'systems/foundryvtt-reve-de-dragon/icons/heures/hd06.webp' }
|
||||||
|
|
||||||
createSprite(pixiTMR) {
|
createSprite(pixiTMR) {
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ export class SortReserve extends Draconique {
|
|||||||
manualMessage() { return false }
|
manualMessage() { return false }
|
||||||
async onActorCreateOwned(actor, item) { }
|
async onActorCreateOwned(actor, item) { }
|
||||||
|
|
||||||
code() { return 'sort' }
|
code() { return 'sortreserve' }
|
||||||
tooltip(sort) { return `${sort.name}, r${sort.data.ptreve_reel}` }
|
tooltip(sort) { return `${sort.name}, r${sort.system.ptreve}` }
|
||||||
img() { return 'systems/foundryvtt-reve-de-dragon/icons/tmr/scroll.webp' }
|
img() { return 'systems/foundryvtt-reve-de-dragon/icons/tmr/scroll.webp' }
|
||||||
|
|
||||||
createSprite(pixiTMR) {
|
createSprite(pixiTMR) {
|
||||||
|
|||||||
@@ -1,27 +1,29 @@
|
|||||||
{"_id":"0zRL8bOpCXNQnIR4","name":"Ruade","permission":{"default":0,"Q2G6GTdrotKzYGUC":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":4,"description":null,"categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-pietinement.webp","effects":[]}
|
{"_id":"0zRL8bOpCXNQnIR4","name":"Ruade","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.0zRL8bOpCXNQnIR4"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-pietinement.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":4,"description":null,"descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702692,"modifiedTime":1663625011172,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"4GmpkphbsmQjvVVK","name":"Escalade","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":false,"dommages":0,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_escalade.webp","effects":[]}
|
{"_id":"4GmpkphbsmQjvVVK","name":"Escalade","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.4GmpkphbsmQjvVVK"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_escalade.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":false,"isparade":false,"ispossession":false,"dommages":0,"description":"","descriptionmj":""},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702692,"modifiedTime":1663625011172,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"6DK46pyO0hzEuuUg","name":"Morsure","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":1,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-morsure.webp","effects":[]}
|
{"_id":"6DK46pyO0hzEuuUg","name":"Morsure","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.6DK46pyO0hzEuuUg"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-morsure.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":1,"description":"","descriptionmj":"","categorie":"generale","isnaturelle":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702692,"modifiedTime":1663625011172,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"BjqRrGtHtTzuNpZB","name":"Griffes et Crocs","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":1,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-griffes.webp","effects":[]}
|
{"name":"Possession","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-entites.c0I93Q53i4ZmxpyT"}},"img":"systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp","effects":[],"system":{"categorie_parade":"","niveau":2,"default_diffLibre":0,"carac_value":14,"iscombat":true,"isparade":false,"ispossession":true,"dommages":0,"description":"<p>L'entité tente de prendre possession du corps de sa victime.</p>","descriptionmj":"","categorie":"melee"},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624948267,"modifiedTime":1663625011162,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"9u16zxXRurCtxuOX","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||||
{"_id":"CYpxxf1uTa78NWR9","name":"Esquive","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"dommages":0,"iscombat":false,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_esquive.webp","effects":[]}
|
{"_id":"BjqRrGtHtTzuNpZB","name":"Griffes et Crocs","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.BjqRrGtHtTzuNpZB"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-griffes.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":1,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702692,"modifiedTime":1663625011172,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"JTuBQCPdumw3DfxH","name":"Crête","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"dommages":3,"iscombat":true,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-crete.webp","effects":[]}
|
{"_id":"CYpxxf1uTa78NWR9","name":"Esquive","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.CYpxxf1uTa78NWR9"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_esquive.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":false,"isparade":false,"ispossession":false,"dommages":0,"description":"","descriptionmj":""},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702692,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"Kt7WlB5Ui97X211z","name":"Vol","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"dommages":0,"iscombat":false,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-vol.webp","effects":[]}
|
{"_id":"JTuBQCPdumw3DfxH","name":"Crête","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.JTuBQCPdumw3DfxH"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-crete.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":3,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702693,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"LWQHz5ymNBzh6ZEr","name":"Cornes","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":2,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-corne.webp","effects":[]}
|
{"_id":"Kt7WlB5Ui97X211z","name":"Vol","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.Kt7WlB5Ui97X211z"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-vol.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":false,"isparade":false,"ispossession":false,"dommages":0,"description":"","descriptionmj":""},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702693,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"NctG7suzvGE7ZZzj","name":"Bras-bouches","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":2,"description":"","categorie_parade":"epees-lourdes","isparade":true,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-brasbouche.webp","effects":[]}
|
{"_id":"LWQHz5ymNBzh6ZEr","name":"Cornes","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.LWQHz5ymNBzh6ZEr"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-corne.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":2,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702693,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"OzHBowOMADRwcVXR","name":"Pierre Tenue","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":2,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-pierretenue.webp","effects":[]}
|
{"_id":"NctG7suzvGE7ZZzj","name":"Bras-bouches","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.NctG7suzvGE7ZZzj"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-brasbouche.webp","effects":[],"system":{"categorie_parade":"epees-lourdes","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":true,"ispossession":false,"dommages":2,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702693,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"PCwbR6lghjydTj93","name":"Grande morsure","permission":{"default":0,"Q2G6GTdrotKzYGUC":3},"type":"competencecreature","data":{"categorie_parade":"","niveau":0,"carac_value":0,"iscombat":true,"isparade":false,"dommages":2,"description":"","default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-morsure.webp","effects":[]}
|
{"_id":"OzHBowOMADRwcVXR","name":"Pierre Tenue","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.OzHBowOMADRwcVXR"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-pierretenue.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":2,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702693,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"PrVuVpwuYaZtwRUi","name":"Piétinement","permission":{"default":0,"Q2G6GTdrotKzYGUC":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":4,"description":null,"categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-pietinement.webp","effects":[]}
|
{"_id":"PCwbR6lghjydTj93","name":"Grande morsure","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.PCwbR6lghjydTj93"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-morsure.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":2,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702693,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"RAnasKnoA3OQgwfv","name":"Pinces","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":3,"description":"","categorie_parade":"epees-lourdes","isparade":true,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-pinces.webp","effects":[]}
|
{"_id":"PrVuVpwuYaZtwRUi","name":"Piétinement","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.PrVuVpwuYaZtwRUi"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-pietinement.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":4,"description":null,"descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702693,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"XgfRxSj8Ty1d3JFM","name":"Mandibules","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":2,"description":"","carac-value":null,"categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-mandibules.webp","effects":[]}
|
{"_id":"RAnasKnoA3OQgwfv","name":"Pinces","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.RAnasKnoA3OQgwfv"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-pinces.webp","effects":[],"system":{"categorie_parade":"epees-lourdes","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":true,"ispossession":false,"dommages":3,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702694,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"Zpl2Bi451vB3r91W","name":"Coup de pied","permission":{"default":0,"Q2G6GTdrotKzYGUC":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":3,"description":null,"categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-coup_de_pied.webp","effects":[]}
|
{"_id":"XgfRxSj8Ty1d3JFM","name":"Mandibules","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.XgfRxSj8Ty1d3JFM"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-mandibules.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":2,"description":"","descriptionmj":"","carac-value":null,"categorie":"generale","isnaturelle":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702694,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"efl1HdDSKpBfImQ1","name":"Pierre Lancée","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":1,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-pierrelancee.webp","effects":[]}
|
{"_id":"Zpl2Bi451vB3r91W","name":"Coup de pied","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.Zpl2Bi451vB3r91W"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-coup_de_pied.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":3,"description":null,"descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702694,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"h9ASt4vrvEgxfj7j","name":"Tronçonneuse","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":10,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-tronconneuse.webp","effects":[]}
|
{"name":"Possession","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-entites.c0I93Q53i4ZmxpyT"}},"img":"systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp","effects":[],"system":{"categorie_parade":"","niveau":2,"default_diffLibre":0,"carac_value":14,"iscombat":true,"isparade":false,"ispossession":true,"dommages":0,"description":"<p>L'entité tente de prendre possession du corps de sa victime.</p>","descriptionmj":"","categorie":"draconic"},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624976822,"modifiedTime":1663625011162,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"duVgxI3Cdko0KzAj","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||||
{"_id":"jhua9kkCs55OV7Yl","name":"Grandes griffes","permission":{"default":0,"Q2G6GTdrotKzYGUC":3},"type":"competencecreature","data":{"categorie_parade":"sans-armes","niveau":0,"carac_value":0,"iscombat":true,"isparade":true,"dommages":2,"description":"","default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-griffes.webp","effects":[]}
|
{"_id":"efl1HdDSKpBfImQ1","name":"Pierre Lancée","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.efl1HdDSKpBfImQ1"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-pierrelancee.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":1,"description":"","descriptionmj":"","categorie":"lancer","isnaturelle":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702694,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"lzEdMrKXbOYrWG5S","name":"Vigilance","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":false,"dommages":0,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_vigilance.webp","effects":[]}
|
{"_id":"h9ASt4vrvEgxfj7j","name":"Tronçonneuse","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.h9ASt4vrvEgxfj7j"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-tronconneuse.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":10,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702694,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"ndNshntOYb1JFNqi","name":"Serres","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":2,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-serres.webp","effects":[]}
|
{"_id":"jhua9kkCs55OV7Yl","name":"Grandes griffes","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.jhua9kkCs55OV7Yl"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-griffes.webp","effects":[],"system":{"categorie_parade":"sans-armes","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":true,"ispossession":false,"dommages":2,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702694,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"os88Rsp7mBkahqmh","name":"Bec","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":0,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-beak.webp","effects":[]}
|
{"_id":"lzEdMrKXbOYrWG5S","name":"Vigilance","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.lzEdMrKXbOYrWG5S"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_vigilance.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":false,"isparade":false,"ispossession":false,"dommages":0,"description":"","descriptionmj":""},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702694,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"qilRzXpVaGceNmQp","name":"Dague","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":1,"description":"","categorie_parade":"dagues","isparade":true,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_dague.webp","effects":[]}
|
{"_id":"ndNshntOYb1JFNqi","name":"Serres","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.ndNshntOYb1JFNqi"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-serres.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":2,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702694,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"qrd9AoZzFgyzFBxz","name":"Griffes","permission":{"default":0,"Q2G6GTdrotKzYGUC":3},"type":"competencecreature","data":{"categorie_parade":"sans-armes","niveau":0,"carac_value":0,"iscombat":true,"isparade":true,"dommages":1,"description":"","default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-griffes.webp","effects":[]}
|
{"_id":"os88Rsp7mBkahqmh","name":"Bec","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.os88Rsp7mBkahqmh"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-beak.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":0,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702695,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"sUdXhpuVVOAlcVpo","name":"Pickpocket","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":false,"dommages":0,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_pickpocket.webp","effects":[]}
|
{"_id":"qilRzXpVaGceNmQp","name":"Dague","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.qilRzXpVaGceNmQp"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_dague.webp","effects":[],"system":{"categorie_parade":"dagues","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":true,"ispossession":false,"dommages":1,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702695,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"shsUV8UpU18c0RJK","name":"Course","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":false,"dommages":0,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_course.webp","effects":[]}
|
{"_id":"qrd9AoZzFgyzFBxz","name":"Griffes","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.qrd9AoZzFgyzFBxz"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-griffes.webp","effects":[],"system":{"categorie_parade":"sans-armes","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":true,"ispossession":false,"dommages":1,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702695,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"yBUVTjTXYfwvzusb","name":"Saut","permission":{"default":0,"Q2G6GTdrotKzYGUC":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":false,"dommages":0,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_saut.webp","effects":[]}
|
{"_id":"sUdXhpuVVOAlcVpo","name":"Pickpocket","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.sUdXhpuVVOAlcVpo"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_pickpocket.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":false,"isparade":false,"ispossession":false,"dommages":0,"description":"","descriptionmj":""},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702695,"modifiedTime":1663625011174,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"yDHZfK4RmwQW4YaW","name":"Discrétion","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":false,"dommages":0,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_discretion.webp","effects":[]}
|
{"_id":"shsUV8UpU18c0RJK","name":"Course","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.shsUV8UpU18c0RJK"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_course.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":false,"isparade":false,"ispossession":false,"dommages":0,"description":"","descriptionmj":""},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702695,"modifiedTime":1663625011174,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
|
{"_id":"yBUVTjTXYfwvzusb","name":"Saut","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.yBUVTjTXYfwvzusb"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_saut.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":false,"isparade":false,"ispossession":false,"dommages":0,"description":"","descriptionmj":"","categorie":"generale"},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702695,"modifiedTime":1663625011174,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
|
{"_id":"yDHZfK4RmwQW4YaW","name":"Discrétion","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.yDHZfK4RmwQW4YaW"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_discretion.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":false,"isparade":false,"ispossession":false,"dommages":0,"description":"","descriptionmj":""},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702695,"modifiedTime":1663625011174,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
|
|||||||
@@ -12,3 +12,4 @@
|
|||||||
{"_id":"gPOQd9NI7AFH0whX","name":"Epée Bâtarde","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":4,"description":"","carac-value":null,"categorie_parade":"epees-lourdes","isparade":true},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-humanoides.YTKld5ggDsHqwYoR"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_epee_1_main.webp","effects":[]}
|
{"_id":"gPOQd9NI7AFH0whX","name":"Epée Bâtarde","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":4,"description":"","carac-value":null,"categorie_parade":"epees-lourdes","isparade":true},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-humanoides.YTKld5ggDsHqwYoR"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_epee_1_main.webp","effects":[]}
|
||||||
{"_id":"j1xHCzfIeYKgXxoH","name":"Morsure","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":1,"description":"","categorie_parade":"","isparade":false},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-morsure.webp","effects":[]}
|
{"_id":"j1xHCzfIeYKgXxoH","name":"Morsure","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":1,"description":"","categorie_parade":"","isparade":false},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-morsure.webp","effects":[]}
|
||||||
{"_id":"lDZ3qUPKN35ob5TH","name":"Grande morsure","permission":{"default":0,"Q2G6GTdrotKzYGUC":3},"type":"competencecreature","data":{"categorie_parade":"","niveau":0,"carac_value":0,"iscombat":true,"isparade":false,"dommages":2,"description":""},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-morsure.webp","effects":[]}
|
{"_id":"lDZ3qUPKN35ob5TH","name":"Grande morsure","permission":{"default":0,"Q2G6GTdrotKzYGUC":3},"type":"competencecreature","data":{"categorie_parade":"","niveau":0,"carac_value":0,"iscombat":true,"isparade":false,"dommages":2,"description":""},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-morsure.webp","effects":[]}
|
||||||
|
{"name":"Possession","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-entites.c0I93Q53i4ZmxpyT"}},"img":"systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp","effects":[],"system":{"categorie_parade":"","niveau":2,"default_diffLibre":-4,"categorie":"melee","carac_value":14,"iscombat":true,"isnaturelle":true,"ispossession":true,"dommages":0,"description":"<p>L'entité tente de prendre possession du corps de sa victime.</p>","descriptionmj":"","isparade":false},"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.22","coreVersion":"10.286","createdTime":1663624976822,"modifiedTime":1664918524164,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"folder":null,"sort":0,"_id":"wDHR5UHWq568lfGa"}
|
||||||
|
|||||||
@@ -1,40 +1,40 @@
|
|||||||
{"name":"Idée fixe : Anorexie. Ne rien avaler, ni solide, ni liquide, pas même une potion","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"anorexie.webp","effects":[],"_id":"0uc2pMIGL03Hq2Hn"}
|
{"name":"Idée fixe : Anorexie. Ne rien avaler, ni solide, ni liquide, pas même une potion","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"0uc2pMIGL03Hq2Hn"}
|
||||||
{"name":"Désir lancinant : Briser un objet de verre","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"briser_verre.webp","effects":[],"_id":"1l59lWbtvYp74OTb"}
|
{"name":"Désir lancinant : Briser un objet de verre","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"1l59lWbtvYp74OTb"}
|
||||||
{"name":"Idée fixe : Cracher dans toute nourriture ou boisson aperçue","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"cracher_nourriture.webp","effects":[],"_id":"22EQLBJfHVYs96iC"}
|
{"name":"Idée fixe : Cracher dans toute nourriture ou boisson aperçue","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"22EQLBJfHVYs96iC"}
|
||||||
{"name":"Idée fixe : Éteindre tout feu rencontré (feu de camp, torche, lanterne, etc.)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"eteindre_feu.webp","effects":[],"_id":"2Rtm78bMKPy8eG4q"}
|
{"name":"Idée fixe : Éteindre tout feu rencontré (feu de camp, torche, lanterne, etc.)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"2Rtm78bMKPy8eG4q"}
|
||||||
{"name":"Désir lancinant : Danser avec un(e) partenaire inconnu(e) (Beauté 13 minimum)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"danser_inconnu.webp","effects":[],"_id":"2i3PndTKG1n3hEUU"}
|
{"name":"Désir lancinant : Danser avec un(e) partenaire inconnu(e) (Beauté 13 minimum)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"2i3PndTKG1n3hEUU"}
|
||||||
{"name":"Idée fixe : Traîner son épée en laisse (ou sa meilleure arme)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"trainer_laisse.webp","effects":[],"_id":"2j1q9e07ZLlIQDYl"}
|
{"name":"Idée fixe : Traîner son épée en laisse (ou sa meilleure arme)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"2j1q9e07ZLlIQDYl"}
|
||||||
{"name":"Désir lancinant : Gagner de l’argent (minimum 10 deniers)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"gagner_argent.webp","effects":[],"_id":"3BcC8lSsP5WIyva7"}
|
{"name":"Désir lancinant : Gagner de l’argent (minimum 10 deniers)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"3BcC8lSsP5WIyva7"}
|
||||||
{"name":"Désir lancinant : Mégalomanie. Être acclamé par un minimum de 10 personnes","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"megalomanie.webp","effects":[],"_id":"3ZjwYyQRatCMnBCi"}
|
{"name":"Désir lancinant : Mégalomanie. Être acclamé par un minimum de 10 personnes","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"3ZjwYyQRatCMnBCi"}
|
||||||
{"name":"Idée fixe : Avoir le visage noirci à la cendre","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"avoir_visage.webp","effects":[],"_id":"6G0lF06jSryTduAt"}
|
{"name":"Idée fixe : Avoir le visage noirci à la cendre","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"6G0lF06jSryTduAt"}
|
||||||
{"name":"Idée fixe : Ne marcher qu’à quatre pattes","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"marcher_quatre_pattes.webp","effects":[],"_id":"7TKsit2Mv9mWGq3C"}
|
{"name":"Idée fixe : Ne marcher qu’à quatre pattes","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"7TKsit2Mv9mWGq3C"}
|
||||||
{"name":"Désir lancinant : Acquérir une chèvre","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"acqu%C3%A9rir_chevre.webp","effects":[],"_id":"8sLXQBqo8XwjAFG0"}
|
{"name":"Désir lancinant : Acquérir une chèvre","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"8sLXQBqo8XwjAFG0"}
|
||||||
{"name":"Idée fixe : Garder les yeux bandés","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"garder_yeux.webp","effects":[],"_id":"E902EEYZHg3zFKq6"}
|
{"name":"Idée fixe : Garder les yeux bandés","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"E902EEYZHg3zFKq6"}
|
||||||
{"name":"Désir lancinant : Danser nu sous la pluie","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"danser_pluie.webp","effects":[],"_id":"F6qL4d4g3qjh045R"}
|
{"name":"Désir lancinant : Danser nu sous la pluie","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"F6qL4d4g3qjh045R"}
|
||||||
{"name":"Idée fixe : Garder sur soi 3d6 kilos de cailloux","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"garder_cailloux.webp","effects":[],"_id":"F8G3rdU1nfJzYwYR"}
|
{"name":"Idée fixe : Garder sur soi 3d6 kilos de cailloux","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"F8G3rdU1nfJzYwYR"}
|
||||||
{"name":"Désir lancinant : Se faire raser la tête","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"raser_tete.webp","effects":[],"_id":"HSNOvBR890dsEDw2"}
|
{"name":"Désir lancinant : Se faire raser la tête","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"HSNOvBR890dsEDw2"}
|
||||||
{"name":"Idée fixe : Aller tout nu, sans porter le moindre paquet ni objet","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"aller_nu.webp","effects":[],"_id":"I0CtQ05xFW6ghcdP"}
|
{"name":"Idée fixe : Aller tout nu, sans porter le moindre paquet ni objet","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"I0CtQ05xFW6ghcdP"}
|
||||||
{"name":"Idée fixe : Boulimie. Manger au moins un point de sust. par heure","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"boulimie.webp","effects":[],"_id":"JcTX8qMS0z8bmdVt"}
|
{"name":"Idée fixe : Boulimie. Manger au moins un point de sust. par heure","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"JcTX8qMS0z8bmdVt"}
|
||||||
{"name":"Désir lancinant : Passer une nuit sur une échelle","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"nuit_echelle.webp","effects":[],"_id":"LlELEB0FhymLx6VM"}
|
{"name":"Désir lancinant : Passer une nuit sur une échelle","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"LlELEB0FhymLx6VM"}
|
||||||
{"name":"Idée fixe : Refuser de monter dans les TMR","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"refuser_tmr.webp","effects":[],"_id":"NpTDqICR7ZuToQrg"}
|
{"name":"Idée fixe : Refuser de monter dans les TMR","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"NpTDqICR7ZuToQrg"}
|
||||||
{"name":"Désir lancinant : Masochisme. Perdre 3 points d’endurance minimum en 1 round","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"masochisme.webp","effects":[],"_id":"NzJJNK0YMAbobu0p"}
|
{"name":"Désir lancinant : Masochisme. Perdre 3 points d’endurance minimum en 1 round","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"NzJJNK0YMAbobu0p"}
|
||||||
{"name":"Désir lancinant : Casser 3d6 oeufs en les jetant à terre","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"casser_oeufs.webp","effects":[],"_id":"OjG8XRbeYtq2jcgB"}
|
{"name":"Désir lancinant : Casser 3d6 oeufs en les jetant à terre","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"OjG8XRbeYtq2jcgB"}
|
||||||
{"name":"Désir lancinant : Traire une vache","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"traire_vache.webp","effects":[],"_id":"QHUOwjMR6AvepGPm"}
|
{"name":"Désir lancinant : Traire une vache","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"QHUOwjMR6AvepGPm"}
|
||||||
{"name":"Désir lancinant : Pisser dans un violon (luth, mandoline, etc.)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"pisser_violon.webp","effects":[],"_id":"S8PVNgxb7TcFXq9g"}
|
{"name":"Désir lancinant : Pisser dans un violon (luth, mandoline, etc.)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"S8PVNgxb7TcFXq9g"}
|
||||||
{"name":"Désir lancinant : Manger du poisson","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"manger_poisson.webp","effects":[],"_id":"SY0SsWtZdxSodMcl"}
|
{"name":"Désir lancinant : Manger du poisson","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"SY0SsWtZdxSodMcl"}
|
||||||
{"name":"Idée fixe : Ne pas franchir de porte. (On peut franchir une fenêtre)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"pas-franchir.webp","effects":[],"_id":"UUTbsktTcxsIe5L5"}
|
{"name":"Idée fixe : Ne pas franchir de porte. (On peut franchir une fenêtre)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"UUTbsktTcxsIe5L5"}
|
||||||
{"name":"Idée fixe : Refuser de se délester du moindre objet, ni donner ni prêter","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"refuser_delester.webp","effects":[],"_id":"VChJbtGFtWoiFNky"}
|
{"name":"Idée fixe : Refuser de se délester du moindre objet, ni donner ni prêter","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"VChJbtGFtWoiFNky"}
|
||||||
{"name":"Idée fixe : Ne s’exprimer que par des cris d’animaux (meuh ! coin-coin ! etc.)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"exprimer_cris.webp","effects":[],"_id":"YCHBbRLiMzTH7IBj"}
|
{"name":"Idée fixe : Ne s’exprimer que par des cris d’animaux (meuh ! coin-coin ! etc.)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"YCHBbRLiMzTH7IBj"}
|
||||||
{"name":"Idée fixe : Vider sur sa tête toute fiole ou flacon aperçu","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"verser_flacon.webp","effects":[],"_id":"afGp9CewfyJKecEE"}
|
{"name":"Idée fixe : Vider sur sa tête toute fiole ou flacon aperçu","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"afGp9CewfyJKecEE"}
|
||||||
{"name":"Désir lancinant : Faire des bulles de savon","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"bulles_savon.webp","effects":[],"_id":"df5oN8Ub3dWTVxNj"}
|
{"name":"Désir lancinant : Faire des bulles de savon","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"df5oN8Ub3dWTVxNj"}
|
||||||
{"name":"Désir lancinant : Entendre braire un âne","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"entendre_ane.webp","effects":[],"_id":"diCCimukdNM6bPub"}
|
{"name":"Désir lancinant : Entendre braire un âne","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"diCCimukdNM6bPub"}
|
||||||
{"name":"Désir lancinant : Se rouler dans la boue","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"se_rouler_boue.webp","effects":[],"_id":"el4lofhhSucMv5xv"}
|
{"name":"Désir lancinant : Se rouler dans la boue","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"el4lofhhSucMv5xv"}
|
||||||
{"name":"Idée fixe : Ne dire que «non» ou négation analogue","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"dire_non.webp","effects":[],"_id":"gMmqdJ9I7Mt8Tg3f"}
|
{"name":"Idée fixe : Ne dire que «non» ou négation analogue","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"gMmqdJ9I7Mt8Tg3f"}
|
||||||
{"name":"Désir lancinant : Manger des champignons","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"manger_champignons.webp","effects":[],"_id":"gadh6aI5iCM82qpP"}
|
{"name":"Désir lancinant : Manger des champignons","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"gadh6aI5iCM82qpP"}
|
||||||
{"name":"Idée fixe : Refuser de se déplacer autrement que porté","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"refuser_deplacer.webp","effects":[],"_id":"hghw6Cldrad1CIiJ"}
|
{"name":"Idée fixe : Refuser de se déplacer autrement que porté","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"hghw6Cldrad1CIiJ"}
|
||||||
{"name":"Idée fixe : Garder une main sur la tête","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"garder_main.webp","effects":[],"_id":"iPYPgxL2uUnphStc"}
|
{"name":"Idée fixe : Garder une main sur la tête","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"iPYPgxL2uUnphStc"}
|
||||||
{"name":"Idée fixe : Appeler les hommes «madame» et les femmes «messire»","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"appeler_hommes_femmes.webp","effects":[],"_id":"j2xIrFWYqhDM4TcN"}
|
{"name":"Idée fixe : Appeler les hommes «madame» et les femmes «messire»","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"j2xIrFWYqhDM4TcN"}
|
||||||
{"name":"Désir lancinant : Se soûler (minimum pas frais)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"se_souler.webp","effects":[],"_id":"jShpKV8mVcqWmYvp"}
|
{"name":"Désir lancinant : Se soûler (minimum pas frais)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},""img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"jShpKV8mVcqWmYvp"}
|
||||||
{"name":"Désir lancinant : Construire une cabane","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"construire_cabane.webp","effects":[],"_id":"mN0yghXkFfj2YctJ"}
|
{"name":"Désir lancinant : Construire une cabane","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"mN0yghXkFfj2YctJ"}
|
||||||
{"name":"Désir lancinant : Embrasser un cochon sur le groin","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"embrasser_cochon.webp","effects":[],"_id":"sjXBBr85OBk4Yg4t"}
|
{"name":"Désir lancinant : Embrasser un cochon sur le groin","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'expérience ne peut plus être gagné par l'exercice en cas de particulière et d'ajustement final négatif.<br />Les points d'expérience dus au stress ne sont pas affectés.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"sjXBBr85OBk4Yg4t"}
|
||||||
{"name":"Idée fixe : Faire le mort","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"faire_mort.webp","effects":[],"_id":"xa4t9Lbt6uLEjap6"}
|
{"name":"Idée fixe : Faire le mort","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet immédiatement et dure jusqu'à la <strong>fin de l'heure du Château Dormant </strong>du <strong>lendemain.<br /></strong>Si passé ce délai, l'occasion de la manifester ne s'est pas présentée, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"xa4t9Lbt6uLEjap6"}
|
||||||
|
|||||||
@@ -1,213 +1,198 @@
|
|||||||
{"name":"Argent (1 sol)","type":"monnaie","img":"systems/foundryvtt-reve-de-dragon/icons/objets/piece_argent_sol.webp","data":{"quantite":null,"valeur_deniers":null,"encombrement":null,"description":"","data":{"quantite":null,"valeur_deniers":null,"encombrement":null}},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"jtRmvSuwkwMmIMf0":3},"flags":{"core":{"sourceId":"Item.6M7WG9ciKuoYtN9i"}},"_id":"0I30m9qcYJk6UR6o"}
|
{"name":"Argent (1 sol)","type":"monnaie","img":"systems/foundryvtt-reve-de-dragon/icons/objets/piece_argent_sol.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Item.6M7WG9ciKuoYtN9i"}},"_id":"0I30m9qcYJk6UR6o","system":{"description":"","descriptionmj":"","encombrement":null,"quantite":null,"qualite":0,"cout":0,"valeur_deniers":null,"data":{"quantite":null,"valeur_deniers":null,"encombrement":null}},"ownership":{"default":0,"jtRmvSuwkwMmIMf0":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206013,"modifiedTime":1669755533740,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"0Vgscex1VV4ybSUQ","name":"Bonnet de laine","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bonnet_laine.webp","data":{"description":"","quantite":1,"encombrement":0.05,"equipe":false,"resistance":0,"qualite":0,"cout":0.06},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.0Vgscex1VV4ybSUQ"}}}
|
{"_id":"0Vgscex1VV4ybSUQ","name":"Bonnet de laine","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bonnet_laine.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.0Vgscex1VV4ybSUQ"}},"system":{"description":"","descriptionmj":"","encombrement":0.05,"quantite":1,"qualite":0,"cout":0.06,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206013,"modifiedTime":1669755533743,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"0ylGrNMzulUaKFP9","name":"Boralm","type":"ingredient","img":"systems/foundryvtt-reve-de-dragon/icons/objets/boralm.webp","data":{"description":"<p>Poudre brune apparaissant sur les parois des grottes.</p>\n<p>VUE/Alchimie à -1.</p>","niveau":0,"encombrement":0.001,"base":0,"quantite":1,"milieu":"Cavernes","rarete":"","categorie":"Alchimie","cout":0.03},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.0ylGrNMzulUaKFP9"}}}
|
{"_id":"1Dc4KzZageae7lhI","name":"Balles de jongleur","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/balle_jongleur.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.1Dc4KzZageae7lhI"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":4,"qualite":0,"cout":0.32,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206013,"modifiedTime":1669755533742,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"1Dc4KzZageae7lhI","name":"Balles de jongleur","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/balle_jongleur.webp","data":{"description":"","quantite":4,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":0.32},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.1Dc4KzZageae7lhI"}}}
|
{"_id":"1O7IJiQSDYxJ5VsD","name":"Bouclier moyen","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/bouclier_moyen.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.1O7IJiQSDYxJ5VsD"}},"system":{"description":"","descriptionmj":"","equipe":false,"encombrement":2,"quantite":1,"qualite":0,"cout":6,"resistance":15,"categorie_parade":"boucliers","dommages":"0","penetration":0,"force":"11","competence":"Bouclier","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":"hast"},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206014,"modifiedTime":1669755533743,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"1O7IJiQSDYxJ5VsD","name":"Bouclier moyen","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/bouclier_moyen.webp","data":{"categorie_parade":"boucliers","description":"","quantite":1,"encombrement":2,"equipe":false,"dommages":"0","penetration":0,"force":"11","resistance":15,"competence":"Bouclier","cout":6,"portee_courte":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"portee_moyenne":0,"portee_extreme":0,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":"hast"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.1O7IJiQSDYxJ5VsD"}}}
|
{"name":"Provisions cuites","type":"nourritureboisson","img":"systems/foundryvtt-reve-de-dragon/icons/objets/provision_cuite.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.1keQMXTZ2iriOuJh"}},"_id":"1keQMXTZ2iriOuJh","system":{"description":"<p>pain, fromage, viande séchée...</p>","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.02,"sust":1,"boisson":false,"desaltere":0,"alcoolise":false,"force":0,"exotisme":0},"ownership":{"default":0,"wYnBx3HmLfGzsj7P":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206014,"modifiedTime":1669755533756,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"name":"Provisions cuites","type":"nourritureboisson","img":"systems/foundryvtt-reve-de-dragon/icons/objets/provision_cuite.webp","data":{"description":"<p>pain, fromage, viande séchée...</p>","sust":1,"boisson":false,"desaltere":0,"alcoolise":false,"force":0,"qualite":0,"exotisme":0,"encombrement":0.1,"quantite":1,"cout":0.02},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"wYnBx3HmLfGzsj7P":3},"flags":{},"_id":"1keQMXTZ2iriOuJh"}
|
{"_id":"2y61gBIFbATQaKDl","name":"1 m2 de laine","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/tissu_laine.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.2y61gBIFbATQaKDl"}},"system":{"description":"","descriptionmj":"","encombrement":0.2,"quantite":1,"qualite":0,"cout":0.1,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206014,"modifiedTime":1669755533739,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"2y61gBIFbATQaKDl","name":"1 m2 de laine","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/tissu_laine.webp","data":{"description":"","quantite":1,"encombrement":0.2,"equipe":false,"resistance":0,"qualite":0,"cout":0.1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.2y61gBIFbATQaKDl"}}}
|
{"_id":"3DJePXhrDWQxbUeM","name":"Dé à jouer en os","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/des_en_os.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.3DJePXhrDWQxbUeM"}},"system":{"description":"","descriptionmj":"","encombrement":0.01,"quantite":1,"qualite":0,"cout":0.1,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206015,"modifiedTime":1669755533747,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"3DJePXhrDWQxbUeM","name":"Dé à jouer en os","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/des_en_os.webp","data":{"description":"","quantite":1,"encombrement":0.01,"equipe":false,"resistance":0,"qualite":0,"cout":0.1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.3DJePXhrDWQxbUeM"}}}
|
{"_id":"3cn9nWtY0Vb1PLTx","name":"Dague de jet","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/objets/dagues.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.3cn9nWtY0Vb1PLTx"}},"system":{"description":"<p>Chaque point de force au dessus de 10 augmente les portées de 1m.</p>\n<p>Chaque point de force en dessous de 9 diminue les portées de 1m.</p>","descriptionmj":"","equipe":false,"encombrement":0.5,"quantite":1,"qualite":0,"cout":3,"resistance":0,"categorie_parade":"","dommages":"1","penetration":0,"force":"0","competence":"Dague","lancer":"Dague de jet","tir":"","portee_courte":3,"portee_moyenne":8,"portee_extreme":15,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"rapide":true,"deuxmains":false,"unemain":true,"initpremierround":"dague"},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206015,"modifiedTime":1669755533747,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"3cn9nWtY0Vb1PLTx","name":"Dague de jet","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/objets/dagues.webp","data":{"categorie_parade":"","description":"<p>Chaque point de force au dessus de 10 augmente les portées de 1m.</p>\n<p>Chaque point de force en dessous de 9 diminue les portées de 1m.</p>","quantite":1,"encombrement":0.5,"equipe":false,"dommages":"1","penetration":0,"force":"0","resistance":0,"competence":"Dague de jet","cout":3,"portee_courte":3,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"portee_moyenne":8,"portee_extreme":15,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":""},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.3cn9nWtY0Vb1PLTx"}}}
|
{"_id":"3t0NhMC0cFQyCZGH","name":"Soufflet","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/soufflet.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.3t0NhMC0cFQyCZGH"}},"system":{"description":"","descriptionmj":"","encombrement":0.2,"quantite":1,"qualite":0,"cout":0.4,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206015,"modifiedTime":1669755533757,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"3mHSocNVPyWkmGBR","name":"Nartha","type":"ingredient","img":"systems/foundryvtt-reve-de-dragon/icons/objets/nartha.webp","data":{"description":"<p>Poudre noire obtenue par disruption alchimique du minerai appelé <em>narthalide</em>, sorte de marne.</p>\n<p>VUE/Alchimie à -3</p>","niveau":0,"encombrement":0.001,"base":0,"quantite":1,"milieu":"","rarete":"","categorie":"Alchimie","cout":0.4},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.3mHSocNVPyWkmGBR"}}}
|
{"_id":"3uWCDH1NOjHJpVo1","name":"Maillet","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/objets/maillet.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.3uWCDH1NOjHJpVo1"}},"system":{"description":"","descriptionmj":"","equipe":false,"encombrement":0.1,"quantite":1,"qualite":0,"cout":0.05,"resistance":7,"categorie_parade":"","dommages":"1","penetration":0,"force":"7","competence":"Masse à 1 main","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":"masse"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206015,"modifiedTime":1669755533753,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"3t0NhMC0cFQyCZGH","name":"Soufflet","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/soufflet.webp","data":{"description":"","quantite":1,"encombrement":0.2,"equipe":false,"resistance":0,"qualite":0,"cout":0.4},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.3t0NhMC0cFQyCZGH"}}}
|
{"_id":"4GeV81qoJrjHIgzR","name":"Tournegraisse","type":"potion","img":"systems/foundryvtt-reve-de-dragon/icons/objets/tournegraisse.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.4GeV81qoJrjHIgzR"}},"system":{"description":"<p>Crème sirupeuse blanchâtre.</p>","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":2,"rarete":"","categorie":"AlchimieAutre","herbe":"","herbebrins":0,"herbebonus":0,"reposalchimique":false,"pr":0,"prpermanent":false,"prdate":0,"soinherbe":"","soinherbebonus":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206015,"modifiedTime":1669755533757,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"3uWCDH1NOjHJpVo1","name":"Maillet","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/objets/maillet.webp","data":{"categorie_parade":"","description":"","quantite":1,"encombrement":0.1,"equipe":false,"dommages":"1","penetration":0,"force":"7","resistance":7,"competence":"Masse à 1 main","cout":0.05,"portee_courte":0,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"portee_moyenne":0,"portee_extreme":0,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":"masse"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.3uWCDH1NOjHJpVo1"}}}
|
{"_id":"4LFXefT0HFpaXQLx","name":"Briquet à silex","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/briquet.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.4LFXefT0HFpaXQLx"}},"system":{"description":"","descriptionmj":"","encombrement":0.08,"quantite":1,"qualite":0,"cout":0.4,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206015,"modifiedTime":1669755533744,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"4GeV81qoJrjHIgzR","name":"Tournegraisse","type":"potion","img":"systems/foundryvtt-reve-de-dragon/icons/objets/tournegraisse.webp","data":{"description":"<p>Crème sirupeuse blanchâtre.</p>","descriptionmj":"","quantite":1,"encombrement":0.1,"rarete":"","categorie":"AlchimieAutre","herbe":"","herbebrins":0,"herbebonus":0,"reposalchimique":false,"pr":0,"prpermanent":false,"prdate":0,"cout":2,"soinherbe":"","soinherbebonus":0},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.4GeV81qoJrjHIgzR"}}}
|
{"_id":"4qPaCKONcrsK6JbQ","name":"Pichet de grès (1 litre)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/pichet.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.4qPaCKONcrsK6JbQ"}},"system":{"description":"","descriptionmj":"","encombrement":0.3,"quantite":1,"qualite":0,"cout":0.3,"contenu":[],"capacite":0.5,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206016,"modifiedTime":1669755533755,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"4LFXefT0HFpaXQLx","name":"Briquet à silex","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/briquet.webp","data":{"description":"","quantite":1,"encombrement":0.08,"equipe":false,"resistance":0,"qualite":0,"cout":0.4},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.4LFXefT0HFpaXQLx"}}}
|
{"_id":"4qoLpa4shvkgDZRy","name":"Culottes de velours","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/culottes_velours.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.4qoLpa4shvkgDZRy"}},"system":{"description":"","descriptionmj":"","encombrement":0.2,"quantite":1,"qualite":0,"cout":6,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206016,"modifiedTime":1669755533747,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"4qPaCKONcrsK6JbQ","name":"Pichet de grès (1 litre)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/pichet.webp","data":{"description":"","capacite":0.5,"encombrement":0.3,"equipe":false,"qualite":0,"contenu":[],"cout":0.3},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.4qPaCKONcrsK6JbQ"}}}
|
{"_id":"5GOk9cMApM4dBcIU","name":"Casserole de fer (1 litre)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/casserole.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.5GOk9cMApM4dBcIU"}},"system":{"description":"","descriptionmj":"","encombrement":0.2,"quantite":1,"qualite":0,"cout":0.3,"contenu":[],"capacite":0.5,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206016,"modifiedTime":1669755533744,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"4qoLpa4shvkgDZRy","name":"Culottes de velours","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/culottes_velours.webp","data":{"description":"","quantite":1,"encombrement":0.2,"equipe":false,"resistance":0,"qualite":0,"cout":6},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.4qoLpa4shvkgDZRy"}}}
|
{"_id":"65SRmXVcyiG5ZW9l","name":"Cuillère de fer","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/cuillere_fer.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.65SRmXVcyiG5ZW9l"}},"system":{"description":"","descriptionmj":"","encombrement":0.05,"quantite":1,"qualite":0,"cout":0.1,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206016,"modifiedTime":1669755533746,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"5GOk9cMApM4dBcIU","name":"Casserole de fer (1 litre)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/casserole.webp","data":{"description":"","capacite":0.5,"encombrement":0.2,"equipe":false,"qualite":0,"contenu":[],"cout":0.3},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.5GOk9cMApM4dBcIU"}}}
|
{"_id":"6MVWA3DYbpw8122A","name":"Entonnoir de fer","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/entonnoir.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.6MVWA3DYbpw8122A"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.15,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206016,"modifiedTime":1669755533748,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"65SRmXVcyiG5ZW9l","name":"Cuillère de fer","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/cuillere_fer.webp","data":{"description":"","quantite":1,"encombrement":0.05,"equipe":false,"resistance":0,"qualite":0,"cout":0.1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.65SRmXVcyiG5ZW9l"}}}
|
{"_id":"6s5QjArwz9w9JIGL","name":"Double dragonne","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/double_dragonne.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.6s5QjArwz9w9JIGL"}},"system":{"description":"<p>Apparue vers la fin du Second Âge, c’était<em> une grande épée à deux mains</em>. Encombrante et prohibant le bouclier, c’était avant tout une épée de duel et de frime.</p>","descriptionmj":"","equipe":false,"encombrement":4,"quantite":1,"qualite":0,"cout":50,"resistance":13,"categorie_parade":"epees-lourdes","dommages":"5","penetration":0,"force":"13","competence":"Epée à 2 mains","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"rapide":false,"deuxmains":true,"unemain":false,"initpremierround":"hast"},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206017,"modifiedTime":1669755533747,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"69vN8bRlnCrRHQCm","name":"Obbadion","type":"ingredient","img":"systems/foundryvtt-reve-de-dragon/icons/objets/l_obbadion.webp","data":{"description":"<p>Poudre bleuâtre obtenue par disruption alchimique du minerai appelé <em>obbadine</em>, sorte de tourbe.</p>\n<p>VUE/Alchimie à -2</p>","niveau":0,"encombrement":0.001,"base":0,"quantite":1,"milieu":"Lieux humides","rarete":"","categorie":"Alchimie","cout":0.2},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.69vN8bRlnCrRHQCm"}}}
|
{"_id":"7B9sKLf4ipRyyEjF","name":"Bouclier lourd","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/bouclier_grand.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.7B9sKLf4ipRyyEjF"}},"system":{"description":"","descriptionmj":"","equipe":false,"encombrement":3,"quantite":1,"qualite":0,"cout":8,"resistance":20,"categorie_parade":"boucliers","dommages":"0","penetration":0,"force":"13","competence":"Bouclier","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":"hast"},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206017,"modifiedTime":1669755533743,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"6MVWA3DYbpw8122A","name":"Entonnoir de fer","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/entonnoir.webp","data":{"description":"","quantite":1,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":0.15},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.6MVWA3DYbpw8122A"}}}
|
{"_id":"7YuWWsFIuZgakGUS","name":"Mortier en marbre","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/mortier.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.7YuWWsFIuZgakGUS"}},"system":{"description":"","descriptionmj":"","encombrement":0.3,"quantite":1,"qualite":0,"cout":0.2,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206017,"modifiedTime":1669755533754,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"6fW8gPkxgeBCKA59","name":"Premier Chant Dérisoire","type":"livre","img":"systems/foundryvtt-reve-de-dragon/icons/competence_hypnos.webp","data":{"description":"<p>Les <em>Chants Dérisoires</em> de Yester l’Ancien ont été peu retranscrits, probablement à cause de leur ineptie fondamentale. En dénicher un exemplaire n’est donc déjà pas chose aisée. Le premier chant, cependant, peut être source de révélation pour les haut-rêvants. La découverte de ce sens caché demande un minimum de +4 en voie d’Hypnos et permet la synthèse du sort de <em>Dérision</em>. Sans son assimilation préalable, la synthèse de ce sort est totalement inenvisageable. Sa difficulté de lecture est de -5, son assimilation requiert 16 points de tâche, périodicité 1 heure.</p>","competence":"Comédie","auteur":"Yester l’Ancien","quantite":1,"difficulte":-5,"points_de_tache":16,"encombrement":0,"xp":"","niveau_minimum":0,"niveau_maximum":0,"cout":0},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"jOzRscDxoXZWpGS6":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.6fW8gPkxgeBCKA59"}}}
|
{"_id":"7c7CO626TCo4lg8b","name":"Petite scie cadre","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/scie.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.7c7CO626TCo4lg8b"}},"system":{"description":"","descriptionmj":"","encombrement":1,"quantite":1,"qualite":0,"cout":6,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206017,"modifiedTime":1669755533755,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"6s5QjArwz9w9JIGL","name":"Double dragonne","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/double_dragonne.webp","data":{"categorie_parade":"epees-lourdes","description":"<p>Apparue vers la fin du Second Âge, c’était<em> une grande épée à deux mains</em>. Encombrante et prohibant le bouclier, c’était avant tout une épée de duel et de frime.</p>","quantite":1,"encombrement":4,"equipe":false,"dommages":"5","penetration":0,"force":"13","resistance":13,"competence":"Epée à 2 mains","cout":50,"portee_courte":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"portee_moyenne":0,"portee_extreme":0,"rapide":false,"deuxmains":true,"unemain":false,"initpremierround":"hast"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.6s5QjArwz9w9JIGL"}}}
|
{"_id":"7u9yAlaFhKcVdEC6","name":"Matériel de chirurgie","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/materiel_chirurgie.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.7u9yAlaFhKcVdEC6"}},"system":{"description":"<p>(pincettes, lancette, crin, aiguille)</p>","descriptionmj":"","encombrement":0.06,"quantite":1,"qualite":0,"cout":1,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206017,"modifiedTime":1669755533754,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"7B9sKLf4ipRyyEjF","name":"Bouclier lourd","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/bouclier_grand.webp","data":{"categorie_parade":"boucliers","description":"","quantite":1,"encombrement":3,"equipe":false,"dommages":"0","penetration":0,"force":"13","resistance":20,"competence":"Bouclier","cout":8,"portee_courte":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"portee_moyenne":0,"portee_extreme":0,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":"hast"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.7B9sKLf4ipRyyEjF"}}}
|
{"_id":"8bwP6zncdFP0O9ew","name":"Corde (10 m)","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/corde.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.8bwP6zncdFP0O9ew"}},"system":{"description":"","descriptionmj":"","encombrement":1,"quantite":1,"qualite":0,"cout":0.3,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206017,"modifiedTime":1669755533745,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"7YuWWsFIuZgakGUS","name":"Mortier en marbre","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/mortier.webp","data":{"description":"","quantite":1,"encombrement":0.3,"equipe":false,"resistance":0,"qualite":0,"cout":0.2},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.7YuWWsFIuZgakGUS"}}}
|
{"_id":"92GDNmNVa2u0gzpx","name":"Massette","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/massette.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.92GDNmNVa2u0gzpx"}},"system":{"description":"","descriptionmj":"","equipe":false,"encombrement":1,"quantite":1,"qualite":0,"cout":2,"resistance":8,"categorie_parade":"","dommages":"2","penetration":0,"force":"9","competence":"Masse à 1 main","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"rapide":true,"deuxmains":false,"unemain":true,"initpremierround":"masse"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206017,"modifiedTime":1669755533753,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"7c7CO626TCo4lg8b","name":"Petite scie cadre","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/scie.webp","data":{"description":"","quantite":1,"encombrement":1,"equipe":false,"resistance":0,"qualite":0,"cout":6},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.7c7CO626TCo4lg8b"}}}
|
{"_id":"9cLkTDugz84gpHUB","name":"Bitume de Camphre","type":"potion","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bitume_de_camphre.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.9cLkTDugz84gpHUB"}},"system":{"description":"<p>Crème sirupeuse grisâtre.</p>","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":2,"rarete":"","categorie":"AlchimieAutre","herbe":"","herbebrins":0,"herbebonus":0,"reposalchimique":false,"pr":0,"prpermanent":false,"prdate":0,"soinherbe":"","soinherbebonus":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206018,"modifiedTime":1669755533742,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"7u9yAlaFhKcVdEC6","name":"Matériel de chirurgie","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/materiel_chirurgie.webp","data":{"description":"<p>(pincettes, lancette, crin, aiguille)</p>","quantite":1,"encombrement":0.06,"equipe":false,"resistance":0,"qualite":0,"cout":1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.7u9yAlaFhKcVdEC6"}}}
|
{"_id":"A3jx5dPkk5IeXSXn","name":"Lait de lune","type":"potion","img":"systems/foundryvtt-reve-de-dragon/icons/objets/lait_de_lune.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.A3jx5dPkk5IeXSXn"}},"system":{"description":"<p>Fluide.</p>\n<p>Lait de laie.</p>","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":1,"rarete":"","categorie":"Alchimie","herbe":"","herbebrins":0,"herbebonus":0,"reposalchimique":false,"pr":0,"prpermanent":false,"prdate":0,"soinherbe":"","soinherbebonus":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206018,"modifiedTime":1669755533752,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"8bwP6zncdFP0O9ew","name":"Corde (10 m)","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/corde.webp","data":{"description":"","quantite":1,"encombrement":1,"equipe":false,"resistance":0,"qualite":0,"cout":0.3},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.8bwP6zncdFP0O9ew"}}}
|
{"name":"Bronze (10 deniers)","type":"monnaie","img":"systems/foundryvtt-reve-de-dragon/icons/objets/piece_bronze_epees.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Item.hifMbbRrRdQxflsx"}},"_id":"A8UcYUIIlb6YfczN","system":{"description":"","descriptionmj":"","encombrement":0.01,"quantite":1,"qualite":0,"cout":0,"valeur_deniers":10,"data":{"quantite":0,"valeur_deniers":10,"encombrement":0.01}},"ownership":{"default":0,"jtRmvSuwkwMmIMf0":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206018,"modifiedTime":1669755533744,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"92GDNmNVa2u0gzpx","name":"Massette","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/massette.webp","data":{"categorie_parade":"","description":"","quantite":1,"encombrement":1,"equipe":false,"dommages":"2","penetration":0,"force":"9","resistance":8,"competence":"Masse à 1 main","cout":2,"portee_courte":0,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"portee_moyenne":0,"portee_extreme":0,"rapide":true,"deuxmains":false,"unemain":true,"initpremierround":"masse"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.92GDNmNVa2u0gzpx"}}}
|
{"_id":"A9nMgTyEwYzdA0zT","name":"Manteau de velours","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/manteau_velours.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.A9nMgTyEwYzdA0zT"}},"system":{"description":"","descriptionmj":"","encombrement":1,"quantite":1,"qualite":0,"cout":10,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206018,"modifiedTime":1669755533753,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"9cLkTDugz84gpHUB","name":"Bitume de Camphre","type":"potion","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bitume_de_camphre.webp","data":{"description":"<p>Crème sirupeuse grisâtre.</p>","descriptionmj":"","quantite":1,"encombrement":0.1,"rarete":"","categorie":"AlchimieAutre","herbe":"","herbebrins":0,"herbebonus":0,"reposalchimique":false,"pr":0,"prpermanent":false,"prdate":0,"cout":2,"soinherbe":"","soinherbebonus":0},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.9cLkTDugz84gpHUB"}}}
|
{"_id":"AOQsKTjIbcy8NV9t","name":"Pierre à aiguiser","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/pierre_a_aiguiser.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.AOQsKTjIbcy8NV9t"}},"system":{"description":"","descriptionmj":"","encombrement":0.2,"quantite":1,"qualite":0,"cout":0.3,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206018,"modifiedTime":1669755533755,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"A3jx5dPkk5IeXSXn","name":"Lait de lune","type":"potion","img":"systems/foundryvtt-reve-de-dragon/icons/objets/lait_de_lune.webp","data":{"description":"<p>Fluide.</p>\n<p>Lait de laie.</p>","quantite":1,"encombrement":0.1,"rarete":"","categorie":"Alchimie","herbe":"","herbebrins":0,"herbebonus":0,"reposalchimique":false,"pr":0,"prpermanent":false,"prdate":0,"cout":1,"soinherbe":"","soinherbebonus":0},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.A3jx5dPkk5IeXSXn"}}}
|
{"_id":"As5kYvyOrWrr8KJm","name":"Etui à luth de cuir","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/etui_luth.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.As5kYvyOrWrr8KJm"}},"system":{"description":"","descriptionmj":"","encombrement":0.2,"quantite":1,"qualite":0,"cout":1,"contenu":[],"capacite":1,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206018,"modifiedTime":1669755533749,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"name":"Bronze (10 deniers)","type":"monnaie","img":"systems/foundryvtt-reve-de-dragon/icons/objets/piece_bronze_epees.webp","data":{"quantite":1,"valeur_deniers":10,"encombrement":0.01,"description":"","data":{"quantite":0,"valeur_deniers":10,"encombrement":0.01}},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"jtRmvSuwkwMmIMf0":3},"flags":{"core":{"sourceId":"Item.hifMbbRrRdQxflsx"}},"_id":"A8UcYUIIlb6YfczN"}
|
{"_id":"B2BhuxveVKMnD8fe","name":"Bottes de cuir souple","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bottes_de_cuir.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.B2BhuxveVKMnD8fe"}},"system":{"description":"","descriptionmj":"","encombrement":0.4,"quantite":1,"qualite":0,"cout":2,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206018,"modifiedTime":1669755533743,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"A9nMgTyEwYzdA0zT","name":"Manteau de velours","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/manteau_velours.webp","data":{"description":"","quantite":1,"encombrement":1,"equipe":false,"resistance":0,"qualite":0,"cout":10},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.A9nMgTyEwYzdA0zT"}}}
|
{"_id":"BQPhNy9AUCpEGgFg","name":"Couteau de cuisine","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/objets/couteau-cuisine.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.BQPhNy9AUCpEGgFg"}},"system":{"description":"","descriptionmj":"","equipe":false,"encombrement":0.2,"quantite":1,"qualite":0,"cout":1,"resistance":6,"categorie_parade":"dagues","dommages":"1","penetration":0,"force":"0","competence":"Dague","lancer":"Dague de jet","tir":"","portee_courte":3,"portee_moyenne":8,"portee_extreme":15,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":"dague"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206018,"modifiedTime":1669755533746,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"AOQsKTjIbcy8NV9t","name":"Pierre à aiguiser","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/pierre_a_aiguiser.webp","data":{"description":"","quantite":1,"encombrement":0.2,"equipe":false,"resistance":0,"qualite":0,"cout":0.3},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.AOQsKTjIbcy8NV9t"}}}
|
{"_id":"CMtQM06J3BZsHHxH","name":"Sandales","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/sandales.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.CMtQM06J3BZsHHxH"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.3,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206018,"modifiedTime":1669755533757,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"As5kYvyOrWrr8KJm","name":"Etui à luth de cuir","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/etui_luth.webp","data":{"description":"","capacite":1,"encombrement":0.2,"equipe":false,"qualite":0,"contenu":[],"cout":1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.As5kYvyOrWrr8KJm"}}}
|
{"_id":"CQSxJv1mgmIeMCbM","name":"Grappin","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/grappin.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.CQSxJv1mgmIeMCbM"}},"system":{"description":"","descriptionmj":"","encombrement":0.5,"quantite":1,"qualite":0,"cout":2,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206018,"modifiedTime":1669755533751,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"B2BhuxveVKMnD8fe","name":"Bottes de cuir souple","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bottes_de_cuir.webp","data":{"description":"","quantite":1,"encombrement":0.4,"equipe":false,"resistance":0,"qualite":0,"cout":2},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.B2BhuxveVKMnD8fe"}}}
|
{"_id":"ElweMV283IUpqaik","name":"Sable-Poudre","type":"potion","img":"systems/foundryvtt-reve-de-dragon/icons/objets/sable_poudre.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.ElweMV283IUpqaik"}},"system":{"description":"<p>Granulés. Poudre blanche.</p>","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":2,"rarete":"","categorie":"AlchimieAutre","herbe":"","herbebrins":0,"herbebonus":0,"reposalchimique":false,"pr":0,"prpermanent":false,"prdate":0,"soinherbe":"","soinherbebonus":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206019,"modifiedTime":1669755533756,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"BQPhNy9AUCpEGgFg","name":"Couteau de cuisine","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/objets/couteau-cuisine.webp","data":{"categorie_parade":"dagues","description":"","quantite":1,"encombrement":0.2,"equipe":false,"dommages":"1","penetration":0,"force":"0","resistance":6,"competence":"Dague","cout":1,"portee_courte":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"portee_moyenne":0,"portee_extreme":0,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":"dague"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.BQPhNy9AUCpEGgFg"}}}
|
{"_id":"Eospy1EFNlhgOyXc","name":"Lacet de cuir (1 m)","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/lacet.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Eospy1EFNlhgOyXc"}},"system":{"description":"","descriptionmj":"","encombrement":0.01,"quantite":1,"qualite":0,"cout":0.06,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206019,"modifiedTime":1669755533752,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"CMtQM06J3BZsHHxH","name":"Sandales","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/sandales.webp","data":{"description":"","quantite":1,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":0.3},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.CMtQM06J3BZsHHxH"}}}
|
{"_id":"F6ZHJth4t0PA5PMB","name":"Alêne, poinçon","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/poincon_2.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.F6ZHJth4t0PA5PMB"}},"system":{"description":"","descriptionmj":"","encombrement":0.05,"quantite":1,"qualite":0,"cout":0.1,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206019,"modifiedTime":1669755533740,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"CQSxJv1mgmIeMCbM","name":"Grappin","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/grappin.webp","data":{"description":"","quantite":1,"encombrement":0.5,"equipe":false,"resistance":0,"qualite":0,"cout":2},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.CQSxJv1mgmIeMCbM"}}}
|
{"_id":"FH3mSvdebfhIL2Af","name":"Topazoïne","type":"potion","img":"systems/foundryvtt-reve-de-dragon/icons/objets/topazoine.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.FH3mSvdebfhIL2Af"}},"system":{"description":"<p>Granulés. Coquille d'oeuf de cane broyé.</p>","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":2,"rarete":"","categorie":"AlchimieAutre","herbe":"","herbebrins":0,"herbebonus":0,"reposalchimique":false,"pr":0,"prpermanent":false,"prdate":0,"soinherbe":"","soinherbebonus":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206019,"modifiedTime":1669755533757,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"D5Z3FaUv91B8eCOP","name":"Obyssum vert","type":"ingredient","img":"systems/foundryvtt-reve-de-dragon/icons/objets/l_obyssum_vert.webp","data":{"description":"<p>Poudre verdâtre apparaissant sur les tiges de certains roseaux.</p>\n<p>VUE/Alchimie à -2</p>","niveau":0,"encombrement":0.001,"base":0,"quantite":1,"milieu":"Lieux humides","rarete":"","categorie":"Alchimie","cout":0.05},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.D5Z3FaUv91B8eCOP"}}}
|
{"_id":"FaNRC7YQzibSdqZU","name":"Plume de fer","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/plume_de_fer.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.FaNRC7YQzibSdqZU"}},"system":{"description":"","descriptionmj":"","encombrement":0.01,"quantite":1,"qualite":0,"cout":0.1,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206019,"modifiedTime":1669755533755,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"ElweMV283IUpqaik","name":"Sable-Poudre","type":"potion","img":"systems/foundryvtt-reve-de-dragon/icons/objets/sable_poudre.webp","data":{"description":"<p>Granulés. Poudre blanche.</p>","descriptionmj":"","quantite":1,"encombrement":0.1,"rarete":"","categorie":"AlchimieAutre","herbe":"","herbebrins":0,"herbebonus":0,"reposalchimique":false,"pr":0,"prpermanent":false,"prdate":0,"cout":2,"soinherbe":"","soinherbebonus":0},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.ElweMV283IUpqaik"}}}
|
{"_id":"Flx5inKGs1GQKoYq","name":"Tube à parchemins","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/tube_parchemin.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Flx5inKGs1GQKoYq"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.5,"contenu":[],"capacite":1.3,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206019,"modifiedTime":1669755533757,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"Eospy1EFNlhgOyXc","name":"Lacet de cuir (1 m)","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/lacet.webp","data":{"description":"","quantite":1,"encombrement":0.01,"equipe":false,"resistance":0,"qualite":0,"cout":0.06},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Eospy1EFNlhgOyXc"}}}
|
{"_id":"GAJIShPe7WugrIVO","name":"Manteau de fourrure","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/manteau_fourrure.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.GAJIShPe7WugrIVO"}},"system":{"description":"<p>En fonction de la qualité de la fourrure, le prix d'un tel manteau peut varier de 1 à 20 sols.</p>","descriptionmj":"","encombrement":1,"quantite":1,"qualite":0,"cout":0,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206020,"modifiedTime":1669755533753,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"F0hcXfGaaYKQ0229","name":"Narcos, voie des Sortilèges","type":"livre","img":"systems/foundryvtt-reve-de-dragon/icons/competence_narcos.webp","data":{"description":"<p>Ce tome imposant, ouvertement destiné aux haut-rêvants, révèle que la voie de Narcos ne possède pas que des rituels, mais également des sortilèges. En saisir le sens demande toutefois un minimum de +4 en voie de Narcos. Il permet de comprendre le principe des sorts de transformation et d’envisager la synthèse de <em>Flèche de feu</em>,<em> Dague de force</em>, <em>Dragonne lame</em> et <em>Gourdindragon</em>. Sans son assimilation préalable, la synthèse de ces sorts est totalement inenvisageable. Sa difficulté de lecture est de -6, son assimilation requiert 28 points de tâche, périodicité 1 heure.</p>","competence":"","auteur":"Segamor le Transformiste","quantite":1,"difficulte":-6,"points_de_tache":28,"encombrement":0,"xp":"","niveau_minimum":0,"niveau_maximum":0,"cout":0},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"jOzRscDxoXZWpGS6":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.F0hcXfGaaYKQ0229"}}}
|
{"_id":"GiquTnEsiVZn7m6Y","name":"Bas de soie","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bas_soie.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.GiquTnEsiVZn7m6Y"}},"system":{"description":"","descriptionmj":"","encombrement":0,"quantite":1,"qualite":0,"cout":3,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206020,"modifiedTime":1669755533742,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"F6ZHJth4t0PA5PMB","name":"Alêne, poinçon","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/poincon_2.webp","data":{"description":"","quantite":1,"encombrement":0.05,"equipe":false,"resistance":0,"qualite":0,"cout":0.1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.F6ZHJth4t0PA5PMB"}}}
|
{"_id":"Gp9ZrwXkqZbJoVVT","name":"1 m² de toile de voile","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/voile.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Gp9ZrwXkqZbJoVVT"}},"system":{"description":"","descriptionmj":"","encombrement":0.2,"quantite":1,"qualite":0,"cout":0.1,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206020,"modifiedTime":1669755533740,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"FH3mSvdebfhIL2Af","name":"Topazoïne","type":"potion","img":"systems/foundryvtt-reve-de-dragon/icons/objets/topazoine.webp","data":{"description":"<p>Granulés. Coquille d'oeuf de cane broyé.</p>","descriptionmj":"","quantite":1,"encombrement":0.1,"rarete":"","categorie":"AlchimieAutre","herbe":"","herbebrins":0,"herbebonus":0,"reposalchimique":false,"pr":0,"prpermanent":false,"prdate":0,"cout":2,"soinherbe":"","soinherbebonus":0},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.FH3mSvdebfhIL2Af"}}}
|
{"_id":"HdciYu5J2SrJO8e3","name":"Épée gnome","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/epee_gnome.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.HdciYu5J2SrJO8e3"}},"system":{"description":"<p>C’est une épée <em>courte</em>, essentiellement fabriquée et portée par les Gnomes au Second Âge.</p>","descriptionmj":"","equipe":false,"encombrement":1,"quantite":1,"qualite":0,"cout":12,"resistance":12,"categorie_parade":"epees-courtes","dommages":"2","penetration":0,"force":"8","competence":"Epée à 1 main","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"rapide":true,"deuxmains":false,"unemain":true,"initpremierround":"epeegnome"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206020,"modifiedTime":1669755533748,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"FaNRC7YQzibSdqZU","name":"Plume de fer","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/plume_de_fer.webp","data":{"description":"","quantite":1,"encombrement":0.01,"equipe":false,"resistance":0,"qualite":0,"cout":0.1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.FaNRC7YQzibSdqZU"}}}
|
{"_id":"HjbB4f1CDz96Hv88","name":"Rasoir","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/objets/rasoir.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.HjbB4f1CDz96Hv88"}},"system":{"description":"","descriptionmj":"","equipe":false,"encombrement":0.1,"quantite":1,"qualite":0,"cout":2,"resistance":0,"categorie_parade":"dagues","dommages":"1","penetration":0,"force":"0","competence":"Dague","lancer":"Dague de jet","tir":"","portee_courte":3,"portee_moyenne":8,"portee_extreme":15,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":"dague"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206021,"modifiedTime":1669755533756,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"Flx5inKGs1GQKoYq","name":"Tube à parchemins","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/tube_parchemin.webp","data":{"description":"","capacite":1.3,"encombrement":0.1,"equipe":false,"qualite":0,"contenu":[],"cout":0.5},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Flx5inKGs1GQKoYq"}}}
|
{"_id":"HsIJSPQ46cec22Y2","name":"Couverture de laine","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/couverture_laine.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.HsIJSPQ46cec22Y2"}},"system":{"description":"","descriptionmj":"","encombrement":0.6,"quantite":1,"qualite":0,"cout":0.3,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206021,"modifiedTime":1669755533746,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"GAJIShPe7WugrIVO","name":"Manteau de fourrure","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/manteau_fourrure.webp","data":{"description":"<p>En fonction de la qualité de la fourrure, le prix d'un tel manteau peut varier de 1 à 20 sols.</p>","quantite":1,"encombrement":1,"equipe":false,"resistance":0,"qualite":0,"cout":0},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.GAJIShPe7WugrIVO"}}}
|
{"_id":"Ig9qIzaZ5SveXLF7","name":"Pelle","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/pelle.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Ig9qIzaZ5SveXLF7"}},"system":{"description":"","descriptionmj":"","encombrement":1,"quantite":1,"qualite":0,"cout":1,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206021,"modifiedTime":1669755533755,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"GiquTnEsiVZn7m6Y","name":"Bas de soie","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bas_soie.webp","data":{"description":"","quantite":1,"encombrement":0,"equipe":false,"resistance":0,"qualite":0,"cout":3},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.GiquTnEsiVZn7m6Y"}}}
|
{"_id":"InTxnjInfBYHsqcR","name":"Poêle à frire (40 cm)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/poele.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.InTxnjInfBYHsqcR"}},"system":{"description":"","descriptionmj":"","encombrement":0.3,"quantite":1,"qualite":0,"cout":0.5,"contenu":[],"capacite":0.5,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206021,"modifiedTime":1669755533755,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"Gp9ZrwXkqZbJoVVT","name":"1 m² de toile de voile","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/voile.webp","data":{"description":"","quantite":1,"encombrement":0.2,"equipe":false,"resistance":0,"qualite":0,"cout":0.1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Gp9ZrwXkqZbJoVVT"}}}
|
{"_id":"JXMef7FXVOG1XYWO","name":"Elixir des gnomes","type":"potion","img":"systems/foundryvtt-reve-de-dragon/icons/objets/elixir_des_gnomes.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.JXMef7FXVOG1XYWO"}},"system":{"description":"<p>Fluide.</p>\n<p>Liqueur violette.</p>","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":1,"rarete":"","categorie":"Alchimie","herbe":"","herbebrins":0,"herbebonus":0,"reposalchimique":false,"pr":0,"prpermanent":false,"prdate":0,"soinherbe":"","soinherbebonus":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206021,"modifiedTime":1669755533747,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"HdciYu5J2SrJO8e3","name":"Épée gnome","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/epee_gnome.webp","data":{"categorie_parade":"epees-courtes","description":"<p>C’est une épée <em>courte</em>, essentiellement fabriquée et portée par les Gnomes au Second Âge.</p>","quantite":1,"encombrement":1,"equipe":false,"dommages":"2","penetration":0,"force":"8","resistance":12,"competence":"Epée à 1 main","cout":12,"portee_courte":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"portee_moyenne":0,"portee_extreme":0,"rapide":true,"deuxmains":false,"unemain":true,"initpremierround":"epeegnome"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.HdciYu5J2SrJO8e3"}}}
|
{"_id":"JfxFBlokIegRWTDo","name":"Torche 1/2 heure (60 min)","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/torche.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.JfxFBlokIegRWTDo"}},"system":{"description":"","descriptionmj":"","encombrement":0.3,"quantite":1,"qualite":0,"cout":0.02,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206021,"modifiedTime":1669755533757,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"HjbB4f1CDz96Hv88","name":"Rasoir","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/objets/rasoir.webp","data":{"categorie_parade":"dagues","description":"","quantite":1,"encombrement":0.1,"equipe":false,"dommages":"1","penetration":0,"force":"0","resistance":0,"competence":"Dague","cout":2,"portee_courte":0,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"portee_moyenne":0,"portee_extreme":0,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":"dague"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.HjbB4f1CDz96Hv88"}}}
|
{"_id":"JhQZDbsmFZBLRcln","name":"Sac en jute (20 litres)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/sac_jute_20.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.JhQZDbsmFZBLRcln"}},"system":{"description":"","descriptionmj":"","encombrement":0.05,"quantite":1,"qualite":0,"cout":0.04,"contenu":[],"capacite":10,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206021,"modifiedTime":1669755533756,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"HsIJSPQ46cec22Y2","name":"Couverture de laine","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/couverture_laine.webp","data":{"description":"","quantite":1,"encombrement":0.6,"equipe":false,"resistance":0,"qualite":0,"cout":0.3},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.HsIJSPQ46cec22Y2"}}}
|
{"_id":"K4n2JuDnoHDUPCZG","name":"Bouilloire de fer (2 litres)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bouilloire.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.K4n2JuDnoHDUPCZG"}},"system":{"description":"","descriptionmj":"","encombrement":0.5,"quantite":1,"qualite":0,"cout":0.5,"contenu":[],"capacite":1,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206022,"modifiedTime":1669755533743,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"Ig9qIzaZ5SveXLF7","name":"Pelle","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/pelle.webp","data":{"description":"","quantite":1,"encombrement":1,"equipe":false,"resistance":0,"qualite":0,"cout":1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Ig9qIzaZ5SveXLF7"}}}
|
{"_id":"KQZIK8ltQ3sQiDGe","name":"Mailles de Fer","type":"armure","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/mailles.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.KQZIK8ltQ3sQiDGe"}},"system":{"description":"<p>Grand haubert de mailles avec capuche À enfiler sur une cotte de cuir souple ou de drap matelassé) + bottes de cuir / métal.</p>\n<p> </p>","descriptionmj":"","equipe":false,"encombrement":6,"quantite":1,"qualite":0,"cout":50,"protection":5,"deterioration":null,"malus":-4},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206022,"modifiedTime":1669755533753,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"InTxnjInfBYHsqcR","name":"Poêle à frire (40 cm)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/poele.webp","data":{"description":"","capacite":0.5,"encombrement":0.3,"equipe":false,"qualite":0,"contenu":[],"cout":0.5},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.InTxnjInfBYHsqcR"}}}
|
{"_id":"KlydiUbayqBgJB6J","name":"Tablette de cire","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/tablette_cire.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.KlydiUbayqBgJB6J"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.2,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206022,"modifiedTime":1669755533757,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"JXMef7FXVOG1XYWO","name":"Elixir des gnomes","type":"potion","img":"systems/foundryvtt-reve-de-dragon/icons/objets/elixir_des_gnomes.webp","data":{"description":"<p>Fluide.</p>\n<p>Liqueur violette.</p>","quantite":1,"encombrement":0.1,"rarete":"","categorie":"Alchimie","herbe":"","herbebrins":0,"herbebonus":0,"reposalchimique":false,"pr":0,"prpermanent":false,"prdate":0,"cout":1,"soinherbe":"","soinherbebonus":0},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.JXMef7FXVOG1XYWO"}}}
|
{"_id":"KvzSNxISkWDoilO8","name":"Gemme Inconnue","type":"objet","flags":{"core":{"sourceId":"Item.V3V3wUXNCG6gzJFB"}},"img":"systems/foundryvtt-reve-de-dragon/icons/gemmes/seliphane.webp","effects":[],"system":{"description":"","descriptionmj":"","encombrement":null,"quantite":1,"qualite":0,"cout":0,"equipe":false,"resistance":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206022,"modifiedTime":1669755533750,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"JfxFBlokIegRWTDo","name":"Torche 1/2 heure (60 min)","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/torche.webp","data":{"description":"","quantite":1,"encombrement":0.3,"equipe":false,"resistance":0,"qualite":0,"cout":0.02},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.JfxFBlokIegRWTDo"}}}
|
{"_id":"LZPEdSIv3KywCwdk","name":"Liquide","type":"munition","img":"systems/foundryvtt-reve-de-dragon/icons/liquides/liquide_neutre.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.LZPEdSIv3KywCwdk"}},"system":{"description":"<p>1 mesure (20cl) d'un liquide.</p>\n<p><em>(à modifier/compléter)</em></p>","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206022,"modifiedTime":1669755533752,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"JhQZDbsmFZBLRcln","name":"Sac en jute (20 litres)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/sac_jute_20.webp","data":{"description":"","capacite":10,"encombrement":0.05,"equipe":false,"qualite":0,"contenu":[],"cout":0.04},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.JhQZDbsmFZBLRcln"}}}
|
{"_id":"LaAP5tsP1Sc43hKO","name":"Lanterne à huile","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/lanterne_huile.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.LaAP5tsP1Sc43hKO"}},"system":{"description":"","descriptionmj":"","encombrement":1,"quantite":1,"qualite":0,"cout":5,"contenu":[],"capacite":0.3,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206022,"modifiedTime":1669755533752,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"K4n2JuDnoHDUPCZG","name":"Bouilloire de fer (2 litres)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bouilloire.webp","data":{"description":"","capacite":1,"encombrement":0.5,"equipe":false,"qualite":0,"contenu":[],"cout":0.5},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.K4n2JuDnoHDUPCZG"}}}
|
{"_id":"LkE8EjPfao9m6Rn7","name":"Huile de Sélikanthe","type":"potion","img":"systems/foundryvtt-reve-de-dragon/icons/objets/huile_de_selikanthe.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.LkE8EjPfao9m6Rn7"}},"system":{"description":"<p>Fluide.</p>\n<p>Liquide légèrement huileux.</p>","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":1,"rarete":"","categorie":"Alchimie","herbe":"","herbebrins":0,"herbebonus":0,"reposalchimique":false,"pr":0,"prpermanent":false,"prdate":0,"soinherbe":"","soinherbebonus":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206022,"modifiedTime":1669755533752,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"KQZIK8ltQ3sQiDGe","name":"Mailles de Fer","type":"armure","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/mailles.webp","data":{"description":"<p>Grand haubert de mailles avec capuche À enfiler sur une cotte de cuir souple ou de drap matelassé) + bottes de cuir / métal.</p>\n<p> </p>","quantite":1,"encombrement":6,"equipe":false,"protection":5,"deterioration":null,"malus":-4,"cout":50},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.KQZIK8ltQ3sQiDGe"}}}
|
{"_id":"Lz4dA2NwxdSZ3FZK","name":"Lime, Râpe","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/lime.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Lz4dA2NwxdSZ3FZK"}},"system":{"description":"","descriptionmj":"","encombrement":0.2,"quantite":1,"qualite":0,"cout":0.5,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206022,"modifiedTime":1669755533752,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"KlydiUbayqBgJB6J","name":"Tablette de cire","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/tablette_cire.webp","data":{"description":"","quantite":1,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":0.2},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.KlydiUbayqBgJB6J"}}}
|
{"_id":"M1RgJDuQUvxjqJVV","name":"Chandelle de suif (1 heure)","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/chandelle.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.M1RgJDuQUvxjqJVV"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.02,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206022,"modifiedTime":1669755533744,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"KvzSNxISkWDoilO8","name":"Gemme Inconnue","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"objet","data":{"description":"","quantite":1,"encombrement":null,"equipe":false,"resistance":0,"qualite":0,"cout":0},"flags":{"core":{"sourceId":"Item.V3V3wUXNCG6gzJFB"}},"img":"systems/foundryvtt-reve-de-dragon/icons/gemmes/seliphane.webp","effects":[]}
|
{"_id":"MGvyXFQJpv6nNynl","name":"Masse lourde","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/masse_lourde.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.MGvyXFQJpv6nNynl"}},"system":{"description":"","descriptionmj":"","equipe":false,"encombrement":3,"quantite":1,"qualite":0,"cout":4,"resistance":10,"categorie_parade":"","dommages":"3/4","penetration":0,"force":"12/11","competence":"Masse à 1 main","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"rapide":false,"deuxmains":true,"unemain":true,"initpremierround":"masse"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206023,"modifiedTime":1669755533753,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"LZPEdSIv3KywCwdk","name":"Liquide","type":"munition","img":"systems/foundryvtt-reve-de-dragon/icons/liquides/liquide_neutre.webp","data":{"description":"<p>1 mesure (20cl) d'un liquide.</p>\n<p><em>(à modifier/compléter)</em></p>","quantite":1,"encombrement":0.1,"equipe":false,"qualite":0,"cout":0},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.LZPEdSIv3KywCwdk"}}}
|
{"_id":"MQxgfYTEQEUhG116","name":"Épée bâtarde","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/epee_batarde.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.MQxgfYTEQEUhG116"}},"system":{"description":"<p>Comme son nom l’indique, c’est une <em>bâtarde </em>de l'épée longue et de l'épée sorde, à la fois longue et large, pouvant s’utiliser à une ou deux mains.</p>","descriptionmj":"","equipe":false,"encombrement":3,"quantite":1,"qualite":0,"cout":30,"resistance":14,"categorie_parade":"epees-lourdes","dommages":"4/5","penetration":0,"force":"13/12","competence":"Epée à 1 main","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"rapide":false,"deuxmains":true,"unemain":true,"initpremierround":"epeebatarde"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206023,"modifiedTime":1669755533748,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"LaAP5tsP1Sc43hKO","name":"Lanterne à huile","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/lanterne_huile.webp","data":{"description":"","capacite":0.3,"encombrement":1,"equipe":false,"qualite":0,"contenu":[],"cout":5},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.LaAP5tsP1Sc43hKO"}}}
|
{"_id":"Mbh2M8JS1Rf0vxEX","name":"Harpe","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/harpe.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Mbh2M8JS1Rf0vxEX"}},"system":{"description":"","descriptionmj":"","encombrement":1,"quantite":1,"qualite":0,"cout":5,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206023,"modifiedTime":1669755533751,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"LkE8EjPfao9m6Rn7","name":"Huile de Sélikanthe","type":"potion","img":"systems/foundryvtt-reve-de-dragon/icons/objets/huile_de_selikanthe.webp","data":{"description":"<p>Fluide.</p>\n<p>Liquide légèrement huileux.</p>","quantite":1,"encombrement":0.1,"rarete":"","categorie":"Alchimie","herbe":"","herbebrins":0,"herbebonus":0,"reposalchimique":false,"pr":0,"prpermanent":false,"prdate":0,"cout":1,"soinherbe":"","soinherbebonus":0},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.LkE8EjPfao9m6Rn7"}}}
|
{"_id":"NCp2kdTKmQGyAh1U","name":"Dague","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/dague.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sheetClass":"","sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.NCp2kdTKmQGyAh1U"}},"system":{"description":"","descriptionmj":"","equipe":false,"encombrement":0.5,"quantite":1,"qualite":0,"cout":3,"resistance":8,"categorie_parade":"dagues","dommages":"1","penetration":0,"force":"7","competence":"Dague","lancer":"Dague de jet","tir":"","portee_courte":3,"portee_moyenne":8,"portee_extreme":15,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"rapide":true,"deuxmains":false,"unemain":true,"initpremierround":"dague"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206023,"modifiedTime":1669755533747,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"Lz4dA2NwxdSZ3FZK","name":"Lime, Râpe","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/lime.webp","data":{"description":"","quantite":1,"encombrement":0.2,"equipe":false,"resistance":0,"qualite":0,"cout":0.5},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Lz4dA2NwxdSZ3FZK"}}}
|
{"_id":"NNLhxjFsoJVdFuit","name":"Bouteille de verre (1 litre)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bouteille_verre.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.NNLhxjFsoJVdFuit"}},"system":{"description":"","descriptionmj":"","encombrement":0.2,"quantite":1,"qualite":0,"cout":0.7,"contenu":[],"capacite":0.5,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206023,"modifiedTime":1669755533744,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"M1RgJDuQUvxjqJVV","name":"Chandelle de suif (1 heure)","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/chandelle.webp","data":{"description":"","quantite":1,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":0.02},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.M1RgJDuQUvxjqJVV"}}}
|
{"_id":"OXFFRZOqlhZDJas3","name":"Béret de velours","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/beret_velours.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.OXFFRZOqlhZDJas3"}},"system":{"description":"","descriptionmj":"","encombrement":0.05,"quantite":1,"qualite":0,"cout":3,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206023,"modifiedTime":1669755533742,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"MGvyXFQJpv6nNynl","name":"Masse lourde","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/masse_lourde.webp","data":{"categorie_parade":"","description":"","quantite":1,"encombrement":3,"equipe":false,"dommages":"3/4","penetration":0,"force":"12/11","resistance":10,"competence":"Masse à 1 main","cout":4,"portee_courte":0,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"portee_moyenne":0,"portee_extreme":0,"rapide":false,"deuxmains":true,"unemain":true,"initpremierround":"masse"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.MGvyXFQJpv6nNynl"}}}
|
{"_id":"OYWzXiQUFsjU5AF2","name":"Perles de Bjwal","type":"potion","img":"systems/foundryvtt-reve-de-dragon/icons/objets/perles_bjwal.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.OYWzXiQUFsjU5AF2"}},"system":{"description":"<p>Petits granulés translucides.</p>","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":1,"rarete":"","categorie":"AlchimieAutre","herbe":"","herbebrins":0,"herbebonus":0,"reposalchimique":false,"pr":0,"prpermanent":false,"prdate":0,"soinherbe":"","soinherbebonus":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206023,"modifiedTime":1669755533755,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"MQxgfYTEQEUhG116","name":"Épée bâtarde","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/epee_batarde.webp","data":{"categorie_parade":"epees-lourdes","description":"<p>Comme son nom l’indique, c’est une <em>bâtarde </em>de l'épée longue et de l'épée sorde, à la fois longue et large, pouvant s’utiliser à une ou deux mains.</p>","quantite":1,"encombrement":3,"equipe":false,"dommages":"4/5","penetration":0,"force":"13/12","resistance":14,"competence":"Epée à 1 main","cout":30,"portee_courte":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"portee_moyenne":0,"portee_extreme":0,"rapide":false,"deuxmains":true,"unemain":true,"initpremierround":"epeebatarde"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.MQxgfYTEQEUhG116"}}}
|
{"_id":"P0yc6QfgKVmM0fpu","name":"Ecuelle de grès","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/ecuelle_gres.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.P0yc6QfgKVmM0fpu"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.1,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206023,"modifiedTime":1669755533747,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"Mbh2M8JS1Rf0vxEX","name":"Harpe","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/harpe.webp","data":{"description":"","quantite":1,"encombrement":1,"equipe":false,"resistance":0,"qualite":0,"cout":5},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Mbh2M8JS1Rf0vxEX"}}}
|
{"_id":"PAqV7Fj8AFEpfEpy","name":"Provisions non-cuites","type":"nourritureboisson","img":"systems/foundryvtt-reve-de-dragon/icons/objets/provision_crue.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Item.2P30CKBRVIPiTf3Z"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.01,"sust":1,"boisson":false,"desaltere":0,"alcoolise":false,"force":0,"exotisme":0},"ownership":{"default":0,"wYnBx3HmLfGzsj7P":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206023,"modifiedTime":1669755533756,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"NCp2kdTKmQGyAh1U","name":"Dague","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/dague.webp","data":{"categorie_parade":"dagues","description":"","quantite":1,"encombrement":0.5,"equipe":false,"dommages":"1","penetration":0,"force":"7","resistance":8,"competence":"Dague","cout":3,"portee_courte":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"portee_moyenne":0,"portee_extreme":0,"rapide":true,"deuxmains":false,"unemain":true,"initpremierround":"dague"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"flags":{"core":{"sheetClass":"","sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.NCp2kdTKmQGyAh1U"}}}
|
{"_id":"PH2J4zR0hwXSg0vc","name":"Charbon de bois 1 kg","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/charbon.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.PH2J4zR0hwXSg0vc"}},"system":{"description":"","descriptionmj":"","encombrement":0.04,"quantite":1,"qualite":0,"cout":0.06,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206023,"modifiedTime":1669755533745,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"NNLhxjFsoJVdFuit","name":"Bouteille de verre (1 litre)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bouteille_verre.webp","data":{"description":"","capacite":0.5,"encombrement":0.2,"equipe":false,"qualite":0,"contenu":[],"cout":0.7},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.NNLhxjFsoJVdFuit"}}}
|
{"_id":"PSc92VlQCdNnbPlg","name":"Lance courte","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/lance.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.PSc92VlQCdNnbPlg"}},"system":{"description":"","descriptionmj":"","equipe":false,"encombrement":2,"quantite":1,"qualite":0,"cout":3,"resistance":5,"categorie_parade":"lances","dommages":"2","penetration":0,"force":"8","competence":"Lance","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"rapide":true,"deuxmains":false,"unemain":true,"initpremierround":"lance"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206024,"modifiedTime":1669755533752,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"OXFFRZOqlhZDJas3","name":"Béret de velours","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/beret_velours.webp","data":{"description":"","quantite":1,"encombrement":0.05,"equipe":false,"resistance":0,"qualite":0,"cout":3},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.OXFFRZOqlhZDJas3"}}}
|
{"_id":"PaJoTirnA6h4F3pH","name":"Hameçon","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/hame%C3%A7on.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.PaJoTirnA6h4F3pH"}},"system":{"description":"","descriptionmj":"","encombrement":0.01,"quantite":1,"qualite":0,"cout":0.1,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206024,"modifiedTime":1669755533751,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"OYWzXiQUFsjU5AF2","name":"Perles de Bjwal","type":"potion","img":"systems/foundryvtt-reve-de-dragon/icons/objets/perles_bjwal.webp","data":{"description":"<p>Petits granulés translucides.</p>","descriptionmj":"","quantite":1,"encombrement":0.1,"rarete":"","categorie":"AlchimieAutre","herbe":"","herbebrins":0,"herbebonus":0,"reposalchimique":false,"pr":0,"prpermanent":false,"prdate":0,"cout":1,"soinherbe":"","soinherbebonus":0},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.OYWzXiQUFsjU5AF2"}}}
|
{"_id":"PkDJ36j7mS3Kfetp","name":"Bouteille de grès (1 litre)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bouteille_gres.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.PkDJ36j7mS3Kfetp"}},"system":{"description":"","descriptionmj":"","encombrement":0.3,"quantite":1,"qualite":0,"cout":0.4,"contenu":[],"capacite":0.5,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206024,"modifiedTime":1669755533744,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"P0yc6QfgKVmM0fpu","name":"Ecuelle de grès","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/ecuelle_gres.webp","data":{"description":"","quantite":1,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":0.1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.P0yc6QfgKVmM0fpu"}}}
|
{"_id":"PrnJrG50u1UPdlJN","name":"Liqueur de Bagdol","type":"potion","img":"systems/foundryvtt-reve-de-dragon/icons/objets/liqueur_de_bagdol.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.PrnJrG50u1UPdlJN"}},"system":{"description":"<p>Fluide. Liquide noir et odorant.</p>","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.5,"rarete":"","categorie":"Alchimie","herbe":"","herbebrins":0,"herbebonus":0,"reposalchimique":false,"pr":0,"prpermanent":false,"prdate":0,"soinherbe":"","soinherbebonus":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206024,"modifiedTime":1669755533752,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"PAqV7Fj8AFEpfEpy","name":"Provisions non-cuites","type":"nourritureboisson","img":"systems/foundryvtt-reve-de-dragon/icons/objets/provision_crue.webp","data":{"description":"","sust":1,"boisson":false,"desaltere":0,"alcoolise":false,"force":0,"qualite":0,"exotisme":0,"encombrement":0.1,"quantite":1,"cout":0.01},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"wYnBx3HmLfGzsj7P":3},"flags":{"core":{"sourceId":"Item.2P30CKBRVIPiTf3Z"}}}
|
{"_id":"PuuPn6WGfU8uBAyb","name":"Robe de soie","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/robe_soie.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.PuuPn6WGfU8uBAyb"}},"system":{"description":"","descriptionmj":"","encombrement":0,"quantite":1,"qualite":0,"cout":10,"equipe":false,"resistance":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206024,"modifiedTime":1669755533756,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"PH2J4zR0hwXSg0vc","name":"Charbon de bois 1 kg","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/charbon.webp","data":{"description":"","quantite":1,"encombrement":0.04,"equipe":false,"resistance":0,"qualite":0,"cout":0.06},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.PH2J4zR0hwXSg0vc"}}}
|
{"_id":"Qh4Tp7lZ6wLnX4w0","name":"Bâton","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/baton.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Qh4Tp7lZ6wLnX4w0"}},"system":{"description":"","descriptionmj":"","equipe":false,"encombrement":2,"quantite":1,"qualite":0,"cout":0.5,"resistance":8,"categorie_parade":"","dommages":"1","penetration":0,"force":"9","competence":"Masse à 2 mains","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"rapide":false,"deuxmains":true,"unemain":false,"initpremierround":"baton"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206024,"modifiedTime":1669755533742,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"PSc92VlQCdNnbPlg","name":"Lance courte","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/lance.webp","data":{"categorie_parade":"lances","description":"","quantite":1,"encombrement":2,"equipe":false,"dommages":"2","penetration":0,"force":"8","resistance":5,"competence":"Lance","cout":3,"portee_courte":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"portee_moyenne":0,"portee_extreme":0,"rapide":true,"deuxmains":false,"unemain":true,"initpremierround":"lance"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.PSc92VlQCdNnbPlg"}}}
|
{"_id":"RKr1ZhTvC6poiNa1","name":"Gros Clou","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/gros_clou.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.RKr1ZhTvC6poiNa1"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.05,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206024,"modifiedTime":1669755533751,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"PaJoTirnA6h4F3pH","name":"Hameçon","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/hame%C3%A7on.webp","data":{"description":"","quantite":1,"encombrement":0.01,"equipe":false,"resistance":0,"qualite":0,"cout":0.1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.PaJoTirnA6h4F3pH"}}}
|
{"_id":"RNxCQWMDy06uQ8uj","name":"Ecuelle de fer","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/ecuelle_fer.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.RNxCQWMDy06uQ8uj"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.15,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206024,"modifiedTime":1669755533747,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"PkDJ36j7mS3Kfetp","name":"Bouteille de grès (1 litre)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bouteille_gres.webp","data":{"description":"","capacite":0.5,"encombrement":0.3,"equipe":false,"qualite":0,"contenu":[],"cout":0.4},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.PkDJ36j7mS3Kfetp"}}}
|
{"_id":"RSni2r8jLccvkc9i","name":"Cristal alchimique","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/cristal_alchimique.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.RSni2r8jLccvkc9i"}},"system":{"description":"","descriptionmj":"","encombrement":0.09,"quantite":1,"qualite":0,"cout":4,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206024,"modifiedTime":1669755533746,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"PrnJrG50u1UPdlJN","name":"Liqueur de Bagdol","type":"potion","img":"systems/foundryvtt-reve-de-dragon/icons/objets/liqueur_de_bagdol.webp","data":{"description":"<p>Fluide. Liquide noir et odorant.</p>","quantite":1,"encombrement":0.1,"rarete":"","categorie":"Alchimie","herbe":"","herbebrins":0,"herbebonus":0,"reposalchimique":false,"pr":0,"prpermanent":false,"prdate":0,"cout":0.5,"soinherbe":"","soinherbebonus":0},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.PrnJrG50u1UPdlJN"}}}
|
{"_id":"RWYaq8tnpgrkh5ED","name":"Flacon de grès (40 cl)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/flacon_gres1.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.RWYaq8tnpgrkh5ED"}},"system":{"description":"","descriptionmj":"","encombrement":0.2,"quantite":1,"qualite":0,"cout":0.15,"contenu":[],"capacite":0.2,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206025,"modifiedTime":1669755533749,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"PuuPn6WGfU8uBAyb","name":"Robe de soie","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/robe_soie.webp","data":{"description":"","quantite":1,"encombrement":0,"equipe":false,"resistance":0,"qualite":0,"cout":10},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"jOzRscDxoXZWpGS6":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.PuuPn6WGfU8uBAyb"}}}
|
{"_id":"Reqo8GC9p7GI9k9N","name":"Chope de grès (20 cl)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/chope_gres.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Reqo8GC9p7GI9k9N"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.1,"contenu":[],"capacite":0.1,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206025,"modifiedTime":1669755533745,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"Qh4Tp7lZ6wLnX4w0","name":"Bâton","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/baton.webp","data":{"categorie_parade":"","description":"","quantite":1,"encombrement":2,"equipe":false,"dommages":"1","penetration":0,"force":"9","resistance":8,"competence":"Masse à 2 mains","cout":0.5,"portee_courte":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"portee_moyenne":0,"portee_extreme":0,"rapide":false,"deuxmains":true,"unemain":false,"initpremierround":"baton"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Qh4Tp7lZ6wLnX4w0"}}}
|
{"_id":"Ri5QtS98FTfgHk2N","name":"Javeline","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/javeline.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Ri5QtS98FTfgHk2N"}},"system":{"description":"","descriptionmj":"","equipe":false,"encombrement":1,"quantite":1,"qualite":0,"cout":1,"resistance":5,"categorie_parade":"lances","dommages":"1","penetration":0,"force":"7","competence":"Lance","lancer":"Javelot","tir":"","portee_courte":6,"portee_moyenne":12,"portee_extreme":20,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"rapide":true,"deuxmains":false,"unemain":true,"initpremierround":"hast"},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206025,"modifiedTime":1669755533752,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"RKr1ZhTvC6poiNa1","name":"Gros Clou","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/gros_clou.webp","data":{"description":"","quantite":1,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":0.05},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.RKr1ZhTvC6poiNa1"}}}
|
{"_id":"Ro5cOOtLLB0lMlzl","name":"Javelot","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/objets/javelot.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Ro5cOOtLLB0lMlzl"}},"system":{"description":"<p>Chaque point de force au dessus de 10 augmente les portées de 1m.</p>\n<p>Chaque point de force en dessous de 9 diminue les portées de 1m.</p>","descriptionmj":"","equipe":false,"encombrement":1,"quantite":1,"qualite":0,"cout":1,"resistance":0,"categorie_parade":"lances","dommages":"1","penetration":0,"force":"0","competence":"Lance","lancer":"Javelot","tir":"","portee_courte":6,"portee_moyenne":12,"portee_extreme":20,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"rapide":true,"deuxmains":false,"unemain":true,"initpremierround":"hast"},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206025,"modifiedTime":1669755533752,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"RNxCQWMDy06uQ8uj","name":"Ecuelle de fer","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/ecuelle_fer.webp","data":{"description":"","quantite":1,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":0.15},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.RNxCQWMDy06uQ8uj"}}}
|
{"_id":"RyW0z9Y5UeZSYjFZ","name":"Savon 500g","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/savon.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.RyW0z9Y5UeZSYjFZ"}},"system":{"description":"","descriptionmj":"","encombrement":0.2,"quantite":1,"qualite":0,"cout":0.2,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206025,"modifiedTime":1669755533757,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"RSni2r8jLccvkc9i","name":"Cristal alchimique","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/cristal_alchimique.webp","data":{"description":"","quantite":1,"encombrement":0.09,"equipe":false,"resistance":0,"qualite":0,"cout":4},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.RSni2r8jLccvkc9i"}}}
|
{"_id":"S3bLtbXe6BzEFCjt","name":"Plaques de Fer","type":"armure","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/armure_plaques.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.S3bLtbXe6BzEFCjt"}},"system":{"description":"<p>L'armure classique du chevalier. Armure complète de plaques (heaume, cuirasse, épaulières, cubitières, ventrière, cuissards, jambières).</p>\n<p> </p>","descriptionmj":"","equipe":false,"encombrement":8,"quantite":1,"qualite":0,"cout":100,"protection":6,"deterioration":0,"malus":-6},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206026,"modifiedTime":1669755533755,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"RWYaq8tnpgrkh5ED","name":"Flacon de grès (40 cl)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/flacon_gres1.webp","data":{"description":"","capacite":0.2,"encombrement":0.2,"equipe":false,"qualite":0,"contenu":[],"cout":0.15},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.RWYaq8tnpgrkh5ED"}}}
|
{"_id":"SZyBQbInuUGASlGb","name":"Tambourin","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/tambourin.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.SZyBQbInuUGASlGb"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.5,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206026,"modifiedTime":1669755533757,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"Reqo8GC9p7GI9k9N","name":"Chope de grès (20 cl)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/chope_gres.webp","data":{"description":"","capacite":0.1,"encombrement":0.1,"equipe":false,"qualite":0,"contenu":[],"cout":0.1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Reqo8GC9p7GI9k9N"}}}
|
{"_id":"Sm28dG9isppoQzPQ","name":"Bas de lin","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bas_lin.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Sm28dG9isppoQzPQ"}},"system":{"description":"","descriptionmj":"","encombrement":0,"quantite":1,"qualite":0,"cout":0.3,"equipe":false,"resistance":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206026,"modifiedTime":1669755533742,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"Ri5QtS98FTfgHk2N","name":"Javeline","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/javeline.webp","data":{"categorie_parade":"lances","description":"","quantite":1,"encombrement":1,"equipe":false,"dommages":"1","penetration":0,"force":"7","resistance":5,"competence":"Lance","cout":1,"portee_courte":0,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"portee_moyenne":0,"portee_extreme":0,"rapide":true,"deuxmains":false,"unemain":true,"initpremierround":""},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Ri5QtS98FTfgHk2N"}}}
|
{"_id":"SrV0r5hnGdKeSIHR","name":"Cuillère de bois","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/cuillere_bois.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.SrV0r5hnGdKeSIHR"}},"system":{"description":"","descriptionmj":"","encombrement":0.03,"quantite":1,"qualite":0,"cout":0.03,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206026,"modifiedTime":1669755533746,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"Ro5cOOtLLB0lMlzl","name":"Javelot","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/objets/javelot.webp","data":{"categorie_parade":"lances","description":"<p>Chaque point de force au dessus de 10 augmente les portées de 1m.</p>\n<p>Chaque point de force en dessous de 9 diminue les portées de 1m.</p>","quantite":1,"encombrement":1,"equipe":false,"dommages":"1","penetration":0,"force":"0","resistance":0,"competence":"Javelot","cout":1,"portee_courte":6,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"portee_moyenne":12,"portee_extreme":20,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":""},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Ro5cOOtLLB0lMlzl"}}}
|
{"_id":"SsnGNjTekvB50uWa","name":"Chapeau de cuir souple","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/chapeau_cuir.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.SsnGNjTekvB50uWa"}},"system":{"description":"","descriptionmj":"","encombrement":0.08,"quantite":1,"qualite":0,"cout":0.5,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206026,"modifiedTime":1669755533744,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"RyW0z9Y5UeZSYjFZ","name":"Savon 500g","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/savon.webp","data":{"description":"","quantite":1,"encombrement":0.2,"equipe":false,"resistance":0,"qualite":0,"cout":0.2},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.RyW0z9Y5UeZSYjFZ"}}}
|
{"_id":"TKsUXJq9w7ezcFGQ","name":"Hache de bataille","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/hache_bataille.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.TKsUXJq9w7ezcFGQ"}},"system":{"description":"","descriptionmj":"","equipe":false,"encombrement":2,"quantite":1,"qualite":0,"cout":15,"resistance":8,"categorie_parade":"haches","dommages":"3/4","penetration":0,"force":"12/11","competence":"Hache à 1 main","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"rapide":false,"deuxmains":true,"unemain":true,"initpremierround":"hachebataille"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206026,"modifiedTime":1669755533751,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"S3bLtbXe6BzEFCjt","name":"Plaques de Fer","type":"armure","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/armure_plaques.webp","data":{"description":"<p>L'armure classique du chevalier. Armure complète de plaques (heaume, cuirasse, épaulières, cubitières, ventrière, cuissards, jambières).</p>\n<p> </p>","quantite":1,"encombrement":8,"equipe":false,"protection":6,"deterioration":0,"malus":-6,"cout":100},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.S3bLtbXe6BzEFCjt"}}}
|
{"_id":"TY6Ft8a6WfxD6pD9","name":"Bobineau de fil","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bobineau.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.TY6Ft8a6WfxD6pD9"}},"system":{"description":"","descriptionmj":"","encombrement":0.01,"quantite":1,"qualite":0,"cout":0.1,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206026,"modifiedTime":1669755533742,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"SZyBQbInuUGASlGb","name":"Tambourin","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/tambourin.webp","data":{"description":"","quantite":1,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":0.5},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.SZyBQbInuUGASlGb"}}}
|
{"_id":"UDmq6CY3NsttcHe4","name":"Peigne en corne","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/peigne.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.UDmq6CY3NsttcHe4"}},"system":{"description":"","descriptionmj":"","encombrement":0.04,"quantite":1,"qualite":0,"cout":0.4,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206026,"modifiedTime":1669755533754,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"Sm28dG9isppoQzPQ","name":"Bas de lin","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bas_lin.webp","data":{"description":"","quantite":1,"encombrement":0,"equipe":false,"resistance":0,"qualite":0,"cout":0.3},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"jOzRscDxoXZWpGS6":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Sm28dG9isppoQzPQ"}}}
|
{"_id":"UE79xKWXTwYAn70K","name":"Arme d’hast","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/hast.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.UE79xKWXTwYAn70K"}},"system":{"description":"","descriptionmj":"","equipe":false,"encombrement":4,"quantite":1,"qualite":0,"cout":10,"resistance":8,"categorie_parade":"hast","dommages":"4","penetration":0,"force":"12","competence":"Armes d'hast","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"rapide":false,"deuxmains":true,"unemain":false,"initpremierround":"hast"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206026,"modifiedTime":1669755533740,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"SrV0r5hnGdKeSIHR","name":"Cuillère de bois","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/cuillere_bois.webp","data":{"description":"","quantite":1,"encombrement":0.03,"equipe":false,"resistance":0,"qualite":0,"cout":0.03},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.SrV0r5hnGdKeSIHR"}}}
|
{"_id":"UICiMF3wBeLsqm8L","name":"Pipe en bois","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/pipe.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.UICiMF3wBeLsqm8L"}},"system":{"description":"","descriptionmj":"","encombrement":0.04,"quantite":1,"qualite":0,"cout":0.1,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206026,"modifiedTime":1669755533755,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"SsnGNjTekvB50uWa","name":"Chapeau de cuir souple","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/chapeau_cuir.webp","data":{"description":"","quantite":1,"encombrement":0.08,"equipe":false,"resistance":0,"qualite":0,"cout":0.5},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.SsnGNjTekvB50uWa"}}}
|
{"_id":"UMfXFhVhdoVQVEKy","name":"Fronde","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/objets/fronde.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.UMfXFhVhdoVQVEKy"}},"system":{"description":"<p>Peut tirer tous les rounds.</p>","descriptionmj":"","equipe":false,"encombrement":0.08,"quantite":1,"qualite":0,"cout":0.6,"resistance":0,"categorie_parade":"","dommages":"1","penetration":0,"force":"0","competence":"","lancer":"","tir":"Fronde","portee_courte":8,"portee_moyenne":15,"portee_extreme":25,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206026,"modifiedTime":1669755533749,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"TKsUXJq9w7ezcFGQ","name":"Hache de bataille","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/hache_bataille.webp","data":{"categorie_parade":"haches","description":"","quantite":1,"encombrement":2,"equipe":false,"dommages":"3/4","penetration":0,"force":"12/11","resistance":8,"competence":"Hache à 1 main","cout":15,"portee_courte":0,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"portee_moyenne":0,"portee_extreme":0,"rapide":false,"deuxmains":true,"unemain":true,"initpremierround":"hachebataille"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.TKsUXJq9w7ezcFGQ"}}}
|
{"_id":"UYXXggulNwnodaOt","name":"Chope de fer (20 cl)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/chope_fer.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.UYXXggulNwnodaOt"}},"system":{"description":"","descriptionmj":"","encombrement":0.08,"quantite":1,"qualite":0,"cout":0.15,"contenu":[],"capacite":0.1,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206027,"modifiedTime":1669755533745,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"TY6Ft8a6WfxD6pD9","name":"Bobineau de fil","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bobineau.webp","data":{"description":"","quantite":1,"encombrement":0.01,"equipe":false,"resistance":0,"qualite":0,"cout":0.1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.TY6Ft8a6WfxD6pD9"}}}
|
{"_id":"UczsYTAoP9koA2SL","name":"Bourse, sachet de tissu","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bourse_sachet.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.UczsYTAoP9koA2SL"}},"system":{"description":"","descriptionmj":"","encombrement":0.01,"quantite":1,"qualite":0,"cout":0.05,"contenu":[],"capacite":0.3,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206107,"modifiedTime":1669755533744,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"UDmq6CY3NsttcHe4","name":"Peigne en corne","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/peigne.webp","data":{"description":"","quantite":1,"encombrement":0.04,"equipe":false,"resistance":0,"qualite":0,"cout":0.4},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.UDmq6CY3NsttcHe4"}}}
|
{"_id":"UsyV9n0byCeYirNC","name":"Esparlongue","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/esparlongue.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.UsyV9n0byCeYirNC"}},"system":{"description":"<p>C’est une épée semblable à la <em>rapière</em>, longue et ne frappant uniquement d’estoc. Elle doit son nom à ce qu’elle était particulièrement en vogue, au Second Âge, dans la cité d’Esparlongue. En ce début du Troisième Âge, toutefois, on lui substitue le plus souvent la <strong>demi-dragonne</strong>, épée très voisine, ne frappant pareillement que d’estoc, mais plus résistante (résistance 10) et moins coûteuse (15 sols) ; son bonus aux dommages (+2) est identique.</p>","descriptionmj":"","equipe":false,"encombrement":1.5,"quantite":1,"qualite":0,"cout":20,"resistance":9,"categorie_parade":"epees-longues","dommages":"2","penetration":0,"force":"10","competence":"Epée à 1 main","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"rapide":true,"deuxmains":false,"unemain":true,"initpremierround":"esparlongue"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206107,"modifiedTime":1669755533748,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"UE79xKWXTwYAn70K","name":"Arme d’hast","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/hast.webp","data":{"categorie_parade":"hast","description":"","quantite":1,"encombrement":4,"equipe":false,"dommages":"4","penetration":0,"force":"12","resistance":8,"competence":"Armes d'hast","cout":10,"portee_courte":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"portee_moyenne":0,"portee_extreme":0,"rapide":false,"deuxmains":true,"unemain":false,"initpremierround":"hast"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.UE79xKWXTwYAn70K"}}}
|
{"_id":"Uxk2tvEqtrmYScjK","name":"Pot à braise","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/pot_a_braise.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Uxk2tvEqtrmYScjK"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.2,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206107,"modifiedTime":1669755533756,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"UICiMF3wBeLsqm8L","name":"Pipe en bois","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/pipe.webp","data":{"description":"","quantite":1,"encombrement":0.04,"equipe":false,"resistance":0,"qualite":0,"cout":0.1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.UICiMF3wBeLsqm8L"}}}
|
{"_id":"VsjRwh9Z9PMpFKdI","name":"Craie 1 bâton","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/craie.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.VsjRwh9Z9PMpFKdI"}},"system":{"description":"","descriptionmj":"","encombrement":0.01,"quantite":1,"qualite":0,"cout":0.01,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206107,"modifiedTime":1669755533746,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"UMfXFhVhdoVQVEKy","name":"Fronde","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/objets/fronde.webp","data":{"categorie_parade":"","description":"<p>Peut tirer tous les rounds.</p>","quantite":1,"encombrement":0.08,"equipe":false,"dommages":"1","penetration":0,"force":"0","resistance":0,"competence":"Fronde","cout":0.6,"portee_courte":8,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"portee_moyenne":15,"portee_extreme":25,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":""},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.UMfXFhVhdoVQVEKy"}}}
|
{"_id":"WC1jMDKcxEJQWGOR","name":"Burette de fer blanc (40 cl)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/burette.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.WC1jMDKcxEJQWGOR"}},"system":{"description":"","descriptionmj":"","encombrement":0.2,"quantite":1,"qualite":0,"cout":0.5,"contenu":[],"capacite":0.2,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206107,"modifiedTime":1669755533744,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"UYXXggulNwnodaOt","name":"Chope de fer (20 cl)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/chope_fer.webp","data":{"description":"","capacite":0.1,"encombrement":0.08,"equipe":false,"qualite":0,"contenu":[],"cout":0.15},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.UYXXggulNwnodaOt"}}}
|
{"_id":"WTHZdtgf6lHUSKDx","name":"Fouet","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/objets/fouet.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.WTHZdtgf6lHUSKDx"}},"system":{"description":"<p>Provoque des dégâts \"non mortels\".</p>\n<p>Les armures sont majorées de 2.</p>\n<p>Si la protection atteint une valeur de 5 ou plus, le fouet ne peut causer de dégât.</p>","descriptionmj":"","equipe":false,"encombrement":0.5,"quantite":1,"qualite":0,"cout":1,"resistance":0,"categorie_parade":"","dommages":"1","penetration":-1,"force":"0","competence":"","lancer":"Fouet","tir":"","portee_courte":2,"portee_moyenne":2,"portee_extreme":3,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":"hast"},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206107,"modifiedTime":1669755533749,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"UczsYTAoP9koA2SL","name":"Bourse, sachet de tissu","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bourse_sachet.webp","data":{"description":"","capacite":0.3,"encombrement":0.01,"equipe":false,"qualite":0,"contenu":[],"cout":0.05},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.UczsYTAoP9koA2SL"}}}
|
{"_id":"WTWXZeoK5HpCrGFy","name":"Hachette","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/objets/hachette.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.WTWXZeoK5HpCrGFy"}},"system":{"description":"","descriptionmj":"","equipe":false,"encombrement":1,"quantite":1,"qualite":0,"cout":4,"resistance":6,"categorie_parade":"haches","dommages":"2","penetration":0,"force":"8","competence":"Hache à 1 main","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":"dague"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206107,"modifiedTime":1669755533751,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"UsyV9n0byCeYirNC","name":"Esparlongue","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/esparlongue.webp","data":{"categorie_parade":"epees-longues","description":"<p>C’est une épée semblable à la <em>rapière</em>, longue et ne frappant uniquement d’estoc. Elle doit son nom à ce qu’elle était particulièrement en vogue, au Second Âge, dans la cité d’Esparlongue. En ce début du Troisième Âge, toutefois, on lui substitue le plus souvent la <strong>demi-dragonne</strong>, épée très voisine, ne frappant pareillement que d’estoc, mais plus résistante (résistance 10) et moins coûteuse (15 sols) ; son bonus aux dommages (+2) est identique.</p>","quantite":1,"encombrement":1.5,"equipe":false,"dommages":"2","penetration":0,"force":"10","resistance":9,"competence":"Epée à 1 main","cout":20,"portee_courte":0,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"portee_moyenne":0,"portee_extreme":0,"rapide":true,"deuxmains":false,"unemain":true,"initpremierround":"esparlongue"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.UsyV9n0byCeYirNC"}}}
|
{"_id":"XTZVrcMNofAviP63","name":"Cire d'abeille 500g","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/cire.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.XTZVrcMNofAviP63"}},"system":{"description":"","descriptionmj":"","encombrement":0.2,"quantite":1,"qualite":0,"cout":0.15,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206108,"modifiedTime":1669755533745,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"Uxk2tvEqtrmYScjK","name":"Pot à braise","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/pot_a_braise.webp","data":{"description":"","quantite":1,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":0.2},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Uxk2tvEqtrmYScjK"}}}
|
{"_id":"XlKp5BvZX8A03fUg","name":"Sac à dos de cuir","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/sac_a_dos.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.XlKp5BvZX8A03fUg"}},"system":{"description":"","descriptionmj":"","encombrement":0.4,"quantite":1,"qualite":0,"cout":1,"contenu":[],"capacite":25,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206108,"modifiedTime":1669755533756,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"VsjRwh9Z9PMpFKdI","name":"Craie 1 bâton","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/craie.webp","data":{"description":"","quantite":1,"encombrement":0.01,"equipe":false,"resistance":0,"qualite":0,"cout":0.01},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.VsjRwh9Z9PMpFKdI"}}}
|
{"_id":"XoslLyWIJYY2RGzz","name":"Fiole de verre (20 cl)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/fiole_verre.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.XoslLyWIJYY2RGzz"}},"system":{"description":"","descriptionmj":"","encombrement":0.06,"quantite":1,"qualite":0,"cout":0.2,"contenu":[],"capacite":0.1,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206108,"modifiedTime":1669755533749,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"WC1jMDKcxEJQWGOR","name":"Burette de fer blanc (40 cl)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/burette.webp","data":{"description":"","capacite":0.2,"encombrement":0.2,"equipe":false,"qualite":0,"contenu":[],"cout":0.5},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.WC1jMDKcxEJQWGOR"}}}
|
{"_id":"XwuLVGasPJXzvC09","name":"Encre 20 cl","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/encre_20cl.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.XwuLVGasPJXzvC09"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.1,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206108,"modifiedTime":1669755533747,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"WTHZdtgf6lHUSKDx","name":"Fouet","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/objets/fouet.webp","data":{"categorie_parade":"","description":"<p>Provoque des dégâts \"non mortels\".</p>\n<p>Les armures sont majorées de 2.</p>\n<p>Si la protection atteint une valeur de 5 ou plus, le fouet ne peut causer de dégât.</p>","quantite":1,"encombrement":0.5,"equipe":false,"dommages":"1","penetration":0,"force":"0","resistance":0,"competence":"Fouet","cout":1,"portee_courte":2,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"portee_moyenne":null,"portee_extreme":null,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":""},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.WTHZdtgf6lHUSKDx"}}}
|
{"_id":"YHPrUuGGGTGZMNAg","name":"Bière","type":"nourritureboisson","img":"systems/foundryvtt-reve-de-dragon/icons/liquides/liquide_biere.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Item.u7lMLkVlFCXBj8Bc"}},"system":{"description":"<p>1 mesure (20cl) de bière.</p>","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.01,"sust":0,"boisson":true,"desaltere":0.8,"alcoolise":true,"force":-1,"exotisme":0,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206108,"modifiedTime":1669755533742,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"WTWXZeoK5HpCrGFy","name":"Hachette","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/objets/hachette.webp","data":{"categorie_parade":"haches","description":"","quantite":1,"encombrement":1,"equipe":false,"dommages":"2","penetration":0,"force":"8","resistance":6,"competence":"Hache à 1 main","cout":4,"portee_courte":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"portee_moyenne":0,"portee_extreme":0,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":"dague"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.WTWXZeoK5HpCrGFy"}}}
|
{"_id":"YNbbSGLnexiXNyXU","name":"Manteau de laine","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/manteau_laine.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.YNbbSGLnexiXNyXU"}},"system":{"description":"","descriptionmj":"","encombrement":0.8,"quantite":1,"qualite":0,"cout":0.6,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206108,"modifiedTime":1669755533753,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"XTZVrcMNofAviP63","name":"Cire d'abeille 500g","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/cire.webp","data":{"description":"","quantite":1,"encombrement":0.2,"equipe":false,"resistance":0,"qualite":0,"cout":0.15},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.XTZVrcMNofAviP63"}}}
|
{"_id":"Yh7VGX3BikmIjVQH","name":"Gourdin","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/gourdin.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Yh7VGX3BikmIjVQH"}},"system":{"description":"","descriptionmj":"","equipe":false,"encombrement":1,"quantite":1,"qualite":0,"cout":0,"resistance":8,"categorie_parade":"","dommages":"1","penetration":0,"force":"7","competence":"Masse à 1 main","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"rapide":true,"deuxmains":false,"unemain":true,"initpremierround":"gourdin"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206108,"modifiedTime":1669755533750,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"XlKp5BvZX8A03fUg","name":"Sac à dos de cuir","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/sac_a_dos.webp","data":{"description":"","capacite":25,"encombrement":0.4,"equipe":false,"qualite":0,"contenu":[],"cout":1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.XlKp5BvZX8A03fUg"}}}
|
{"_id":"Yyn39VDRnO6oA3Uq","name":"Echecs draconics en bois","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/echecs.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Yyn39VDRnO6oA3Uq"}},"system":{"description":"","descriptionmj":"","encombrement":0.5,"quantite":1,"qualite":0,"cout":2,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206108,"modifiedTime":1669755533747,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"XoslLyWIJYY2RGzz","name":"Fiole de verre (20 cl)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/fiole_verre.webp","data":{"description":"","capacite":0.1,"encombrement":0.06,"equipe":false,"qualite":0,"contenu":[],"cout":0.2},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.XoslLyWIJYY2RGzz"}}}
|
{"_id":"Z0ij7qpoYeWMVocP","name":"Ceinturon de cuir","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/ceinturon.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Z0ij7qpoYeWMVocP"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.5,"contenu":[],"capacite":6,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206108,"modifiedTime":1669755533744,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"XwuLVGasPJXzvC09","name":"Encre 20 cl","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/encre_20cl.webp","data":{"description":"","quantite":1,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":0.1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.XwuLVGasPJXzvC09"}}}
|
{"_id":"ZLda3pfrbiKucSea","name":"Cornebouffe","type":"nourritureboisson","img":"systems/foundryvtt-reve-de-dragon/icons/objets/cornebouffe.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Item.NuwD0kiJyoqevKib"}},"system":{"description":"<p><span class=\"fontstyle0\">La cornebouffe est une préparation à base de gibier, élaborée dans les forêts proches de la mer par des chasseurs spécialisés : les </span><span class=\"fontstyle2\">cornebouffiers</span><span class=\"fontstyle0\">. Acheminée vers les ports, principaux consommateurs, elle constitue l’aliment de base de la plupart des marins.</span></p>\n<p><span class=\"fontstyle0\">Certains voyageurs qui l’ont expérimentée et en ont accepté l’exotisme, en transportent parfois en cas de disette. Pratiquement, il s’agit de gibier référentiellement cornu (bramart, cornicochon, mercureuil), que l’on cuit et recuit dans de l’eau de mer avec des herbes, jusqu’à obtenir une pâte, sorte de mastic, que l’on façonne en forme de galettes, puis que l’on laisse longuement sécher au soleil. On aboutit au final à des sortes de petites briques plates, de la taille d’une demi-main, de couleur vert-de-gris, et à peu près aussi dures que les briques véritables. La meilleure façon de consommer ces galettes est de les réhydrater avec de l’eau chaude, c’est la façon dite </span><span class=\"fontstyle2\">soupée </span><span class=\"fontstyle0\">: on obtient une sorte de soupe ou de bouillie gluante. L’autre façon, dite sèche, consiste à les grignoter telles quelles comme des biscuits, mais il est impératif de boire beaucoup par dessus, sous peine d’une soif torride accompagnée de maux d’estomac.</span></p>\n<p><span class=\"fontstyle0\">Légère, peu encombrante, et surtout nourrissante, une galette de cornebouffe suffit pour un repas. Quant au goût, eh bien... ceux qui disent que, tant qu’à y aller, autant manger directement des crottes de chien à la croque-au-sel, ne sont probablement que des enfants gâtés et difficiles.</span></p>\n<p><span class=\"fontstyle0\">Aliment de longue conservation (pratiquement inaltérable), la cornebouffe possède un des meilleurs rapports sustentation/encombrement.</span></p>","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.02,"sust":3,"boisson":false,"desaltere":0,"alcoolise":false,"force":0,"exotisme":-2,"equipe":false,"resistance":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206108,"modifiedTime":1669755533746,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"YHPrUuGGGTGZMNAg","name":"Bière","type":"nourritureboisson","img":"systems/foundryvtt-reve-de-dragon/icons/liquides/liquide_biere.webp","data":{"description":"<p>1 mesure (20cl) de bière.</p>","sust":0,"boisson":true,"desaltere":0.8,"alcoolise":true,"force":-1,"qualite":0,"exotisme":0,"encombrement":0.1,"quantite":1,"cout":0.01,"equipe":false},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Item.u7lMLkVlFCXBj8Bc"}}}
|
{"_id":"ZaAKf4n8mtevbMM0","name":"Hydromel","type":"nourritureboisson","img":"systems/foundryvtt-reve-de-dragon/icons/liquides/liquide_biere.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.ZaAKf4n8mtevbMM0"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.04,"sust":0,"boisson":true,"desaltere":0.6,"alcoolise":true,"force":-4,"exotisme":0},"ownership":{"default":0,"wYnBx3HmLfGzsj7P":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206109,"modifiedTime":1669755533752,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"YNHDt4EerstJvx5l","name":"Le Principe Drachromatique","type":"livre","img":"systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp","data":{"description":"<p>Cet ouvrage de profonde érudition sur l’origine des couleurs et leur signification onirique est foncièrement incompréhensible, à moins de posséder un minimum de +4 en voie d’Oniros. Il permet d’envisager la synthèse des sorts d’<em>Invulnérabilité Chromatique</em> et de <em>Transmutation Chromatique</em>. Sans son assimilation préalable, la synthèse de ces sorts est totalement inenvisageable. Sa difficulté de lecture est de -4, son assimilation requiert 26 points de tâche, périodicité 1 heure.</p>","competence":"","auteur":"Anonyme","quantite":1,"difficulte":-4,"points_de_tache":26,"encombrement":0,"xp":"","niveau_minimum":0,"niveau_maximum":0,"cout":0},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"jOzRscDxoXZWpGS6":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.YNHDt4EerstJvx5l"}}}
|
{"_id":"a3Wj2WNKFrzqRGVG","name":"Chemise de soie","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/chemise_soie.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.a3Wj2WNKFrzqRGVG"}},"system":{"description":"","descriptionmj":"","encombrement":0,"quantite":1,"qualite":0,"cout":6,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206109,"modifiedTime":1669755533745,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"YNbbSGLnexiXNyXU","name":"Manteau de laine","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/manteau_laine.webp","data":{"description":"","quantite":1,"encombrement":0.8,"equipe":false,"resistance":0,"qualite":0,"cout":0.6},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.YNbbSGLnexiXNyXU"}}}
|
{"_id":"b0f08L5CDeFIMluC","name":"Cuir Souple","type":"armure","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/cuir_souple.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.b0f08L5CDeFIMluC"}},"system":{"description":"<p>Même épaisseur que nos modernes blousons de cuir. Pourpoint ou cotte de cuir souple + culottes de cuir souple + bottes de cuir souple.</p>\n<p> </p>","descriptionmj":"","equipe":false,"encombrement":0,"quantite":1,"qualite":0,"cout":6,"protection":2,"deterioration":0,"malus":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206109,"modifiedTime":1669755533747,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"Yh7VGX3BikmIjVQH","name":"Gourdin","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/gourdin.webp","data":{"categorie_parade":"","description":"","quantite":1,"encombrement":1,"equipe":false,"dommages":"1","penetration":0,"force":"7","resistance":8,"competence":"Masse à 1 main","cout":0,"portee_courte":0,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"portee_moyenne":0,"portee_extreme":0,"rapide":true,"deuxmains":false,"unemain":true,"initpremierround":"gourdin"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Yh7VGX3BikmIjVQH"}}}
|
{"_id":"bA0JDA7awoWhu0vO","name":"Teinture d'Erozonne","type":"potion","img":"systems/foundryvtt-reve-de-dragon/icons/objets/teinture_erozonne.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.bA0JDA7awoWhu0vO"}},"system":{"description":"<p>Fluide. </p>\n<p>Liquide rosâtre.</p>","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":2,"rarete":"","categorie":"Alchimie","herbe":"","herbebrins":0,"herbebonus":0,"reposalchimique":false,"pr":0,"prpermanent":false,"prdate":0,"soinherbe":"","soinherbebonus":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206109,"modifiedTime":1669755533757,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"Yyn39VDRnO6oA3Uq","name":"Echecs draconics en bois","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/echecs.webp","data":{"description":"","quantite":1,"encombrement":0.5,"equipe":false,"resistance":0,"qualite":0,"cout":2},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Yyn39VDRnO6oA3Uq"}}}
|
{"_id":"beQ9d4QQwZDQl5NA","name":"Flûte à bec","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/flute_bec.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.beQ9d4QQwZDQl5NA"}},"system":{"description":"","descriptionmj":"","encombrement":0.09,"quantite":1,"qualite":0,"cout":1,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206109,"modifiedTime":1669755533749,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"Z0ij7qpoYeWMVocP","name":"Ceinturon de cuir","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/ceinturon.webp","data":{"description":"","capacite":6,"encombrement":0.1,"equipe":false,"qualite":0,"contenu":[],"cout":0.5},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Z0ij7qpoYeWMVocP"}}}
|
{"_id":"bgkEBYUEFLvAaeVf","name":"Luth, viole","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/luth.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.bgkEBYUEFLvAaeVf"}},"system":{"description":"","descriptionmj":"","encombrement":1,"quantite":1,"qualite":0,"cout":7,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206109,"modifiedTime":1669755533753,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"ZLda3pfrbiKucSea","name":"Cornebouffe","type":"nourritureboisson","img":"systems/foundryvtt-reve-de-dragon/icons/objets/cornebouffe.webp","data":{"description":"<p><span class=\"fontstyle0\">La cornebouffe est une préparation à base de gibier, élaborée dans les forêts proches de la mer par des chasseurs spécialisés : les </span><span class=\"fontstyle2\">cornebouffiers</span><span class=\"fontstyle0\">. Acheminée vers les ports, principaux consommateurs, elle constitue l’aliment de base de la plupart des marins.</span></p>\n<p><span class=\"fontstyle0\">Certains voyageurs qui l’ont expérimentée et en ont accepté l’exotisme, en transportent parfois en cas de disette. Pratiquement, il s’agit de gibier référentiellement cornu (bramart, cornicochon, mercureuil), que l’on cuit et recuit dans de l’eau de mer avec des herbes, jusqu’à obtenir une pâte, sorte de mastic, que l’on façonne en forme de galettes, puis que l’on laisse longuement sécher au soleil. On aboutit au final à des sortes de petites briques plates, de la taille d’une demi-main, de couleur vert-de-gris, et à peu près aussi dures que les briques véritables. La meilleure façon de consommer ces galettes est de les réhydrater avec de l’eau chaude, c’est la façon dite </span><span class=\"fontstyle2\">soupée </span><span class=\"fontstyle0\">: on obtient une sorte de soupe ou de bouillie gluante. L’autre façon, dite sèche, consiste à les grignoter telles quelles comme des biscuits, mais il est impératif de boire beaucoup par dessus, sous peine d’une soif torride accompagnée de maux d’estomac.</span></p>\n<p><span class=\"fontstyle0\">Légère, peu encombrante, et surtout nourrissante, une galette de cornebouffe suffit pour un repas. Quant au goût, eh bien... ceux qui disent que, tant qu’à y aller, autant manger directement des crottes de chien à la croque-au-sel, ne sont probablement que des enfants gâtés et difficiles.</span></p>\n<p><span class=\"fontstyle0\">Aliment de longue conservation (pratiquement inaltérable), la cornebouffe possède un des meilleurs rapports sustentation/encombrement.</span></p>","sust":3,"boisson":false,"desaltere":0,"alcoolise":false,"force":0,"qualite":0,"exotisme":-2,"encombrement":0.1,"quantite":1,"cout":0.02,"equipe":false,"resistance":0},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"flags":{"core":{"sourceId":"Item.NuwD0kiJyoqevKib"}}}
|
{"_id":"cVZbnh5cYxBx6P5b","name":"Burin, gouge, ciseau","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/gouge.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.cVZbnh5cYxBx6P5b"}},"system":{"description":"","descriptionmj":"","encombrement":0.2,"quantite":1,"qualite":0,"cout":0.3,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206109,"modifiedTime":1669755533744,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"ZaAKf4n8mtevbMM0","name":"Hydromel","type":"nourritureboisson","img":"systems/foundryvtt-reve-de-dragon/icons/liquides/liquide_biere.webp","data":{"description":"","sust":0,"boisson":true,"desaltere":0.6,"alcoolise":true,"force":-4,"qualite":0,"exotisme":0,"encombrement":0.1,"quantite":1,"cout":0.04},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"wYnBx3HmLfGzsj7P":3},"flags":{}}
|
{"_id":"ckKnviu9SHvWgya0","name":"Bougie de cire (2 heures)","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bougie.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.ckKnviu9SHvWgya0"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.05,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206109,"modifiedTime":1669755533743,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"a3Wj2WNKFrzqRGVG","name":"Chemise de soie","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/chemise_soie.webp","data":{"description":"","quantite":1,"encombrement":0,"equipe":false,"resistance":0,"qualite":0,"cout":6},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.a3Wj2WNKFrzqRGVG"}}}
|
{"_id":"cobfvOmFpti5lJuK","name":"Chemise de lin","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/chemise_lin.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.cobfvOmFpti5lJuK"}},"system":{"description":"","descriptionmj":"","encombrement":0,"quantite":1,"qualite":0,"cout":0.3,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206109,"modifiedTime":1669755533745,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"b0f08L5CDeFIMluC","name":"Cuir Souple","type":"armure","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/cuir_souple.webp","data":{"description":"<p>Même épaisseur que nos modernes blousons de cuir. Pourpoint ou cotte de cuir souple + culottes de cuir souple + bottes de cuir souple.</p>\n<p> </p>","quantite":1,"encombrement":0,"equipe":false,"protection":2,"deterioration":0,"malus":0,"cout":6},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.b0f08L5CDeFIMluC"}}}
|
{"_id":"dBR6KXvfmjjIcwsc","name":"Pilon en marbre","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/pilon.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.dBR6KXvfmjjIcwsc"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.2,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206110,"modifiedTime":1669755533755,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"bA0JDA7awoWhu0vO","name":"Teinture d'Erozonne","type":"potion","img":"systems/foundryvtt-reve-de-dragon/icons/objets/teinture_erozonne.webp","data":{"description":"<p>Fluide. </p>\n<p>Liquide rosâtre.</p>","quantite":1,"encombrement":0.1,"rarete":"","categorie":"Alchimie","herbe":"","herbebrins":0,"herbebonus":0,"reposalchimique":false,"pr":0,"prpermanent":false,"prdate":0,"cout":2,"soinherbe":"","soinherbebonus":0},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.bA0JDA7awoWhu0vO"}}}
|
{"_id":"dLiMJO6aUkh0EuIZ","name":"Épée dragonne","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/epee_dragonne.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.dLiMJO6aUkh0EuIZ"}},"system":{"description":"<p>C’est une épée <em>longue</em>, plus robuste que l’esparlongue, pouvant également frapper de taille.</p>","descriptionmj":"","equipe":false,"encombrement":2,"quantite":1,"qualite":0,"cout":20,"resistance":12,"categorie_parade":"epees-longues","dommages":"3","penetration":0,"force":"11","competence":"Epée à 1 main","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"rapide":true,"deuxmains":false,"unemain":true,"initpremierround":"epeedragonne"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206110,"modifiedTime":1669755533748,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"beQ9d4QQwZDQl5NA","name":"Flûte à bec","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/flute_bec.webp","data":{"description":"","quantite":1,"encombrement":0.09,"equipe":false,"resistance":0,"qualite":0,"cout":1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.beQ9d4QQwZDQl5NA"}}}
|
{"_id":"eK28jEeQiJdd93L3","name":"Bouclier léger","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/bouclier_petit.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.eK28jEeQiJdd93L3"}},"system":{"description":"","descriptionmj":"","equipe":false,"encombrement":1,"quantite":1,"qualite":0,"cout":4,"resistance":13,"categorie_parade":"boucliers","dommages":"0","penetration":0,"force":"8","competence":"Bouclier","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":"hast"},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206110,"modifiedTime":1669755533743,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"bgkEBYUEFLvAaeVf","name":"Luth, viole","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/luth.webp","data":{"description":"","quantite":1,"encombrement":1,"equipe":false,"resistance":0,"qualite":0,"cout":7},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.bgkEBYUEFLvAaeVf"}}}
|
{"_id":"fAzYb7kkW6QxG6i6","name":"Graisse à Bottes 500g","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/graisse_a_cuir.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.fAzYb7kkW6QxG6i6"}},"system":{"description":"","descriptionmj":"","encombrement":0.2,"quantite":1,"qualite":0,"cout":0.3,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206110,"modifiedTime":1669755533750,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"bxDITKRhXiyvLhMz","name":"Candique","type":"ingredient","img":"systems/foundryvtt-reve-de-dragon/icons/objets/candique.webp","data":{"description":"<p>Poudre blanche apparaissant sous l’écorce de nombreux arbres,</p>\n<p>VUE/Alchimie à 0.</p>","niveau":0,"encombrement":0.001,"base":0,"quantite":1,"milieu":"Forêts","rarete":"","categorie":"Alchimie","cout":0.02},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.bxDITKRhXiyvLhMz"}}}
|
{"_id":"fDwsTMuug0Z5BdaA","name":"Cuir / Metal","type":"armure","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/cuir_metal.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.fDwsTMuug0Z5BdaA"}},"system":{"description":"<p>Cuir épais clouté, ou petites plaquettes, écailles ou anneaux de fer cousus sur le cuir. Pectoral ou cotte de cuir/métal + jupon ou cuissards de cuir / métal sur culottes de cuir souple + bottes de cuir / métal + casque de métal.</p>\n<p> </p>","descriptionmj":"","equipe":false,"encombrement":4,"quantite":1,"qualite":0,"cout":20,"protection":"4","deterioration":0,"malus":-2},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206110,"modifiedTime":1669755533746,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"cVZbnh5cYxBx6P5b","name":"Burin, gouge, ciseau","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/gouge.webp","data":{"description":"","quantite":1,"encombrement":0.2,"equipe":false,"resistance":0,"qualite":0,"cout":0.3},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.cVZbnh5cYxBx6P5b"}}}
|
{"_id":"fLKFTvLWoj7juxQE","name":"Flèche, carreau","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/fleche.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.fLKFTvLWoj7juxQE"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.1,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206110,"modifiedTime":1669755533749,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"ckKnviu9SHvWgya0","name":"Bougie de cire (2 heures)","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bougie.webp","data":{"description":"","quantite":1,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":0.05},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.ckKnviu9SHvWgya0"}}}
|
{"_id":"fOfVLKBacNEsDBn1","name":"Brandevin","type":"nourritureboisson","img":"systems/foundryvtt-reve-de-dragon/icons/liquides/liquide_sang.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.fOfVLKBacNEsDBn1"}},"system":{"description":"<p>Dose de 10cl de Brandevin</p>","descriptionmj":"","encombrement":0.05,"quantite":1,"qualite":0,"cout":0.1,"sust":0,"boisson":true,"desaltere":0.2,"alcoolise":true,"force":-5,"exotisme":0},"ownership":{"default":0,"wYnBx3HmLfGzsj7P":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206110,"modifiedTime":1669755533744,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"cobfvOmFpti5lJuK","name":"Chemise de lin","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/chemise_lin.webp","data":{"description":"","quantite":1,"encombrement":0,"equipe":false,"resistance":0,"qualite":0,"cout":0.3},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.cobfvOmFpti5lJuK"}}}
|
{"name":"Etain (1 denier)","type":"monnaie","img":"systems/foundryvtt-reve-de-dragon/icons/objets/piece_etain_poisson.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Item.UFCII7LUClrCWElV"}},"_id":"fhP2azbUBfmpF441","system":{"description":"","descriptionmj":"","encombrement":0.01,"quantite":0,"qualite":0,"cout":0,"valeur_deniers":1},"ownership":{"default":0,"jtRmvSuwkwMmIMf0":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206110,"modifiedTime":1669755533748,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"dBR6KXvfmjjIcwsc","name":"Pilon en marbre","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/pilon.webp","data":{"description":"","quantite":1,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":0.2},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.dBR6KXvfmjjIcwsc"}}}
|
{"_id":"gfU7oZL1JYqF3lAW","name":"Robe de lin","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/robe_lin.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.gfU7oZL1JYqF3lAW"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.6,"equipe":false,"resistance":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206111,"modifiedTime":1669755533756,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"dLiMJO6aUkh0EuIZ","name":"Épée dragonne","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/epee_dragonne.webp","data":{"categorie_parade":"epees-longues","description":"<p>C’est une épée <em>longue</em>, plus robuste que l’esparlongue, pouvant également frapper de taille.</p>","quantite":1,"encombrement":2,"equipe":false,"dommages":"3","penetration":0,"force":"11","resistance":12,"competence":"Epée à 1 main","cout":20,"portee_courte":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"portee_moyenne":0,"portee_extreme":0,"rapide":true,"deuxmains":false,"unemain":true,"initpremierround":"epeedragonne"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.dLiMJO6aUkh0EuIZ"}}}
|
{"_id":"gmBC6SO3F5d64Vpl","name":"Miroir en cuivre poli 20 cm","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/miroir.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.gmBC6SO3F5d64Vpl"}},"system":{"description":"","descriptionmj":"","encombrement":0.2,"quantite":1,"qualite":0,"cout":1,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206111,"modifiedTime":1669755533754,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"eK28jEeQiJdd93L3","name":"Bouclier léger","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/bouclier_petit.webp","data":{"categorie_parade":"boucliers","description":"","quantite":1,"encombrement":1,"equipe":false,"dommages":"0","penetration":0,"force":"8","resistance":13,"competence":"Bouclier","cout":4,"portee_courte":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"portee_moyenne":0,"portee_extreme":0,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":"hast"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.eK28jEeQiJdd93L3"}}}
|
{"name":"Or (10 sols)","type":"monnaie","img":"systems/foundryvtt-reve-de-dragon/icons/objets/piece_or_sol.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Item.CmqfrDQgL61XIAqt"}},"_id":"gmbvvEx7hPrAy3zh","system":{"description":"","descriptionmj":"","encombrement":0.01,"quantite":0,"qualite":0,"cout":0,"valeur_deniers":1000},"ownership":{"default":0,"jtRmvSuwkwMmIMf0":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206111,"modifiedTime":1669755533754,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"fAzYb7kkW6QxG6i6","name":"Graisse à Bottes 500g","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/graisse_a_cuir.webp","data":{"description":"","quantite":1,"encombrement":0.2,"equipe":false,"resistance":0,"qualite":0,"cout":0.3},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.fAzYb7kkW6QxG6i6"}}}
|
{"_id":"godMVR796aSUVjLu","name":"Fléau léger","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/fleau_leger.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.godMVR796aSUVjLu"}},"system":{"description":"","descriptionmj":"","equipe":false,"encombrement":2,"quantite":1,"qualite":0,"cout":12,"resistance":10,"categorie_parade":"","dommages":"3","penetration":0,"force":"12","competence":"Fléau","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"rapide":false,"deuxmains":false,"unemain":true,"initpremierround":"fleau"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206111,"modifiedTime":1669755533749,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"fDwsTMuug0Z5BdaA","name":"Cuir / Metal","type":"armure","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/cuir_metal.webp","data":{"description":"<p>Cuir épais clouté, ou petites plaquettes, écailles ou anneaux de fer cousus sur le cuir. Pectoral ou cotte de cuir/métal + jupon ou cuissards de cuir / métal sur culottes de cuir souple + bottes de cuir / métal + casque de métal.</p>\n<p> </p>","quantite":1,"encombrement":4,"equipe":false,"protection":"4","deterioration":0,"malus":-2,"cout":20},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.fDwsTMuug0Z5BdaA"}}}
|
{"_id":"hEPimS3H8jihDuUS","name":"Crayon à mine de plomb","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/crayon_plomb.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.hEPimS3H8jihDuUS"}},"system":{"description":"","descriptionmj":"","encombrement":0.02,"quantite":1,"qualite":0,"cout":0.3,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206111,"modifiedTime":1669755533746,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"fLKFTvLWoj7juxQE","name":"Flèche, carreau","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/fleche.webp","data":{"description":"","quantite":1,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":0.1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.fLKFTvLWoj7juxQE"}}}
|
{"_id":"hVgd4APvAW8sbXf0","name":"Grande hache","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/grande_hache.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.hVgd4APvAW8sbXf0"}},"system":{"description":"","descriptionmj":"","equipe":false,"encombrement":3,"quantite":1,"qualite":0,"cout":15,"resistance":8,"categorie_parade":"haches","dommages":"4","penetration":0,"force":"13","competence":"Hache à 2 mains","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"rapide":false,"deuxmains":true,"unemain":false,"initpremierround":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206111,"modifiedTime":1669755533751,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"fOfVLKBacNEsDBn1","name":"Brandevin","type":"nourritureboisson","img":"systems/foundryvtt-reve-de-dragon/icons/liquides/liquide_sang.webp","data":{"description":"<p>Dose de 10cl de Brandevin</p>","sust":0,"boisson":true,"desaltere":0.2,"alcoolise":true,"force":-5,"qualite":0,"exotisme":0,"encombrement":0.05,"quantite":1,"cout":0.1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"wYnBx3HmLfGzsj7P":3},"flags":{}}
|
{"_id":"hjsIxUmanyz5otLJ","name":"Marmite de fer (3 litres)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/marmite.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.hjsIxUmanyz5otLJ"}},"system":{"description":"","descriptionmj":"","encombrement":0.6,"quantite":1,"qualite":0,"cout":0.6,"contenu":[],"capacite":1.5,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206111,"modifiedTime":1669755533753,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"name":"Etain (1 denier)","type":"monnaie","img":"systems/foundryvtt-reve-de-dragon/icons/objets/piece_etain_poisson.webp","data":{"quantite":0,"valeur_deniers":1,"encombrement":0.01,"description":""},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"jtRmvSuwkwMmIMf0":3},"flags":{"core":{"sourceId":"Item.UFCII7LUClrCWElV"}},"_id":"fhP2azbUBfmpF441"}
|
{"_id":"htaHjhHwVhlBnZjv","name":"Fléau lourd","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/fleau_lourd.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.htaHjhHwVhlBnZjv"}},"system":{"description":"","descriptionmj":"","equipe":false,"encombrement":3,"quantite":1,"qualite":0,"cout":15,"resistance":10,"categorie_parade":"","dommages":"4","penetration":0,"force":"13","competence":"Fléau","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"rapide":false,"deuxmains":false,"unemain":true,"initpremierround":"fleau"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206111,"modifiedTime":1669755533749,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"gYFprGGUUVG1Apcf","name":"Carquois","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/carquois.webp","data":{"description":"","capacite":2,"encombrement":0.1,"equipe":false,"qualite":0,"contenu":[],"cout":0.5},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.zYI8mDiysWtmsSyy"}}}
|
{"_id":"huvZ4dMPpn9gk9km","name":"Sel","type":"objet","flags":{"core":{"sourceId":"Item.fLEyryhRi8Nw37SP"}},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/sel.webp","effects":[],"system":{"description":"","descriptionmj":"","encombrement":0.01,"quantite":1,"qualite":0,"cout":null,"equipe":false,"resistance":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206111,"modifiedTime":1669755533757,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"gfU7oZL1JYqF3lAW","name":"Robe de lin","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/robe_lin.webp","data":{"description":"","quantite":1,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":0.6},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"jOzRscDxoXZWpGS6":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.gfU7oZL1JYqF3lAW"}}}
|
{"_id":"iCvphbPdxUcfqetd","name":"Aumônière","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/aumoniere.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.iCvphbPdxUcfqetd"}},"system":{"description":"<p>Comme une bourse, mais sous forme d'une coque en cuir rigide.</p>","descriptionmj":"","encombrement":0,"quantite":1,"qualite":0,"cout":0.2,"contenu":[],"capacite":0.25,"equipe":false},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206112,"modifiedTime":1669755533740,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"gmBC6SO3F5d64Vpl","name":"Miroir en cuivre poli 20 cm","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/miroir.webp","data":{"description":"","quantite":1,"encombrement":0.2,"equipe":false,"resistance":0,"qualite":0,"cout":1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.gmBC6SO3F5d64Vpl"}}}
|
{"_id":"iGHudg5kBOfYWgwV","name":"Arc","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/objets/arc.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.iGHudg5kBOfYWgwV"}},"system":{"description":"<p>Nie jusqu'à 2 points d'armure.</p>\n<p>Rechargement 1/2 round (s'il tire en début de round, il pourra recharger durant le reste du round pour tirer de nouveau au début du round suivant).</p>","descriptionmj":"","equipe":false,"encombrement":1,"quantite":1,"qualite":0,"cout":10,"resistance":0,"categorie_parade":"","dommages":"2","penetration":2,"force":"0","competence":"","lancer":"","tir":"Arc","portee_courte":10,"portee_moyenne":20,"portee_extreme":50,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":"hast"},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206112,"modifiedTime":1669755533740,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"name":"Or (10 sols)","type":"monnaie","img":"systems/foundryvtt-reve-de-dragon/icons/objets/piece_or_sol.webp","data":{"quantite":0,"valeur_deniers":1000,"encombrement":0.01,"description":""},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"jtRmvSuwkwMmIMf0":3},"flags":{"core":{"sourceId":"Item.CmqfrDQgL61XIAqt"}},"_id":"gmbvvEx7hPrAy3zh"}
|
{"_id":"iq8ZZgphxOUgC1bi","name":"Flûte traversière de roseau","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/flute_traversiere.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.iq8ZZgphxOUgC1bi"}},"system":{"description":"","descriptionmj":"","encombrement":0.08,"quantite":1,"qualite":0,"cout":0.12,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206112,"modifiedTime":1669755533749,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"godMVR796aSUVjLu","name":"Fléau léger","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/fleau_leger.webp","data":{"categorie_parade":"","description":"","quantite":1,"encombrement":2,"equipe":false,"dommages":"3","penetration":0,"force":"12","resistance":10,"competence":"Fléau","cout":12,"portee_courte":0,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"portee_moyenne":0,"portee_extreme":0,"rapide":false,"deuxmains":false,"unemain":true,"initpremierround":"fleau"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.godMVR796aSUVjLu"}}}
|
{"_id":"iss7ARW8oRoe1umi","name":"Eau","type":"nourritureboisson","img":"systems/foundryvtt-reve-de-dragon/icons/liquides/liquide_eau.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Item.DAFP7z5gzl1O3rCV"}},"system":{"description":"<p><span style=\"color: #191813; font-family: CaslonAntique; font-size: 16px; letter-spacing: 1px; text-align: justify; background-color: #f5f5f0;\">1 mesure (20cl) d'eau.</span></p>","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0,"sust":0,"boisson":true,"desaltere":1,"alcoolise":false,"force":0,"exotisme":0,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206112,"modifiedTime":1669755533747,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"hEPimS3H8jihDuUS","name":"Crayon à mine de plomb","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/crayon_plomb.webp","data":{"description":"","quantite":1,"encombrement":0.02,"equipe":false,"resistance":0,"qualite":0,"cout":0.3},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.hEPimS3H8jihDuUS"}}}
|
{"_id":"iuSOVPBsK8Zg6hoY","name":"1 m² de bâche","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bache.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.iuSOVPBsK8Zg6hoY"}},"system":{"description":null,"descriptionmj":"","encombrement":0.5,"quantite":1,"qualite":0,"cout":0.2,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206112,"modifiedTime":1669755533739,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"hVgd4APvAW8sbXf0","name":"Grande hache","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/grande_hache.webp","data":{"categorie_parade":"haches","description":"","quantite":1,"encombrement":3,"equipe":false,"dommages":"4","penetration":0,"force":"13","resistance":8,"competence":"Hache à 2 mains","cout":15,"portee_courte":0,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"portee_moyenne":0,"portee_extreme":0,"rapide":false,"deuxmains":true,"unemain":false,"initpremierround":""},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.hVgd4APvAW8sbXf0"}}}
|
{"_id":"j9WpAl1SwHEovg3b","name":"Tresse de crin","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/tresse.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.j9WpAl1SwHEovg3b"}},"system":{"description":"","descriptionmj":"","encombrement":0.02,"quantite":1,"qualite":0,"cout":0.1,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206112,"modifiedTime":1669755533757,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"hjsIxUmanyz5otLJ","name":"Marmite de fer (3 litres)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/marmite.webp","data":{"description":"","capacite":1.5,"encombrement":0.6,"equipe":false,"qualite":0,"contenu":[],"cout":0.6},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.hjsIxUmanyz5otLJ"}}}
|
{"_id":"jHxnzdBSVzr7Z7wH","name":"Robe de velours","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/robe_velours.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.jHxnzdBSVzr7Z7wH"}},"system":{"description":"","descriptionmj":"","encombrement":0.3,"quantite":1,"qualite":0,"cout":10,"equipe":false,"resistance":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206112,"modifiedTime":1669755533756,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"htaHjhHwVhlBnZjv","name":"Fléau lourd","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/fleau_lourd.webp","data":{"categorie_parade":"","description":"","quantite":1,"encombrement":3,"equipe":false,"dommages":"4","penetration":0,"force":"13","resistance":10,"competence":"Fléau","cout":15,"portee_courte":0,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"portee_moyenne":0,"portee_extreme":0,"rapide":false,"deuxmains":false,"unemain":true,"initpremierround":"fleau"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.htaHjhHwVhlBnZjv"}}}
|
{"_id":"jKWA5NjsjH0kIZzK","name":"Chaudron de fer (5 litres)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/chaudron.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.jKWA5NjsjH0kIZzK"}},"system":{"description":"","descriptionmj":"","encombrement":1,"quantite":1,"qualite":0,"cout":1,"contenu":[],"capacite":2.5,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206112,"modifiedTime":1669755533745,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"huvZ4dMPpn9gk9km","name":"Sel","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"objet","data":{"description":"","quantite":1,"encombrement":0.01,"equipe":false,"resistance":0,"qualite":0,"cout":null},"flags":{"core":{"sourceId":"Item.fLEyryhRi8Nw37SP"}},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/sel.webp","effects":[]}
|
{"_id":"jZMfiBnBXwW91drM","name":"Sablier 15 minutes","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/sablier.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.jZMfiBnBXwW91drM"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":2,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206112,"modifiedTime":1669755533756,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"iCvphbPdxUcfqetd","name":"Aumônière","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/aumoniere.webp","data":{"description":"<p>Comme une bourse, mais sous forme d'une coque en cuir rigide.</p>","capacite":0.25,"encombrement":0,"equipe":false,"qualite":0,"contenu":[],"cout":0.2},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"jOzRscDxoXZWpGS6":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.iCvphbPdxUcfqetd"}}}
|
{"_id":"jchAu828fr8TLtwi","name":"Lait","type":"nourritureboisson","img":"systems/foundryvtt-reve-de-dragon/icons/liquides/liquide_lait.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Item.6i90SWaq5Me0us8X"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.01,"sust":0.2,"boisson":true,"desaltere":1,"alcoolise":false,"force":0,"exotisme":0,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206113,"modifiedTime":1669755533752,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"iGHudg5kBOfYWgwV","name":"Arc","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/objets/arc.webp","data":{"categorie_parade":"","description":"<p>Nie jusqu'à 2 points d'armure.</p>\n<p>Rechargement 1/2 round (s'il tire en début de round, il pourra recharger durant le reste du round pour tirer de nouveau au début du round suivant).</p>","quantite":1,"encombrement":1,"equipe":false,"dommages":"2","penetration":2,"force":"0","resistance":0,"competence":"Arc","cout":10,"portee_courte":10,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"portee_moyenne":20,"portee_extreme":50,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":""},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.iGHudg5kBOfYWgwV"}}}
|
{"_id":"jyBy6mDAGvJb9k0l","name":"1 m2 de lin","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/tissu_lin.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.jyBy6mDAGvJb9k0l"}},"system":{"description":"","descriptionmj":"","encombrement":0,"quantite":1,"qualite":0,"cout":0.15,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206113,"modifiedTime":1669755533739,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"iq8ZZgphxOUgC1bi","name":"Flûte traversière de roseau","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/flute_traversiere.webp","data":{"description":"","quantite":1,"encombrement":0.08,"equipe":false,"resistance":0,"qualite":0,"cout":0.12},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.iq8ZZgphxOUgC1bi"}}}
|
{"_id":"kFUh4027jnAdqbyK","name":"Gelée royale","type":"potion","img":"systems/foundryvtt-reve-de-dragon/icons/objets/gelee_royale.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.kFUh4027jnAdqbyK"}},"system":{"description":"<p>Crème sirupeuse.</p>","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.2,"rarete":"","categorie":"AlchimieAutre","herbe":"","herbebrins":0,"herbebonus":0,"reposalchimique":false,"pr":0,"prpermanent":false,"prdate":0,"soinherbe":"","soinherbebonus":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206113,"modifiedTime":1669755533750,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"iss7ARW8oRoe1umi","name":"Eau","type":"nourritureboisson","img":"systems/foundryvtt-reve-de-dragon/icons/liquides/liquide_eau.webp","data":{"description":"<p><span style=\"color: #191813; font-family: CaslonAntique; font-size: 16px; letter-spacing: 1px; text-align: justify; background-color: #f5f5f0;\">1 mesure (20cl) d'eau.</span></p>","sust":0,"boisson":true,"desaltere":1,"alcoolise":false,"force":0,"qualite":0,"exotisme":0,"encombrement":0.1,"quantite":1,"cout":0,"equipe":false},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Item.DAFP7z5gzl1O3rCV"}}}
|
{"_id":"keLCmhsbxHK39UIy","name":"Mirobolant","type":"potion","img":"systems/foundryvtt-reve-de-dragon/icons/objets/mirobolant.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.keLCmhsbxHK39UIy"}},"system":{"description":"<p>Fluide.</p>\n<p>Liquide rougeâtre clair et sans dépot.</p>","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":2,"rarete":"","categorie":"Alchimie","herbe":"","herbebrins":0,"herbebonus":0,"reposalchimique":false,"pr":0,"prpermanent":false,"prdate":0,"soinherbe":"","soinherbebonus":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206113,"modifiedTime":1669755533754,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"iuSOVPBsK8Zg6hoY","name":"1 m² de bâche","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bache.webp","data":{"description":null,"quantite":1,"encombrement":0.5,"equipe":false,"resistance":0,"qualite":0,"cout":0.2},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.iuSOVPBsK8Zg6hoY"}}}
|
{"_id":"lJMKVPB5zlG9UqMD","name":"Pourpoint de velours","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/pourpoint_velours.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.lJMKVPB5zlG9UqMD"}},"system":{"description":"","descriptionmj":"","encombrement":0.2,"quantite":1,"qualite":0,"cout":8,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206113,"modifiedTime":1669755533756,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"j9WpAl1SwHEovg3b","name":"Tresse de crin","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/tresse.webp","data":{"description":"","quantite":1,"encombrement":0.02,"equipe":false,"resistance":0,"qualite":0,"cout":0.1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.j9WpAl1SwHEovg3b"}}}
|
{"_id":"lKkYFkzWVs2TZDZP","name":"Petit pot de fard","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/fard.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.lKkYFkzWVs2TZDZP"}},"system":{"description":"","descriptionmj":"","encombrement":0.04,"quantite":1,"qualite":0,"cout":0.3,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206113,"modifiedTime":1669755533755,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"jHxnzdBSVzr7Z7wH","name":"Robe de velours","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/robe_velours.webp","data":{"description":"","quantite":1,"encombrement":0.3,"equipe":false,"resistance":0,"qualite":0,"cout":10},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"jOzRscDxoXZWpGS6":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.jHxnzdBSVzr7Z7wH"}}}
|
{"_id":"lOI2HVu3B6EDY4sE","name":"Arbalète","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/objets/arbalete.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.lOI2HVu3B6EDY4sE"}},"system":{"description":"<p>Nie jusqu'à 2 points d'armure.</p>\n<p>Rechargement 1 round.</p>","descriptionmj":"","equipe":false,"encombrement":3,"quantite":1,"qualite":0,"cout":30,"resistance":0,"categorie_parade":"","dommages":"3","penetration":2,"force":"0","competence":"","lancer":"","tir":"Arbalète","portee_courte":15,"portee_moyenne":30,"portee_extreme":70,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206114,"modifiedTime":1669755533740,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"jKWA5NjsjH0kIZzK","name":"Chaudron de fer (5 litres)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/chaudron.webp","data":{"description":"","capacite":2.5,"encombrement":1,"equipe":false,"qualite":0,"contenu":[],"cout":1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.jKWA5NjsjH0kIZzK"}}}
|
{"_id":"lq7pjDQESNbZOQ3n","name":"1 m2 de soie ou de velours","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/tissu_velours.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.lq7pjDQESNbZOQ3n"}},"system":{"description":"","descriptionmj":"","encombrement":0,"quantite":1,"qualite":0,"cout":3,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206114,"modifiedTime":1669755533740,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"jZMfiBnBXwW91drM","name":"Sablier 15 minutes","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/sablier.webp","data":{"description":"","quantite":1,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":2},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.jZMfiBnBXwW91drM"}}}
|
{"_id":"m9yuZjp9DK7pSqPK","name":"Lanterne à bougie","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/lanterne_bougie.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.m9yuZjp9DK7pSqPK"}},"system":{"description":"","descriptionmj":"","encombrement":1,"quantite":1,"qualite":0,"cout":3,"contenu":[],"capacite":0.1,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206114,"modifiedTime":1669755533752,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"jchAu828fr8TLtwi","name":"Lait","type":"nourritureboisson","img":"systems/foundryvtt-reve-de-dragon/icons/liquides/liquide_lait.webp","data":{"description":"","sust":0.2,"boisson":true,"desaltere":1,"alcoolise":false,"force":0,"qualite":0,"exotisme":0,"encombrement":0.1,"quantite":1,"cout":0.01,"equipe":false},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Item.6i90SWaq5Me0us8X"}}}
|
{"_id":"n2HMv0xv0MFpuiKp","name":"Parchemin 1 feuille","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/parchemin_1_feuille.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.n2HMv0xv0MFpuiKp"}},"system":{"description":"","descriptionmj":"","encombrement":0.02,"quantite":1,"qualite":0,"cout":0.2,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206114,"modifiedTime":1669755533754,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"jyBy6mDAGvJb9k0l","name":"1 m2 de lin","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/tissu_lin.webp","data":{"description":"","quantite":1,"encombrement":0,"equipe":false,"resistance":0,"qualite":0,"cout":0.15},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.jyBy6mDAGvJb9k0l"}}}
|
{"_id":"nBhYyPbRwcWswiyC","name":"Tonnelet (10 litres)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/tonnelet.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.nBhYyPbRwcWswiyC"}},"system":{"description":"","descriptionmj":"","encombrement":1,"quantite":1,"qualite":0,"cout":0.25,"contenu":[],"capacite":5,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206114,"modifiedTime":1669755533757,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"kFUh4027jnAdqbyK","name":"Gelée royale","type":"potion","img":"systems/foundryvtt-reve-de-dragon/icons/objets/gelee_royale.webp","data":{"description":"<p>Crème sirupeuse.</p>","descriptionmj":"","quantite":1,"encombrement":0.1,"rarete":"","categorie":"AlchimieAutre","herbe":"","herbebrins":0,"herbebonus":0,"reposalchimique":false,"pr":0,"prpermanent":false,"prdate":0,"cout":0.2,"soinherbe":"","soinherbebonus":0},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.kFUh4027jnAdqbyK"}}}
|
{"_id":"nPczxZ7yylpmGSyO","name":"Crochet de serrurier","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/crochet.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.nPczxZ7yylpmGSyO"}},"system":{"description":"","descriptionmj":"","encombrement":0.2,"quantite":1,"qualite":0,"cout":0.3,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206114,"modifiedTime":1669755533746,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"keLCmhsbxHK39UIy","name":"Mirobolant","type":"potion","img":"systems/foundryvtt-reve-de-dragon/icons/objets/mirobolant.webp","data":{"description":"<p>Fluide.</p>\n<p>Liquide rougeâtre clair et sans dépot.</p>","quantite":1,"encombrement":0.1,"rarete":"","categorie":"Alchimie","herbe":"","herbebrins":0,"herbebonus":0,"reposalchimique":false,"pr":0,"prpermanent":false,"prdate":0,"cout":2,"soinherbe":"","soinherbebonus":0},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.keLCmhsbxHK39UIy"}}}
|
{"_id":"nl9cICrauIOEXwFP","name":"Cordelette (10 m)","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/cordelette.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.nl9cICrauIOEXwFP"}},"system":{"description":"","descriptionmj":"","encombrement":0.2,"quantite":1,"qualite":0,"cout":0.2,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206114,"modifiedTime":1669755533746,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"lJMKVPB5zlG9UqMD","name":"Pourpoint de velours","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/pourpoint_velours.webp","data":{"description":"","quantite":1,"encombrement":0.2,"equipe":false,"resistance":0,"qualite":0,"cout":8},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.lJMKVPB5zlG9UqMD"}}}
|
{"_id":"nqMyaOqBfTxdP9tg","name":"Cor en corne","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/cor_corne.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.nqMyaOqBfTxdP9tg"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.6,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206114,"modifiedTime":1669755533745,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"lKkYFkzWVs2TZDZP","name":"Petit pot de fard","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/fard.webp","data":{"description":"","quantite":1,"encombrement":0.04,"equipe":false,"resistance":0,"qualite":0,"cout":0.3},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.lKkYFkzWVs2TZDZP"}}}
|
{"_id":"oXpPZ9LS1nsU0nGT","name":"Épée sorde","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/epee_sord.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.oXpPZ9LS1nsU0nGT"}},"system":{"description":"<p>C’est une épée plus courte que la dragonne, mais plus <em>large</em>. Elle peut s’utiliser à une ou deux mains. Sa grande solidité en fait l’épée de prédilection des gardes et des soldats.</p>\n<p>C’est probablement à elle que le <em>Guerrier Sorde</em> doit son nom (à moins que ce ne soit l’inverse).</p>","descriptionmj":"","equipe":false,"encombrement":2,"quantite":1,"qualite":0,"cout":20,"resistance":15,"categorie_parade":"epees-lourdes","dommages":"3/4","penetration":null,"force":"12/11","competence":"Epée à 1 main","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"rapide":false,"deuxmains":true,"unemain":true,"initpremierround":"epeesorde"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206115,"modifiedTime":1669755533748,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"lOI2HVu3B6EDY4sE","name":"Arbalète","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/objets/arbalete.webp","data":{"categorie_parade":"","description":"<p>Nie jusqu'à 2 points d'armure.</p>\n<p>Rechargement 1 round.</p>","quantite":1,"encombrement":3,"equipe":false,"dommages":"3","penetration":2,"force":"0","resistance":0,"competence":"Arbalète","cout":30,"portee_courte":15,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"portee_moyenne":30,"portee_extreme":70,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":""},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.lOI2HVu3B6EDY4sE"}}}
|
{"_id":"of2LbmmB4EtlSwte","name":"Sac en jute (50 litres)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/sac_jute_50.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.of2LbmmB4EtlSwte"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.08,"contenu":[],"capacite":25,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206115,"modifiedTime":1669755533757,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"lq7pjDQESNbZOQ3n","name":"1 m2 de soie ou de velours","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/tissu_velours.webp","data":{"description":"","quantite":1,"encombrement":0,"equipe":false,"resistance":0,"qualite":0,"cout":3},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.lq7pjDQESNbZOQ3n"}}}
|
{"_id":"orpj8CumQ39xMOHy","name":"Brosse à cheveux","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/Brosse.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.orpj8CumQ39xMOHy"}},"system":{"description":"","descriptionmj":"","encombrement":0.06,"quantite":1,"qualite":0,"cout":1,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206115,"modifiedTime":1669755533744,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"m9yuZjp9DK7pSqPK","name":"Lanterne à bougie","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/lanterne_bougie.webp","data":{"description":"","capacite":0.1,"encombrement":1,"equipe":false,"qualite":0,"contenu":[],"cout":3},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.m9yuZjp9DK7pSqPK"}}}
|
{"_id":"phfgVizT4ekUwqFq","name":"Selle et harnais","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/selle.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.phfgVizT4ekUwqFq"}},"system":{"description":"","descriptionmj":"","encombrement":4,"quantite":1,"qualite":0,"cout":5,"contenu":[],"capacite":25,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206115,"modifiedTime":1669755533757,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"mOZodpJYobvmZO9o","name":"Le Narcolepton","type":"livre","img":"systems/foundryvtt-reve-de-dragon/icons/competence_narcos.webp","data":{"description":"<p>Cet ouvrage ne peut être assimilé que si l’on possède un niveau minimum de zéro en voie de Narcos. Il confère un bonus de synthèse de +3 aux sept Écailles de Protection présentées dans les règles (Venin, Maladie, Feu, Magie, Projectiles, Lames, Griffes et crocs), mais aucun bonus de points de sorts. Sa difficulté de lecture est de -4, son assimilation requiert 24 points de tâche, périodicité une heure.</p>","competence":"","auteur":"anonyme","quantite":1,"difficulte":-4,"points_de_tache":24,"encombrement":0,"xp":"","niveau_minimum":0,"niveau_maximum":0,"cout":0},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"jOzRscDxoXZWpGS6":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.mOZodpJYobvmZO9o"}}}
|
{"_id":"q5zaNnlmNZZChi31","name":"Miel","type":"nourritureboisson","img":"systems/foundryvtt-reve-de-dragon/icons/objets/gelee_royale.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Item.0UhqiYISVSiztBfv"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.4,"sust":2,"boisson":false,"desaltere":0,"alcoolise":false,"force":0,"exotisme":0},"ownership":{"default":0,"wYnBx3HmLfGzsj7P":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206115,"modifiedTime":1669755533754,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"n2HMv0xv0MFpuiKp","name":"Parchemin 1 feuille","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/parchemin_1_feuille.webp","data":{"description":"","quantite":1,"encombrement":0.02,"equipe":false,"resistance":0,"qualite":0,"cout":0.2},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.n2HMv0xv0MFpuiKp"}}}
|
{"_id":"qCLTOjlIOvlj0uo7","name":"Chaperon de laine","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/chaperon_laine.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.qCLTOjlIOvlj0uo7"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.2,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206115,"modifiedTime":1669755533744,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"nBhYyPbRwcWswiyC","name":"Tonnelet (10 litres)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/tonnelet.webp","data":{"description":"","capacite":5,"encombrement":1,"equipe":false,"qualite":0,"contenu":[],"cout":0.25},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.nBhYyPbRwcWswiyC"}}}
|
{"_id":"qWhl9EfdnJx4KFTZ","name":"Bas de laine","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bas_laine.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.qWhl9EfdnJx4KFTZ"}},"system":{"description":"","descriptionmj":"","encombrement":0,"quantite":1,"qualite":0,"cout":0.1,"equipe":false,"resistance":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206115,"modifiedTime":1669755533742,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"nIOEB0PpMaACqD65","name":"Obyssum gris","type":"ingredient","img":"systems/foundryvtt-reve-de-dragon/icons/objets/l_obyssum_gris.webp","data":{"description":"<p>Plus rare que le vert, poudre grisâtre apparaissant le long de certaines lianes des marais.</p>\n<p>VUE/Alchimie à -4</p>","niveau":0,"encombrement":0.001,"base":0,"quantite":1,"milieu":"Marais","rarete":"","categorie":"Alchimie","cout":0.1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.nIOEB0PpMaACqD65"}}}
|
{"_id":"sSgPT3aKDOZ25svO","name":"Porte plume en bois","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/porte_plume2.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.sSgPT3aKDOZ25svO"}},"system":{"description":"","descriptionmj":"","encombrement":0.02,"quantite":1,"qualite":0,"cout":0.05,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206115,"modifiedTime":1669755533756,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"nPczxZ7yylpmGSyO","name":"Crochet de serrurier","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/crochet.webp","data":{"description":"","quantite":1,"encombrement":0.2,"equipe":false,"resistance":0,"qualite":0,"cout":0.3},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.nPczxZ7yylpmGSyO"}}}
|
{"_id":"sXoStuW19r9zVi1S","name":"Flacon de verre (40 cl)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/flacon_verre.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.sXoStuW19r9zVi1S"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.3,"contenu":[],"capacite":0.2,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206115,"modifiedTime":1669755533749,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"ncpONCxPPNZ9YbBr","name":"Chramaelium","type":"ingredient","img":"systems/foundryvtt-reve-de-dragon/icons/objets/chramaelium.webp","data":{"description":"<p>Poudre rouge obtenue par disruption alchimique de la <em>chramaele</em>, minerai ayant l’apparence de la glaise.</p>\n<p>VUE/Alchimie à -4</p>","niveau":0,"encombrement":0.001,"base":0,"quantite":1,"milieu":"","rarete":"","categorie":"Alchimie","cout":0.5},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.ncpONCxPPNZ9YbBr"}}}
|
{"_id":"sbgHtwEj4sK9cMh7","name":"Livre","type":"livre","flags":{"core":{"sourceId":"Item.1bn0Q8cO1qRWQvlf"}},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/livre.webp","effects":[],"system":{"description":"","descriptionmj":"","encombrement":1,"quantite":1,"qualite":0,"cout":3,"competence":"Ecriture","auteur":"Inconnu","difficulte":0,"points_de_tache":0,"xp":"0","niveau_minimum":0,"niveau_maximum":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206117,"modifiedTime":1669755533752,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"nl9cICrauIOEXwFP","name":"Cordelette (10 m)","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/cordelette.webp","data":{"description":"","quantite":1,"encombrement":0.2,"equipe":false,"resistance":0,"qualite":0,"cout":0.2},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.nl9cICrauIOEXwFP"}}}
|
{"_id":"skTWp8PUgIG2U2ne","name":"Cire à cacheter","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/cire_a_cacheter.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.skTWp8PUgIG2U2ne"}},"system":{"description":"","descriptionmj":"","encombrement":0.02,"quantite":1,"qualite":0,"cout":0.2,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206117,"modifiedTime":1669755533745,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"nqMyaOqBfTxdP9tg","name":"Cor en corne","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/cor_corne.webp","data":{"description":"","quantite":1,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":0.6},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.nqMyaOqBfTxdP9tg"}}}
|
{"_id":"slusKo2nVCtFwDkN","name":"Sang","type":"munition","img":"systems/foundryvtt-reve-de-dragon/icons/liquides/liquide_sang.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.slusKo2nVCtFwDkN"}},"system":{"description":"<p>1 mesure (20cl) de sang.</p>","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206117,"modifiedTime":1669755533757,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"oXpPZ9LS1nsU0nGT","name":"Épée sorde","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/epee_sord.webp","data":{"categorie_parade":"epees-lourdes","description":"<p>C’est une épée plus courte que la dragonne, mais plus <em>large</em>. Elle peut s’utiliser à une ou deux mains. Sa grande solidité en fait l’épée de prédilection des gardes et des soldats.</p>\n<p>C’est probablement à elle que le <em>Guerrier Sorde</em> doit son nom (à moins que ce ne soit l’inverse).</p>","quantite":1,"encombrement":2,"equipe":false,"dommages":"3/4","penetration":null,"force":"12/11","resistance":15,"competence":"Epée à 1 main","cout":20,"portee_courte":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"portee_moyenne":0,"portee_extreme":0,"rapide":false,"deuxmains":true,"unemain":true,"initpremierround":"epeesorde"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.oXpPZ9LS1nsU0nGT"}}}
|
{"_id":"snupUovwaPAe46aD","name":"Fiole en grès (20 cl)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/fiole_gres.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.snupUovwaPAe46aD"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.1,"contenu":[],"capacite":0.1,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206117,"modifiedTime":1669755533749,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"of2LbmmB4EtlSwte","name":"Sac en jute (50 litres)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/sac_jute_50.webp","data":{"description":"","capacite":25,"encombrement":0.1,"equipe":false,"qualite":0,"contenu":[],"cout":0.08},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.of2LbmmB4EtlSwte"}}}
|
{"_id":"szOThadvQvFcS79R","name":"Cuir Epais","type":"armure","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/cuir_epais.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.szOThadvQvFcS79R"}},"system":{"description":"<p>Cuir très épais comme le cuir de botte. Pectoral de cuir épais + jupon de bandes ou de tresses de cuir ou cuissards de cuir épais sur culottes de cuir souple + bottes dures + casque de cuir.</p>\n<p> </p>","descriptionmj":"","equipe":false,"encombrement":2,"quantite":1,"qualite":0,"cout":10,"protection":3,"deterioration":0,"malus":-1},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206117,"modifiedTime":1669755533746,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"orpj8CumQ39xMOHy","name":"Brosse à cheveux","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/Brosse.webp","data":{"description":"","quantite":1,"encombrement":0.06,"equipe":false,"resistance":0,"qualite":0,"cout":1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.orpj8CumQ39xMOHy"}}}
|
{"_id":"tBFt4h3jqINsOxLI","name":"Outre (2 litres)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/outre.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.tBFt4h3jqINsOxLI"}},"system":{"description":"","descriptionmj":"","encombrement":0.08,"quantite":1,"qualite":0,"cout":0.2,"contenu":[],"capacite":1,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206117,"modifiedTime":1669755533754,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"oyAyc3tp1JrIFfos","name":"L'Oniricon","type":"livre","img":"systems/foundryvtt-reve-de-dragon/icons/icone_parchement_vierge.svg","data":{"description":"<p>Cet abécédaire draconic permet de gagner jusqu’à 80 points d’expérience en voie d’Oniros, jusqu’à concurrence du niveau +1. C’est un livre pour débutants, inutile aux haut-rêvants confirmés. Sa difficulté de lecture est de -2, son assimilation requiert 20 points de tâche, périodicité une heure. Le gain final est de 4d10+40 points d’expérience en voie d’Oniros.</p>","competence":"","auteur":"anonyme","quantite":1,"difficulte":-2,"points_de_tache":0,"encombrement":0,"xp":"4d10+40","niveau_minimum":0,"niveau_maximum":0,"cout":0},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"jOzRscDxoXZWpGS6":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.oyAyc3tp1JrIFfos"}}}
|
{"_id":"tMWzePiuMtiCQnAU","name":"Marteau","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/objets/marteau.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.tMWzePiuMtiCQnAU"}},"system":{"description":"","descriptionmj":"","equipe":false,"encombrement":0.3,"quantite":1,"qualite":0,"cout":1,"resistance":8,"categorie_parade":"","dommages":"2","penetration":0,"force":"7","competence":"Masse à 1 main","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":"masse"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206117,"modifiedTime":1669755533753,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"phfgVizT4ekUwqFq","name":"Selle et harnais","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/selle.webp","data":{"description":"","capacite":25,"encombrement":4,"equipe":false,"qualite":0,"contenu":[],"cout":5},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.phfgVizT4ekUwqFq"}}}
|
{"_id":"tY3shj5FA8nwMgxX","name":"Vin","type":"nourritureboisson","img":"systems/foundryvtt-reve-de-dragon/icons/liquides/liquide_vin.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Item.QNNWTG5yqQKmcpJ7"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.01,"sust":0,"boisson":true,"desaltere":0.6,"alcoolise":true,"force":-2,"exotisme":0,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206117,"modifiedTime":1669755533758,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"q5zaNnlmNZZChi31","name":"Miel","type":"nourritureboisson","img":"systems/foundryvtt-reve-de-dragon/icons/objets/gelee_royale.webp","data":{"description":"","sust":2,"boisson":false,"desaltere":0,"alcoolise":false,"force":0,"qualite":0,"exotisme":0,"encombrement":0.1,"quantite":1,"cout":0.4},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"wYnBx3HmLfGzsj7P":3},"flags":{"core":{"sourceId":"Item.0UhqiYISVSiztBfv"}}}
|
{"_id":"tZWQCuRr1ic3S0pL","name":"Souliers","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/souliers.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.tZWQCuRr1ic3S0pL"}},"system":{"description":"","descriptionmj":"","encombrement":0.2,"quantite":1,"qualite":0,"cout":0.8,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206117,"modifiedTime":1669755533757,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"qCLTOjlIOvlj0uo7","name":"Chaperon de laine","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/chaperon_laine.webp","data":{"description":"","quantite":1,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":0.2},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.qCLTOjlIOvlj0uo7"}}}
|
{"name":"Repas moyen à l'auberge","type":"nourritureboisson","img":"systems/foundryvtt-reve-de-dragon/icons/objets/provision_cuite.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.tn1kvxEVoLyYODyg"}},"_id":"tn1kvxEVoLyYODyg","system":{"description":"","descriptionmj":"","encombrement":0.3,"quantite":1,"qualite":3,"cout":0.1,"sust":3,"boisson":false,"desaltere":0,"alcoolise":false,"force":0,"exotisme":0},"ownership":{"default":0,"wYnBx3HmLfGzsj7P":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206117,"modifiedTime":1669755533756,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"qWhl9EfdnJx4KFTZ","name":"Bas de laine","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bas_laine.webp","data":{"description":"","quantite":1,"encombrement":0,"equipe":false,"resistance":0,"qualite":0,"cout":0.1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"jOzRscDxoXZWpGS6":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.qWhl9EfdnJx4KFTZ"}}}
|
{"_id":"tswamwK2oKNARhjA","name":"Verre grossissant","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/verre_grossissant.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.tswamwK2oKNARhjA"}},"system":{"description":"","descriptionmj":"","encombrement":0.02,"quantite":1,"qualite":0,"cout":2,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206118,"modifiedTime":1669755533758,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"sSgPT3aKDOZ25svO","name":"Porte plume en bois","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/porte_plume2.webp","data":{"description":"","quantite":1,"encombrement":0.02,"equipe":false,"resistance":0,"qualite":0,"cout":0.05},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.sSgPT3aKDOZ25svO"}}}
|
{"_id":"ueBk3MbdEaMbzyPS","name":"Ficelle (10 m)","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/ficelle.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.ueBk3MbdEaMbzyPS"}},"system":{"description":"","descriptionmj":"","encombrement":0.02,"quantite":1,"qualite":0,"cout":0.1,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206118,"modifiedTime":1669755533749,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"sXoStuW19r9zVi1S","name":"Flacon de verre (40 cl)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/flacon_verre.webp","data":{"description":"","capacite":0.2,"encombrement":0.1,"equipe":false,"qualite":0,"contenu":[],"cout":0.3},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.sXoStuW19r9zVi1S"}}}
|
{"_id":"ueJnUMLK1vpL8xOB","name":"Stylet de bronze","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/stylet_de_bronze.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.ueJnUMLK1vpL8xOB"}},"system":{"description":"","descriptionmj":"","encombrement":0.02,"quantite":1,"qualite":0,"cout":0.12,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206118,"modifiedTime":1669755533757,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"sbgHtwEj4sK9cMh7","name":"Livre","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"livre","data":{"description":"","competence":"Ecriture","auteur":"Inconnu","quantite":1,"difficulte":0,"points_de_tache":0,"encombrement":1,"xp":"0","cout":3},"flags":{"core":{"sourceId":"Item.1bn0Q8cO1qRWQvlf"}},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/livre.webp","effects":[]}
|
{"_id":"uwwunMSrJoUYTDkG","name":"Seau de bois ferré (10 litres)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/seau_ferre.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.uwwunMSrJoUYTDkG"}},"system":{"description":"","descriptionmj":"","encombrement":1,"quantite":1,"qualite":0,"cout":0.2,"contenu":[],"capacite":5,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206118,"modifiedTime":1669755533757,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"skTWp8PUgIG2U2ne","name":"Cire à cacheter","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/cire_a_cacheter.webp","data":{"description":"","quantite":1,"encombrement":0.02,"equipe":false,"resistance":0,"qualite":0,"cout":0.2},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.skTWp8PUgIG2U2ne"}}}
|
{"_id":"vQ494sD9FgFI08kZ","name":"Drap Matelassé","type":"armure","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/drap_matelasse.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.vQ494sD9FgFI08kZ"}},"system":{"description":"<p>Deux épaisseurs de drap surpiquées, avec rembourrage de laine.</p>\n<p>Pourpoint ou cotte de drap matelassé + culottes de drap matelassé + bottes de cuir souple. Le pourpoint est une sorte de veste ; la cotte est une sorte de tunique, lacée sur la poitrine, et descendant jusqu’aux genoux, façon Robin des Bois.</p>\n<p> </p>","descriptionmj":"","equipe":false,"encombrement":0,"quantite":1,"qualite":0,"cout":4,"protection":1,"deterioration":0,"malus":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206118,"modifiedTime":1669755533747,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"slusKo2nVCtFwDkN","name":"Sang","type":"munition","img":"systems/foundryvtt-reve-de-dragon/icons/liquides/liquide_sang.webp","data":{"description":"<p>1 mesure (20cl) de sang.</p>","quantite":1,"encombrement":0.1,"equipe":false,"qualite":0,"cout":0},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.slusKo2nVCtFwDkN"}}}
|
{"name":"Épée demi-dragonne","type":"arme","flags":{"core":{"sourceId":"Item.ErwaSLcGryAbYjkm"}},"img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/demi_dragonne.webp","effects":[],"_id":"vnlRGjt7X6yQRObA","system":{"description":null,"descriptionmj":"","equipe":false,"encombrement":1.5,"quantite":1,"qualite":0,"cout":15,"resistance":10,"categorie_parade":"epees-longues","dommages":"2","penetration":0,"force":"10","competence":"Epée à 1 main","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"rapide":true,"deuxmains":false,"unemain":true,"initpremierround":"epeedragonne"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206118,"modifiedTime":1669755533748,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"snupUovwaPAe46aD","name":"Fiole en grès (20 cl)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/fiole_gres.webp","data":{"description":"","capacite":0.1,"encombrement":0.1,"equipe":false,"qualite":0,"contenu":[],"cout":0.1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.snupUovwaPAe46aD"}}}
|
{"_id":"wPE64RRcuLlvuPrY","name":"Épée cyane","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/epee_cyane.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.wPE64RRcuLlvuPrY"}},"system":{"description":"<p>Long <em>cimeterre </em>à l’acier bleuté, exclusivement fabriqué par les Cyans ou Hommes bleus.</p>","descriptionmj":"","equipe":false,"encombrement":2,"quantite":1,"qualite":0,"cout":25,"resistance":12,"categorie_parade":"epees-lourdes","dommages":"3","penetration":0,"force":"11","competence":"Epée à 1 main","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"rapide":true,"deuxmains":false,"unemain":true,"initpremierround":"epeecyane"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206118,"modifiedTime":1669755533748,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"szOThadvQvFcS79R","name":"Cuir Epais","type":"armure","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/cuir_epais.webp","data":{"description":"<p>Cuir très épais comme le cuir de botte. Pectoral de cuir épais + jupon de bandes ou de tresses de cuir ou cuissards de cuir épais sur culottes de cuir souple + bottes dures + casque de cuir.</p>\n<p> </p>","quantite":1,"encombrement":2,"equipe":false,"protection":3,"deterioration":0,"malus":-1,"cout":10},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.szOThadvQvFcS79R"}}}
|
{"_id":"wcW5KcideGi8EY67","name":"Gants de cuir","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/gants_de_cuir.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.wcW5KcideGi8EY67"}},"system":{"description":"","descriptionmj":"","encombrement":0.05,"quantite":1,"qualite":0,"cout":1,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206118,"modifiedTime":1669755533750,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"tBFt4h3jqINsOxLI","name":"Outre (2 litres)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/outre.webp","data":{"description":"","capacite":1,"encombrement":0.08,"equipe":false,"qualite":0,"contenu":[],"cout":0.2},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.tBFt4h3jqINsOxLI"}}}
|
{"_id":"wpWaqe96x3cvqTXy","name":"Robe de laine","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/robe_laine.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.wpWaqe96x3cvqTXy"}},"system":{"description":"","descriptionmj":"","encombrement":0.2,"quantite":1,"qualite":0,"cout":0.4,"equipe":false,"resistance":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206118,"modifiedTime":1669755533756,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"tMWzePiuMtiCQnAU","name":"Marteau","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/objets/marteau.webp","data":{"categorie_parade":"","description":"","quantite":1,"encombrement":0.3,"equipe":false,"dommages":"2","penetration":0,"force":"7","resistance":8,"competence":"Masse à 1 main","cout":1,"portee_courte":0,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"portee_moyenne":0,"portee_extreme":0,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":"masse"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.tMWzePiuMtiCQnAU"}}}
|
{"_id":"x4g6bDu3eUllSSSJ","name":"Eponge de mer","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/eponge.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.x4g6bDu3eUllSSSJ"}},"system":{"description":"","descriptionmj":"","encombrement":0.04,"quantite":1,"qualite":0,"cout":1,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206118,"modifiedTime":1669755533748,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"tY3shj5FA8nwMgxX","name":"Vin","type":"nourritureboisson","img":"systems/foundryvtt-reve-de-dragon/icons/liquides/liquide_vin.webp","data":{"description":"","sust":0,"boisson":true,"desaltere":0.6,"alcoolise":true,"force":-2,"qualite":0,"exotisme":0,"encombrement":0.1,"quantite":1,"cout":0.01,"equipe":false},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Item.QNNWTG5yqQKmcpJ7"}}}
|
{"_id":"xfdeDEyMK8YtBpzC","name":"Huile 20 cl (4 heures)","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/huile.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.xfdeDEyMK8YtBpzC"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.04,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206119,"modifiedTime":1669755533752,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"tZWQCuRr1ic3S0pL","name":"Souliers","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/souliers.webp","data":{"description":"","quantite":1,"encombrement":0.2,"equipe":false,"resistance":0,"qualite":0,"cout":0.8},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.tZWQCuRr1ic3S0pL"}}}
|
{"_id":"xuk60njqtrSZusSX","name":"Chemise de laine","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/chemise_laine.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.xuk60njqtrSZusSX"}},"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.2,"equipe":false,"resistance":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206119,"modifiedTime":1669755533745,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"name":"Repas moyen à l'auberge","type":"nourritureboisson","img":"systems/foundryvtt-reve-de-dragon/icons/objets/provision_cuite.webp","data":{"description":"","sust":3,"boisson":false,"desaltere":0,"alcoolise":false,"force":0,"qualite":3,"exotisme":0,"encombrement":0.3,"quantite":1,"cout":0.1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"wYnBx3HmLfGzsj7P":3},"flags":{},"_id":"tn1kvxEVoLyYODyg"}
|
{"_id":"yILNvELKbsz2OOln","name":"Ecritoire","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/ecritoire.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.yILNvELKbsz2OOln"}},"system":{"description":"","descriptionmj":"","encombrement":1,"quantite":1,"qualite":0,"cout":1,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206179,"modifiedTime":1669755533747,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"tswamwK2oKNARhjA","name":"Verre grossissant","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/verre_grossissant.webp","data":{"description":"","quantite":1,"encombrement":0.02,"equipe":false,"resistance":0,"qualite":0,"cout":2},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.tswamwK2oKNARhjA"}}}
|
{"_id":"yO9Vx7tqF8qbZoYw","name":"Besace de cuir","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/besace.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.yO9Vx7tqF8qbZoYw"}},"system":{"description":"","descriptionmj":"","encombrement":0.2,"quantite":1,"qualite":0,"cout":0.5,"contenu":[],"capacite":10,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206179,"modifiedTime":1669755533742,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"ueBk3MbdEaMbzyPS","name":"Ficelle (10 m)","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/ficelle.webp","data":{"description":"","quantite":1,"encombrement":0.02,"equipe":false,"resistance":0,"qualite":0,"cout":0.1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.ueBk3MbdEaMbzyPS"}}}
|
{"_id":"zQWlnUsd8bPySujd","name":"Aiguille à coudre","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/aiguille.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.zQWlnUsd8bPySujd"}},"system":{"description":"","descriptionmj":"","encombrement":0.01,"quantite":1,"qualite":0,"cout":0.1,"equipe":false,"resistance":0},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206179,"modifiedTime":1669755533740,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"ueJnUMLK1vpL8xOB","name":"Stylet de bronze","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/stylet_de_bronze.webp","data":{"description":"","quantite":1,"encombrement":0.02,"equipe":false,"resistance":0,"qualite":0,"cout":0.12},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.ueJnUMLK1vpL8xOB"}}}
|
{"_id":"zYI8mDiysWtmsSyy","name":"Carquois","type":"conteneur","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.zYI8mDiysWtmsSyy"}},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/carquois.webp","effects":[],"system":{"description":"","descriptionmj":"","encombrement":0.1,"quantite":1,"qualite":0,"cout":0.5,"contenu":[],"capacite":2,"equipe":false},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206179,"modifiedTime":1669755533744,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"uwwunMSrJoUYTDkG","name":"Seau de bois ferré (10 litres)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/seau_ferre.webp","data":{"description":"","capacite":5,"encombrement":1,"equipe":false,"qualite":0,"contenu":[],"cout":0.2},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.uwwunMSrJoUYTDkG"}}}
|
{"_id":"zlDa1vwmls6Uf4pt","name":"Bourse de cuir","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bourse.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.zlDa1vwmls6Uf4pt"}},"system":{"description":"","descriptionmj":"","encombrement":0.01,"quantite":1,"qualite":0,"cout":0.1,"contenu":[],"capacite":0.5,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.10","coreVersion":"10.290","createdTime":1668808206179,"modifiedTime":1669755533743,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||||
{"_id":"vQ494sD9FgFI08kZ","name":"Drap Matelassé","type":"armure","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/drap_matelasse.webp","data":{"description":"<p>Deux épaisseurs de drap surpiquées, avec rembourrage de laine.</p>\n<p>Pourpoint ou cotte de drap matelassé + culottes de drap matelassé + bottes de cuir souple. Le pourpoint est une sorte de veste ; la cotte est une sorte de tunique, lacée sur la poitrine, et descendant jusqu’aux genoux, façon Robin des Bois.</p>\n<p> </p>","quantite":1,"encombrement":0,"equipe":false,"protection":1,"deterioration":0,"malus":0,"cout":4},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.vQ494sD9FgFI08kZ"}}}
|
|
||||||
{"name":"Épée demi-dragonne","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"arme","data":{"categorie_parade":"epees-longues","description":null,"quantite":1,"encombrement":1.5,"equipe":false,"dommages":"2","penetration":0,"force":"10","resistance":10,"competence":"Epée à 1 main","cout":15,"portee_courte":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"portee_moyenne":0,"portee_extreme":0,"rapide":true,"deuxmains":false,"unemain":true,"initpremierround":"epeedragonne"},"flags":{"core":{"sourceId":"Item.ErwaSLcGryAbYjkm"}},"img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/demi_dragonne.webp","effects":[],"_id":"vnlRGjt7X6yQRObA"}
|
|
||||||
{"_id":"wPE64RRcuLlvuPrY","name":"Épée cyane","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/epee_cyane.webp","data":{"categorie_parade":"epees-lourdes","description":"<p>Long <em>cimeterre </em>à l’acier bleuté, exclusivement fabriqué par les Cyans ou Hommes bleus.</p>","quantite":1,"encombrement":2,"equipe":false,"dommages":"3","penetration":0,"force":"11","resistance":12,"competence":"Epée à 1 main","cout":25,"portee_courte":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"portee_moyenne":0,"portee_extreme":0,"rapide":true,"deuxmains":false,"unemain":true,"initpremierround":"epeecyane"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.wPE64RRcuLlvuPrY"}}}
|
|
||||||
{"_id":"wcW5KcideGi8EY67","name":"Gants de cuir","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/gants_de_cuir.webp","data":{"description":"","quantite":1,"encombrement":0.05,"equipe":false,"resistance":0,"qualite":0,"cout":1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.wcW5KcideGi8EY67"}}}
|
|
||||||
{"_id":"wpWaqe96x3cvqTXy","name":"Robe de laine","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/robe_laine.webp","data":{"description":"","quantite":1,"encombrement":0.2,"equipe":false,"resistance":0,"qualite":0,"cout":0.4},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"jOzRscDxoXZWpGS6":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.wpWaqe96x3cvqTXy"}}}
|
|
||||||
{"_id":"wwWRn95ByBD08eGQ","name":"Le Paradoxe de l’Immobilité Rapide","type":"livre","img":"systems/foundryvtt-reve-de-dragon/icons/competence_hypnos.webp","data":{"description":"<p>Ce texte de pure logique ne peut être assimilé que si l’on possède un minimum de +4 en voie d’Hypnos. Il permet d’envisager la synthèse du sort de <em>Concentration</em>. (Sans son assimilation préalable, la synthèse de ce sort est totalement inenvisageable.) Sa difficulté de lecture est de -5, son assimilation requiert 12 points de tâche, périodicité 1 heure.</p>","competence":"","auteur":"Wanister de Bravo","quantite":1,"difficulte":-5,"points_de_tache":12,"encombrement":0,"xp":"","niveau_minimum":0,"niveau_maximum":0,"cout":0},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"jOzRscDxoXZWpGS6":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.wwWRn95ByBD08eGQ"}}}
|
|
||||||
{"_id":"x4g6bDu3eUllSSSJ","name":"Eponge de mer","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/eponge.webp","data":{"description":"","quantite":1,"encombrement":0.04,"equipe":false,"resistance":0,"qualite":0,"cout":1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.x4g6bDu3eUllSSSJ"}}}
|
|
||||||
{"_id":"xfdeDEyMK8YtBpzC","name":"Huile 20 cl (4 heures)","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/huile.webp","data":{"description":"","quantite":1,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":0.04},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.xfdeDEyMK8YtBpzC"}}}
|
|
||||||
{"_id":"xuk60njqtrSZusSX","name":"Chemise de laine","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/chemise_laine.webp","data":{"description":"","quantite":1,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":0.2},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"jOzRscDxoXZWpGS6":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.xuk60njqtrSZusSX"}}}
|
|
||||||
{"_id":"yILNvELKbsz2OOln","name":"Ecritoire","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/ecritoire.webp","data":{"description":"","quantite":1,"encombrement":1,"equipe":false,"resistance":0,"qualite":0,"cout":1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.yILNvELKbsz2OOln"}}}
|
|
||||||
{"_id":"yO9Vx7tqF8qbZoYw","name":"Besace de cuir","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/besace.webp","data":{"description":"","capacite":10,"encombrement":0.2,"equipe":false,"qualite":0,"contenu":[],"cout":0.5},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.yO9Vx7tqF8qbZoYw"}}}
|
|
||||||
{"_id":"z3xiBzZBZXlaRVzZ","name":"Le Grand Iris","type":"livre","img":"systems/foundryvtt-reve-de-dragon/icons/competence_hypnos.webp","data":{"description":"<p>Cette judicieuse réflexion sur les sorts d’illusion visuelle d’Hypnos ne peut être assimilée que si l’on possède au minimum zéro en voie d’Hypnos. Il confère un bonus de synthèse de +2 et de 12 points de sorts aux trois yeux d’Hypnos : Invisibilité, Transfiguration, Métamorphose. Sa difficulté de lecture est de -3, son assimilation requiert 16 points de tâche, périodicité une heure.</p>","competence":"","auteur":"Khrachtchoum le Problémeux","quantite":1,"difficulte":-3,"points_de_tache":16,"encombrement":0,"xp":"0","niveau_minimum":0,"niveau_maximum":0,"cout":0},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"jOzRscDxoXZWpGS6":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.z3xiBzZBZXlaRVzZ"}}}
|
|
||||||
{"_id":"zQWlnUsd8bPySujd","name":"Aiguille à coudre","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/aiguille.webp","data":{"description":"","quantite":1,"encombrement":0.01,"equipe":false,"resistance":0,"qualite":0,"cout":0.1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.zQWlnUsd8bPySujd"}}}
|
|
||||||
{"_id":"zYI8mDiysWtmsSyy","name":"Carquois","permission":{"default":0,"jOzRscDxoXZWpGS6":3},"type":"conteneur","data":{"description":"","capacite":2,"encombrement":0.1,"equipe":false,"qualite":0,"cout":0.5},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/carquois.webp","effects":[]}
|
|
||||||
{"_id":"zlDa1vwmls6Uf4pt","name":"Bourse de cuir","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bourse.webp","data":{"description":"","capacite":0.5,"encombrement":0.01,"equipe":false,"qualite":0,"contenu":[],"cout":0.1},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"rYShh2P1DNavdoBD":3},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.zlDa1vwmls6Uf4pt"}}}
|
|
||||||
|
|||||||