Compare commits
41 Commits
fvtt-les-h
...
fvtt-les-h
| Author | SHA1 | Date | |
|---|---|---|---|
| 4d41986c12 | |||
| d04731f475 | |||
| 44a641a0ca | |||
| 1ad022d193 | |||
| 1c7cf343b1 | |||
| d4b00e3508 | |||
| adc912e6cd | |||
| 51a457ebf6 | |||
| 2e9c558027 | |||
| bcd0758328 | |||
| 2b680a203f | |||
| e3d7874dce | |||
| ab6a5832c0 | |||
| d83a999974 | |||
| b83890a764 | |||
| 5ad3c165e5 | |||
| 2b3e774cbb | |||
| 96f8d2bceb | |||
| e288c90ee4 | |||
| 8916de8613 | |||
| 8598df5a57 | |||
| 8781462c8d | |||
| 8c38aead3e | |||
| 67bf71e6c0 | |||
| 63d15e82bb | |||
| 62c3787cea | |||
| df61abac19 | |||
| a7d1a14c52 | |||
| b0dc6f36e4 | |||
| 5109d2aa91 | |||
| 51c162ecbb | |||
| 44d02b0cd1 | |||
| 9b1600304a | |||
| 2dff59c829 | |||
| 55a2a8e3c3 | |||
| 2da1f56a91 | |||
| 66bd9dd2c8 | |||
| 15427f3747 | |||
| 577eccbbd3 | |||
| 05026d454b | |||
| 6497369d7f |
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.history/
|
||||
10
README.md
10
README.md
@@ -1,8 +1,8 @@
|
||||
# Système Foundry pour Hawkmoon (French RPG, Titam France/Sombres Projets)
|
||||
# Système Foundry pour Les Héritiers (French RPG, Titam France/Sombres Projets)
|
||||
|
||||
## EN
|
||||
|
||||
Unofficial system for Hawkmoon (French version from Titam France).
|
||||
Unofficial system for Les Heritiers (from Titam France).
|
||||
|
||||
This system has been approved by Département des Sombres Projets ( http://www.titam-france.fr/ ), thanks !
|
||||
|
||||
@@ -10,7 +10,7 @@ Books are mandatory to play and are available at : http://www.titam-france.fr
|
||||
|
||||
## FR
|
||||
|
||||
Système non-officiel pour le JDR Hawkmoon (Titam France/Sombres Projets).
|
||||
Système non-officiel pour le JDR Les Héritiers (Titam France/Sombres Projets).
|
||||
|
||||
Ce système a été autorisé par le Département des Sombres Projets ( http://www.titam-france.fr/ ), merci à eux !
|
||||
|
||||
@@ -18,7 +18,7 @@ Les livres du jeu sont nécessaires pour jouer, et sont disponibles ici : http:/
|
||||
|
||||
# Credits
|
||||
|
||||
Hawkmoon, le jeu de rôle du Troisième Millénaire, is a property of Titam France/Sombres Projets.
|
||||
Les Héritiers, is a property of Titam France/Sombres Projets.
|
||||
|
||||
# Developmement
|
||||
|
||||
@@ -26,4 +26,4 @@ LeRatierBretonnien
|
||||
|
||||
# Tests, icones et saisie des données
|
||||
|
||||
Prêtre, Blondin, Zechrub/Chris, Kyllian, Lightbringer
|
||||
Prêtre, Carter
|
||||
|
||||
BIN
assets/icons/sort.webp
Normal file
BIN
assets/icons/sort.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 88 KiB |
BIN
assets/scenes/8DjkNeeujp2qff1N-thumb.webp
Normal file
BIN
assets/scenes/8DjkNeeujp2qff1N-thumb.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.2 KiB |
BIN
assets/scenes/ZjIQTg8S4hLZ4kXN-thumb.webp
Normal file
BIN
assets/scenes/ZjIQTg8S4hLZ4kXN-thumb.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.8 KiB |
BIN
assets/scenes/aanMTXv8znDyE6qb-thumb.webp
Normal file
BIN
assets/scenes/aanMTXv8znDyE6qb-thumb.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.2 KiB |
BIN
assets/scenes/ypDutqjqZcr7lx6I-thumb.webp
Normal file
BIN
assets/scenes/ypDutqjqZcr7lx6I-thumb.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.4 KiB |
BIN
assets/ui/heritiers_background_01.webp
Normal file
BIN
assets/ui/heritiers_background_01.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 192 KiB |
44
lang/fr.json
44
lang/fr.json
@@ -1,30 +1,24 @@
|
||||
{
|
||||
"ACTOR": {
|
||||
"TypePersonnage": "Personnage",
|
||||
"TypePNJ": "PNJ"
|
||||
"TYPES": {
|
||||
"Actor": {
|
||||
"personnage": "Personnage",
|
||||
"pnj": "PNJ"
|
||||
},
|
||||
|
||||
"ITEM": {
|
||||
"TypeArtefact": "Artefact",
|
||||
"TypeArme": "Arme",
|
||||
"TypeTalent": "Talent",
|
||||
"TypeHistorique": "Historique",
|
||||
"TypeProfil": "Profil",
|
||||
"TypeCompetence": "Compétence",
|
||||
"TypeProtection": "Protection",
|
||||
"TypeMonnaie": "Monnaie",
|
||||
"TypeEquipement": "Equipement",
|
||||
"TypeRessource": "Ressource",
|
||||
"TypeContact": "Contact"
|
||||
|
||||
},
|
||||
|
||||
"HAWKMOON": {
|
||||
"ui": {
|
||||
"editContact": "Modifier le contact",
|
||||
"deleteContact": "Supprimer le contact",
|
||||
"editTrait": "Modifier le trait",
|
||||
"deleteTrait": "Supprimer le trait"
|
||||
"Item": {
|
||||
"accessoire": "Accessoire",
|
||||
"arme": "Arme",
|
||||
"atoutfeerique": "Atout féerique",
|
||||
"avantage": "Avantage",
|
||||
"capacitenaturelle": "Capacité naturelle",
|
||||
"competence": "Compétence",
|
||||
"contact": "Contact",
|
||||
"desavantage": "Désavantage",
|
||||
"equipement": "Equipement",
|
||||
"fee": "Fée",
|
||||
"pouvoir": "Pouvoir",
|
||||
"profil": "Profil",
|
||||
"protection": "Protection",
|
||||
"sort": "Sort"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ export class HeritiersActorPNJSheet extends HeritiersActorSheet {
|
||||
/** @override */
|
||||
static get defaultOptions() {
|
||||
|
||||
return mergeObject(super.defaultOptions, {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
classes: ["fvtt-les-heritiers", "sheet", "actor"],
|
||||
template: "systems/fvtt-les-heritiers/templates/actor-pnj-sheet.html",
|
||||
width: 780,
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
import { HeritiersUtility } from "./heritiers-utility.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class HeritiersActorSheet extends ActorSheet {
|
||||
export class HeritiersActorSheet extends foundry.appv1.sheets.ActorSheet {
|
||||
|
||||
/** @override */
|
||||
static get defaultOptions() {
|
||||
|
||||
return mergeObject(super.defaultOptions, {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
classes: ["fvtt-les-heritiers", "sheet", "actor"],
|
||||
template: "systems/fvtt-les-heritiers/templates/actor-sheet.html",
|
||||
width: 780,
|
||||
@@ -24,7 +24,7 @@ export class HeritiersActorSheet extends ActorSheet {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async getData() {
|
||||
const objectData = duplicate(this.object)
|
||||
const objectData = foundry.utils.duplicate(this.object)
|
||||
|
||||
let formData = {
|
||||
title: this.title,
|
||||
@@ -40,28 +40,31 @@ export class HeritiersActorSheet extends ActorSheet {
|
||||
skills: this.actor.getSkills(),
|
||||
utileSkillsMental: this.actor.organizeUtileSkills("mental"),
|
||||
utileSkillsPhysical: this.actor.organizeUtileSkills("physical"),
|
||||
competencesMagie: HeritiersUtility.getCompetencesMagie(),
|
||||
futileSkills: this.actor.organizeFutileSkills(),
|
||||
contacts: this.actor.organizeContacts(),
|
||||
armes: duplicate(this.actor.getWeapons()),
|
||||
monnaies: duplicate(this.actor.getMonnaies()),
|
||||
pouvoirs: duplicate(this.actor.getPouvoirs()),
|
||||
fee: duplicate(this.actor.getFee() || {} ),
|
||||
protections: duplicate(this.actor.getArmors()),
|
||||
armes: foundry.utils.duplicate(this.actor.getWeapons()),
|
||||
monnaies: foundry.utils.duplicate(this.actor.getMonnaies()),
|
||||
pouvoirs: foundry.utils.duplicate(this.actor.getPouvoirs()),
|
||||
fee: foundry.utils.duplicate(this.actor.getFee() || {}),
|
||||
protections: foundry.utils.duplicate(this.actor.getArmors()),
|
||||
combat: this.actor.getCombatValues(),
|
||||
equipements: duplicate(this.actor.getEquipments()),
|
||||
avantages: duplicate(this.actor.getAvantages()),
|
||||
atouts: duplicate(this.actor.getAtouts()),
|
||||
capacites: duplicate(this.actor.getCapacites()),
|
||||
desavantages: duplicate(this.actor.getDesavantages()),
|
||||
profils: duplicate(this.actor.getProfils()),
|
||||
equipements: foundry.utils.duplicate(this.actor.getEquipments()),
|
||||
avantages: foundry.utils.duplicate(this.actor.getAvantages()),
|
||||
atouts: foundry.utils.duplicate(this.actor.getAtouts()),
|
||||
capacites: foundry.utils.duplicate(this.actor.getCapacites()),
|
||||
desavantages: foundry.utils.duplicate(this.actor.getDesavantages()),
|
||||
profils: foundry.utils.duplicate(this.actor.getProfils()),
|
||||
pvMalus: this.actor.getPvMalus(),
|
||||
heritage: game.settings.get("fvtt-les-heritiers", "heritiers-heritage"),
|
||||
initiative: this.actor.getFlag("world", "last-initiative") || -1,
|
||||
description: await TextEditor.enrichHTML(this.object.system.biodata.description, {async: true}),
|
||||
revesetranges: await TextEditor.enrichHTML(this.object.system.biodata.revesetranges, {async: true}),
|
||||
secretsdecouverts: await TextEditor.enrichHTML(this.object.system.biodata.secretsdecouverts, {async: true}),
|
||||
questions: await TextEditor.enrichHTML(this.object.system.biodata.questions, {async: true}),
|
||||
habitat: await TextEditor.enrichHTML(this.object.system.biodata.habitat, {async: true}),
|
||||
playernotes: await TextEditor.enrichHTML(this.object.system.biodata.playernotes, {async: true}),
|
||||
description: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.biodata.description, { async: true }),
|
||||
revesetranges: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.biodata.revesetranges, { async: true }),
|
||||
secretsdecouverts: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.biodata.secretsdecouverts, { async: true }),
|
||||
questions: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.biodata.questions, { async: true }),
|
||||
habitat: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.biodata.habitat, { async: true }),
|
||||
playernotes: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.biodata.playernotes, { async: true }),
|
||||
magieList: this.actor.prepareMagie(),
|
||||
options: this.options,
|
||||
owner: this.document.isOwner,
|
||||
editScore: this.options.editScore,
|
||||
@@ -76,19 +79,42 @@ export class HeritiersActorSheet extends ActorSheet {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getCelluleTalents( ) {
|
||||
let talents = []
|
||||
for(let cellule of game.actors) {
|
||||
if (cellule.type == "cellule") {
|
||||
let found = cellule.system.members.find( it => it.id == this.actor.id)
|
||||
if (found) {
|
||||
talents = talents.concat( cellule.getTalents() )
|
||||
dialogRecupUsage() {
|
||||
new Dialog({
|
||||
title: "Récupération des Points d'Usage",
|
||||
content: "<p>Combien de Points d'Usage souhaitez-vous récupérer ?</p>",
|
||||
buttons: {
|
||||
one: {
|
||||
icon: '<i class="fas fa-check"></i>',
|
||||
label: "1 Point",
|
||||
callback: () => {
|
||||
this.actor.recupUsage(1)
|
||||
}
|
||||
},
|
||||
two: {
|
||||
icon: '<i class="fas fa-check"></i>',
|
||||
label: "2 Points",
|
||||
callback: () => {
|
||||
this.actor.recupUsage(2)
|
||||
}
|
||||
},
|
||||
four: {
|
||||
icon: '<i class="fas fa-check"></i>',
|
||||
label: "4 Points",
|
||||
callback: () => {
|
||||
this.actor.recupUsage(4)
|
||||
}
|
||||
},
|
||||
all: {
|
||||
icon: '<i class="fas fa-check"></i>',
|
||||
label: "Tous les Points",
|
||||
callback: () => {
|
||||
this.actor.recupUsage(100)
|
||||
}
|
||||
}
|
||||
}
|
||||
return talents
|
||||
}).render(true)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/** @override */
|
||||
activateListeners(html) {
|
||||
@@ -153,19 +179,51 @@ export class HeritiersActorSheet extends ActorSheet {
|
||||
let compId = li.data("item-id")
|
||||
this.actor.rollCompetence(compId)
|
||||
})
|
||||
html.find('.roll-sort').click((event) => {
|
||||
const li = $(event.currentTarget).parents(".item")
|
||||
let sortId = li.data("item-id")
|
||||
this.actor.rollSort(sortId)
|
||||
})
|
||||
html.find('.roll-attaque-arme').click((event) => {
|
||||
const li = $(event.currentTarget).parents(".item")
|
||||
let armeId = li.data("item-id")
|
||||
this.actor.rollAttaqueArme(armeId)
|
||||
})
|
||||
html.find('.roll-attaque-brutale-arme').click((event) => {
|
||||
const li = $(event.currentTarget).parents(".item")
|
||||
let armeId = li.data("item-id")
|
||||
this.actor.rollAttaqueBrutaleArme(armeId)
|
||||
})
|
||||
html.find('.roll-attaque-charge-arme').click((event) => {
|
||||
const li = $(event.currentTarget).parents(".item")
|
||||
let armeId = li.data("item-id")
|
||||
this.actor.rollAttaqueChargeArme(armeId)
|
||||
})
|
||||
html.find('.roll-assomer-arme').click((event) => {
|
||||
const li = $(event.currentTarget).parents(".item")
|
||||
let armeId = li.data("item-id")
|
||||
this.actor.rollAssomerArme(armeId)
|
||||
})
|
||||
|
||||
html.find('.roll-pouvoir').click((event) => {
|
||||
const li = $(event.currentTarget).parents(".item")
|
||||
let pouvoirId = li.data("item-id")
|
||||
this.actor.rollPouvoir(pouvoirId)
|
||||
})
|
||||
html.find('.dialog-recup-usage').click((event) => {
|
||||
this.dialogRecupUsage()
|
||||
})
|
||||
|
||||
html.find('.item-add').click((event) => {
|
||||
const itemType = $(event.currentTarget).data("type")
|
||||
if (itemType == "sort") {
|
||||
// Get data-sort-competence
|
||||
let sortCompetence = $(event.currentTarget).data("sort-competence");
|
||||
if (sortCompetence) {
|
||||
this.actor.createEmbeddedDocuments('Item', [{ name: `Nouveau ${itemType} de ${sortCompetence}`, type: itemType, system: { competence: sortCompetence } }], { renderSheet: true })
|
||||
return
|
||||
}
|
||||
}
|
||||
this.actor.createEmbeddedDocuments('Item', [{ name: `Nouveau ${itemType}`, type: itemType }], { renderSheet: true })
|
||||
})
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ export class HeritiersActor extends Actor {
|
||||
const skills = await HeritiersUtility.loadCompendium("fvtt-les-heritiers.competences")
|
||||
data.items = []
|
||||
for (let skill of skills) {
|
||||
if (skill.system.categorie == "utile") {
|
||||
if (skill.system.categorie == "utile" && skill.system.profil != "magie") {
|
||||
data.items.push(skill.toObject())
|
||||
}
|
||||
}
|
||||
@@ -54,26 +54,8 @@ export class HeritiersActor extends Actor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
prepareArme(arme) {
|
||||
arme = duplicate(arme)
|
||||
let combat = this.getCombatValues()
|
||||
if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
|
||||
let bonusDefense = 0
|
||||
arme.system.competence = duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
|
||||
arme.system.attrKey = "pui"
|
||||
arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
|
||||
arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
|
||||
arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense
|
||||
arme.system.isdefense = true
|
||||
}
|
||||
if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
|
||||
arme.system.competence = duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
|
||||
arme.system.attrKey = "adr"
|
||||
arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
|
||||
arme.system.totalDegats = arme.system.degats
|
||||
if (arme.system.isdefense) {
|
||||
arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
|
||||
}
|
||||
}
|
||||
arme = foundry.utils.duplicate(arme)
|
||||
arme.system.isMelee = HeritiersUtility.isArmeMelee(arme)
|
||||
return arme
|
||||
}
|
||||
|
||||
@@ -88,13 +70,23 @@ export class HeritiersActor extends Actor {
|
||||
return armes
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getOtherMeleeWeapons(excludeArme) {
|
||||
let armes = []
|
||||
for (let arme of this.items) {
|
||||
if (HeritiersUtility.isArmeMelee(arme) && arme.id != excludeArme._id) {
|
||||
armes.push(this.prepareArme(arme))
|
||||
}
|
||||
}
|
||||
return armes
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getMonnaies() {
|
||||
return this.items.filter(it => it.type == "monnaie")
|
||||
}
|
||||
|
||||
/* ----------------------- --------------------- */
|
||||
addMember(actorId) {
|
||||
let members = duplicate(this.system.members)
|
||||
let members = foundry.utils.duplicate(this.system.members)
|
||||
members.push({ id: actorId })
|
||||
this.update({ 'system.members': members })
|
||||
}
|
||||
@@ -143,13 +135,67 @@ export class HeritiersActor extends Actor {
|
||||
return this.getItemSorted(["profil"])
|
||||
}
|
||||
getPouvoirs() {
|
||||
return this.getItemSorted( ["pouvoir"])
|
||||
let pouvoirs = []
|
||||
for (let item of this.items) {
|
||||
if (item.type == "pouvoir") {
|
||||
let itemObj = foundry.utils.duplicate(item)
|
||||
itemObj.maxUsage = this.getPouvoirUsageMax(item)
|
||||
pouvoirs.push(itemObj)
|
||||
}
|
||||
}
|
||||
HeritiersUtility.sortArrayObjectsByName(pouvoirs)
|
||||
return pouvoirs
|
||||
}
|
||||
getSorts() {
|
||||
return this.getItemSorted(["sort"])
|
||||
}
|
||||
getCompetencesMagie() {
|
||||
let comp = []
|
||||
for (let item of this.items) {
|
||||
if (item.type == "competence" && item.system.profil == "magie") {
|
||||
let itemObj = foundry.utils.duplicate(item)
|
||||
comp.push(itemObj)
|
||||
}
|
||||
}
|
||||
HeritiersUtility.sortArrayObjectsByName(comp)
|
||||
return comp
|
||||
}
|
||||
|
||||
prepareMagie() {
|
||||
let magieList = []
|
||||
for (let item of this.items) {
|
||||
if (item.type == "competence" && item.system.profil == "magie") {
|
||||
let magie = {}
|
||||
magie.name = item.name
|
||||
magie.competence = foundry.utils.duplicate(item)
|
||||
magie.rang = Math.round(item.system.niveau / 2);
|
||||
magie.rangGenericName = game.system.lesheritiers.config.rangName[magie.rang];
|
||||
console.log("Magie", item.name, item.system.niveau, magie.rang, magie.rangGenericName)
|
||||
magie.rangSpecificName = game.system.lesheritiers.config.rangNameSpecific[item.name][magie.rangGenericName];
|
||||
magie.sorts = {
|
||||
1: { nomNiveau: magie.competence.system.nomniveau["1"], sorts: [] },
|
||||
2: { nomNiveau: magie.competence.system.nomniveau["2"], sorts: [] },
|
||||
3: { nomNiveau: magie.competence.system.nomniveau["3"], sorts: [] },
|
||||
4: { nomNiveau: magie.competence.system.nomniveau["4"], sorts: [] }
|
||||
}
|
||||
for (let sort of this.items) {
|
||||
if (sort.type == "sort" && sort.system.competence == item.name) {
|
||||
let sortObj = foundry.utils.duplicate(sort)
|
||||
sortObj.sdValue = HeritiersUtility.getSDSortValue(Number(sort.system.niveau))
|
||||
magie.sorts[Number(sort.system.niveau)].sorts.push(sortObj)
|
||||
}
|
||||
}
|
||||
magieList.push(magie)
|
||||
}
|
||||
}
|
||||
return magieList
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getSkills() {
|
||||
let comp = []
|
||||
for (let item of this.items) {
|
||||
item = duplicate(item)
|
||||
item = foundry.utils.duplicate(item)
|
||||
if (item.type == "competence") {
|
||||
comp.push(item)
|
||||
}
|
||||
@@ -160,7 +206,7 @@ export class HeritiersActor extends Actor {
|
||||
/* -------------------------------------------- */
|
||||
prepareUtileSkill(item) {
|
||||
let specList = []
|
||||
if (item && item.system.categorie && item.system.categorie == "utile") {
|
||||
if (item?.system?.categorie == "utile") {
|
||||
for (let spec of item.system.specialites) {
|
||||
specList.push(spec.name)
|
||||
}
|
||||
@@ -169,6 +215,28 @@ export class HeritiersActor extends Actor {
|
||||
item.specList = specList.toString()
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
organizeMagicSkills() {
|
||||
let comp = {}
|
||||
for (let key in game.system.lesheritiers.config.competenceProfil) {
|
||||
if (game.system.lesheritiers.config.competenceProfil[key].kind == "magical")
|
||||
comp[key] = { skills: [], niveau: 0 }
|
||||
}
|
||||
for (let item of this.items) {
|
||||
if (item.type == "competence") {
|
||||
if (item.system.categorie == "utile" && comp[item.system.profil]) {
|
||||
this.prepareUtileSkill(item)
|
||||
comp[item.system.profil].skills.push(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let key in comp) {
|
||||
HeritiersUtility.sortArrayObjectsByName(comp[key].skills)
|
||||
}
|
||||
return Object.fromEntries(Object.entries(comp).sort())
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
organizeUtileSkills(kind = "mental") {
|
||||
let comp = {}
|
||||
@@ -190,6 +258,7 @@ export class HeritiersActor extends Actor {
|
||||
}
|
||||
return Object.fromEntries(Object.entries(comp).sort())
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
organizeContacts() {
|
||||
let contactList = {}
|
||||
@@ -256,9 +325,39 @@ export class HeritiersActor extends Actor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async prepareData() {
|
||||
|
||||
let pvMax = (this.system.caracteristiques.con.rang * 3) + 9 + this.system.pv.mod
|
||||
if (this.system.pv.max != pvMax) {
|
||||
this.update({ 'system.pv.max': pvMax })
|
||||
}
|
||||
if (this.system.biodata.magie || this.type == "pnj") {
|
||||
let pointsAmes = this.system.caracteristiques.esp.rang + this.system.caracteristiques.san.rang + this.getMaxRangMagie()
|
||||
if (this.system.magie.pointsame.max != pointsAmes) {
|
||||
this.update({ 'system.magie.pointsame.max': pointsAmes })
|
||||
}
|
||||
}
|
||||
|
||||
super.prepareData();
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getMaxRangMagie() {
|
||||
let niv = 0
|
||||
let bestMagie
|
||||
for (let comp of this.items) {
|
||||
if (comp.type == "competence" && comp.system.profil == "magie") {
|
||||
if (comp.system.niveau > niv) {
|
||||
bestMagie = comp
|
||||
niv = comp.system.niveau
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bestMagie) {
|
||||
return Math.round(bestMagie.system.niveau / 2)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
prepareDerivedData() {
|
||||
|
||||
@@ -278,7 +377,7 @@ export class HeritiersActor extends Actor {
|
||||
getItemById(id) {
|
||||
let item = this.items.find(item => item.id == id);
|
||||
if (item) {
|
||||
item = duplicate(item)
|
||||
item = foundry.utils.duplicate(item)
|
||||
}
|
||||
return item;
|
||||
}
|
||||
@@ -286,7 +385,7 @@ export class HeritiersActor extends Actor {
|
||||
/* -------------------------------------------- */
|
||||
async equipItem(itemId) {
|
||||
let item = this.items.find(item => item.id == itemId)
|
||||
if (item && item.system) {
|
||||
if (item?.system) {
|
||||
let update = { _id: item.id, "system.equipped": !item.system.equipped }
|
||||
await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
|
||||
}
|
||||
@@ -312,15 +411,15 @@ export class HeritiersActor extends Actor {
|
||||
/* -------------------------------------------- */
|
||||
getPvMalus() {
|
||||
if (this.system.pv.value > 0) {
|
||||
if (this.system.pv.value < this.system.pv.max / 2) {
|
||||
return -1
|
||||
}
|
||||
if (this.system.pv.value < 5) {
|
||||
return -2
|
||||
return { name: "Santé", value: -2 }
|
||||
}
|
||||
return 0
|
||||
if (this.system.pv.value < this.system.pv.max / 2) {
|
||||
return { name: "Santé", value: -1 }
|
||||
}
|
||||
return "Moribond(e)"
|
||||
return { name: "Santé", value: 0 }
|
||||
}
|
||||
return { name: "Moribond(e)", value: -50 }
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -336,7 +435,7 @@ export class HeritiersActor extends Actor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getCarac(attrKey) {
|
||||
return duplicate(this.system.caracteristiques)
|
||||
return foundry.utils.duplicate(this.system.caracteristiques)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -347,7 +446,7 @@ export class HeritiersActor extends Actor {
|
||||
/* -------------------------------------------- */
|
||||
async equipGear(equipmentId) {
|
||||
let item = this.items.find(item => item.id == equipmentId);
|
||||
if (item && item.system.data) {
|
||||
if (item?.system) {
|
||||
let update = { _id: item.id, "system.equipped": !item.system.equipped };
|
||||
await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
|
||||
}
|
||||
@@ -357,13 +456,13 @@ export class HeritiersActor extends Actor {
|
||||
getSubActors() {
|
||||
let subActors = [];
|
||||
for (let id of this.system.subactors) {
|
||||
subActors.push(duplicate(game.actors.get(id)));
|
||||
subActors.push(foundry.utils.duplicate(game.actors.get(id)));
|
||||
}
|
||||
return subActors;
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
async addSubActor(subActorId) {
|
||||
let subActors = duplicate(this.system.subactors);
|
||||
let subActors = foundry.utils.duplicate(this.system.subactors);
|
||||
subActors.push(subActorId);
|
||||
await this.update({ 'system.subactors': subActors });
|
||||
}
|
||||
@@ -385,11 +484,12 @@ export class HeritiersActor extends Actor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async incDecAdversite(adv, incDec = 0) {
|
||||
let adversite = duplicate(this.system.adversite)
|
||||
let adversite = foundry.utils.duplicate(this.system.adversite)
|
||||
adversite[adv] += Number(incDec)
|
||||
adversite[adv] = Math.max(adversite[adv], 0)
|
||||
this.update({ 'system.adversite': adversite })
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async incDecQuantity(objetId, incDec = 0) {
|
||||
let objetQ = this.items.get(objetId)
|
||||
@@ -432,7 +532,7 @@ export class HeritiersActor extends Actor {
|
||||
/* -------------------------------------------- */
|
||||
async setPredilectionUsed(compId, predIdx) {
|
||||
let comp = this.items.get(compId)
|
||||
let pred = duplicate(comp.system.predilections)
|
||||
let pred = foundry.utils.duplicate(comp.system.predilections)
|
||||
pred[predIdx].used = true
|
||||
await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
|
||||
}
|
||||
@@ -454,7 +554,7 @@ export class HeritiersActor extends Actor {
|
||||
}
|
||||
if (arme.system.totalDefensif > maxDef) {
|
||||
maxDef = arme.system.totalDefensif
|
||||
bestArme = duplicate(arme)
|
||||
bestArme = foundry.utils.duplicate(arme)
|
||||
}
|
||||
}
|
||||
return bestArme
|
||||
@@ -469,7 +569,7 @@ export class HeritiersActor extends Actor {
|
||||
for (let auto of talent.system.automations) {
|
||||
if (auto.eventtype === "prepare-roll") {
|
||||
if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
|
||||
talent = duplicate(talent)
|
||||
talent = foundry.utils.duplicate(talent)
|
||||
talent.system.bonus = auto.bonus
|
||||
talent.system.baCost = auto.baCost
|
||||
talents.push(talent)
|
||||
@@ -494,7 +594,9 @@ export class HeritiersActor extends Actor {
|
||||
}
|
||||
return this.system.combat.esquive.demasquee
|
||||
}
|
||||
|
||||
getCurrentResistancePhysique() {
|
||||
return this.system.combat.resistancephysique.value
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getTricherie() {
|
||||
return this.system.rang.tricherie.value
|
||||
@@ -507,9 +609,27 @@ export class HeritiersActor extends Actor {
|
||||
incDecTricherie(value) {
|
||||
let tricherie = this.system.rang.tricherie
|
||||
tricherie.value += value
|
||||
if (tricherie.value < 0 || tricherie.value > tricherie.max) {
|
||||
ui.notifications.warn("Pas assez de points de Tricherie !")
|
||||
return false
|
||||
}
|
||||
tricherie.value = Math.max(tricherie.value, 0)
|
||||
tricherie.value = Math.min(tricherie.value, tricherie.max)
|
||||
this.update({ 'system.rang.tricherie': tricherie })
|
||||
return true
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getPireCompetence(compName1, compName2) {
|
||||
let comp1 = this.items.find(it => it.name == compName1)
|
||||
let comp2 = this.items.find(it => it.name == compName2)
|
||||
if (comp1 && comp2) {
|
||||
if (comp1.system.niveau > comp2.system.niveau) {
|
||||
return comp1
|
||||
} else {
|
||||
return comp2
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -527,16 +647,17 @@ export class HeritiersActor extends Actor {
|
||||
rollData.useTricherie = false
|
||||
rollData.useSpecialite = false
|
||||
rollData.useHeritage = false
|
||||
rollData.pvMalus = this.getPvMalus()
|
||||
rollData.pouvoirPointsUsage = 1
|
||||
rollData.rulesMalus.push(this.getPvMalus())
|
||||
|
||||
if (compId) {
|
||||
rollData.competence = duplicate(this.items.get(compId) || {})
|
||||
rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
|
||||
this.prepareUtileSkill(rollData.competence)
|
||||
rollData.actionImg = rollData.competence?.img
|
||||
}
|
||||
if (compName) {
|
||||
rollData.competence = duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
|
||||
if (rollData.competence && rollData.competence.name) {
|
||||
rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
|
||||
if (rollData.competence?.name) {
|
||||
this.prepareUtileSkill(rollData.competence)
|
||||
rollData.actionImg = rollData.competence?.img
|
||||
} else {
|
||||
@@ -584,7 +705,6 @@ export class HeritiersActor extends Actor {
|
||||
async rollRootCompetence(compKey) {
|
||||
let rollData = this.getCommonRollData()
|
||||
rollData.mode = "competence"
|
||||
console.log("Compkey", compKey)
|
||||
rollData.competence = { name: this.system.competences[compKey].label, system: { niveau: this.system.competences[compKey].niveau } }
|
||||
console.log("RollDatra", rollData)
|
||||
let rollDialog = await HeritiersRollDialog.create(this, rollData)
|
||||
@@ -599,83 +719,292 @@ export class HeritiersActor extends Actor {
|
||||
let rollDialog = await HeritiersRollDialog.create(this, rollData)
|
||||
rollDialog.render(true)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
inDecCarac(key, incDec) {
|
||||
let carac = this.system.caracteristiques[key]
|
||||
carac.value += incDec
|
||||
if (carac.value < 0 || carac.value > carac.max) {
|
||||
ui.notifications.warn("Pas assez de points dans cette caractéristique !")
|
||||
return false
|
||||
}
|
||||
carac.value = Math.max(carac.value, 0)
|
||||
carac.value = Math.min(carac.value, carac.max)
|
||||
this.update({ [`system.caracteristiques.${key}`]: carac })
|
||||
return true
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollSort(sortId) {
|
||||
let sort = this.items.get(sortId)
|
||||
let comp = this.items.find(it => it.type == "competence" && it.name.toLowerCase() == sort.system.competence.toLowerCase())
|
||||
if (!comp) {
|
||||
ui.notifications.warn("Compétence de magie associée non trouvée !")
|
||||
return
|
||||
}
|
||||
|
||||
let rollData = this.getCommonRollData(comp.id)
|
||||
rollData.mode = "sort"
|
||||
rollData.sort = foundry.utils.duplicate(sort)
|
||||
rollData.sdValue = HeritiersUtility.getSDSortValue(Number(sort.system.niveau))
|
||||
rollData.sortPointsAme = Number(sort.system.niveau)
|
||||
if (rollData.sortPointsAme > this.system.magie.pointsame.value) {
|
||||
// Vérifier si au moins 1 point d'Esprit est disponible
|
||||
if (this.system.caracteristiques.esp.value < 1) {
|
||||
ui.notifications.warn("Pas assez de Points d'Esprit ni de Points d'Ame pour lancer ce sort (requis: 1, disponible: " + this.system.caracteristiques.esp.value + ")")
|
||||
return
|
||||
} else {
|
||||
rollData.spendEsprit = true
|
||||
ui.notifications.warn(`Vous n'avez pas assez de Points d'Ame pour lancer ce sort (requis: ${rollData.sortPointsAme}, disponible: ${this.system.magie.pointsame.value}). Un Point d'Esprit sera utilisé à la place si vous effectuez le lancer.`)
|
||||
}
|
||||
}
|
||||
|
||||
if (sort.system.carac2 != "none") {
|
||||
// get the best carac between carac1 and carac2
|
||||
if (this.system.caracteristiques[sort.system.carac1].value > this.system.caracteristiques[sort.system.carac2].value) {
|
||||
rollData.caracKey = sort.system.carac1
|
||||
} else {
|
||||
rollData.caracKey = sort.system.carac2
|
||||
}
|
||||
rollData.caracMessage = "Ce sort peut être lancé avec " + game.system.lesheritiers.config.caracList[sort.system.carac1] + " ou " + game.system.lesheritiers.config.caracList[sort.system.carac2] + ". La meilleure caractéristique a été selectionnée."
|
||||
} else {
|
||||
rollData.caracKey = sort.system.carac1
|
||||
}
|
||||
console.log("RollData", rollData)
|
||||
let rollDialog = await HeritiersRollDialog.create(this, rollData)
|
||||
rollDialog.render(true)
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollAttaqueArme(armeId) {
|
||||
let arme = this.items.get(armeId)
|
||||
if (arme) {
|
||||
arme = foundry.utils.duplicate(arme)
|
||||
arme.system.isMelee = HeritiersUtility.isArmeMelee(arme)
|
||||
let competenceName = "Tir"
|
||||
let key = "prec"
|
||||
if (arme.system.categorie == "blanche" || arme.system.categorie == "improvise") {
|
||||
if (arme.system.isMelee) {
|
||||
competenceName = "Mêlée"
|
||||
key = "agi"
|
||||
}
|
||||
let rollData = this.getCommonRollData(undefined, competenceName)
|
||||
rollData.carac = this.system.caracteristiques[key]
|
||||
rollData.caracKey = key
|
||||
rollData.arme = duplicate(arme)
|
||||
rollData.arme = arme
|
||||
rollData.mode = "arme"
|
||||
rollData.armes = this.getOtherMeleeWeapons(arme)
|
||||
if (rollData.defenderTokenId && arme.system.isMelee) {
|
||||
rollData.cacheDifficulte = true
|
||||
}
|
||||
console.log(">>>> ARME", rollData)
|
||||
let rollDialog = await HeritiersRollDialog.create(this, rollData)
|
||||
rollDialog.render(true)
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollAttaqueBrutaleArme(armeId) {
|
||||
let arme = this.items.get(armeId)
|
||||
if (arme) {
|
||||
let key = "for"
|
||||
let competenceName = "Mêlée"
|
||||
arme.system.isMelee = HeritiersUtility.isArmeMelee(arme)
|
||||
let rollData = this.getCommonRollData(undefined, competenceName)
|
||||
rollData.carac = this.system.caracteristiques[key]
|
||||
rollData.caracKey = key
|
||||
rollData.arme = foundry.utils.duplicate(arme)
|
||||
rollData.mode = "attaquebrutale"
|
||||
rollData.armes = this.getOtherMeleeWeapons(arme)
|
||||
rollData.rulesMalus.push({ name: "Attaque brutale", value: -2 })
|
||||
let rollDialog = await HeritiersRollDialog.create(this, rollData)
|
||||
rollDialog.render(true)
|
||||
}
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
async rollAttaqueChargeArme(armeId) {
|
||||
let arme = this.items.get(armeId)
|
||||
if (arme) {
|
||||
let key = "agi"
|
||||
arme.system.isMelee = HeritiersUtility.isArmeMelee(arme)
|
||||
let pireCompetence = this.getPireCompetence("Mêlée", "Mouvement")
|
||||
let rollData = this.getCommonRollData(undefined, pireCompetence.name)
|
||||
rollData.carac = this.system.caracteristiques[key]
|
||||
rollData.caracKey = key
|
||||
rollData.arme = foundry.utils.duplicate(arme)
|
||||
rollData.armes = this.getOtherMeleeWeapons(arme)
|
||||
rollData.mode = "attaquecharge"
|
||||
let rollDialog = await HeritiersRollDialog.create(this, rollData)
|
||||
rollDialog.render(true)
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollAssomerArme(armeId) {
|
||||
let arme = this.items.get(armeId)
|
||||
if (arme) {
|
||||
let competenceName = "Mêlée"
|
||||
//arme.system.isMelee = HeritiersUtility.isArmeMelee(arme)
|
||||
let rollData = this.getCommonRollData(undefined, competenceName)
|
||||
rollData.carac = this.system.caracteristiques["agi"]
|
||||
rollData.caracKey = "agi"
|
||||
rollData.arme = foundry.utils.duplicate(arme)
|
||||
rollData.mode = "assommer"
|
||||
if (rollData.defenderTokenId) {
|
||||
rollData.cacheDifficulte = true
|
||||
}
|
||||
let rollDialog = await HeritiersRollDialog.create(this, rollData)
|
||||
rollDialog.render(true)
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
pouvoirPassifDialog(pouvoir) {
|
||||
let rollData = this.getCommonRollData()
|
||||
rollData.pouvoir = pouvoir
|
||||
rollData.mode = "pouvoirpassif"
|
||||
rollData.pouvoirPointsUsage = 0
|
||||
rollData.noRoll = true
|
||||
|
||||
let d = new Dialog({
|
||||
title: "Activer le pouvoir passif " + pouvoir.name,
|
||||
content: "<p>Choisissez le nombre de Points d'Usage</p>",
|
||||
buttons: {
|
||||
one: {
|
||||
icon: '<i class="fas fa-check"></i>',
|
||||
label: "1 Point d'Usage",
|
||||
callback: () => {
|
||||
rollData.pouvoirPointsUsage = 1;
|
||||
HeritiersUtility.rollHeritiers(rollData);
|
||||
}
|
||||
},
|
||||
two: {
|
||||
icon: '<i class="fas fa-check"></i>',
|
||||
label: "2 Points d'Usage",
|
||||
callback: () => {
|
||||
rollData.pouvoirPointsUsage = 2;
|
||||
HeritiersUtility.rollHeritiers(rollData);
|
||||
}
|
||||
},
|
||||
three: {
|
||||
icon: '<i class="fas fa-check"></i>',
|
||||
label: "3 Points d'Usage",
|
||||
callback: () => {
|
||||
rollData.pouvoirPointsUsage = 3;
|
||||
HeritiersUtility.rollHeritiers(rollData);
|
||||
}
|
||||
},
|
||||
four: {
|
||||
icon: '<i class="fas fa-check"></i>',
|
||||
label: "4 Points d'Usage",
|
||||
callback: () => {
|
||||
rollData.pouvoirPointsUsage = 4;
|
||||
HeritiersUtility.rollHeritiers(rollData);
|
||||
}
|
||||
},
|
||||
close: {
|
||||
icon: '<i class="fas fa-times"></i>',
|
||||
label: "Annuler",
|
||||
callback: () => {
|
||||
}
|
||||
}
|
||||
},
|
||||
default: "one",
|
||||
render: html => console.log("Pouvoir passif"),
|
||||
close: html => console.log("No option")
|
||||
});
|
||||
d.render(true);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollPouvoir(pouvoirId) {
|
||||
let pouvoir = this.items.get(pouvoirId)
|
||||
if (pouvoir) {
|
||||
if (pouvoir.system.pouvoirtype == "passif") {
|
||||
this.pouvoirPassifDialog(pouvoir)
|
||||
return
|
||||
}
|
||||
|
||||
let rollData = this.getCommonRollData(undefined, undefined)
|
||||
if ( pouvoir.system.feeriemasque != "autre") {
|
||||
rollData.pouvoirBase = duplicate(this.system.rang[pouvoir.system.feeriemasque.toLowerCase()])
|
||||
rollData.pouvoirBase.label = "Féerie"
|
||||
rollData.carac = duplicate(this.system.caracteristiques[pouvoir.system.carac])
|
||||
rollData.caracKey = pouvoir.system.carac
|
||||
}
|
||||
rollData.pouvoir = duplicate(pouvoir)
|
||||
|
||||
rollData.pouvoirMaxUsage = this.getPouvoirUsageMax(pouvoir)
|
||||
rollData.pouvoir = foundry.utils.duplicate(pouvoir)
|
||||
rollData.mode = "pouvoir"
|
||||
|
||||
if (pouvoir.system.feeriemasque != "autre") {
|
||||
rollData.pouvoirBase = foundry.utils.duplicate(this.system.rang[pouvoir.system.feeriemasque.toLowerCase()])
|
||||
rollData.pouvoirBase.label = "Féerie"
|
||||
if (pouvoir.system.istest && !pouvoir.system.carac) {
|
||||
ui.notifications.warn("Le pouvoir actif " + pouvoir.name + " n'a pas de caractéristique associée")
|
||||
}
|
||||
if (pouvoir.system.istest) {
|
||||
rollData.carac = foundry.utils.duplicate(this.system.caracteristiques[pouvoir.system.carac])
|
||||
rollData.caracKey = pouvoir.system.carac
|
||||
} else {
|
||||
rollData.noRoll = true
|
||||
HeritiersUtility.rollHeritiers(rollData);
|
||||
return;
|
||||
//this.incDecPointsUsage(pouvoir.id, -rollData.pouvoirPointsUsage)
|
||||
//ui.notifications.warn("Le pouvoir actif " + pouvoir.name + " a été utilisé, dépense de " + pouvoirPointsUsage + " points d'usage")
|
||||
}
|
||||
}
|
||||
let rollDialog = await HeritiersRollDialog.create(this, rollData)
|
||||
rollDialog.render(true)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollArmeOffensif(armeId) {
|
||||
let arme = this.items.get(armeId)
|
||||
if (arme.type == "arme") {
|
||||
arme = this.prepareArme(arme)
|
||||
}
|
||||
let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
|
||||
rollData.arme = arme
|
||||
HeritiersUtility.updateWithTarget(rollData)
|
||||
console.log("ARME!", rollData)
|
||||
let rollDialog = await HeritiersRollDialog.create(this, rollData)
|
||||
rollDialog.render(true)
|
||||
incDecPointsAme(value) {
|
||||
let newValue = this.system.magie.pointsame.value + value
|
||||
newValue = Math.max(newValue, 0)
|
||||
newValue = Math.min(newValue, this.system.magie.pointsame.max)
|
||||
this.update({ 'system.magie.pointsame.value': newValue })
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollArmeDegats(armeId, targetVigueur = undefined) {
|
||||
let arme = this.items.get(armeId)
|
||||
if (arme.type == "arme") {
|
||||
arme = this.prepareArme(arme)
|
||||
incDecPV(value) {
|
||||
let newValue = this.system.pv.value + value
|
||||
newValue = Math.max(newValue, 0)
|
||||
newValue = Math.min(newValue, this.system.pv.max)
|
||||
this.update({ 'system.pv.value': newValue })
|
||||
}
|
||||
console.log("DEGATS", arme)
|
||||
let roll = new Roll("1d10+" + arme.system.totalDegats).roll({ async: false })
|
||||
await HeritiersUtility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
|
||||
let nbEtatPerdus = 0
|
||||
if (targetVigueur) {
|
||||
nbEtatPerdus = Math.floor(roll.total / targetVigueur)
|
||||
}
|
||||
let rollData = {
|
||||
arme: arme,
|
||||
finalResult: roll.total,
|
||||
alias: this.name,
|
||||
actorImg: this.img,
|
||||
actorId: this.id,
|
||||
actionImg: arme.img,
|
||||
targetVigueur: targetVigueur,
|
||||
nbEtatPerdus: nbEtatPerdus
|
||||
}
|
||||
HeritiersUtility.createChatWithRollMode(rollData.alias, {
|
||||
content: await renderTemplate(`systems/fvtt-les-heritiers/templates/chat-degats-result.html`, rollData)
|
||||
})
|
||||
|
||||
/* -------------------------------------------- */
|
||||
incDecPointsUsage(pouvoirId, value) {
|
||||
let pouvoir = this.items.get(pouvoirId)
|
||||
let newValue = pouvoir.system.pointsusagecourant + value
|
||||
newValue = Math.max(newValue, 0)
|
||||
newValue = Math.min(newValue, this.getPouvoirUsageMax(pouvoir))
|
||||
this.updateEmbeddedDocuments('Item', [{ _id: pouvoirId, 'system.pointsusagecourant': newValue }])
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getPouvoirUsage(pouvoirId) {
|
||||
let pouvoir = this.items.get(pouvoirId)
|
||||
return pouvoir.system.pointsusagecourant
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getPouvoirUsageMax(pouvoir) {
|
||||
if (pouvoir.system.masquetype == "masque") {
|
||||
return this.system.rang.masque.value
|
||||
}
|
||||
return this.system.rang.feerie.value
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
recupUsage(value) {
|
||||
let updates = []
|
||||
for (let pouvoir of this.items) {
|
||||
if (pouvoir.type == "pouvoir") {
|
||||
let newValue = pouvoir.system.pointsusagecourant + value
|
||||
newValue = Math.max(newValue, 0)
|
||||
newValue = Math.min(newValue, this.getPouvoirUsageMax(pouvoir))
|
||||
updates.push({ _id: pouvoir.id, 'system.pointsusagecourant': newValue })
|
||||
}
|
||||
}
|
||||
if (updates.length > 0) {
|
||||
this.updateEmbeddedDocuments('Item', updates)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,8 @@ export const HERITIERS_CONFIG = {
|
||||
"combattant": { kind: "physical", name: "Combattant" },
|
||||
"erudit": { kind: "mental", name: "Erudit" },
|
||||
"savant": { kind: "mental", name: "Savant" },
|
||||
"gentleman": {kind: "mental",name:"Gentleman"}
|
||||
"gentleman": { kind: "mental", name: "Gentleman" },
|
||||
"magie": { kind: "magical", name: "Magie" },
|
||||
},
|
||||
baseTestPouvoir: {
|
||||
"feerie": "Féerie",
|
||||
@@ -65,32 +66,39 @@ export const HERITIERS_CONFIG = {
|
||||
},
|
||||
seuilsDifficulte: {
|
||||
"-1": "Aucun/Non applicable",
|
||||
"5": "Enfantine",
|
||||
"6": "Triviale",
|
||||
"7": "Moins Triviale",
|
||||
"8": "Aisée",
|
||||
"7": "Moins Aisée",
|
||||
"10": "Normale",
|
||||
"11": "Moins Normale",
|
||||
"12": "Compliquée",
|
||||
"13": "Plus Compliquée",
|
||||
"14": "Difficile",
|
||||
"15": "Plus Difficile",
|
||||
"16": "Très Difficile",
|
||||
"17": "Très Très Difficile",
|
||||
"18": "Critique",
|
||||
"19": "Plus Critique",
|
||||
"20": "Insurmontable",
|
||||
"20": "Très Insurmontable",
|
||||
"22": "Surhumaine",
|
||||
"23": "Très Surhumaine",
|
||||
"24": "Epique",
|
||||
"25": "Plus Epique",
|
||||
"26": "Légendaire",
|
||||
"26": "Très Légendaire",
|
||||
"28": "Mythique",
|
||||
"29": "Plus Mythique",
|
||||
"30": "Divine"
|
||||
"5": "Enfantine (5)",
|
||||
"6": "Triviale (6)",
|
||||
"7": "Moins Triviale (7)",
|
||||
"8": "Aisée (8)",
|
||||
"9": "Moins Aisée (9)",
|
||||
"10": "Normale (10)",
|
||||
"11": "Moins Normale (11)",
|
||||
"12": "Compliquée (12)",
|
||||
"13": "Plus Compliquée (13)",
|
||||
"14": "Difficile (14)",
|
||||
"15": "Plus Difficile (15)",
|
||||
"16": "Très Difficile (16)",
|
||||
"17": "Très Très Difficile (17)",
|
||||
"18": "Critique (18)",
|
||||
"19": "Plus Critique (19)",
|
||||
"20": "Insurmontable (20)",
|
||||
"21": "Très Insurmontable (21)",
|
||||
"22": "Surhumaine (22)",
|
||||
"23": "Très Surhumaine (23)",
|
||||
"24": "Epique (24)",
|
||||
"25": "Plus Epique (25)",
|
||||
"26": "Légendaire (26)",
|
||||
"27": "Très Légendaire (27)",
|
||||
"28": "Mythique (28)",
|
||||
"29": "Plus Mythique (29)",
|
||||
"30": "Divine (30)"
|
||||
},
|
||||
|
||||
attaqueCible: {
|
||||
"none": "Aucune",
|
||||
"membre": "Membre",
|
||||
"main": "Main",
|
||||
"tete": "Tête/Coeur"
|
||||
},
|
||||
|
||||
categorieArme: {
|
||||
@@ -138,7 +146,155 @@ export const HERITIERS_CONFIG = {
|
||||
"traditionnelle": "Traditionnelle",
|
||||
"moderne": "Moderne",
|
||||
"orientale": "Orientale"
|
||||
},
|
||||
typeContact: {
|
||||
"contact": "Contact",
|
||||
"allie": "Allié",
|
||||
"ennemi": "Ennemi",
|
||||
"interet": "Personne d'interêt"
|
||||
},
|
||||
niveauContact: {
|
||||
"1": "1",
|
||||
"2": "2",
|
||||
"3": "3",
|
||||
},
|
||||
pointsUsageList: {
|
||||
"1": "1",
|
||||
"2": "2",
|
||||
"3": "3",
|
||||
"4": "4",
|
||||
},
|
||||
attaquePlusieursList: {
|
||||
"0": "0",
|
||||
"1": "+1",
|
||||
"2": "+2",
|
||||
},
|
||||
attaque2ArmesListe: [
|
||||
{ value: "0", label: "Aucun" },
|
||||
{ value: "-4", label: "Deux armes à 1 main" },
|
||||
{ value: "-2", label: "Deux armes naturelles" },
|
||||
{ value: "-2", label: "Avec spécialisation \"Mauvaise Main\"" }
|
||||
],
|
||||
typeProfil: {
|
||||
"mineur": "Mineur",
|
||||
"majeur": "Majeur",
|
||||
},
|
||||
bonusMalusContext: [
|
||||
{ value: "-6", label: "-6" },
|
||||
{ value: "-5", label: "-5" },
|
||||
{ value: "-4", label: "-4" },
|
||||
{ value: "-3", label: "-3" },
|
||||
{ value: "-2", label: "-2" },
|
||||
{ value: "-1", label: "-1" },
|
||||
{ value: "0", label: "0" },
|
||||
{ value: "1", label: "+1" },
|
||||
{ value: "2", label: "+2" },
|
||||
{ value: "3", label: "+3" },
|
||||
{ value: "4", label: "+4" },
|
||||
{ value: "5", label: "+5" },
|
||||
{ value: "6", label: "+6" }
|
||||
],
|
||||
listNiveauSort: {
|
||||
"1": "1",
|
||||
"2": "2",
|
||||
"3": "3",
|
||||
"4": "4"
|
||||
},
|
||||
listRangSort: {
|
||||
"1": "1",
|
||||
"2": "2",
|
||||
"3": "3",
|
||||
"4": "4",
|
||||
"5": "5",
|
||||
"6": "6",
|
||||
"7": "7"
|
||||
},
|
||||
listNiveau: {
|
||||
"0": "0",
|
||||
"1": "1",
|
||||
"2": "2",
|
||||
"3": "3",
|
||||
"4": "4",
|
||||
"5": "5",
|
||||
"6": "6",
|
||||
"7": "7",
|
||||
"8": "8",
|
||||
"9": "9",
|
||||
"10": "10"
|
||||
},
|
||||
rangName: [
|
||||
"Novice",
|
||||
"Novice",
|
||||
"Adepte",
|
||||
"Maître",
|
||||
"Grand Maître"
|
||||
],
|
||||
rangNameSpecific: {
|
||||
"Druidisme": {
|
||||
"Novice": "Eubage",
|
||||
"Adepte": "Saronide",
|
||||
"Maître": "Ovate",
|
||||
"Grand Maître": "Archidruide"
|
||||
},
|
||||
"Faëomancie": {
|
||||
"Novice": "Marmiton",
|
||||
"Adepte": "Queux",
|
||||
"Maître": "Chef",
|
||||
"Grand Maître": "Maître-queux"
|
||||
},
|
||||
"Nécromancie": {
|
||||
"Novice": "Inexpertus",
|
||||
"Adepte": "Discipulus",
|
||||
"Maître": "Dominus",
|
||||
"Grand Maître": "Magister"
|
||||
},
|
||||
"Necromancie": {
|
||||
"Novice": "Inexpertus",
|
||||
"Adepte": "Discipulus",
|
||||
"Maître": "Dominus",
|
||||
"Grand Maître": "Magister"
|
||||
},
|
||||
"Magie du Clan": {
|
||||
"Novice": "Apprenti",
|
||||
"Adepte": "Disciple",
|
||||
"Maître": "Maître",
|
||||
"Grand Maître": "Éminence"
|
||||
},
|
||||
"Magie du Clan - Souffle du Combat": {
|
||||
"Novice": "Apprenti",
|
||||
"Adepte": "Disciple",
|
||||
"Maître": "Maître",
|
||||
"Grand Maître": "Éminence"
|
||||
},
|
||||
"Magie du Clan - Souffle du Mouvement": {
|
||||
"Novice": "Apprenti",
|
||||
"Adepte": "Disciple",
|
||||
"Maître": "Maître",
|
||||
"Grand Maître": "Éminence"
|
||||
},
|
||||
"Magie du Clan - Souffle de l'Esprit": {
|
||||
"Novice": "Apprenti",
|
||||
"Adepte": "Disciple",
|
||||
"Maître": "Maître",
|
||||
"Grand Maître": "Éminence"
|
||||
},
|
||||
"Théurgie": {
|
||||
"Novice": "Frère",
|
||||
"Adepte": "Père",
|
||||
"Maître": "Saint",
|
||||
"Grand Maître": "Apôtre"
|
||||
},
|
||||
"Grand Langage": {
|
||||
"Novice": "Éveillé",
|
||||
"Adepte": "Initié",
|
||||
"Maître": "Sage",
|
||||
"Grand Maître": "Docteur"
|
||||
}
|
||||
},
|
||||
soufflesMagieDuClan: {
|
||||
"Souffle du Combat": "Souffle du Combat",
|
||||
"Souffle du Mouvement": "Souffle du Mouvement",
|
||||
"Souffle de l'Esprit": "Souffle de l'Esprit"
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/**
|
||||
* Extend the basic ActorSheet with some very simple modifications
|
||||
* @extends {ActorSheet}
|
||||
*/
|
||||
|
||||
import { HeritiersActorSheet } from "./heritiers-actor-sheet.js";
|
||||
import { HeritiersUtility } from "./heritiers-utility.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class HeritiersCreatureSheet extends HeritiersActorSheet {
|
||||
|
||||
/** @override */
|
||||
static get defaultOptions() {
|
||||
|
||||
return mergeObject(super.defaultOptions, {
|
||||
classes: ["fvtt-les-heritiers", "sheet", "actor"],
|
||||
template: "systems/fvtt-les-heritiers/templates/creature-sheet.html",
|
||||
width: 640,
|
||||
height: 720,
|
||||
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "stats" }],
|
||||
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: null }],
|
||||
editScore: false
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,12 @@ import { HeritiersUtility } from "./heritiers-utility.js";
|
||||
* Extend the basic ItemSheet with some very simple modifications
|
||||
* @extends {ItemSheet}
|
||||
*/
|
||||
export class HeritiersItemSheet extends ItemSheet {
|
||||
export class HeritiersItemSheet extends foundry.appv1.sheets.ItemSheet {
|
||||
|
||||
/** @override */
|
||||
static get defaultOptions() {
|
||||
|
||||
return mergeObject(super.defaultOptions, {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
classes: ["fvtt-les-heritiers", "sheet", "item"],
|
||||
template: "systems/fvtt-les-heritiers/templates/item-sheet.html",
|
||||
dragDrop: [{ dragSelector: null, dropSelector: null }],
|
||||
@@ -48,7 +48,7 @@ export class HeritiersItemSheet extends ItemSheet {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async getData() {
|
||||
const objectData = duplicate(this.object)
|
||||
const objectData = foundry.utils.duplicate(this.object)
|
||||
let formData = {
|
||||
title: this.title,
|
||||
id: this.id,
|
||||
@@ -62,11 +62,25 @@ export class HeritiersItemSheet extends ItemSheet {
|
||||
options: this.options,
|
||||
owner: this.document.isOwner,
|
||||
config: game.system.lesheritiers.config,
|
||||
description: await TextEditor.enrichHTML(this.object.system.description, {async: true}),
|
||||
isArmeMelee: HeritiersUtility.isArmeMelee(this.object),
|
||||
description: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.description, {async: true}),
|
||||
mr: (this.object.type == 'specialisation'),
|
||||
isGM: game.user.isGM
|
||||
isGM: game.user.isGM,
|
||||
usageMax: -1
|
||||
}
|
||||
|
||||
// Items specific data
|
||||
if (this.object.type == 'pouvoir' && this.document.isOwner && this.actor) {
|
||||
formData.usageMax = this.actor.getPouvoirUsageMax(this.object)
|
||||
if (this.object.system.pointsusagecourant == -1) {
|
||||
this.object.system.pointsusagecourant = formData.usageMax
|
||||
}
|
||||
}
|
||||
if (this.object.type == 'sort' ) {
|
||||
formData.competencesMagie = HeritiersUtility.getCompetencesMagie()
|
||||
}
|
||||
|
||||
|
||||
//this.options.editable = !(this.object.origin == "embeddedItem");
|
||||
console.log("ITEM DATA", formData, this);
|
||||
return formData;
|
||||
@@ -86,7 +100,7 @@ export class HeritiersItemSheet extends ItemSheet {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
postItem() {
|
||||
let chatData = duplicate(HeritiersUtility.data(this.item));
|
||||
let chatData = foundry.utils.duplicate(HeritiersUtility.data(this.item));
|
||||
if (this.actor) {
|
||||
chatData.actor = { id: this.actor.id };
|
||||
}
|
||||
@@ -128,52 +142,52 @@ export class HeritiersItemSheet extends ItemSheet {
|
||||
})
|
||||
|
||||
html.find('#add-specialite').click(ev => {
|
||||
let spec = duplicate(this.object.system.specialites)
|
||||
spec.push( { name: "Nouvelle Spécialité", id: randomID(16), used: false })
|
||||
let spec = foundry.utils.duplicate(this.object.system.specialites)
|
||||
spec.push( { name: "Nouvelle Spécialité", id: foundry.utils.randomID(16), used: false })
|
||||
this.object.update( { 'system.specialites': spec })
|
||||
})
|
||||
html.find('.delete-specialite').click(ev => {
|
||||
const li = $(ev.currentTarget).parents(".specialite-item")
|
||||
let index = li.data("specialite-index")
|
||||
let spec = duplicate(this.object.system.specialites)
|
||||
let spec = foundry.utils.duplicate(this.object.system.specialites)
|
||||
spec.splice(index,1)
|
||||
this.object.update( { 'system.specialites': spec })
|
||||
})
|
||||
html.find('.edit-specialite').change(ev => {
|
||||
const li = $(ev.currentTarget).parents(".specialite-item")
|
||||
let index = li.data("specialite-index")
|
||||
let spec = duplicate(this.object.system.specialites)
|
||||
let spec = foundry.utils.duplicate(this.object.system.specialites)
|
||||
spec[index].name = ev.currentTarget.value
|
||||
spec[index].id = spec[index].id || randomID(16)
|
||||
spec[index].id = spec[index].id || foundry.utils.randomID(16)
|
||||
this.object.update( { 'system.specialites': spec })
|
||||
})
|
||||
html.find('.edit-specialite-description').change(ev => {
|
||||
const li = $(ev.currentTarget).parents(".specialite-item")
|
||||
let index = li.data("specialite-index")
|
||||
let spec = duplicate(this.object.system.specialites)
|
||||
let spec = foundry.utils.duplicate(this.object.system.specialites)
|
||||
spec[index].description = ev.currentTarget.value
|
||||
spec[index].id = spec[index].id || randomID(16)
|
||||
spec[index].id = spec[index].id || foundry.utils.randomID(16)
|
||||
this.object.update( { 'system.specialites': spec })
|
||||
})
|
||||
|
||||
html.find('#add-automation').click(ev => {
|
||||
let autom = duplicate(this.object.system.automations)
|
||||
autom.push( { eventtype: "on-drop", name: "Automatisation 1", competence: "", minLevel: 0, id: randomID(16) })
|
||||
let autom = foundry.utils.duplicate(this.object.system.automations)
|
||||
autom.push( { eventtype: "on-drop", name: "Automatisation 1", competence: "", minLevel: 0, id: foundry.utils.randomID(16) })
|
||||
this.object.update( { 'system.automations': autom })
|
||||
})
|
||||
html.find('.delete-automation').click(ev => {
|
||||
const li = $(ev.currentTarget).parents(".automation-item")
|
||||
let index = li.data("automation-index")
|
||||
let autom = duplicate(this.object.system.automations)
|
||||
let autom = foundry.utils.duplicate(this.object.system.automations)
|
||||
autom.splice(index,1)
|
||||
this.object.update( { 'system.automations': autom })
|
||||
})
|
||||
html.find('.automation-edit-field').change(ev => {
|
||||
let index = $(ev.currentTarget).data("automation-index")
|
||||
let field = $(ev.currentTarget).data("automation-field")
|
||||
let auto = duplicate(this.object.system.automations)
|
||||
let auto = foundry.utils.duplicate(this.object.system.automations)
|
||||
auto[index][field] = ev.currentTarget.value
|
||||
auto[index].id = auto[index].id || randomID(16)
|
||||
auto[index].id = auto[index].id || foundry.utils.randomID(16)
|
||||
this.object.update( { 'system.automations': auto })
|
||||
})
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ export const defaultItemImg = {
|
||||
fee: "systems/fvtt-les-heritiers/assets/icons/faery_type.webp",
|
||||
profil: "systems/fvtt-les-heritiers/assets/icons/profil.webp",
|
||||
equipement: "systems/fvtt-les-heritiers/assets/icons/equipement.webp",
|
||||
sort: "systems/fvtt-les-heritiers/assets/icons/sort.webp",
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,7 +12,6 @@ import { HeritiersActor } from "./heritiers-actor.js";
|
||||
import { HeritiersItemSheet } from "./heritiers-item-sheet.js";
|
||||
import { HeritiersActorSheet } from "./heritiers-actor-sheet.js";
|
||||
import { HeritiersActorPNJSheet } from "./heritiers-actor-pnj-sheet.js";
|
||||
import { HeritiersCreatureSheet } from "./heritiers-creature-sheet.js";
|
||||
import { HeritiersUtility } from "./heritiers-utility.js";
|
||||
import { HeritiersCombat } from "./heritiers-combat.js";
|
||||
import { HeritiersItem } from "./heritiers-item.js";
|
||||
@@ -47,6 +46,8 @@ Hooks.once("init", async function () {
|
||||
CONFIG.Combat.documentClass = HeritiersCombat
|
||||
CONFIG.Actor.documentClass = HeritiersActor
|
||||
CONFIG.Item.documentClass = HeritiersItem
|
||||
// Create an object of bonus/malus from -6 to +6 signed
|
||||
HERITIERS_CONFIG.bonusMalus = Array.from({ length: 7 }, (v, k) => toString(k - 6))
|
||||
game.system.lesheritiers = {
|
||||
HeritiersUtility,
|
||||
config: HERITIERS_CONFIG
|
||||
@@ -54,12 +55,12 @@ Hooks.once("init", async function () {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
// Register sheet application classes
|
||||
Actors.unregisterSheet("core", ActorSheet);
|
||||
Actors.registerSheet("fvtt-les-heritiers", HeritiersActorSheet, { types: ["personnage"], makeDefault: true })
|
||||
Actors.registerSheet("fvtt-les-heritiers", HeritiersActorPNJSheet, { types: ["pnj"], makeDefault: true })
|
||||
foundry.documents.collections.Actors.unregisterSheet("core", foundry.appv1.sheets.ActorSheet);
|
||||
foundry.documents.collections.Actors.registerSheet("fvtt-les-heritiers", HeritiersActorSheet, { types: ["personnage"], makeDefault: true })
|
||||
foundry.documents.collections.Actors.registerSheet("fvtt-les-heritiers", HeritiersActorPNJSheet, { types: ["pnj"], makeDefault: true })
|
||||
|
||||
Items.unregisterSheet("core", ItemSheet);
|
||||
Items.registerSheet("fvtt-les-heritiers", HeritiersItemSheet, { makeDefault: true })
|
||||
foundry.documents.collections.Items.unregisterSheet("core", foundry.appv1.sheets.ItemSheet);
|
||||
foundry.documents.collections.Items.registerSheet("fvtt-les-heritiers", HeritiersItemSheet, { makeDefault: true })
|
||||
|
||||
HeritiersUtility.init()
|
||||
|
||||
@@ -79,30 +80,16 @@ function welcomeMessage() {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
// Register world usage statistics
|
||||
function registerUsageCount(registerKey) {
|
||||
if (game.user.isGM) {
|
||||
game.settings.register(registerKey, "world-key", {
|
||||
name: "Unique world key",
|
||||
scope: "world",
|
||||
config: false,
|
||||
default: "",
|
||||
type: String
|
||||
});
|
||||
async function importDefaultScene() {
|
||||
let exists = game.scenes.find(j => j.name == "Accueil");
|
||||
if (!exists) {
|
||||
const scenes = await HeritiersUtility.loadCompendium("fvtt-les-heritiers.scenes")
|
||||
let newDocuments = scenes.filter(i => i.name == "Accueil");
|
||||
await game.scenes.documentClass.create(newDocuments);
|
||||
game.scenes.find(i => i.name == "Accueil").activate();
|
||||
}
|
||||
}
|
||||
|
||||
let worldKey = game.settings.get(registerKey, "world-key")
|
||||
if (worldKey == undefined || worldKey == "") {
|
||||
worldKey = randomID(32)
|
||||
game.settings.set(registerKey, "world-key", worldKey)
|
||||
}
|
||||
// Simple API counter
|
||||
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}"`
|
||||
//$.ajaxSetup({
|
||||
//headers: { 'Access-Control-Allow-Origin': '*' }
|
||||
//})
|
||||
$.ajax(regURL)
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Foundry VTT Initialization */
|
||||
@@ -120,14 +107,15 @@ Hooks.once("ready", function () {
|
||||
});
|
||||
}
|
||||
|
||||
registerUsageCount('fvtt-les-heritiers')
|
||||
welcomeMessage()
|
||||
import("https://www.uberwald.me/fvtt_appcount/count-class-ready.js").then(moduleCounter => {
|
||||
console.log("ClassCounter loaded", moduleCounter)
|
||||
moduleCounter.ClassCounter.registerUsageCount()
|
||||
}).catch(err =>
|
||||
console.log("No stats available, giving up.")
|
||||
)
|
||||
welcomeMessage();
|
||||
importDefaultScene();
|
||||
|
||||
// CSS patch for v9
|
||||
if (game.version) {
|
||||
let sidebar = document.getElementById("sidebar");
|
||||
sidebar.style.width = "min-content";
|
||||
}
|
||||
});
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -137,10 +125,9 @@ Hooks.on("chatMessage", (html, content, msg) => {
|
||||
if (content[0] == '/') {
|
||||
let regExp = /(\S+)/g;
|
||||
let commands = content.match(regExp);
|
||||
if (game.system.mournblade.commands.processChatCommand(commands, content, msg)) {
|
||||
if (game.system.lesheritiers.commands.processChatCommand(commands, content, msg)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ export class HeritiersRollDialog extends Dialog {
|
||||
/* -------------------------------------------- */
|
||||
static async create(actor, rollData) {
|
||||
|
||||
let options = { classes: ["HeritiersDialog"], width: 320, height: 'fit-content', 'z-index': 99999 };
|
||||
let html = await renderTemplate('systems/fvtt-les-heritiers/templates/roll-dialog-generic.html', rollData);
|
||||
let options = { classes: ["HeritiersDialog"], width: 420, height: 'fit-content', 'z-index': 99999 };
|
||||
let html = await foundry.applications.handlebars.renderTemplate('systems/fvtt-les-heritiers/templates/roll-dialog-generic.html', rollData);
|
||||
|
||||
return new HeritiersRollDialog(actor, rollData, html, options);
|
||||
}
|
||||
@@ -18,18 +18,31 @@ export class HeritiersRollDialog extends Dialog {
|
||||
icon: '<i class="fas fa-check"></i>',
|
||||
label: "Lancer 1d8",
|
||||
callback: () => { this.roll("d8") }
|
||||
},
|
||||
rolld10: {
|
||||
}
|
||||
}
|
||||
let enableD10 = false
|
||||
let enableD12 = false
|
||||
if (rollData.mode == "pouvoir" || rollData.competence?.system.niveau > 0) {
|
||||
enableD10 = true
|
||||
}
|
||||
if (rollData.mode == "pouvoir" || rollData.competence?.system.niveau > 1) {
|
||||
enableD12 = true
|
||||
}
|
||||
if (enableD10) {
|
||||
buttons.rolld10 = {
|
||||
icon: '<i class="fas fa-check"></i>',
|
||||
label: "Lancer 1d10",
|
||||
callback: () => { this.roll("d10") }
|
||||
},
|
||||
rolld12: {
|
||||
}
|
||||
}
|
||||
if (enableD12) {
|
||||
buttons.rolld12 = {
|
||||
icon: '<i class="fas fa-check"></i>',
|
||||
label: "Lancer 1d12",
|
||||
callback: () => { this.roll("d12") }
|
||||
}
|
||||
}
|
||||
|
||||
if (rollData.tricherie) {
|
||||
buttons["rollTricherie"] = {
|
||||
icon: '<i class="fas fa-check"></i>',
|
||||
@@ -55,7 +68,7 @@ export class HeritiersRollDialog extends Dialog {
|
||||
buttons: buttons,
|
||||
close: close
|
||||
}
|
||||
// Overwrite in case of carac only -> 1d10
|
||||
// Overwrite in case of carac only -> 1d8
|
||||
if (rollData.mode == "carac") {
|
||||
conf.buttons = {
|
||||
rolld8: {
|
||||
@@ -96,7 +109,6 @@ export class HeritiersRollDialog extends Dialog {
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
var dialog = this;
|
||||
function onLoad() {
|
||||
}
|
||||
$(function () { onLoad(); });
|
||||
@@ -105,19 +117,30 @@ export class HeritiersRollDialog extends Dialog {
|
||||
this.rollData.sdValue = Number(event.currentTarget.value)
|
||||
})
|
||||
html.find('#caracKey').change(async (event) => {
|
||||
//console.log("caracKey", event.currentTarget.value)
|
||||
this.rollData.caracKey = String(event.currentTarget.value)
|
||||
})
|
||||
html.find('#bonus-malus-context').change((event) => {
|
||||
this.rollData.bonusMalusContext = Number(event.currentTarget.value)
|
||||
})
|
||||
html.find('#useTricherie').change((event) => {
|
||||
this.rollData.useTricherie = event.currentTarget.checked
|
||||
html.find('#bonus-attaque-plusieurs').change((event) => {
|
||||
this.rollData.bonusAttaquePlusieurs = Number(event.currentTarget.value)
|
||||
})
|
||||
html.find('#useSpecialite').change((event) => {
|
||||
this.rollData.useSpecialite = event.currentTarget.checked
|
||||
})
|
||||
html.find('#useHeritage').change((event) => {
|
||||
this.rollData.useHeritage = event.currentTarget.checked
|
||||
html.find('#pouvoirPointsUsage').change((event) => {
|
||||
this.rollData.pouvoirPointsUsage = Number(event.currentTarget.value)
|
||||
})
|
||||
html.find('#attaqueDos').change((event) => {
|
||||
this.rollData.attaqueDos = event.currentTarget.checked
|
||||
})
|
||||
html.find('#bonus-attaque-seconde-arme').change((event) => {
|
||||
this.rollData.secondeArme = String(event.currentTarget.value)
|
||||
})
|
||||
html.find('#attaque-cible').change((event) => {
|
||||
this.rollData.attaqueCible = String(event.currentTarget.value)
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,45 @@
|
||||
import { HeritiersCombat } from "./heritiers-combat.js";
|
||||
import { HeritiersCommands } from "./heritiers-commands.js";
|
||||
|
||||
const __facesAdjacentes = {
|
||||
"d8": {
|
||||
1: [4, 8, 6],
|
||||
2: [7, 5, 3],
|
||||
3: [2, 8, 6],
|
||||
4: [1, 5, 7],
|
||||
5: [2, 4, 8],
|
||||
6: [1, 7, 3],
|
||||
7: [2, 4, 6],
|
||||
8: [1, 3, 5]
|
||||
},
|
||||
"d10": {
|
||||
1: [4, 6, 9, 7],
|
||||
2: [6, 8, 5, 9],
|
||||
3: [7, 5, 8, 10],
|
||||
4: [10, 6, 7, 1],
|
||||
5: [3, 9, 2, 8],
|
||||
6: [1, 4, 2, 9],
|
||||
7: [1, 3, 4, 10],
|
||||
8: [2, 10, 5, 3],
|
||||
9: [1, 5, 6, 2],
|
||||
10: [8, 4, 3, 7]
|
||||
},
|
||||
"d12": {
|
||||
1: [2, 3, 4, 5, 6],
|
||||
2: [1, 6, 8, 12, 3],
|
||||
3: [1, 4, 11, 12, 2],
|
||||
4: [1, 5, 10, 11, 3],
|
||||
5: [1, 6, 9, 10, 4],
|
||||
6: [1, 2, 8, 9, 5],
|
||||
7: [8, 9, 10, 11, 12],
|
||||
8: [2, 6, 9, 7, 12],
|
||||
9: [5, 10, 7, 8, 6],
|
||||
10: [4, 11, 7, 9, 5],
|
||||
11: [7, 10, 4, 3, 12],
|
||||
12: [2, 8, 7, 11, 3]
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class HeritiersUtility {
|
||||
|
||||
@@ -9,7 +48,7 @@ export class HeritiersUtility {
|
||||
/* -------------------------------------------- */
|
||||
static async init() {
|
||||
Hooks.on('renderChatLog', (log, html, data) => HeritiersUtility.chatListeners(html))
|
||||
Hooks.on("getChatLogEntryContext", (html, options) => HeritiersUtility.chatRollMenu(html, options))
|
||||
/* Unused for Heitiers : Hooks.on("getChatMessageContextOptions", (html, options) => HeritiersUtility.chatRollMenu(html, options))*/
|
||||
|
||||
this.rollDataStore = {}
|
||||
this.defenderStore = {}
|
||||
@@ -65,6 +104,42 @@ export class HeritiersUtility {
|
||||
const skills = await HeritiersUtility.loadCompendium("fvtt-les-heritiers.competences")
|
||||
this.skills = skills.map(i => i.toObject())
|
||||
|
||||
this.competencesMagie = this.skills.filter(s => s.system.profil == "magie")
|
||||
|
||||
game.settings.register("fvtt-les-heritiers", "heritiers-heritage", {
|
||||
name: "Points d'héritage",
|
||||
hint: "Points d'héritage du groupe",
|
||||
scope: "world",
|
||||
config: true,
|
||||
default: 0,
|
||||
type: Number
|
||||
})
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static getSDSortValue(niveau) {
|
||||
if (niveau <= 1) return 12;
|
||||
if (niveau == 2) return 14;
|
||||
if (niveau == 3) return 16;
|
||||
if (niveau > 3) return 18;
|
||||
return 18;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static getCompetencesMagie() {
|
||||
return this.competencesMagie
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static buildCompetencesMagie() {
|
||||
let competences = foundry.utils.duplicate(this.getCompetencesMagie())
|
||||
for (let comp of competences) {
|
||||
// Calcul du rang
|
||||
let rang = Math.round(comp.system.niveau / 2);
|
||||
competences.system.rang = rang;
|
||||
competences.system.rangGenericName = game.system.lesheritiers.config.rangName[rang];
|
||||
competences.system.rangSpecificName = game.system.lesheritiers.config.rangNameSpecific[comp.Name][competences.system.rangGenericName];
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -86,18 +161,29 @@ export class HeritiersUtility {
|
||||
/* -------------------------------------------- */
|
||||
static async chatListeners(html) {
|
||||
|
||||
html.on("click", '.predilection-reroll', async event => {
|
||||
$(html).on("click", '.predilection-reroll', async event => {
|
||||
let predIdx = $(event.currentTarget).data("predilection-index")
|
||||
let messageId = HeritiersUtility.findChatMessageId(event.currentTarget)
|
||||
let message = game.messages.get(messageId)
|
||||
let rollData = message.getFlag("world", "heritiers-roll")
|
||||
let actor = this.getActorFromRollData(rollData)
|
||||
await actor.setPredilectionUsed(rollData.competence._id, predIdx)
|
||||
rollData.competence = duplicate(actor.getCompetence(rollData.competence._id))
|
||||
rollData.competence = foundry.utils.duplicate(actor.getCompetence(rollData.competence._id))
|
||||
HeritiersUtility.rollHeritiers(rollData)
|
||||
})
|
||||
|
||||
html.on("click", '.roll-chat-degat', async event => {
|
||||
$(html).on("click", '.roll-tricherie-2', async event => {
|
||||
let messageId = HeritiersUtility.findChatMessageId(event.currentTarget)
|
||||
let message = game.messages.get(messageId)
|
||||
let rollData = message.getFlag("world", "heritiers-roll")
|
||||
let actor = this.getActorFromRollData(rollData)
|
||||
if (await actor.incDecTricherie(-2)) {
|
||||
rollData.forcedValue = Number($(event.currentTarget).data("dice-value"))
|
||||
HeritiersUtility.rollHeritiers(rollData)
|
||||
}
|
||||
})
|
||||
|
||||
$(html).on("click", '.roll-chat-degat', async event => {
|
||||
let messageId = HeritiersUtility.findChatMessageId(event.currentTarget)
|
||||
let message = game.messages.get(messageId)
|
||||
let rollData = message.getFlag("world", "heritiers-roll")
|
||||
@@ -114,10 +200,9 @@ export class HeritiersUtility {
|
||||
'systems/fvtt-les-heritiers/templates/partial-item-header.html',
|
||||
'systems/fvtt-les-heritiers/templates/partial-item-description.html',
|
||||
'systems/fvtt-les-heritiers/templates/partial-item-nav.html',
|
||||
'systems/fvtt-les-heritiers/templates/partial-utile-skills.html',
|
||||
'systems/fvtt-les-heritiers/templates/partial-list-niveau.html'
|
||||
'systems/fvtt-les-heritiers/templates/partial-utile-skills.html'
|
||||
]
|
||||
return loadTemplates(templatePaths);
|
||||
return foundry.applications.handlebars.loadTemplates(templatePaths);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -194,7 +279,7 @@ export class HeritiersUtility {
|
||||
|
||||
let id = rollData.rollId;
|
||||
let oldRollData = this.rollDataStore[id] || {};
|
||||
let newRollData = mergeObject(oldRollData, rollData);
|
||||
let newRollData = foundry.utils.mergeObject(oldRollData, rollData);
|
||||
this.rollDataStore[id] = newRollData;
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
@@ -212,7 +297,6 @@ export class HeritiersUtility {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static onSocketMesssage(msg) {
|
||||
//console.log("SOCKET MESSAGE", msg.name, game.user.character.id, msg.data.defenderId);
|
||||
if (msg.name == "msg_update_defense_state") {
|
||||
this.updateDefenseState(msg.data.defenderId, msg.data.rollId);
|
||||
}
|
||||
@@ -290,11 +374,12 @@ export class HeritiersUtility {
|
||||
if (isTricherieHeritage) {
|
||||
let resTab = [rollData.roll.terms[0].results[0].result, rollData.roll.terms[0].results[1].result, rollData.roll.terms[0].results[2].result]
|
||||
rollData.diceResult = resTab[0] + "," + resTab[1] + "," + resTab[2]
|
||||
let subResult = Math.max(Math.max(resTab[0], resTab[1]), resTab[2])
|
||||
let foundryTotal = resTab[0] + resTab[1] + resTab[2]
|
||||
if (resTab[1] == 1) { resTab[1] -= 4 }
|
||||
if (resTab[2] == 1) { resTab[2] -= 6 }
|
||||
if (resTab[2] == 2) { resTab[2] -= 7 }
|
||||
rollData.finalResult = rollData.roll.total - subResult + Math.max(Math.max(resTab[0], resTab[1]), resTab[2])
|
||||
rollData.diceValue = Math.max(Math.max(resTab[0], resTab[1]), resTab[2])
|
||||
rollData.finalResult = rollData.roll.total - foundryTotal + rollData.diceValue
|
||||
|
||||
// Gestion des résultats spéciaux
|
||||
resTab = resTab.sort()
|
||||
@@ -319,8 +404,9 @@ export class HeritiersUtility {
|
||||
|
||||
} else {
|
||||
rollData.finalResult = rollData.roll.total
|
||||
let rollValue = rollData.roll.terms[0].results[0].result
|
||||
rollData.diceResult = rollData.roll.terms[0].results[0].result
|
||||
let rollValue = rollData.forcedValue || rollData.roll.terms[0].results[0].result
|
||||
rollData.diceResult = rollValue
|
||||
rollData.diceValue = rollValue
|
||||
if (rollData.mainDice.includes("d10")) {
|
||||
if (rollValue == 1) {
|
||||
rollData.finalResult -= 3 + rollValue // substract 3 and the 1 value that has been added
|
||||
@@ -331,19 +417,41 @@ export class HeritiersUtility {
|
||||
rollData.finalResult -= 5 + rollValue // Remove also the dice result has it has been added already
|
||||
}
|
||||
}
|
||||
if (!rollData.forcedValue) {
|
||||
rollData.adjacentFaces = foundry.utils.duplicate(__facesAdjacentes[rollData.mainDice][rollData.diceValue])
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static computeArmeDegats(rollData, actor) {
|
||||
rollData.degatsArme = rollData.arme.system.degats + rollData.marge
|
||||
if (rollData.attaqueDeuxArmes != 0 && rollData.secondeArme) {
|
||||
let secondeArme = actor.items.get(secondeArme)
|
||||
if (secondeArme) {
|
||||
rollData.degatsArme += secondeArme.system.degats
|
||||
rollData.degatsArme += actor.system.caracteristiques.for.value
|
||||
}
|
||||
} else {
|
||||
if (rollData.arme.system.categorie == "lourde") {
|
||||
rollData.degatsArme += actor.system.caracteristiques.for.value
|
||||
}
|
||||
if (rollData.arme.system.categorie == "blanche" || rollData.arme.system.categorie == "improvise") {
|
||||
rollData.degatsArme += Math.max(0, actor.system.caracteristiques.for.value - 2)
|
||||
}
|
||||
if (rollData.mode == "attaquecharge") {
|
||||
rollData.degatsArme += 3
|
||||
}
|
||||
}
|
||||
if (rollData.attaqueCible == "membre") {
|
||||
rollData.degatsArme -= 2
|
||||
}
|
||||
if (rollData.attaqueCible == "main") {
|
||||
rollData.degatsArme -= 3
|
||||
}
|
||||
if (rollData.attaqueCible == "tete") {
|
||||
rollData.degatsArme *= 3
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -353,6 +461,10 @@ export class HeritiersUtility {
|
||||
rollData.isSuccess = (rollData.finalResult >= seuil)
|
||||
rollData.isCriticalSuccess = ((rollData.finalResult - seuil) >= 7)
|
||||
rollData.isCriticalFailure = ((rollData.finalResult - seuil) <= -7)
|
||||
// Si compétence > 0 et d8 -> echec critique impossible
|
||||
if (rollData?.competence?.system.niveau > 0 && rollData?.mainDice == "d8") {
|
||||
rollData.isCriticalFailure = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,61 +478,127 @@ export class HeritiersUtility {
|
||||
this.computeArmeDegats(rollData, actor)
|
||||
}
|
||||
this.createChatWithRollMode(rollData.alias, {
|
||||
content: await renderTemplate(`systems/fvtt-les-heritiers/templates/chat-cc-result.html`, rollData)
|
||||
content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-les-heritiers/templates/chat-cc-result.html`, rollData)
|
||||
}, rollData, "selfroll")
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
static async displayAsssomer(rollData, actor, nomAttaque, etatAssomer, valeurDefense) {
|
||||
rollData.defenderMode = nomAttaque
|
||||
rollData.etatAssommer = etatAssomer
|
||||
rollData.defenderValue = valeurDefense
|
||||
rollData.marge = 0
|
||||
this.computeMarge(rollData, valeurDefense)
|
||||
rollData.dureeAssommer = (rollData.marge) ? rollData.marge * 2 : 1
|
||||
this.createChatWithRollMode(rollData.alias, {
|
||||
content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-les-heritiers/templates/chat-assommer-result.html`, rollData)
|
||||
}, rollData, "selfroll")
|
||||
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async rollHeritiers(rollData) {
|
||||
|
||||
let actor = this.getActorFromRollData(rollData)
|
||||
|
||||
if (typeof (rollData.pvMalus) != "number") {
|
||||
ui.notifications.warn("Votre personnage est Moribond(e). Aucun jet autorisé")
|
||||
if (rollData.mode == "pouvoir" && actor.getPouvoirUsage(rollData.pouvoir._id) < rollData.pouvoirPointsUsage) {
|
||||
ui.notifications.warn("Pas assez de points d'usage pour ce pouvoir.")
|
||||
return
|
||||
}
|
||||
|
||||
//rollData.actionImg = "systems/fvtt-les-heritiers/assets/icons/" + actor.system.attributs[rollData.attrKey].labelnorm + ".webp"
|
||||
rollData.carac = duplicate(actor.system.caracteristiques[rollData.caracKey])
|
||||
if (rollData.caracKey == "pre") rollData.caracKey = "pres"; // Patch tomanage wrong carac key
|
||||
rollData.carac = foundry.utils.duplicate(actor.system.caracteristiques[rollData.caracKey])
|
||||
|
||||
if (rollData.forcedValue) {
|
||||
rollData.diceFormula = rollData.forcedValue
|
||||
} else {
|
||||
if (rollData.useTricherie || rollData.useHeritage) {
|
||||
rollData.diceFormula = "{1d8, 1d10, 1d12}"
|
||||
} else {
|
||||
rollData.diceFormula = "1" + rollData.mainDice + "kh1"
|
||||
}
|
||||
}
|
||||
|
||||
let rangValue = 0
|
||||
if (rollData.rang) {
|
||||
rangValue = rollData.rang.value
|
||||
}
|
||||
if (rollData.competence) {
|
||||
let compmod = (rollData.competence.system.niveau == 0) ? -3 : 0
|
||||
let compmod = 0 // Bonus de compétence à 0 dans Les Heritiers
|
||||
let specBonus = (rollData.useSpecialite) ? 1 : 0
|
||||
rollData.diceFormula += `+${rollData.carac.value}+${rangValue}+${rollData.competence.system.niveau}+${specBonus}+${rollData.bonusMalusContext}+${compmod}`
|
||||
} else if (rollData.pouvoirBase) {
|
||||
rollData.diceFormula += `+${rollData.pouvoirBase.value}+${rangValue}+${rollData.bonusMalusContext}`
|
||||
rollData.diceFormula += `+${rollData.carac.value}+${rollData.pouvoirBase.value}+${rangValue}+${rollData.bonusMalusContext}`
|
||||
} else {
|
||||
rollData.diceFormula += `+${rollData.carac.value}+${rangValue}+${rollData.bonusMalusContext}`
|
||||
}
|
||||
rollData.diceFormula += `+${rollData.pvMalus}`
|
||||
let ruleMalus = 0
|
||||
for (let malus of rollData.rulesMalus) {
|
||||
ruleMalus += malus.value
|
||||
}
|
||||
rollData.diceFormula += `+${ruleMalus}`
|
||||
|
||||
let myRoll = new Roll(rollData.diceFormula).roll({ async: false })
|
||||
// Gestion bonus attaque à plusieurs
|
||||
let bonusAttaque = rollData.bonusAttaquePlusieurs
|
||||
if (rollData.attaqueDos) {
|
||||
bonusAttaque = 2
|
||||
if (rollData.bonusAttaquePlusieurs) {
|
||||
bonusAttaque = 3 // Valeur max, cf règle page 197
|
||||
}
|
||||
}
|
||||
rollData.diceFormula += `+${bonusAttaque}`
|
||||
|
||||
// Gestion attaque avec 2 armes
|
||||
if (rollData.attaqueDeuxArmes != 0) {
|
||||
rollData.diceFormula += `+${rollData.attaqueDeuxArmes}`
|
||||
}
|
||||
// Gestion des attaques ciblées
|
||||
if (rollData.attaqueCible != "none") {
|
||||
if (rollData.attaqueCible == "membre") {
|
||||
rollData.diceFormula += `-2`
|
||||
}
|
||||
if (rollData.attaqueCible == "main") {
|
||||
rollData.diceFormula += `-3`
|
||||
}
|
||||
if (rollData.attaqueCible == "tete") {
|
||||
rollData.diceFormula += `-6`
|
||||
}
|
||||
}
|
||||
|
||||
if (!rollData.noRoll) {
|
||||
let myRoll = await new Roll(rollData.diceFormula).roll()
|
||||
await this.showDiceSoNice(myRoll, game.settings.get("core", "rollMode"))
|
||||
rollData.roll = myRoll
|
||||
rollData.roll = foundry.utils.duplicate(myRoll)
|
||||
console.log(">>>> ", myRoll)
|
||||
this.computeResult(actor, rollData)
|
||||
this.computeMarge(rollData, rollData.sdValue) // Calcul de la marge si seuil présent
|
||||
}
|
||||
|
||||
if (rollData.mode == "init") {
|
||||
actor.setFlag("world", "last-initiative", rollData.finalResult)
|
||||
}
|
||||
|
||||
// Gestion pouvoir et points d'usage
|
||||
if (rollData.mode == "pouvoir" || rollData.mode == "pouvoirpassif") {
|
||||
actor.incDecPointsUsage(rollData.pouvoir._id, -rollData.pouvoirPointsUsage)
|
||||
}
|
||||
// Gestion sort et points d'âme
|
||||
if (rollData.mode == "sort") {
|
||||
if (rollData.spendEsprit) {
|
||||
actor.inDecCarac("esp", -1)
|
||||
} else {
|
||||
actor.incDecPointsAme(-rollData.sortPointsAme)
|
||||
if (rollData.sort.system.competence == "Magie du Clan") {
|
||||
actor.incDecPV(-2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.createChatWithRollMode(rollData.alias, {
|
||||
content: await renderTemplate(`systems/fvtt-les-heritiers/templates/chat-generic-result.html`, rollData)
|
||||
content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-les-heritiers/templates/chat-generic-result.html`, rollData)
|
||||
}, rollData)
|
||||
|
||||
if (rollData.defenderTokenId && rollData.arme) {
|
||||
// Gestion attaque standard
|
||||
if ((rollData.mode == "arme" || rollData.mode == "attaquebrutale" || rollData.mode == "attaquecharge") &&
|
||||
rollData.defenderTokenId && rollData.arme) {
|
||||
if (rollData.arme.system.categorie != "trait" && rollData.arme.system.categorie != "poing" && rollData.arme.system.categorie != "epaule") {
|
||||
await this.displayUneDefense(rollData, actor, "Parade", rollData.defenderParade)
|
||||
await this.displayUneDefense(rollData, actor, "Esquive", rollData.defenderEsquive)
|
||||
@@ -430,6 +608,13 @@ export class HeritiersUtility {
|
||||
ui.notifications.warn("Pas de difficulté positionnée pour l'attaque à distance.")
|
||||
}
|
||||
}
|
||||
// Gestion assomer
|
||||
if (rollData.mode == "assommer" && rollData.defenderTokenId && rollData.arme) {
|
||||
await this.displayAsssomer(rollData, actor, "Assommer", "Surprise", rollData.defenderResistancePhysique)
|
||||
await this.displayAsssomer(rollData, actor, "Assommer", "Conscient, Résistance+6", rollData.defenderResistancePhysique + 6)
|
||||
await this.displayAsssomer(rollData, actor, "Assommer", "Conscient, Parade", rollData.defenderParade)
|
||||
await this.displayAsssomer(rollData, actor, "Assommer", "Conscient, Esquive", rollData.defenderEsquive + 6)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -437,16 +622,16 @@ export class HeritiersUtility {
|
||||
static async bonusRollHeritiers(rollData) {
|
||||
rollData.bonusFormula = rollData.addedBonus
|
||||
|
||||
let bonusRoll = new Roll(rollData.bonusFormula).roll({ async: false })
|
||||
let bonusRoll = await new Roll(rollData.bonusFormula).roll()
|
||||
await this.showDiceSoNice(bonusRoll, game.settings.get("core", "rollMode"));
|
||||
rollData.bonusRoll = bonusRoll
|
||||
rollData.bonusRoll = foundry.utils.duplicate(bonusRoll)
|
||||
|
||||
rollData.finalResult += rollData.bonusRoll.total
|
||||
|
||||
this.computeResult(rollData)
|
||||
|
||||
this.createChatWithRollMode(rollData.alias, {
|
||||
content: await renderTemplate(`systems/fvtt-les-heritiers/templates/chat-generic-result.html`, rollData)
|
||||
content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-les-heritiers/templates/chat-generic-result.html`, rollData)
|
||||
}, rollData)
|
||||
|
||||
}
|
||||
@@ -456,6 +641,10 @@ export class HeritiersUtility {
|
||||
return game.users.filter(filter).map(user => user._id);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static isArmeMelee(arme) {
|
||||
return (arme.type == "arme" && (arme.system.categorie == "lourde" || arme.system.categorie == "blanche" || arme.system.categorie == "improvise"))
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
static getWhisperRecipients(rollMode, name) {
|
||||
switch (rollMode) {
|
||||
@@ -473,7 +662,7 @@ export class HeritiersUtility {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static blindMessageToGM(chatOptions) {
|
||||
let chatGM = duplicate(chatOptions);
|
||||
let chatGM = foundry.utils.duplicate(chatOptions);
|
||||
chatGM.whisper = this.getUsers(user => user.isGM);
|
||||
chatGM.content = "Blinde message of " + game.user.name + "<br>" + chatOptions.content;
|
||||
console.log("blindMessageToGM", chatGM);
|
||||
@@ -537,11 +726,17 @@ export class HeritiersUtility {
|
||||
/* -------------------------------------------- */
|
||||
static getBasicRollData() {
|
||||
let rollData = {
|
||||
rollId: randomID(16),
|
||||
rollId: foundry.utils.randomID(16),
|
||||
rollMode: game.settings.get("core", "rollMode"),
|
||||
sdList: game.system.lesheritiers.config.seuilsDifficulte,
|
||||
sdValue: -1,
|
||||
bonusMalusContext: 0
|
||||
bonusAttaquePlusieurs: 0,
|
||||
attaqueDeuxArmes: 0,
|
||||
attaqueDos: false,
|
||||
bonusMalusContext: 0,
|
||||
attaqueCible: "none",
|
||||
config: game.system.lesheritiers.config,
|
||||
rulesMalus: []
|
||||
}
|
||||
return rollData
|
||||
}
|
||||
@@ -555,6 +750,7 @@ export class HeritiersUtility {
|
||||
rollData.defenderName = defender.name
|
||||
rollData.defenderParade = defender.getCurrentParade()
|
||||
rollData.defenderEsquive = defender.getCurrentEsquive()
|
||||
rollData.defenderResistancePhysique = defender.getCurrentResistancePhysique()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -608,13 +804,13 @@ export class HeritiersUtility {
|
||||
static chatRollMenu(html, options) {
|
||||
let canApply = li => canvas.tokens.controlled.length && li.find(".heritiers-roll").length
|
||||
let canApplyBA = function (li) {
|
||||
let message = game.messages.get(li.attr("data-message-id"))
|
||||
let message = game.messages.get($(li).attr("data-message-id"))
|
||||
let rollData = message.getFlag("world", "heritiers-roll")
|
||||
let actor = this.getActorFromRollData(rollData)
|
||||
return (!rollData.isReroll && actor.getBonneAventure() > 0)
|
||||
}
|
||||
let canApplyPE = function (li) {
|
||||
let message = game.messages.get(li.attr("data-message-id"))
|
||||
let message = game.messages.get($(li).attr("data-message-id"))
|
||||
let rollData = message.getFlag("world", "heritiers-roll")
|
||||
let actor = this.getActorFromRollData(rollData)
|
||||
return (!rollData.isReroll && actor.getEclat() > 0)
|
||||
@@ -649,11 +845,11 @@ export class HeritiersUtility {
|
||||
/* -------------------------------------------- */
|
||||
static async confirmDelete(actorSheet, li) {
|
||||
let itemId = li.data("item-id");
|
||||
let msgTxt = "<p>Are you sure to remove this Item ?";
|
||||
let msgTxt = "<p>Certain de supprimer cet item ?";
|
||||
let buttons = {
|
||||
delete: {
|
||||
icon: '<i class="fas fa-check"></i>',
|
||||
label: "Yes, remove it",
|
||||
label: "Oui !",
|
||||
callback: () => {
|
||||
actorSheet.actor.deleteEmbeddedDocuments("Item", [itemId]);
|
||||
li.slideUp(200, () => actorSheet.render(false));
|
||||
@@ -661,12 +857,12 @@ export class HeritiersUtility {
|
||||
},
|
||||
cancel: {
|
||||
icon: '<i class="fas fa-times"></i>',
|
||||
label: "Cancel"
|
||||
label: "Non !"
|
||||
}
|
||||
}
|
||||
msgTxt += "</p>";
|
||||
let d = new Dialog({
|
||||
title: "Confirm removal",
|
||||
title: "Confirmer la suppression",
|
||||
content: msgTxt,
|
||||
buttons: buttons,
|
||||
default: "cancel"
|
||||
@@ -674,21 +870,56 @@ export class HeritiersUtility {
|
||||
d.render(true);
|
||||
}
|
||||
|
||||
/************************************************************************************/
|
||||
static async __create_talents_table() {
|
||||
let compName = "fvtt-les-heritiers.talents-cellule"
|
||||
const compData = await HeritiersUtility.loadCompendium(compName)
|
||||
let talents = compData.map(i => i.toObject())
|
||||
static loadSort() {
|
||||
// Create afolder in the item directory if it doesn't exist
|
||||
if (!game.folders.getName("Magie du Clan")) {
|
||||
Folder.create({
|
||||
name: "Magie du Clan",
|
||||
type: "Item",
|
||||
color: "#3b1361"
|
||||
});
|
||||
}
|
||||
|
||||
let htmlTab = "<table border='1'><tbody>";
|
||||
for (let entryData of talents) {
|
||||
console.log(entryData)
|
||||
htmlTab += `<tr><td>@UUID[Compendium.${compName}.${entryData._id}]{${entryData.name}}</td>`
|
||||
htmlTab += `<td>${entryData.system.description}</td>`;
|
||||
//htmlTab += `<td>${entryData.system.resumebonus}</td>`;
|
||||
htmlTab += "</tr>\n";
|
||||
}
|
||||
htmlTab += "</table>";
|
||||
await JournalEntry.create({ name: 'Liste des Talents de Cellule', content: htmlTab });
|
||||
// Load the srcdata/sorts-druidisme.json file
|
||||
return fetch("systems/fvtt-les-heritiers/srcdata/sort_magieduclan.json")
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log("Sorts Magie du Clan loaded:", data);
|
||||
this.sortDruidisme = data;
|
||||
// Loop through the spell and create the "sort "item based on the JSON content
|
||||
data.forEach(spell => {
|
||||
spell.name = spell.name;
|
||||
spell.type = "sort";
|
||||
spell.system = {
|
||||
niveau: spell.niveau,
|
||||
competence: spell.competence,
|
||||
carac1: spell.carac1,
|
||||
carac2: spell.carac2,
|
||||
description: spell.description,
|
||||
ingredients: spell.ingredients,
|
||||
portee: spell.portee,
|
||||
duree: spell.duree,
|
||||
concentration: spell.concentration,
|
||||
critique: spell.critique,
|
||||
resistance: spell.resistance,
|
||||
coutactivation: spell.coutactivation
|
||||
};
|
||||
spell.img = "systems/fvtt-les-heritiers/assets/icons/sort.webp";
|
||||
spell.folder = game.folders.getName("Magie du Clan").id;
|
||||
|
||||
// Create the item in the world
|
||||
Item.create(spell)
|
||||
.then(item => {
|
||||
console.log("Sort created:", item);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("Error creating sort item:", error);
|
||||
});
|
||||
})
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("Error loading druidism spells:", error);
|
||||
return [];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
BIN
packs/archetypes-fees/000179.ldb
Normal file
BIN
packs/archetypes-fees/000179.ldb
Normal file
Binary file not shown.
0
packs/archetypes-fees/000242.log
Normal file
0
packs/archetypes-fees/000242.log
Normal file
1
packs/archetypes-fees/CURRENT
Normal file
1
packs/archetypes-fees/CURRENT
Normal file
@@ -0,0 +1 @@
|
||||
MANIFEST-000240
|
||||
0
packs/archetypes-fees/LOCK
Normal file
0
packs/archetypes-fees/LOCK
Normal file
8
packs/archetypes-fees/LOG
Normal file
8
packs/archetypes-fees/LOG
Normal file
@@ -0,0 +1,8 @@
|
||||
2025/09/13-00:19:21.334396 7fa5077fe6c0 Recovering log #238
|
||||
2025/09/13-00:19:21.344951 7fa5077fe6c0 Delete type=3 #236
|
||||
2025/09/13-00:19:21.345013 7fa5077fe6c0 Delete type=0 #238
|
||||
2025/09/13-00:23:49.906242 7fa506bff6c0 Level-0 table #243: started
|
||||
2025/09/13-00:23:49.906282 7fa506bff6c0 Level-0 table #243: 0 bytes OK
|
||||
2025/09/13-00:23:49.919621 7fa506bff6c0 Delete type=0 #241
|
||||
2025/09/13-00:23:49.943471 7fa506bff6c0 Manual compaction at level-0 from '!items!1NhJH4IJpxsGmLB8' @ 72057594037927935 : 1 .. '!items!y1yOenfAJTsb3r6e' @ 0 : 0; will stop at (end)
|
||||
2025/09/13-00:23:49.943533 7fa506bff6c0 Manual compaction at level-1 from '!items!1NhJH4IJpxsGmLB8' @ 72057594037927935 : 1 .. '!items!y1yOenfAJTsb3r6e' @ 0 : 0; will stop at (end)
|
||||
8
packs/archetypes-fees/LOG.old
Normal file
8
packs/archetypes-fees/LOG.old
Normal file
@@ -0,0 +1,8 @@
|
||||
2025/09/12-22:42:55.465809 7fa507fff6c0 Recovering log #234
|
||||
2025/09/12-22:42:55.475838 7fa507fff6c0 Delete type=3 #232
|
||||
2025/09/12-22:42:55.475940 7fa507fff6c0 Delete type=0 #234
|
||||
2025/09/13-00:19:16.157291 7fa506bff6c0 Level-0 table #239: started
|
||||
2025/09/13-00:19:16.157318 7fa506bff6c0 Level-0 table #239: 0 bytes OK
|
||||
2025/09/13-00:19:16.169152 7fa506bff6c0 Delete type=0 #237
|
||||
2025/09/13-00:19:16.189346 7fa506bff6c0 Manual compaction at level-0 from '!items!1NhJH4IJpxsGmLB8' @ 72057594037927935 : 1 .. '!items!y1yOenfAJTsb3r6e' @ 0 : 0; will stop at (end)
|
||||
2025/09/13-00:19:16.189422 7fa506bff6c0 Manual compaction at level-1 from '!items!1NhJH4IJpxsGmLB8' @ 72057594037927935 : 1 .. '!items!y1yOenfAJTsb3r6e' @ 0 : 0; will stop at (end)
|
||||
BIN
packs/archetypes-fees/MANIFEST-000240
Normal file
BIN
packs/archetypes-fees/MANIFEST-000240
Normal file
Binary file not shown.
BIN
packs/armes-et-protection/000179.ldb
Normal file
BIN
packs/armes-et-protection/000179.ldb
Normal file
Binary file not shown.
0
packs/armes-et-protection/000242.log
Normal file
0
packs/armes-et-protection/000242.log
Normal file
1
packs/armes-et-protection/CURRENT
Normal file
1
packs/armes-et-protection/CURRENT
Normal file
@@ -0,0 +1 @@
|
||||
MANIFEST-000240
|
||||
0
packs/armes-et-protection/LOCK
Normal file
0
packs/armes-et-protection/LOCK
Normal file
8
packs/armes-et-protection/LOG
Normal file
8
packs/armes-et-protection/LOG
Normal file
@@ -0,0 +1,8 @@
|
||||
2025/09/13-00:19:21.364108 7fa50cbf96c0 Recovering log #238
|
||||
2025/09/13-00:19:21.373869 7fa50cbf96c0 Delete type=3 #236
|
||||
2025/09/13-00:19:21.373934 7fa50cbf96c0 Delete type=0 #238
|
||||
2025/09/13-00:23:49.943627 7fa506bff6c0 Level-0 table #243: started
|
||||
2025/09/13-00:23:49.943672 7fa506bff6c0 Level-0 table #243: 0 bytes OK
|
||||
2025/09/13-00:23:49.953247 7fa506bff6c0 Delete type=0 #241
|
||||
2025/09/13-00:23:49.997730 7fa506bff6c0 Manual compaction at level-0 from '!items!1ETVaPBtjDtzelK1' @ 72057594037927935 : 1 .. '!items!zbsVCsWxRzkzzG1N' @ 0 : 0; will stop at (end)
|
||||
2025/09/13-00:23:49.997793 7fa506bff6c0 Manual compaction at level-1 from '!items!1ETVaPBtjDtzelK1' @ 72057594037927935 : 1 .. '!items!zbsVCsWxRzkzzG1N' @ 0 : 0; will stop at (end)
|
||||
8
packs/armes-et-protection/LOG.old
Normal file
8
packs/armes-et-protection/LOG.old
Normal file
@@ -0,0 +1,8 @@
|
||||
2025/09/12-22:42:55.493084 7fa50d3fa6c0 Recovering log #234
|
||||
2025/09/12-22:42:55.503204 7fa50d3fa6c0 Delete type=3 #232
|
||||
2025/09/12-22:42:55.503264 7fa50d3fa6c0 Delete type=0 #234
|
||||
2025/09/13-00:19:16.181338 7fa506bff6c0 Level-0 table #239: started
|
||||
2025/09/13-00:19:16.181386 7fa506bff6c0 Level-0 table #239: 0 bytes OK
|
||||
2025/09/13-00:19:16.189077 7fa506bff6c0 Delete type=0 #237
|
||||
2025/09/13-00:19:16.189385 7fa506bff6c0 Manual compaction at level-0 from '!items!1ETVaPBtjDtzelK1' @ 72057594037927935 : 1 .. '!items!zbsVCsWxRzkzzG1N' @ 0 : 0; will stop at (end)
|
||||
2025/09/13-00:19:16.189457 7fa506bff6c0 Manual compaction at level-1 from '!items!1ETVaPBtjDtzelK1' @ 72057594037927935 : 1 .. '!items!zbsVCsWxRzkzzG1N' @ 0 : 0; will stop at (end)
|
||||
BIN
packs/armes-et-protection/MANIFEST-000240
Normal file
BIN
packs/armes-et-protection/MANIFEST-000240
Normal file
Binary file not shown.
BIN
packs/atouts-feeriques/000179.ldb
Normal file
BIN
packs/atouts-feeriques/000179.ldb
Normal file
Binary file not shown.
0
packs/atouts-feeriques/000242.log
Normal file
0
packs/atouts-feeriques/000242.log
Normal file
1
packs/atouts-feeriques/CURRENT
Normal file
1
packs/atouts-feeriques/CURRENT
Normal file
@@ -0,0 +1 @@
|
||||
MANIFEST-000240
|
||||
0
packs/atouts-feeriques/LOCK
Normal file
0
packs/atouts-feeriques/LOCK
Normal file
8
packs/atouts-feeriques/LOG
Normal file
8
packs/atouts-feeriques/LOG
Normal file
@@ -0,0 +1,8 @@
|
||||
2025/09/13-00:19:21.308006 7fa50d3fa6c0 Recovering log #238
|
||||
2025/09/13-00:19:21.319049 7fa50d3fa6c0 Delete type=3 #236
|
||||
2025/09/13-00:19:21.319109 7fa50d3fa6c0 Delete type=0 #238
|
||||
2025/09/13-00:23:49.894650 7fa506bff6c0 Level-0 table #243: started
|
||||
2025/09/13-00:23:49.894688 7fa506bff6c0 Level-0 table #243: 0 bytes OK
|
||||
2025/09/13-00:23:49.906014 7fa506bff6c0 Delete type=0 #241
|
||||
2025/09/13-00:23:49.943452 7fa506bff6c0 Manual compaction at level-0 from '!items!0fPXtA5LkLgG8uDj' @ 72057594037927935 : 1 .. '!items!zvtBlG6KCIn0oCVk' @ 0 : 0; will stop at (end)
|
||||
2025/09/13-00:23:49.943519 7fa506bff6c0 Manual compaction at level-1 from '!items!0fPXtA5LkLgG8uDj' @ 72057594037927935 : 1 .. '!items!zvtBlG6KCIn0oCVk' @ 0 : 0; will stop at (end)
|
||||
8
packs/atouts-feeriques/LOG.old
Normal file
8
packs/atouts-feeriques/LOG.old
Normal file
@@ -0,0 +1,8 @@
|
||||
2025/09/12-22:42:55.438389 7fa5077fe6c0 Recovering log #234
|
||||
2025/09/12-22:42:55.449024 7fa5077fe6c0 Delete type=3 #232
|
||||
2025/09/12-22:42:55.449158 7fa5077fe6c0 Delete type=0 #234
|
||||
2025/09/13-00:19:16.107423 7fa506bff6c0 Level-0 table #239: started
|
||||
2025/09/13-00:19:16.107448 7fa506bff6c0 Level-0 table #239: 0 bytes OK
|
||||
2025/09/13-00:19:16.119476 7fa506bff6c0 Delete type=0 #237
|
||||
2025/09/13-00:19:16.144823 7fa506bff6c0 Manual compaction at level-0 from '!items!0fPXtA5LkLgG8uDj' @ 72057594037927935 : 1 .. '!items!zvtBlG6KCIn0oCVk' @ 0 : 0; will stop at (end)
|
||||
2025/09/13-00:19:16.144857 7fa506bff6c0 Manual compaction at level-1 from '!items!0fPXtA5LkLgG8uDj' @ 72057594037927935 : 1 .. '!items!zvtBlG6KCIn0oCVk' @ 0 : 0; will stop at (end)
|
||||
BIN
packs/atouts-feeriques/MANIFEST-000240
Normal file
BIN
packs/atouts-feeriques/MANIFEST-000240
Normal file
Binary file not shown.
BIN
packs/avantages/000179.ldb
Normal file
BIN
packs/avantages/000179.ldb
Normal file
Binary file not shown.
0
packs/avantages/000242.log
Normal file
0
packs/avantages/000242.log
Normal file
1
packs/avantages/CURRENT
Normal file
1
packs/avantages/CURRENT
Normal file
@@ -0,0 +1 @@
|
||||
MANIFEST-000240
|
||||
0
packs/avantages/LOCK
Normal file
0
packs/avantages/LOCK
Normal file
8
packs/avantages/LOG
Normal file
8
packs/avantages/LOG
Normal file
@@ -0,0 +1,8 @@
|
||||
2025/09/13-00:19:21.268491 7fa5077fe6c0 Recovering log #238
|
||||
2025/09/13-00:19:21.279675 7fa5077fe6c0 Delete type=3 #236
|
||||
2025/09/13-00:19:21.279726 7fa5077fe6c0 Delete type=0 #238
|
||||
2025/09/13-00:23:49.863626 7fa506bff6c0 Level-0 table #243: started
|
||||
2025/09/13-00:23:49.863658 7fa506bff6c0 Level-0 table #243: 0 bytes OK
|
||||
2025/09/13-00:23:49.873805 7fa506bff6c0 Delete type=0 #241
|
||||
2025/09/13-00:23:49.894434 7fa506bff6c0 Manual compaction at level-0 from '!items!0EAAt0qSzcD9VRBH' @ 72057594037927935 : 1 .. '!items!zfpjROW9LDAlXUkN' @ 0 : 0; will stop at (end)
|
||||
2025/09/13-00:23:49.894484 7fa506bff6c0 Manual compaction at level-1 from '!items!0EAAt0qSzcD9VRBH' @ 72057594037927935 : 1 .. '!items!zfpjROW9LDAlXUkN' @ 0 : 0; will stop at (end)
|
||||
8
packs/avantages/LOG.old
Normal file
8
packs/avantages/LOG.old
Normal file
@@ -0,0 +1,8 @@
|
||||
2025/09/12-22:42:55.400653 7fa50cbf96c0 Recovering log #234
|
||||
2025/09/12-22:42:55.410659 7fa50cbf96c0 Delete type=3 #232
|
||||
2025/09/12-22:42:55.410812 7fa50cbf96c0 Delete type=0 #234
|
||||
2025/09/13-00:19:16.132163 7fa506bff6c0 Level-0 table #239: started
|
||||
2025/09/13-00:19:16.132192 7fa506bff6c0 Level-0 table #239: 0 bytes OK
|
||||
2025/09/13-00:19:16.144694 7fa506bff6c0 Delete type=0 #237
|
||||
2025/09/13-00:19:16.144842 7fa506bff6c0 Manual compaction at level-0 from '!items!0EAAt0qSzcD9VRBH' @ 72057594037927935 : 1 .. '!items!zfpjROW9LDAlXUkN' @ 0 : 0; will stop at (end)
|
||||
2025/09/13-00:19:16.144872 7fa506bff6c0 Manual compaction at level-1 from '!items!0EAAt0qSzcD9VRBH' @ 72057594037927935 : 1 .. '!items!zfpjROW9LDAlXUkN' @ 0 : 0; will stop at (end)
|
||||
BIN
packs/avantages/MANIFEST-000240
Normal file
BIN
packs/avantages/MANIFEST-000240
Normal file
Binary file not shown.
BIN
packs/capacites/000179.ldb
Normal file
BIN
packs/capacites/000179.ldb
Normal file
Binary file not shown.
0
packs/capacites/000242.log
Normal file
0
packs/capacites/000242.log
Normal file
1
packs/capacites/CURRENT
Normal file
1
packs/capacites/CURRENT
Normal file
@@ -0,0 +1 @@
|
||||
MANIFEST-000240
|
||||
0
packs/capacites/LOCK
Normal file
0
packs/capacites/LOCK
Normal file
8
packs/capacites/LOG
Normal file
8
packs/capacites/LOG
Normal file
@@ -0,0 +1,8 @@
|
||||
2025/09/13-00:19:21.296168 7fa507fff6c0 Recovering log #238
|
||||
2025/09/13-00:19:21.305712 7fa507fff6c0 Delete type=3 #236
|
||||
2025/09/13-00:19:21.305760 7fa507fff6c0 Delete type=0 #238
|
||||
2025/09/13-00:23:49.884597 7fa506bff6c0 Level-0 table #243: started
|
||||
2025/09/13-00:23:49.884644 7fa506bff6c0 Level-0 table #243: 0 bytes OK
|
||||
2025/09/13-00:23:49.894226 7fa506bff6c0 Delete type=0 #241
|
||||
2025/09/13-00:23:49.894466 7fa506bff6c0 Manual compaction at level-0 from '!items!0cNSRJVPk3GbvxfD' @ 72057594037927935 : 1 .. '!items!yWDg2KlXEz33TSmZ' @ 0 : 0; will stop at (end)
|
||||
2025/09/13-00:23:49.894528 7fa506bff6c0 Manual compaction at level-1 from '!items!0cNSRJVPk3GbvxfD' @ 72057594037927935 : 1 .. '!items!yWDg2KlXEz33TSmZ' @ 0 : 0; will stop at (end)
|
||||
8
packs/capacites/LOG.old
Normal file
8
packs/capacites/LOG.old
Normal file
@@ -0,0 +1,8 @@
|
||||
2025/09/12-22:42:55.426015 7fa507fff6c0 Recovering log #234
|
||||
2025/09/12-22:42:55.435789 7fa507fff6c0 Delete type=3 #232
|
||||
2025/09/12-22:42:55.435841 7fa507fff6c0 Delete type=0 #234
|
||||
2025/09/13-00:19:16.144975 7fa506bff6c0 Level-0 table #239: started
|
||||
2025/09/13-00:19:16.145001 7fa506bff6c0 Level-0 table #239: 0 bytes OK
|
||||
2025/09/13-00:19:16.157163 7fa506bff6c0 Delete type=0 #237
|
||||
2025/09/13-00:19:16.189315 7fa506bff6c0 Manual compaction at level-0 from '!items!0cNSRJVPk3GbvxfD' @ 72057594037927935 : 1 .. '!items!yWDg2KlXEz33TSmZ' @ 0 : 0; will stop at (end)
|
||||
2025/09/13-00:19:16.189405 7fa506bff6c0 Manual compaction at level-1 from '!items!0cNSRJVPk3GbvxfD' @ 72057594037927935 : 1 .. '!items!yWDg2KlXEz33TSmZ' @ 0 : 0; will stop at (end)
|
||||
BIN
packs/capacites/MANIFEST-000240
Normal file
BIN
packs/capacites/MANIFEST-000240
Normal file
Binary file not shown.
BIN
packs/competences/000231.ldb
Normal file
BIN
packs/competences/000231.ldb
Normal file
Binary file not shown.
0
packs/competences/000246.log
Normal file
0
packs/competences/000246.log
Normal file
1
packs/competences/CURRENT
Normal file
1
packs/competences/CURRENT
Normal file
@@ -0,0 +1 @@
|
||||
MANIFEST-000244
|
||||
0
packs/competences/LOCK
Normal file
0
packs/competences/LOCK
Normal file
8
packs/competences/LOG
Normal file
8
packs/competences/LOG
Normal file
@@ -0,0 +1,8 @@
|
||||
2025/09/13-00:19:21.255755 7fa507fff6c0 Recovering log #242
|
||||
2025/09/13-00:19:21.265612 7fa507fff6c0 Delete type=3 #240
|
||||
2025/09/13-00:19:21.265700 7fa507fff6c0 Delete type=0 #242
|
||||
2025/09/13-00:23:49.874022 7fa506bff6c0 Level-0 table #247: started
|
||||
2025/09/13-00:23:49.874085 7fa506bff6c0 Level-0 table #247: 0 bytes OK
|
||||
2025/09/13-00:23:49.884276 7fa506bff6c0 Delete type=0 #245
|
||||
2025/09/13-00:23:49.894451 7fa506bff6c0 Manual compaction at level-0 from '!folders!FBCujRu055QLePB2' @ 72057594037927935 : 1 .. '!items!zEl2NQsnCpELVWzh' @ 0 : 0; will stop at (end)
|
||||
2025/09/13-00:23:49.894495 7fa506bff6c0 Manual compaction at level-1 from '!folders!FBCujRu055QLePB2' @ 72057594037927935 : 1 .. '!items!zEl2NQsnCpELVWzh' @ 0 : 0; will stop at (end)
|
||||
8
packs/competences/LOG.old
Normal file
8
packs/competences/LOG.old
Normal file
@@ -0,0 +1,8 @@
|
||||
2025/09/12-22:42:55.386980 7fa5077fe6c0 Recovering log #238
|
||||
2025/09/12-22:42:55.397627 7fa5077fe6c0 Delete type=3 #236
|
||||
2025/09/12-22:42:55.397730 7fa5077fe6c0 Delete type=0 #238
|
||||
2025/09/13-00:19:16.119722 7fa506bff6c0 Level-0 table #243: started
|
||||
2025/09/13-00:19:16.119769 7fa506bff6c0 Level-0 table #243: 0 bytes OK
|
||||
2025/09/13-00:19:16.131930 7fa506bff6c0 Delete type=0 #241
|
||||
2025/09/13-00:19:16.144833 7fa506bff6c0 Manual compaction at level-0 from '!folders!FBCujRu055QLePB2' @ 72057594037927935 : 1 .. '!items!zEl2NQsnCpELVWzh' @ 0 : 0; will stop at (end)
|
||||
2025/09/13-00:19:16.144865 7fa506bff6c0 Manual compaction at level-1 from '!folders!FBCujRu055QLePB2' @ 72057594037927935 : 1 .. '!items!zEl2NQsnCpELVWzh' @ 0 : 0; will stop at (end)
|
||||
BIN
packs/competences/MANIFEST-000244
Normal file
BIN
packs/competences/MANIFEST-000244
Normal file
Binary file not shown.
BIN
packs/desavantages/000179.ldb
Normal file
BIN
packs/desavantages/000179.ldb
Normal file
Binary file not shown.
0
packs/desavantages/000242.log
Normal file
0
packs/desavantages/000242.log
Normal file
1
packs/desavantages/CURRENT
Normal file
1
packs/desavantages/CURRENT
Normal file
@@ -0,0 +1 @@
|
||||
MANIFEST-000240
|
||||
0
packs/desavantages/LOCK
Normal file
0
packs/desavantages/LOCK
Normal file
8
packs/desavantages/LOG
Normal file
8
packs/desavantages/LOG
Normal file
@@ -0,0 +1,8 @@
|
||||
2025/09/13-00:19:21.283146 7fa50cbf96c0 Recovering log #238
|
||||
2025/09/13-00:19:21.293685 7fa50cbf96c0 Delete type=3 #236
|
||||
2025/09/13-00:19:21.293809 7fa50cbf96c0 Delete type=0 #238
|
||||
2025/09/13-00:23:49.853271 7fa506bff6c0 Level-0 table #243: started
|
||||
2025/09/13-00:23:49.853312 7fa506bff6c0 Level-0 table #243: 0 bytes OK
|
||||
2025/09/13-00:23:49.863450 7fa506bff6c0 Delete type=0 #241
|
||||
2025/09/13-00:23:49.894416 7fa506bff6c0 Manual compaction at level-0 from '!items!2QqvtClSVnh5ejXu' @ 72057594037927935 : 1 .. '!items!xzRJ6JP1HqoqxLdj' @ 0 : 0; will stop at (end)
|
||||
2025/09/13-00:23:49.894477 7fa506bff6c0 Manual compaction at level-1 from '!items!2QqvtClSVnh5ejXu' @ 72057594037927935 : 1 .. '!items!xzRJ6JP1HqoqxLdj' @ 0 : 0; will stop at (end)
|
||||
8
packs/desavantages/LOG.old
Normal file
8
packs/desavantages/LOG.old
Normal file
@@ -0,0 +1,8 @@
|
||||
2025/09/12-22:42:55.413587 7fa50d3fa6c0 Recovering log #234
|
||||
2025/09/12-22:42:55.423498 7fa50d3fa6c0 Delete type=3 #232
|
||||
2025/09/12-22:42:55.423555 7fa50d3fa6c0 Delete type=0 #234
|
||||
2025/09/13-00:19:16.096714 7fa506bff6c0 Level-0 table #239: started
|
||||
2025/09/13-00:19:16.096799 7fa506bff6c0 Level-0 table #239: 0 bytes OK
|
||||
2025/09/13-00:19:16.107186 7fa506bff6c0 Delete type=0 #237
|
||||
2025/09/13-00:19:16.144811 7fa506bff6c0 Manual compaction at level-0 from '!items!2QqvtClSVnh5ejXu' @ 72057594037927935 : 1 .. '!items!xzRJ6JP1HqoqxLdj' @ 0 : 0; will stop at (end)
|
||||
2025/09/13-00:19:16.144850 7fa506bff6c0 Manual compaction at level-1 from '!items!2QqvtClSVnh5ejXu' @ 72057594037927935 : 1 .. '!items!xzRJ6JP1HqoqxLdj' @ 0 : 0; will stop at (end)
|
||||
BIN
packs/desavantages/MANIFEST-000240
Normal file
BIN
packs/desavantages/MANIFEST-000240
Normal file
Binary file not shown.
BIN
packs/magie-sorts/000032.ldb
Normal file
BIN
packs/magie-sorts/000032.ldb
Normal file
Binary file not shown.
0
packs/magie-sorts/000043.log
Normal file
0
packs/magie-sorts/000043.log
Normal file
1
packs/magie-sorts/CURRENT
Normal file
1
packs/magie-sorts/CURRENT
Normal file
@@ -0,0 +1 @@
|
||||
MANIFEST-000041
|
||||
0
packs/magie-sorts/LOCK
Normal file
0
packs/magie-sorts/LOCK
Normal file
8
packs/magie-sorts/LOG
Normal file
8
packs/magie-sorts/LOG
Normal file
@@ -0,0 +1,8 @@
|
||||
2025/09/13-00:19:21.321878 7fa50cbf96c0 Recovering log #39
|
||||
2025/09/13-00:19:21.331597 7fa50cbf96c0 Delete type=3 #37
|
||||
2025/09/13-00:19:21.331753 7fa50cbf96c0 Delete type=0 #39
|
||||
2025/09/13-00:23:49.919835 7fa506bff6c0 Level-0 table #44: started
|
||||
2025/09/13-00:23:49.919864 7fa506bff6c0 Level-0 table #44: 0 bytes OK
|
||||
2025/09/13-00:23:49.931115 7fa506bff6c0 Delete type=0 #42
|
||||
2025/09/13-00:23:49.943487 7fa506bff6c0 Manual compaction at level-0 from '!folders!NE8l8XLXdVUw0aZm' @ 72057594037927935 : 1 .. '!items!zjQQhJpujpdbG4zl' @ 0 : 0; will stop at (end)
|
||||
2025/09/13-00:23:49.943562 7fa506bff6c0 Manual compaction at level-1 from '!folders!NE8l8XLXdVUw0aZm' @ 72057594037927935 : 1 .. '!items!zjQQhJpujpdbG4zl' @ 0 : 0; will stop at (end)
|
||||
8
packs/magie-sorts/LOG.old
Normal file
8
packs/magie-sorts/LOG.old
Normal file
@@ -0,0 +1,8 @@
|
||||
2025/09/12-22:42:55.452797 7fa50d3fa6c0 Recovering log #35
|
||||
2025/09/12-22:42:55.462675 7fa50d3fa6c0 Delete type=3 #33
|
||||
2025/09/12-22:42:55.462724 7fa50d3fa6c0 Delete type=0 #35
|
||||
2025/09/13-00:19:16.169291 7fa506bff6c0 Level-0 table #40: started
|
||||
2025/09/13-00:19:16.169344 7fa506bff6c0 Level-0 table #40: 0 bytes OK
|
||||
2025/09/13-00:19:16.181136 7fa506bff6c0 Delete type=0 #38
|
||||
2025/09/13-00:19:16.189366 7fa506bff6c0 Manual compaction at level-0 from '!folders!NE8l8XLXdVUw0aZm' @ 72057594037927935 : 1 .. '!items!zjQQhJpujpdbG4zl' @ 0 : 0; will stop at (end)
|
||||
2025/09/13-00:19:16.189440 7fa506bff6c0 Manual compaction at level-1 from '!folders!NE8l8XLXdVUw0aZm' @ 72057594037927935 : 1 .. '!items!zjQQhJpujpdbG4zl' @ 0 : 0; will stop at (end)
|
||||
BIN
packs/magie-sorts/MANIFEST-000041
Normal file
BIN
packs/magie-sorts/MANIFEST-000041
Normal file
Binary file not shown.
@@ -10,7 +10,7 @@
|
||||
{"name":"Élémentaire majeur (Légendaire)","type":"pouvoir","img":"systems/fvtt-les-heritiers/assets/icons/power.webp","system":{"pouvoirtype":"metamorphose","masquetype":"demasque","niveau":"legendaire","activation":"2 points d’usage au lieu d’un, ainsi qu’1 point temporaire de Constitution.","istest":false,"feeriemasque":"feerie","zoneffet":"","testautre":"Attaque avec des crocs","carac":"pres","duree":"une scène","cibles":"","effet":"transformation en élémentaire de son\naffinité ; absorbe Féérie points de dégâts sauf contre des attaques efficaces (élément contraire ou argent). \nAttaques : effectuées avec Mêlée + AGI ; dégâts élémentaires = Féérie + MR (pas de bonus de Force).\n","portee":"","resistance":"aucune","resistanceautre":"Esquive / test d’opposition de Mêlée ou Ressort + Force pour se dégager.","isvirulence":false,"virulence":"","description":"<p>Le djinn se transforme en élémentaire majeur de très grande taille (environ 2,5 mètres de haut et d’envergure), avec d’importants pouvoirs de contrôle de son élément de prédilection : tornade de sable ou d’eau, contrôle du feu, tempête, etc. Ce contrôle élémentaire est de forme relativement libre selon la vraisemblance et ce qu’autorise le Docte et sa puissance est comparable au Pouvoir profond du phénix Contrôle du feu (voir p. 264). Il utilise ses longs bras (1,5 m) pour porter des attaques élémentaires avec des effets critiques liés : le feu enflamme les vêtements, l’eau et le sable étourdissent, l’air ajoute des dégâts de projection ou de chute, etc.</p>\n<p>Les attaques physiques portées contre lui sont réduites d’autant de points de dégâts que son rang de Féérie, sauf si elles font intervenir de l’argent. Toutefois, projeter sur lui une grande quantité (1 m3 environ) d’un élément auquel il est vulnérable (l’eau pour les djinns du feu, la terre ou le sable pour les djinns de l’eau, le vent pour les djinns de sable, le feu pour les djinns de l’air) pourra contraindre un djinn légendaire à abandonner sa forme d’Élémentaire majeur.</p>","zoneeffet":""},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-les-heritiers","systemVersion":"10.0.18","coreVersion":"10.291","createdTime":1678214487456,"modifiedTime":1678303349575,"lastModifiedBy":"xGnwWyEbO2k89UsP"},"_id":"4v8Z2ThDSwwWb0DU","folder":null,"sort":0,"ownership":{"default":0,"xGnwWyEbO2k89UsP":3}}
|
||||
{"name":"Psychotopie","type":"pouvoir","img":"systems/fvtt-les-heritiers/assets/icons/power.webp","system":{"pouvoirtype":"actif","masquetype":"masque","niveau":"normal","activation":"Féérie + Esprit et une transe de 5 minutes au moins, contre un SD variable selon la taille et les événements se déroulant dans le lieu (une chambre isolée depuis des années : SD10 ; un immeuble rempli d'habitants dans lequel il y a fréquemment du passage : SD 20).","istest":true,"feeriemasque":"feerie","zoneffet":"","testautre":"","carac":"esp","duree":"","cibles":"un seul lieu","effet":"apprend des informations marquantes sur un lieu","portee":"un lieu (pas plus grand qu’un bâtiment)","resistance":"aucune","resistanceautre":"","isvirulence":false,"virulence":"","description":"<p><strong>Type de Pouvoir : </strong>actif.</p>\n<p><strong>Activation : </strong>Féérie + Esprit et une transe de 5 minutes au moins, contre un SD variable selon la taille et les événements se déroulant dans le lieu (une chambre isolée depuis des années : SD10 ; un immeuble rempli d'habitants dans lequel il y a fréquemment du passage : SD 20).</p>\n<p><strong>Cibles :</strong> un seul lieu.</p>\n<p><strong>Effet :</strong> apprend des informations marquantes sur un lieu.</p>\n<p><strong>Zone d’effet : </strong>un lieu (pas plus grand qu’un bâtiment).</p>\n<p>La créature est capable, après avoir établi un contact mental avec un lieu par une transe prolongée, de récupérer des informations sur ce qui s’y est passé. En fonction de sa MR, elle aura accès à différents détails : paroles prononcées récemment ou qui ont marqué l’atmosphère, traits physiques généraux de protagonistes présents (odeur, poids, etc.). Les événements marquants (meurtre, incendie, etc.) imprègnent davantage un lieu et faciliteront le SD du test à la discrétion du Docte mais peuvent rester imperceptibles dans la masse d’informations si le lieu est vaste et fréquenté.</p>","zoneeffet":""},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-les-heritiers","systemVersion":"10.0.18","coreVersion":"10.291","createdTime":1678280900282,"modifiedTime":1678314472642,"lastModifiedBy":"3jSVOAZZNxArxD7h"},"_id":"672N9fk2mJahvJIL","folder":null,"sort":0,"ownership":{"default":0,"3jSVOAZZNxArxD7h":3}}
|
||||
{"name":"Doppelgänger universel","type":"pouvoir","img":"systems/fvtt-les-heritiers/assets/icons/power.webp","system":{"pouvoirtype":"metamorphose","masquetype":"demasque","niveau":"legendaire","activation":"test de Masque + Féérie contre un SD de 10 + Prestance de la personne imitée modifiée par la précision de la source servant à l’imitation (connaissance personnelle profonde = bonus de + 3, connaissance personnelle superficielle = + 1, photographie = - 1, illustration fidèle = - 2).","istest":true,"feeriemasque":"Masque","zoneffet":"","testautre":"","carac":"agi","duree":" une scène.","cibles":"","effet":"prendre l’apparence de n’importe qui.","portee":"","resistance":"autre","resistanceautre":"percer à jour le protys légendaire nécessite un test de Sensibilité (Psychologie) + Perception en opposition au test de Féérie + Masque du protys.","isvirulence":false,"virulence":"","description":"<p><strong>Type de Pouvoir : </strong>démasqué ; actif puis métamorphose pour adopter l’identité imitée.</p>\n<p><strong>Activation : </strong>test de Masque + Féérie contre un SD de 10 + Prestance de la personne imitée modifiée par la précision de la source servant à l’imitation (connaissance personnelle profonde = bonus de + 3, connaissance personnelle superficielle = + 1, photographie = - 1, illustration fidèle = - 2).</p>\n<p><strong>Durée : </strong>une scène.</p>\n<p><strong>Effet : </strong>prendre l’apparence de n’importe qui.</p>\n<p><strong>Résistance : </strong>percer à jour le protys légendaire nécessite un test de Sensibilité (Psychologie) + Perception en opposition au test de Féérie + Masque du protys.</p>\n<p>Le protys légendaire est capable, pendant une scène, de prendre l’apparence (traits du visage, corpulence, etc.) de n’importe quel individu dont il aurait vu le visage en réalité ou en photographie, voire sur une illustration suffisamment fidèle. Il peut même imiter une fée avec ses capacités naturelles (ailes, crocs, pelage, etc.) au point de pouvoir s’en servir normalement (il pourra ainsi voler, utiliser une queue préhensile, etc.). Il n’aura en revanche pas accès aux Pouvoirs de la fée imitée.</p>","zoneeffet":""},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-les-heritiers","systemVersion":"10.0.21","coreVersion":"10.291","createdTime":1678354656026,"modifiedTime":1678356879899,"lastModifiedBy":"3jSVOAZZNxArxD7h"},"_id":"67ECitVegs2SFn2g","folder":null,"sort":0,"ownership":{"default":0,"3jSVOAZZNxArxD7h":3}}
|
||||
{"name":"Souffle enflammé","type":"pouvoir","img":"systems/fvtt-les-heritiers/assets/icons/power.webp","system":{"pouvoirtype":"actif","masquetype":"masque","niveau":"normal","activation":" test de Féérie + Agilité ou Précision.","istest":false,"feeriemasque":"feerie","zoneffet":"","testautre":"","carac":"pre","duree":"","cibles":"une seule.","effet":"souffle de feu de dégâts = 2 + MR","portee":"Féérie mètres.","resistance":"autre","resistanceautre":"Esquive","isvirulence":false,"virulence":"","description":"<p><strong>Type de Pouvoir : </strong>actif.</p>\n<p><strong>Activation : </strong>test de Féérie + Agilité ou Précision.</p>\n<p><strong>Cibles : </strong>une seule.</p>\n<p><strong>Effet : </strong>souffle de feu de dégâts = 2 + MR.</p>\n<p><strong>Portée : </strong>Féérie mètres.</p>\n<p><strong>Résistance : </strong>Esquive.</p>\n<p>La créature souffle un jet de feu capables d’enflammer les matériaux combustibles (papier, tissus, bois) et faire des dégâts sur une cible. Cette dernière peut être durablement enflammée si les dégâts subis sont de 8 ou plus (en cumulant les attaques). La cible subira alors 1 point de dégât par tour jusqu’à ce que les flammes soient éteintes par la cible ou un allié. En as de réussite critique du Souffle enflammé, la cible peut perdre, en plus de points de Vie, un point de Prestance permanent à moins d’être soignée immédiatement.</p>","zoneeffet":""},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-les-heritiers","systemVersion":"10.0.18","coreVersion":"10.291","createdTime":1678293330850,"modifiedTime":1678314472644,"lastModifiedBy":"3jSVOAZZNxArxD7h"},"_id":"68wj1CJt4oipIedV","folder":null,"sort":0,"ownership":{"default":0,"3jSVOAZZNxArxD7h":3}}
|
||||
{"name":"Souffle enflammé","type":"pouvoir","img":"systems/fvtt-les-heritiers/assets/icons/power.webp","system":{"pouvoirtype":"actif","masquetype":"masque","niveau":"normal","activation":" test de Féérie + Agilité ou Précision.","istest":true,"feeriemasque":"feerie","zoneffet":"","testautre":"","carac":"agi","duree":"","cibles":"une seule.","effet":"souffle de feu de dégâts = 2 + MR","portee":"Féérie mètres.","resistance":"autre","resistanceautre":"Esquive","isvirulence":false,"virulence":"","description":"<p><strong>Type de Pouvoir : </strong>actif.</p>\n<p><strong>Activation : </strong>test de Féérie + Agilité ou Précision.</p>\n<p><strong>Cibles : </strong>une seule.</p>\n<p><strong>Effet : </strong>souffle de feu de dégâts = 2 + MR.</p>\n<p><strong>Portée : </strong>Féérie mètres.</p>\n<p><strong>Résistance : </strong>Esquive.</p>\n<p>La créature souffle un jet de feu capables d’enflammer les matériaux combustibles (papier, tissus, bois) et faire des dégâts sur une cible. Cette dernière peut être durablement enflammée si les dégâts subis sont de 8 ou plus (en cumulant les attaques). La cible subira alors 1 point de dégât par tour jusqu’à ce que les flammes soient éteintes par la cible ou un allié. En as de réussite critique du Souffle enflammé, la cible peut perdre, en plus de points de Vie, un point de Prestance permanent à moins d’être soignée immédiatement.</p>","zoneeffet":""},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-les-heritiers","systemVersion":"10.1.3","coreVersion":"10.291","createdTime":1678293330850,"modifiedTime":1682875304779,"lastModifiedBy":"xGnwWyEbO2k89UsP"},"_id":"68wj1CJt4oipIedV","folder":null,"sort":0,"ownership":{"default":0,"3jSVOAZZNxArxD7h":3}}
|
||||
{"name":"Chute indolore","type":"pouvoir","img":"systems/fvtt-les-heritiers/assets/icons/power.webp","system":{"pouvoirtype":"passif","masquetype":"masque","niveau":"normal","activation":"","istest":false,"feeriemasque":"feerie","zoneffet":"","testautre":"","carac":"pres","duree":"","cibles":"","effet":"la hauteur d’une chute est réduite de Féérie x 4 m pour le calcul de son SD.","portee":"","resistance":"aucune","resistanceautre":"Celle de la structure ou de l’objet (voir p. 204).","isvirulence":false,"virulence":"","description":"<p>La créature est capable d’affronter les pires chutes sans se faire mal. Lorsque ce Pouvoir est actif, on soustrait Féérie x 4 m à la hauteur de la chute pour le calcul de son SD.</p>\n<p><strong>Exemple</strong> : <em>si une créature a 4 en Féérie et chute de 20 m, c’est comme si elle ne chutait que de 4 m (elle ignore 4 x 4 = 16 m). Le SD de son test de Ressort + Agilité pour limiter les dégâts de la chute sera égal à 8 au lieu de 22 (voir le tableau des chutes, p. 190).</em></p>"},"effects":[],"flags":{"core":{"sourceId":"Item.745Qz4iEGB7RnBPk"}},"_stats":{"systemId":"fvtt-les-heritiers","systemVersion":"10.0.18","coreVersion":"10.291","createdTime":1678214487456,"modifiedTime":1678303349644,"lastModifiedBy":"xGnwWyEbO2k89UsP"},"_id":"6v3s1I0blnPJHipG","folder":null,"sort":0,"ownership":{"default":0,"xGnwWyEbO2k89UsP":3}}
|
||||
{"name":"Charme","type":"pouvoir","img":"systems/fvtt-les-heritiers/assets/icons/power.webp","system":{"pouvoirtype":"actif","masquetype":"masque","niveau":"normal","activation":"test de Féérie + Prestance.","istest":true,"feeriemasque":"feerie","zoneffet":"","testautre":"","carac":"pres","duree":"Féérie + MR jours.","cibles":" une cible.","effet":"la cible tombe amoureuse.","portee":"conversation.","resistance":"psychiquepassive","resistanceautre":"Celle de la structure ou de l’objet (voir p. 204).","isvirulence":false,"virulence":"","description":"<p>La créature est capable, au cours d’une conversation, de faire tomber sa cible follement amoureuse d’elle si elle ne Résiste pas. La cible, une fois éprise de la créature, aura du mal à lui refuser quelque chose mais ne fera rien qui puisse directement nuire à ses jours et ira rarement contre son code moral.</p>\n<p>Pour la pousser à une telle extrémité, la créature devra obtenir une réussite critique ou réussir un test de Rhétorique ou Séduction de SD 15 minimum (au jugement du Docte) bénéficiant d’un bonus égal à la MR du Pouvoir.</p>"},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-les-heritiers","systemVersion":"10.0.18","coreVersion":"10.291","createdTime":1678214487456,"modifiedTime":1678303349644,"lastModifiedBy":"xGnwWyEbO2k89UsP"},"_id":"745Qz4iEGB7RnBPk","folder":null,"sort":0,"ownership":{"default":0,"xGnwWyEbO2k89UsP":3}}
|
||||
{"name":"Sujet qui fâche","type":"pouvoir","img":"systems/fvtt-les-heritiers/assets/icons/power.webp","system":{"pouvoirtype":"actif","masquetype":"masque","niveau":"normal","activation":"test de Féérie + Esprit.","istest":true,"feeriemasque":"feerie","zoneffet":"","testautre":"","carac":"esp","duree":"","cibles":" une cible","effet":"fait deviner ce qui fâche quelqu’un ; fait perdre automatiquement un point de Sang-froid quand ce sujet est abordé et pousse à la colère.","portee":" à vue","resistance":"autre","resistanceautre":"psychique pour ne pas être percé à jour puis Fortitude + Sang-froid pour garder le contrôle contre un SD difficile (13 ou plus) fixé par le Docte.","isvirulence":false,"virulence":"","description":"<p><strong>Type de Pouvoir :</strong> actif.</p>\n<p><strong>Activation : </strong>test de Féérie + Esprit.</p>\n<p><strong>Cibles : </strong>une cible.</p>\n<p><strong>Effet :</strong> fait deviner ce qui fâche quelqu’un ; fait perdre automatiquement un point de Sang-froid quand ce sujet est abordé et pousse à la colère.</p>\n<p><strong>Portée :</strong> à vue.</p>\n<p><strong>Résistance : </strong>psychique pour ne pas être percé à jour puis Fortitude + Sang-froid pour garder le contrôle contre un SD difficile (13 ou plus) fixé par le Docte.</p>\n<p>Lorsqu’elle active ce Pouvoir, la créature peut, en observant son interlocuteur (il peut avoir un bonus d’après des éléments qu’il connaît), trouver instinctivement le sujet qui va le fâcher et, selon son caractère, le mettre en colère ou le faire fuir en rougissant. Ce peut être un complexe, une histoire louche, une phobie… Toutefois, elle n’est pas obligée d’en faire usage : le Docte doit juste lui communiquer le sujet susceptible de froisser la personne en question.<br>Si la victime Résiste, la créature n’est pas sûre du « sujet qui fâche ». En cas de succès du Pouvoir, si la créature se sert du Sujet qui fâche, la cible perd automatiquement un point de Sang-froid (effet non cumulable) et doit réussir à se maîtriser pour ne pas montrer sa colère ou sa gêne. Toutefois, la victime ne peut que maîtriser ses réactions apparentes (et bouillir intérieurement).</p>","zoneeffet":""},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-les-heritiers","systemVersion":"10.0.18","coreVersion":"10.291","createdTime":1678313273572,"modifiedTime":1678314472645,"lastModifiedBy":"3jSVOAZZNxArxD7h"},"_id":"7BsyUzwv31oxldYQ","folder":null,"sort":0,"ownership":{"default":0,"3jSVOAZZNxArxD7h":3}}
|
||||
|
||||
BIN
packs/pouvoirs/000180.ldb
Normal file
BIN
packs/pouvoirs/000180.ldb
Normal file
Binary file not shown.
0
packs/pouvoirs/000243.log
Normal file
0
packs/pouvoirs/000243.log
Normal file
1
packs/pouvoirs/CURRENT
Normal file
1
packs/pouvoirs/CURRENT
Normal file
@@ -0,0 +1 @@
|
||||
MANIFEST-000241
|
||||
0
packs/pouvoirs/LOCK
Normal file
0
packs/pouvoirs/LOCK
Normal file
8
packs/pouvoirs/LOG
Normal file
8
packs/pouvoirs/LOG
Normal file
@@ -0,0 +1,8 @@
|
||||
2025/09/13-00:19:21.348439 7fa507fff6c0 Recovering log #239
|
||||
2025/09/13-00:19:21.360125 7fa507fff6c0 Delete type=3 #237
|
||||
2025/09/13-00:19:21.360264 7fa507fff6c0 Delete type=0 #239
|
||||
2025/09/13-00:23:49.931363 7fa506bff6c0 Level-0 table #244: started
|
||||
2025/09/13-00:23:49.931398 7fa506bff6c0 Level-0 table #244: 0 bytes OK
|
||||
2025/09/13-00:23:49.943278 7fa506bff6c0 Delete type=0 #242
|
||||
2025/09/13-00:23:49.943503 7fa506bff6c0 Manual compaction at level-0 from '!items!19r9ijZUyvnlIqgm' @ 72057594037927935 : 1 .. '!items!zON0h5SjFyANjPnA' @ 0 : 0; will stop at (end)
|
||||
2025/09/13-00:23:49.943549 7fa506bff6c0 Manual compaction at level-1 from '!items!19r9ijZUyvnlIqgm' @ 72057594037927935 : 1 .. '!items!zON0h5SjFyANjPnA' @ 0 : 0; will stop at (end)
|
||||
8
packs/pouvoirs/LOG.old
Normal file
8
packs/pouvoirs/LOG.old
Normal file
@@ -0,0 +1,8 @@
|
||||
2025/09/12-22:42:55.479036 7fa5077fe6c0 Recovering log #235
|
||||
2025/09/12-22:42:55.489910 7fa5077fe6c0 Delete type=3 #233
|
||||
2025/09/12-22:42:55.489968 7fa5077fe6c0 Delete type=0 #235
|
||||
2025/09/13-00:19:16.189644 7fa506bff6c0 Level-0 table #240: started
|
||||
2025/09/13-00:19:16.189704 7fa506bff6c0 Level-0 table #240: 0 bytes OK
|
||||
2025/09/13-00:19:16.196200 7fa506bff6c0 Delete type=0 #238
|
||||
2025/09/13-00:19:16.217660 7fa506bff6c0 Manual compaction at level-0 from '!items!19r9ijZUyvnlIqgm' @ 72057594037927935 : 1 .. '!items!zON0h5SjFyANjPnA' @ 0 : 0; will stop at (end)
|
||||
2025/09/13-00:19:16.217703 7fa506bff6c0 Manual compaction at level-1 from '!items!19r9ijZUyvnlIqgm' @ 72057594037927935 : 1 .. '!items!zON0h5SjFyANjPnA' @ 0 : 0; will stop at (end)
|
||||
BIN
packs/pouvoirs/MANIFEST-000241
Normal file
BIN
packs/pouvoirs/MANIFEST-000241
Normal file
Binary file not shown.
0
packs/profils/000240.log
Normal file
0
packs/profils/000240.log
Normal file
1
packs/profils/CURRENT
Normal file
1
packs/profils/CURRENT
Normal file
@@ -0,0 +1 @@
|
||||
MANIFEST-000238
|
||||
0
packs/profils/LOCK
Normal file
0
packs/profils/LOCK
Normal file
7
packs/profils/LOG
Normal file
7
packs/profils/LOG
Normal file
@@ -0,0 +1,7 @@
|
||||
2025/09/13-00:19:21.376814 7fa50d3fa6c0 Recovering log #236
|
||||
2025/09/13-00:19:21.387738 7fa50d3fa6c0 Delete type=3 #234
|
||||
2025/09/13-00:19:21.387807 7fa50d3fa6c0 Delete type=0 #236
|
||||
2025/09/13-00:23:49.964101 7fa506bff6c0 Level-0 table #241: started
|
||||
2025/09/13-00:23:49.964142 7fa506bff6c0 Level-0 table #241: 0 bytes OK
|
||||
2025/09/13-00:23:49.974966 7fa506bff6c0 Delete type=0 #239
|
||||
2025/09/13-00:23:49.997771 7fa506bff6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
|
||||
7
packs/profils/LOG.old
Normal file
7
packs/profils/LOG.old
Normal file
@@ -0,0 +1,7 @@
|
||||
2025/09/12-22:42:55.506022 7fa507fff6c0 Recovering log #232
|
||||
2025/09/12-22:42:55.525934 7fa507fff6c0 Delete type=3 #230
|
||||
2025/09/12-22:42:55.525996 7fa507fff6c0 Delete type=0 #232
|
||||
2025/09/13-00:19:16.203395 7fa506bff6c0 Level-0 table #237: started
|
||||
2025/09/13-00:19:16.203465 7fa506bff6c0 Level-0 table #237: 0 bytes OK
|
||||
2025/09/13-00:19:16.210478 7fa506bff6c0 Delete type=0 #235
|
||||
2025/09/13-00:19:16.217685 7fa506bff6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
|
||||
BIN
packs/profils/MANIFEST-000238
Normal file
BIN
packs/profils/MANIFEST-000238
Normal file
Binary file not shown.
BIN
packs/scenes/000148.ldb
Normal file
BIN
packs/scenes/000148.ldb
Normal file
Binary file not shown.
0
packs/scenes/000211.log
Normal file
0
packs/scenes/000211.log
Normal file
1
packs/scenes/CURRENT
Normal file
1
packs/scenes/CURRENT
Normal file
@@ -0,0 +1 @@
|
||||
MANIFEST-000209
|
||||
0
packs/scenes/LOCK
Normal file
0
packs/scenes/LOCK
Normal file
8
packs/scenes/LOG
Normal file
8
packs/scenes/LOG
Normal file
@@ -0,0 +1,8 @@
|
||||
2025/09/13-00:19:21.390036 7fa507fff6c0 Recovering log #207
|
||||
2025/09/13-00:19:21.400355 7fa507fff6c0 Delete type=3 #205
|
||||
2025/09/13-00:19:21.400412 7fa507fff6c0 Delete type=0 #207
|
||||
2025/09/13-00:23:49.953427 7fa506bff6c0 Level-0 table #212: started
|
||||
2025/09/13-00:23:49.953466 7fa506bff6c0 Level-0 table #212: 0 bytes OK
|
||||
2025/09/13-00:23:49.963802 7fa506bff6c0 Delete type=0 #210
|
||||
2025/09/13-00:23:49.997755 7fa506bff6c0 Manual compaction at level-0 from '!scenes!8DjkNeeujp2qff1N' @ 72057594037927935 : 1 .. '!scenes!ypDutqjqZcr7lx6I' @ 0 : 0; will stop at (end)
|
||||
2025/09/13-00:23:49.997800 7fa506bff6c0 Manual compaction at level-1 from '!scenes!8DjkNeeujp2qff1N' @ 72057594037927935 : 1 .. '!scenes!ypDutqjqZcr7lx6I' @ 0 : 0; will stop at (end)
|
||||
8
packs/scenes/LOG.old
Normal file
8
packs/scenes/LOG.old
Normal file
@@ -0,0 +1,8 @@
|
||||
2025/09/12-22:42:55.528860 7fa5077fe6c0 Recovering log #203
|
||||
2025/09/12-22:42:55.539814 7fa5077fe6c0 Delete type=3 #201
|
||||
2025/09/12-22:42:55.539881 7fa5077fe6c0 Delete type=0 #203
|
||||
2025/09/13-00:19:16.210679 7fa506bff6c0 Level-0 table #208: started
|
||||
2025/09/13-00:19:16.210735 7fa506bff6c0 Level-0 table #208: 0 bytes OK
|
||||
2025/09/13-00:19:16.217528 7fa506bff6c0 Delete type=0 #206
|
||||
2025/09/13-00:19:16.217694 7fa506bff6c0 Manual compaction at level-0 from '!scenes!8DjkNeeujp2qff1N' @ 72057594037927935 : 1 .. '!scenes!ypDutqjqZcr7lx6I' @ 0 : 0; will stop at (end)
|
||||
2025/09/13-00:19:16.217733 7fa506bff6c0 Manual compaction at level-1 from '!scenes!8DjkNeeujp2qff1N' @ 72057594037927935 : 1 .. '!scenes!ypDutqjqZcr7lx6I' @ 0 : 0; will stop at (end)
|
||||
BIN
packs/scenes/MANIFEST-000209
Normal file
BIN
packs/scenes/MANIFEST-000209
Normal file
Binary file not shown.
19
srcdata/normalize.py
Normal file
19
srcdata/normalize.py
Normal file
@@ -0,0 +1,19 @@
|
||||
import json
|
||||
|
||||
FIELDS = ["name", "competence", "description", "duree", "portee", "concentration", "critique", "ingredients", "resistance"]
|
||||
|
||||
def capitalize_first_letter(s):
|
||||
if isinstance(s, str) and s:
|
||||
return s[0].upper() + s[1:]
|
||||
return s
|
||||
|
||||
with open("../srcdata/sort_magieduclan.json", "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
|
||||
for spell in data:
|
||||
for field in FIELDS:
|
||||
if field in spell:
|
||||
spell[field] = capitalize_first_letter(spell[field])
|
||||
|
||||
with open("../srcdata/sort_magieduclan.json", "w", encoding="utf-8") as f:
|
||||
json.dump(data, f, ensure_ascii=False, indent=2)
|
||||
287
srcdata/sort_druidisme.json
Normal file
287
srcdata/sort_druidisme.json
Normal file
@@ -0,0 +1,287 @@
|
||||
[
|
||||
{
|
||||
"name": "Rituels de purification",
|
||||
"description": "Les rituels de purification consistent à laver une souillure le plus souvent physique et/ou spirituelle, quand le mauvais œil (ou une malédiction) a été placé sur un lieu ou un objet : sang et tripes de cochon versés dans un puits, chouette aux yeux crevés clouée à une porte, crucifix figé dans un chêne, poupée de paille percée d’aiguilles, etc. Outre le nettoyage des éléments physiques, le rituel consiste à recourir aux plantes purgatives et aux fumigations naturelles appropriées, associées à une récitation de formules consacrées à la Grande Mère. Note : un individu changé en animal contre son gré à l’aide d’une amulette druidique ou d’une potion de faëomancie est considéré comme « maudit » et peut être purifié à l’aide de ce rituel pour retrouver sa forme d’origine. Le SD du rituel sera égal au SD du niveau de maîtrise du sort qui a servi à la métamorphose, ou bien fixé par le Docte.",
|
||||
"niveau": 1,
|
||||
"competence": "Druidisme",
|
||||
"carac1": "esp",
|
||||
"carac2": "pres",
|
||||
"duree": "",
|
||||
"portee": "",
|
||||
"concentration": "",
|
||||
"critique": "",
|
||||
"ingredients": "Plantes purgatives et aux fumigations naturelles appropriées",
|
||||
"resistance": "",
|
||||
"coutactivation": ""
|
||||
},
|
||||
{
|
||||
"name": "Philtre de veille",
|
||||
"description": "Faire macérer des poignées de ronces et d’orties dans de l’eau salée du lever jusqu’au coucher de soleil. Pour chaque poignée macérée est produite une dose de philtre. Égoutter les ronces et les orties, les calciner et réduire le charbon ainsi obtenu en une fine poudre. Incorporer celle-ci au liquide issu de la macération ; faire chauffer jusqu’à ébullition. Réciter les paroles propitiatoires. Ce philtre doit être bu à la nuit tombée. Son utilisateur ne ressent pas les effets de la fatigue pendant la nuit et le jour qui suit, et il ne subit pas les désagréments du manque de sommeil (battements de cœur, troubles de la perception, somnolence…). En revanche, il s’effondrera de sommeil au prochain coucher de soleil.",
|
||||
"niveau": 1,
|
||||
"competence": "Druidisme",
|
||||
"carac1": "esp",
|
||||
"carac2": "prec",
|
||||
"duree": "Jusqu’au prochain coucher de soleil",
|
||||
"portee": "",
|
||||
"concentration": "Macération (du lever au coucher de soleil) + préparation",
|
||||
"critique": "Le philtre dure une journée de plus",
|
||||
"ingredients": "Ronces et orties",
|
||||
"resistance": "",
|
||||
"coutactivation": ""
|
||||
},
|
||||
{
|
||||
"name": "Philtre de sommeil",
|
||||
"description": "Faire bouillir les fleurs de belladone et de passiflore ensemble. Ajouter à la décoction une pointe de miel pour le goût. Renforce le pouvoir soporifique et apaisant des plantes par les paroles rituelles. Le goût sucré rend ce philtre facile à dissimuler dans une pâtisserie ou dans un fruit qui en serait imbibé pendant une nuit. Celui qui absorbe ce philtre commencera à s’assoupir une minute après, et dormira sur ses deux oreilles dans les trois minutes qui suivent.",
|
||||
"niveau": 1,
|
||||
"competence": "Druidisme",
|
||||
"carac1": "esp",
|
||||
"carac2": "prec",
|
||||
"duree": "6 heures, sauf si le dormeur est réveillé de manière active par autrui",
|
||||
"portee": "",
|
||||
"concentration": "Préparation",
|
||||
"critique": "La durée est doublée",
|
||||
"ingredients": "Belladone, passiflore et miel",
|
||||
"resistance": "Physique contre le résultat du sort (ou SD 14) pour ne pas s’assoupir",
|
||||
"coutactivation": ""
|
||||
},
|
||||
{
|
||||
"name": "Philtre d’amour",
|
||||
"description": "Faire macérer les pétales d’une rose dans de l’eau. Piler les racines d’une mandragore et les incorporer à la macération. Intégrer au mélange trois larmes en prononçant le poème rituel, puis filtrer le tout. Boire ce philtre rend surnaturellement attirant : il fait bénéficier d’un bonus de + 2 à toute tentative de séduction. Ce bonus est cumulable avec d’autres de même nature (par exemple issus d’avantages ou d’atouts féériques).",
|
||||
"niveau": 1,
|
||||
"competence": "Druidisme",
|
||||
"carac1": "esp",
|
||||
"carac2": "prec",
|
||||
"duree": "Jusqu’à ce que l’utilisateur se lave",
|
||||
"portee": "",
|
||||
"concentration": "Préparation",
|
||||
"critique": "L’utilisateur bénéficie non plus d’un bonus de + 2, mais d’un bonus de + 3 à toutes ses tentatives de séduction",
|
||||
"ingredients": "Mandragore et rose",
|
||||
"resistance": "",
|
||||
"coutactivation": ""
|
||||
},
|
||||
{
|
||||
"name": "Philtre de descendance féérique",
|
||||
"description": "Réduire les fleurs d’acacia et clous de girofle en poudre, mélanger aux larmes et réciter les paroles sacrées au moment d’une pleine lune. Quelques gouttes de ce philtre bues par une femme ou une fée avant de faire l’amour garantiront que, si elle conçoit un enfant avec un Faux-Semblant, celui-ci sera également un Faux-Semblant (de l’espèce du père ou de la mère). Un philtre équivalent élaboré avec des larmes humaines garantit que l’enfant éventuel sera humain.",
|
||||
"niveau": 1,
|
||||
"competence": "Druidisme",
|
||||
"carac1": "esp",
|
||||
"carac2": "prec",
|
||||
"duree": "2 heures",
|
||||
"portee": "",
|
||||
"concentration": "Préparation",
|
||||
"critique": "Le philtre accroît considérablement les chances de fécondation",
|
||||
"ingredients": "Fleurs d’acacia, clous de girofle, larmes de pixie ou d’humain",
|
||||
"resistance": "",
|
||||
"coutactivation": ""
|
||||
},
|
||||
{
|
||||
"name": "Philtre de bienveillance végétale",
|
||||
"description": "Écraser les feuilles de lierre et en retirer le jus. Mélanger celui-ci à du jus de sureau. Le mélange doit être exposé pendant une nuit à la lueur de la pleine lune, au cours de laquelle le druide répétera le poème consacré. La préparation ainsi obtenue rendra la présence de la personne qui la boit très agréable à la végétation environnante. Celle-ci s’écartera sur son passage, même s’il s’agit de ronciers inextricables, et se refermera derrière elle comme si personne n’était passé, facilitant les trajets à travers les broussailles, sous-bois ou jungles comme si elle marchait sur un chemin pédestre. Si un test de Survie est requis, un bonus reflétant cette collaboration des plantes sera fixé par le Docte.",
|
||||
"niveau": 1,
|
||||
"competence": "Druidisme",
|
||||
"carac1": "esp",
|
||||
"carac2": "prec",
|
||||
"duree": "6 heures",
|
||||
"portee": "",
|
||||
"concentration": "Exposition pendant une nuit + préparation",
|
||||
"critique": "La durée est doublée",
|
||||
"ingredients": "Feuilles de lierre, baies de sureau",
|
||||
"resistance": "",
|
||||
"coutactivation": ""
|
||||
},
|
||||
{
|
||||
"name": "Philtre tord-boyaux",
|
||||
"description": "Envelopper les baies de houx dans les feuilles d’hortensia, écraser le tout et en extraire le jus. Diluer le liquide dans sept gouttes de rosée et réciter les paroles consacrées afin que le philtre soit presque indétectable et que son goût normalement très amer devienne douceâtre. Descriptif du poison : Voies d’administration : ingestion. Toxicité : 5 Virulence : 15 Signature : 15. L’avantage de ce philtre est qu’il passera beaucoup plus facilement pour une simple intoxication alimentaire qu’un empoisonnement à l’arsenic. Complexité : n. a. Temps de fabrication : une heure avant l’aube Effets : le philtre tord-boyaux est un liquide translucide au goût douceâtre. Ce goût subtil est aisément dissimulé dans un plat à la saveur prononcée. La substance a l’insigne avantage de ne pas perdre ses effets lors d’une éventuelle cuisson. Ingéré, le poison commence à faire effet au cours de la digestion (deux heures). Il cause des maux de ventre, des vomissements et des diarrhées si aigus que celui qui l’ingère se tordra de douleur pendant 4 heures. En cas d’échec à un test de Ressort (Endurer) + CON SD 15 pour Résister à la Virulence du poison, la victime perdra Toxicité + ME points de vie en plus de subir un malus de - 5 à toutes ses actions. En cas de réussite, ce malus est réduit à - 2. Note : voir le supplément Drogues délicieuses et effroyables poisons pour plus de détails sur le fonctionnement des poisons, et sur la terminologie propre à ces derniers qui est employée ici pour ce philtre. Notez que deux des poisons qui sont décrits dans cet opuscule, « Humeur de basilic » et « Sang de manticore », sont aussi des poisons fabriqués par les druides la plupart du temps.",
|
||||
"niveau": 1,
|
||||
"competence": "Druidisme",
|
||||
"carac1": "esp",
|
||||
"carac2": "prec",
|
||||
"duree": "4 heures (effets)",
|
||||
"portee": "",
|
||||
"concentration": "Une heure avant l’aube (fabrication)",
|
||||
"critique": "La Signature est augmentée de 2",
|
||||
"ingredients": "Baies de houx et feuilles d’hortensia",
|
||||
"resistance": "Physique (ressort + con)",
|
||||
"coutactivation": ""
|
||||
},
|
||||
{
|
||||
"name": "Le rituel des Portes d’Avalon",
|
||||
"description": "Voilà bien longtemps déjà que, pour les profanes, les chemins d’Avalon se sont perdus dans les brumes de l’oubli. Désormais, seuls les druides sont en mesure de s’y rendre grâce au rituel des portes d’Avalon. Ce rituel est un secret bien gardé parmi les druides, car nombreux sont les ennemis de la Grande Mère et des fées qui aimeraient trouver le chemin de la contrée féérique pour en voler les ressources ou pire, la pervertir voire la détruire. Pour se rendre en Avalon, le druide doit trouver un portail, c’est-à-dire deux chênes aux ramures inextricablement entrelacées. Il peut également, grâce à ses pouvoirs, le fabriquer. Puis il doit réciter le poème rituel tout en avalant un gland issu d’un chêne avalonien. Lorsque sa litanie prend fin, le brouillard se lève et entoure les chênes dont on n’aperçoit plus que les troncs. En regardant attentivement, on peut discerner une fine pellicule d’eau ruisseler des ramures qui finissent par disparaître. Le passage est ouvert. Les invités du druide peuvent passer, mais attention ! Le passage se referme dès lors que le druide est passé, à moins que ce dernier ne le maintienne ouvert à dessein, ce qui est normalement interdit. Note : ce rituel est enseigné à tous les Saronides et ne requiert pas l’habituelle dépense de 5 points d’XP accompagnant l’apprentissage d’un nouveau sort.",
|
||||
"niveau": 2,
|
||||
"competence": "Druidisme",
|
||||
"carac1": "esp",
|
||||
"carac2": "pres",
|
||||
"duree": "",
|
||||
"portee": "Au portail",
|
||||
"concentration": "Réciter le poème rituel",
|
||||
"critique": "",
|
||||
"ingredients": "Gland issu d’un chêne avalonien",
|
||||
"resistance": "",
|
||||
"coutactivation": ""
|
||||
},
|
||||
{
|
||||
"name": "Rituel de malédiction",
|
||||
"description": "Les druides sont censés déjouer les malédictions, purifier les lieux souillés ou les victimes du mauvais œil. Cependant, à partir du deuxième cercle, ils sont capables eux-mêmes de maudire un objet, une personne ou un lieu. Un rituel de malédiction fonctionne à rebours d’un rituel de purification. Le druide trouve un objet ou une substance comme support de sa malédiction et récite des paroles rituelles désignant la cible, le plus souvent à minuit, à la faveur de la lune. L’effet de ce type de malédiction mineure est ouvert aux fantaisies du Docte (ou des joueurs) : pustules sur la langue, chute de cheveux (s’accompagnant d’un malus de -1 en Prestance), maladresse chronique (malus de -1 en Précision ou Agilité), etc. Si vous songez à une malédiction majeure aux effets bien plus redoutables, augmentez le SD et exigez un rituel collectif. Dans tous les cas, une malédiction majeure sera très mal vue au sein de la communauté druidique et le responsable risque l’exclusion. Note : le fonctionnement de ce rituel est enseigné à tous les Saronides et ne requiert pas l’habituelle dépense de 5 points d’XP accompagnant l’apprentissage d’un nouveau sort.",
|
||||
"niveau": 2,
|
||||
"competence": "Druidisme",
|
||||
"carac1": "esp",
|
||||
"carac2": "pres",
|
||||
"duree": "",
|
||||
"portee": "",
|
||||
"concentration": "Récite des paroles rituelles",
|
||||
"critique": "",
|
||||
"ingredients": "Objet ou une substance comme support",
|
||||
"resistance": "Psychique ou physique (la plus élevée de la cible)",
|
||||
"coutactivation": ""
|
||||
},
|
||||
{
|
||||
"name": "Semence de lierre rouge",
|
||||
"description": "Enduire la graine de lierre avec du crottin d’hippogriffe et attendre trois jours. Après cela, une pousse sortira de la graine et il faudra chanter une strophe d’épopée en celte transformant la graine germée en arme. Lorsque celle-ci touchera le sol à proximité d’un ennemi de celui qui l’a lancée, des lianes de lierre rouge enchevêtreront ses pieds jusqu’aux genoux et conféreront un malus de -1 aux actions de la cible impliquant un mouvement. Ensuite, à chaque tour, le lierre montera davantage et deviendra plus vigoureux et difficile à trancher. La victime pourra se battre, mais non bouger ses jambes et souffrira donc d’un malus de -1 supplémentaire pour toute attaque de Mêlée, parade ou bien esquive. Le malus maximum est -5, quand la cible est presque immobilisée par un lierre rouge qui lui enserre tout le corps jusqu’à la tête. Il faudra trancher ou brûler le lierre en causant 10 points de dégâts grâce à une arme tranchante ou un jet de flamme avec un SD de 13 (un échec critique signifiera que le coup a touché la cible). Sans arme tranchante ou flamme, le lierre rouge continuera à pousser et se renforcer, mais finira par se flétrir au bout de 15 minutes.",
|
||||
"niveau": 2,
|
||||
"competence": "Druidisme",
|
||||
"carac1": "esp",
|
||||
"carac2": "",
|
||||
"duree": "15 minutes (si non coupée/brûlée)",
|
||||
"portee": "À proximité",
|
||||
"concentration": "Préparation sur trois jours + chant",
|
||||
"critique": "Les points de vie du lierre sont doublés pour déterminer combien de coups d’armes tranchantes sont nécessaires afin de le couper",
|
||||
"ingredients": "Une graine de lierre avalonien et du crottin d’hippogriffe",
|
||||
"resistance": "",
|
||||
"coutactivation": ""
|
||||
},
|
||||
{
|
||||
"name": "Semence de ronce curatrice",
|
||||
"description": "Cracher sur la ronce et l’enduire de pollen d’églantine avalonien. L’enterrer en récitant le poème consacré et attendre trois jours. Le troisième jour, alors que l’aube étend son voile de rosée sur le monde, déterrer la ronce qui émet une très légère aura verte et pulsatile. Une fois que la ronce a été bénie, le druide doit l’appliquer sur la blessure qu’il veut guérir. Ses épines s’enfoncent douloureusement dans la peau du blessé afin de la refermer, tels des points de suture. Le blessé regagne instantanément 1d8 points de vie car la ronce sert de cicatrisant. Lorsque la cicatrisation naturelle du blessé est terminée, la ronce sèche et tombe d’elle-même. Cette semence permet de cicatriser, mais aussi d’ôter les corps étrangers (comme les balles) : la ronce s’introduit jusqu’au matériau, l’enserre et le repousse, non sans causer une douleur extrême si aucun anesthésiant n’est utilisé (test de Ressort + CON SD 14 pour ne pas s’évanouir pendant ME minutes).",
|
||||
"niveau": 2,
|
||||
"competence": "Druidisme",
|
||||
"carac1": "esp",
|
||||
"carac2": "",
|
||||
"duree": "Jusqu’à cicatrisation naturelle",
|
||||
"portee": "Contact",
|
||||
"concentration": "Préparation sur trois jours + poème",
|
||||
"critique": "La semence rend directement 8 points de vie au lieu d’1d8",
|
||||
"ingredients": "Ronce du pays d’hiver et pollen d’églantine avalonienne",
|
||||
"resistance": "Ressort (con)",
|
||||
"coutactivation": ""
|
||||
},
|
||||
{
|
||||
"name": "Semence de force",
|
||||
"description": "Faire bouillir une poignée de fleurs de trèfle rouge pendant une journée, puis faire macérer la feuille de chêne avalonien dans le liquide obtenu. Faire sécher la feuille de chêne avalonien au soleil jusqu’à ce que des petits piquants poussent sur cette dernière. Après bénédiction du druide, l’utilisateur doit poser la feuille de chêne enchantée sur son plexus solaire et appuyer jusqu’à ce que les petits piquants lui rentrent dans la peau. La feuille s’intègre alors temporairement au corps de l’utilisateur. Elle lui confère un bonus temporaire de + 2 en Force. Ce bonus est cumulable avec celui de la Capacité naturelle Force accrue (mais aucune créature naturelle ne peut avoir plus de 10 en Force). Au prochain lever de soleil, la feuille de chêne tombe d’elle-même, jaunie et racornie.",
|
||||
"niveau": 2,
|
||||
"competence": "Druidisme",
|
||||
"carac1": "esp",
|
||||
"carac2": "",
|
||||
"duree": "Jusqu’au prochain lever de soleil",
|
||||
"portee": "Contact",
|
||||
"concentration": "Préparation d'une journée + séchage + bénédiction",
|
||||
"critique": "Bonus de + 3 au lieu de + 2",
|
||||
"ingredients": "Feuille de chêne avalonien et fleurs de trèfle rouge",
|
||||
"resistance": "",
|
||||
"coutactivation": ""
|
||||
},
|
||||
{
|
||||
"name": "Semence de chêne",
|
||||
"description": "Écraser les baies du gui avalonien et recouvrir le gland de la substance obtenue. Exposer le gland sur un lit de gui avalonien au soleil pendant sept jours, puis réciter le poème consacré et cracher sur le gland. Après bénédiction, lorsque la semence de chêne touche la terre, c’est-à-dire le berceau de la Grande Mère, elle se met à pousser à une vitesse fulgurante. En cinq tours, la plante a atteint sa pleine maturité. Elle suit, ensuite, son cycle naturel. Note : dans l’intention d’utiliser la semence de chêne pour le rituel des Portes d’Avalon, il suffit d’en planter deux à trois mètres de distance l’une de l’autre et d’attendre sept jours.",
|
||||
"niveau": 2,
|
||||
"competence": "Druidisme",
|
||||
"carac1": "esp",
|
||||
"carac2": "",
|
||||
"duree": "Suit son cycle naturel après 5 tours de croissance",
|
||||
"portee": "",
|
||||
"concentration": "Préparation sur sept jours + poème",
|
||||
"critique": "Le chêne généré grâce à cette semence est sage, et prodiguera des conseils avisés à ceux qui peuvent communiquer avec lui. C’est un miracle de la Grande Mère qui deviendra objet de soin des druides et des fées proches de la nature",
|
||||
"ingredients": "Gland et gui avalonien",
|
||||
"resistance": "",
|
||||
"coutactivation": ""
|
||||
},
|
||||
{
|
||||
"name": "Semence de haricot magique",
|
||||
"description": "Le druide doit cueillir lui-même des haricots, les écosser et en faire sécher les semences pendant deux jours. Ensuite, il lui faut demander à une licorne qu’elle crache dessus, et réciter les paroles rituelles. Au contact de la terre, comme dans le conte, le haricot poussera à une vitesse prodigieuse et atteindra une hauteur de 12 mètres. Il est possible de grimper aux branches comme à une échelle ou bien de se placer au-dessus de la graine pour être hissé au moment de la croissance. Le haricot supporte un poids de 500 kg. Pour atteindre sa pleine hauteur, 3 minutes sont requises. Le Pouvoir Main verte du sylve sur un haricot magique divisera par 3 le temps de croissance, multipliera par 3 sa capacité de charge ainsi que la hauteur atteinte, jusqu’à 36 mètres (46 mètres avec une réussite critique). Note : la durée de vie de cette plante géante est limitée. Au bout de 6 heures, elle se flétrira puis pourrira.",
|
||||
"niveau": 2,
|
||||
"competence": "Druidisme",
|
||||
"carac1": "esp",
|
||||
"carac2": "",
|
||||
"duree": "6 heures",
|
||||
"portee": "",
|
||||
"concentration": "Préparation sur deux jours + salive de licorne + poème",
|
||||
"critique": "La hauteur du haricot est augmentée de 10 mètres",
|
||||
"ingredients": "Haricot avalonien du pays d’été et salive de licorne",
|
||||
"resistance": "",
|
||||
"coutactivation": ""
|
||||
},
|
||||
{
|
||||
"name": "Amulette de métamorphose en aigle",
|
||||
"description": "Le druide doit préparer une pâte en mélangeant l’argile et l’eau de rosée. Lorsque la pâte atteint la bonne consistance, il doit la modeler en forme d’aigle et y planter la plume d’aigle en prononçant les paroles rituelles. Pour utiliser son amulette, le druide doit la briser sur sa cible en récitant à nouveau les paroles rituelles. Il transforme alors sa cible en aigle. Il peut, bien entendu, être la cible de son propre sort. Certains druides punissent leurs ennemis en les transformant pour longtemps, ou à jamais, en animaux. Cette amulette est déclinable en toutes sortes d’animaux et de plantes, et les druides les plus cruels n’hésitent pas à transformer leur cible en crapaud… Cependant, notez que le druide doit apprendre un nouveau sort pour chaque animal en lequel il peut se changer ou transformer autrui. En effet, ces amulettes reposent sur la connaissance des noms secrets des choses et des êtres qui nécessitent un apprentissage complexe. Note : il existe des amulettes similaires permettant d’octroyer temporairement le Pouvoir de Communication animale ou végétale à la cible pendant une semaine. Elles constituent un sort différent et requièrent un apprentissage dédié (et donc la dépense d’XP afférente).",
|
||||
"niveau": 3,
|
||||
"competence": "Druidisme",
|
||||
"carac1": "prec",
|
||||
"carac2": "",
|
||||
"duree": "Une semaine, ou jusqu’à ce que le druide désire faire cesser la métamorphose",
|
||||
"portee": "Contact",
|
||||
"concentration": "Préparation",
|
||||
"critique": "Celui qui est métamorphosé en aigle peut parler aux animaux, quels qu’ils soient",
|
||||
"ingredients": "Plume d’aigle, eau de rosée avalonienne, argile avalonien",
|
||||
"resistance": "Physique pour une cible récalcitrante au pouvoir de l’amulette",
|
||||
"coutactivation": ""
|
||||
},
|
||||
{
|
||||
"name": "Amulette de cercle de protection",
|
||||
"description": "L’Ovate doit baigner la large pierre dans de l’eau vive, la sécher et la faire chauffer pendant une journée. À ce moment, il doit appliquer la feuille de chêne sur la pierre de manière qu’elle s’incruste dedans en récitant les paroles rituelles. Pour activer le cercle de protection, le druide doit délimiter de manière continue son aire d’action (fil enterré, frise dans la pierre, canalisation d’eau…), qui a pour rayon maximal la valeur de Prestance du druide x 100 m. Puis il enterre son amulette au centre du cercle en répétant les paroles rituelles. Dès lors, le cercle de protection est actif, ce qui signifie que nul ne peut y entrer sans y avoir été invité à voix haute par le druide. Les contrevenants sont bloqués par une force invisible. Forcer le passage est possible en réussissant un test de Ressort + FOR ou Fortitude + ESP contre un SD égal au score du test du druide. En cas d’échec, le contrevenant s’évanouira si sa Résistance psychique est inférieure au SD du sort, sinon, il souffrira d’une migraine causant un malus de - 2.",
|
||||
"niveau": 3,
|
||||
"competence": "Druidisme",
|
||||
"carac1": "prec",
|
||||
"carac2": "",
|
||||
"duree": "Tant que le cercle est brisé ou que l’amulette est déterrée",
|
||||
"portee": "Valeur de Prestance du druide x 100 m (rayon)",
|
||||
"concentration": "Préparation d'une journée + délimitation",
|
||||
"critique": "Le cercle ne peut être brisé que si l’amulette est déterrée",
|
||||
"ingredients": "Large pierre, feuille de chêne avalonien",
|
||||
"resistance": "Ressort (for / fort / esp)",
|
||||
"coutactivation": ""
|
||||
},
|
||||
{
|
||||
"name": "Amulette d’orage",
|
||||
"description": "Le druide doit tailler la branche de frêne avalonien en une baguette de la taille de son avant-bras, et l’immerger pendant une semaine dans l’eau de pluie d’Avalon. Lorsqu’il la sort de l’eau, il doit y graver une rune secrète et prononcer les paroles rituelles. Pour utiliser son amulette, le druide doit voir le ciel et psalmodier les paroles rituelles en le contemplant. Puis, sur la dernière syllabe, il brise la baguette. À partir de ce moment, les nuées commencent à converger et le ciel s’obscurcit ; au bout de dix minutes, la pluie se met à tomber. Dix minutes plus tard, l’orage est là. Le druide peut manipuler l’orage, le déplacer, faire varier l’intensité de ses pluies et, surtout, manier la foudre. Pour ce faire, il doit réussir un test de Druidisme + PER SD 15. En cas de réussite, il foudroie sa cible qui subit [MR + 6] points de dégâts. Il peut manier la foudre une fois par tour (une Action), mais cela lui coûte 3 points d’Âme à chaque fois (et un point temporaire d’Esprit quand sa réserve d’Âme est épuisée). Note : il existe d’autres amulettes pour contrôler le temps qu’il fait (invoquer le soleil ou la pluie, etc.). Ce sont des sorts différents, requérant un apprentissage à part entière, mais qui fonctionnent de manière équivalente. Par exemple, une amulette de blizzard fera venir une tempête de neige et le druide pourra diriger de violentes bourrasques à la place de la foudre, ne causant pas de dégâts mais faisant tomber les cibles. Cependant, la température extérieure ne doit pas excéder 10 degrés pour que cette amulette fonctionne.",
|
||||
"niveau": 3,
|
||||
"competence": "Druidisme",
|
||||
"carac1": "prec",
|
||||
"carac2": "",
|
||||
"duree": "Jusqu’à ce que le druide s’endorme ou perde conscience",
|
||||
"portee": "",
|
||||
"concentration": "Préparation d'une semaine + activation",
|
||||
"critique": "L’orage se déclenche en une minute",
|
||||
"ingredients": "Branche de frêne avalonien et eau de pluie avalonienne",
|
||||
"resistance": "",
|
||||
"coutactivation": "3 points d’Âme (et 1 point temporaire d’Esprit si jauge d’Âme épuisée) par utilisation de la foudre"
|
||||
},
|
||||
{
|
||||
"name": "Amulette de renaissance du Bras",
|
||||
"description": "L’Ovate doit enrouler la patte d’ours dans les feuilles de marronnier avalonien en prononçant les paroles rituelles. Puis il fait sécher le tout au soleil (la patte ne pourrit pas car elle est déjà enchantée). Pour utiliser son amulette, le druide doit humecter la patte d’ours avec le sang du manchot. Puis il la jette dans un grand feu en répétant les paroles rituelles tout au long de la combustion. La cible sent alors son bras repousser au fur et à mesure que la patte d’ours se consume. Lorsqu’elle est complètement consumée, la cible a complètement récupéré son bras et l’usage de celui-ci. Le druide peut être la cible de son propre sort.",
|
||||
"niveau": 3,
|
||||
"competence": "Druidisme",
|
||||
"carac1": "prec",
|
||||
"carac2": "",
|
||||
"duree": "Définitive",
|
||||
"portee": "Contact",
|
||||
"concentration": "Préparation + séchage + combustion",
|
||||
"critique": "Le bras nouvellement acquis est irrigué par les forces de la Grande Mère. Il bénéficie d’un bonus perpétuel de + 1 en Force (dans la limite du rang 10). Ce bonus est invisible : la cible n’a pas un bras plus gros que l’autre",
|
||||
"ingredients": "Feuilles de marronnier avalonien et patte d’ours décédé de mort naturelle",
|
||||
"resistance": "",
|
||||
"coutactivation": ""
|
||||
},
|
||||
{
|
||||
"name": "Rituel de réenchantement",
|
||||
"description": "Un Ovate aidé d’au moins trois confrères est capable de restaurer la Féérie d’un Faux-Semblant qui aurait été victime du Grand Rituel d’exorcisme (voir p. 67) (l’équivalent d’une malédiction majeure pour sa victime). Le druide peut, en récitant les paroles rituelles pendant trois heures et surtout, au moyen d’une quantité invraisemblable de poudre d’aile de pixie, réenchanter la victime de l’exorcisme et lui restituer un rang de Féérie. La victime devra ensuite séjourner un an en Avalon pour redévelopper sa Féérie et pouvoir à nouveau se démasquer. Elle sera de la même espèce et conservera la même apparence qu’avant, mais devra réapprendre progressivement à utiliser ses Pouvoirs. Note : ce sort difficile, et rarement pratiqué, est connu des Ovates sans qu’ils aient besoin de dépenser d’XP pour l’apprendre. Il fait partie de leur initiation druidique.",
|
||||
"niveau": 3,
|
||||
"competence": "Druidisme",
|
||||
"carac1": "esp",
|
||||
"carac2": "",
|
||||
"duree": "Permanente (restauration), un an (redéveloppement de Féérie)",
|
||||
"portee": "",
|
||||
"concentration": "Trois heures de récitation",
|
||||
"critique": "",
|
||||
"ingredients": "Poudre d’aile de pixie",
|
||||
"resistance": "",
|
||||
"coutactivation": ""
|
||||
}
|
||||
]
|
||||
137
srcdata/sort_faeomancie.json
Normal file
137
srcdata/sort_faeomancie.json
Normal file
@@ -0,0 +1,137 @@
|
||||
[
|
||||
{
|
||||
"name": "Potion de faiblesse à l’argent",
|
||||
"description": "Le bénéficiaire est vulnérable à l’argent comme s’il était une fée pendant les trente prochaines minutes s’il a bu la potion, pendant 10 tours s’il l’a respirée, pendant les deux prochains tours s’il en a seulement été aspergé. Cette préparation est sans effet sur une fée.",
|
||||
"niveau": "1",
|
||||
"competence": "Faëomancie",
|
||||
"carac1": "precision",
|
||||
"carac2": "sang-froid",
|
||||
"duree": "Trente prochaines minutes s’il a bu la potion, pendant 10 tours s’il l’a respirée, pendant les deux prochains tours s’il en a seulement été aspergé",
|
||||
"portee": "",
|
||||
"concentration": "",
|
||||
"critique": "",
|
||||
"ingredients": "Cinq litres de sang de fée.",
|
||||
"resistance": "",
|
||||
"coutactivation": ""
|
||||
},
|
||||
{
|
||||
"name": "Émincé de force d’ogre",
|
||||
"description": "Le bénéficiaire obtient + 1 en Force. Note : c’est là un exemple de recette où des ingrédients alternatifs sont faciles à substituer ; en l’occurrence, les biceps de toute fée disposant de la Capacité naturelle Force accrue pourront constituer un ingrédient alternatif.",
|
||||
"niveau": "1",
|
||||
"competence": "Faëomancie",
|
||||
"carac1": "precision",
|
||||
"carac2": "sang-froid",
|
||||
"duree": "",
|
||||
"portee": "",
|
||||
"concentration": "",
|
||||
"critique": "",
|
||||
"ingredients": "Un biceps d’ogre, une pincée de poivre fort, une livre de saindoux d’ogre.",
|
||||
"resistance": "",
|
||||
"coutactivation": ""
|
||||
},
|
||||
{
|
||||
"name": "Masque de fée",
|
||||
"description": "Le visage et la peau du bénéficiaire sont profondément modifiés pour lui donner l’apparence d’une fée de l’espèce de celle qu’il a dépecée, qu’il soit lui-même un humain ou un Faux-Semblant. Un bonus égal à la MR/2 du test de Faëomancie sera appliqué aux éventuels tests de Comédie + PRES requis pour ne pas être percé à jour. L’effet perdure pendant MR jours. Note : la taille du bénéficiaire n’est pas changée et il ne lui poussera pas d’ailes ou autres appendices, même si l’espèce féérique imitée est censée en avoir. Ces détails peuvent trahir son déguisement qui devra donc être complété soit grâce à une autre préparation faëomantique, soit par des appendices postiches, s’il ne veut pas qu’un Faux-Semblant le perce à jour aisément grâce à un test d’Observation + PER au SD en opposition au test de Comédie + PRES.",
|
||||
"niveau": "2",
|
||||
"competence": "Faëomancie",
|
||||
"carac1": "precision",
|
||||
"carac2": "sang-froid",
|
||||
"duree": "MR jours",
|
||||
"portee": "",
|
||||
"concentration": "",
|
||||
"critique": "",
|
||||
"ingredients": "Peau du visage d’un Faux-Semblant démasqué ou d’une fée encore en vie ; poudre d’aile de pixie ; sang de la victime ; graisse de protys",
|
||||
"resistance": "",
|
||||
"coutactivation": ""
|
||||
},
|
||||
{
|
||||
"name": "CromesQuis de calme angÉliQue",
|
||||
"description": "Le bénéficiaire obtient le Pouvoir Calme pendant au moins trente minutes.",
|
||||
"niveau": "2",
|
||||
"competence": "Faëomancie",
|
||||
"carac1": "precision",
|
||||
"carac2": "sang-froid",
|
||||
"duree": "Au moins trente minutes",
|
||||
"portee": "",
|
||||
"concentration": "",
|
||||
"critique": "",
|
||||
"ingredients": "Un os de mâchoire d’ange, sept cheveux d’ange, un cœur d’ange.",
|
||||
"resistance": "",
|
||||
"coutactivation": ""
|
||||
},
|
||||
{
|
||||
"name": "Ragoût de ramollissement du mÉtal",
|
||||
"description": "Le bénéficiaire obtient le Pouvoir profond Ramollissement du métal pendant au moins trente minutes.",
|
||||
"niveau": "3",
|
||||
"competence": "Faëomancie",
|
||||
"carac1": "precision",
|
||||
"carac2": "sang-froid",
|
||||
"duree": "Au moins trente minutes",
|
||||
"portee": "",
|
||||
"concentration": "",
|
||||
"critique": "",
|
||||
"ingredients": "100 g de moelle d’os de gnome profond, un demi-litre de bile de gnome profond, un litre de vin rouge (pour le goût), 2 kg de chair de gnome profond, 10 g de poudre d’aile de pixie. Note : un Maître-queux n’a pas besoin que le gnome soit un gnome profond.",
|
||||
"resistance": "",
|
||||
"coutactivation": ""
|
||||
},
|
||||
{
|
||||
"name": "Baguette de main verte",
|
||||
"description": "Il suffit ensuite de planter la baguette imbibée de sang dans le sol ou sur un végétal pour activer le Pouvoir Main verte.",
|
||||
"niveau": "3",
|
||||
"competence": "Faëomancie",
|
||||
"carac1": "precision",
|
||||
"carac2": "sang-froid",
|
||||
"duree": "1 heure",
|
||||
"portee": "",
|
||||
"concentration": "",
|
||||
"critique": "",
|
||||
"ingredients": "Doigts/racines de sylve, sève de hêtre, cendres de cocatrice, poudre d’aile de pixie et baguette d’osier creuse",
|
||||
"resistance": "",
|
||||
"coutactivation": "2 points de vie"
|
||||
},
|
||||
{
|
||||
"name": "Canne de souffle enflammÉ",
|
||||
"description": "La main du porteur doit être au contact du tissu imbibé de sang pour déclencher le jet de Souffle enflammé.",
|
||||
"niveau": "3",
|
||||
"competence": "Faëomancie",
|
||||
"carac1": "precision",
|
||||
"carac2": "sang-froid",
|
||||
"duree": "1 heure",
|
||||
"portee": "",
|
||||
"concentration": "",
|
||||
"critique": "",
|
||||
"ingredients": "Gésier de phénix, humeur de basilic, poudre de silex, poudre d’aile de pixie, canne, tissu et pommeau métallique",
|
||||
"resistance": "",
|
||||
"coutactivation": "3 points de vie"
|
||||
},
|
||||
{
|
||||
"name": "Diadème de penséces impures",
|
||||
"description": "Une fois coiffé du diadème, pressez ce dernier sur le front pour faire perler le sang. Le Pouvoir Pensées impures sera utilisable par le porteur 5 minutes plus tard.",
|
||||
"niveau": "3",
|
||||
"competence": "Faëomancie",
|
||||
"carac1": "precision",
|
||||
"carac2": "sang-froid",
|
||||
"duree": "1 heure",
|
||||
"portee": "",
|
||||
"concentration": "",
|
||||
"critique": "",
|
||||
"ingredients": "Cœur de succube, humeur de basilic, poudre d’aile de pixie, diadème et trois joyaux creux",
|
||||
"resistance": "",
|
||||
"coutactivation": "3 points de vie"
|
||||
},
|
||||
{
|
||||
"name": "Lunettes de vision nocturne",
|
||||
"description": "Une fois les lunettes prêtes, verser plusieurs gouttes de sang sur chaque verre. Leur usage sera possible 5 minutes plus tard.",
|
||||
"niveau": "3",
|
||||
"competence": "Faëomancie",
|
||||
"carac1": "precision",
|
||||
"carac2": "sang-froid",
|
||||
"duree": "1 heure",
|
||||
"portee": "",
|
||||
"concentration": "",
|
||||
"critique": "",
|
||||
"ingredients": "8 iris et cornées de Faux-Semblants ayant accès à la vision nocturne (4 par verre), salive de troll, poudre d’aile de pixie, lunettes de verre très fin (cristal)",
|
||||
"resistance": "",
|
||||
"coutactivation": "1 point de vie"
|
||||
}
|
||||
]
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user