Gestion des signes draconiques #455

Closed
vincent.vandeme wants to merge 233 commits from v1.4-signes-draconiques into master
13 changed files with 110 additions and 89 deletions
Showing only changes of commit e1f0d199c1 - Show all commits

View File

@ -71,7 +71,7 @@ export class RdDActorEntiteSheet extends ActorSheet {
// Update Inventory Item
html.find('.item-edit').click(ev => {
const li = $(ev.currentTarget).parents(".item");
const item = this.actor.getEmbeddedDocuments('Item', li.data("itemId"));
const item = this.actor.getEmbeddedDocument('Item', li.data("itemId"));
item.sheet.render(true);
});

View File

@ -173,16 +173,16 @@ export class RdDActorSheet extends ActorSheet {
/* -------------------------------------------- */
async creerObjet() {
let itemType = $("#creer-equipement").val();
let itemType = $(".item-type").val();
await this.createItem('Nouveau ' + itemType, itemType);
}
/* -------------------------------------------- */
async selectObjetType() {
let itemType = ["objet", "arme", "armure", "conteneur", "herbe", "ingredient", "livre", "potion", "munition", "monnaie"];
let options = '<span class="competence-label">Selectionnez le type d\'équipement</span><select id="creer-equipement">';
for (let typeName of itemType) {
options += '<option value="' + typeName + '">' + typeName + '</option>'
let typeObjets = ["objet", "arme", "armure", "conteneur", "herbe", "ingredient", "livre", "potion", "munition", "monnaie"];
let options = `<span class="competence-label">Selectionnez le type d'équipement</span><select class="item-type">`;
for (let typeName of typeObjets) {
options += `<option value="${typeName}">${typeName}</option>`
}
options += '</select>';
let d = new Dialog({
@ -198,7 +198,28 @@ export class RdDActorSheet extends ActorSheet {
});
d.render(true);
}
/* -------------------------------------------- */
async selectTypeOeuvre() {
let typeOeuvres = ["oeuvre", "recettecuisine", "musique", "chant", "danse", "jeu" ];
let options = `<span class="competence-label">Selectionnez le type d'oeuvre</span><select class="item-type">`;
for (let typeName of typeOeuvres) {
options += `<option value="${typeName}">${typeName}</option>`
}
options += '</select>';
let d = new Dialog({
title: "Créer une oeuvre",
content: options,
buttons: {
one: {
icon: '<i class="fas fa-check"></i>',
label: "Créer l'oeuvre",
callback: () => this.creerObjet()
}
}
});
d.render(true);
}
/* -------------------------------------------- */
/** @override */
activateListeners(html) {
@ -246,12 +267,15 @@ export class RdDActorSheet extends ActorSheet {
ev.preventDefault();
}
});
html.find('#creer-tache').click(ev => {
html.find('.creer-tache').click(ev => {
this.createEmptyTache();
});
html.find('#creer-un-objet').click(ev => {
html.find('.creer-un-objet').click(ev => {
this.selectObjetType();
});
html.find('.creer-une-oeuvre').click(ev => {
this.selectTypeOeuvre();
});
html.find('#nettoyer-conteneurs').click(ev => {
this.actor.nettoyerConteneurs();
});
@ -407,19 +431,19 @@ export class RdDActorSheet extends ActorSheet {
// Display info about queue
html.find('.queuesouffle-label a').click((event) => {
let myID = event.currentTarget.attributes['data-item-id'].value;
const item = this.actor.getEmbeddedDocuments('Item', myID);
const item = this.actor.getEmbeddedDocument('Item', myID);
item.sheet.render(true);
});
// Info sort
html.find('.sort-label a').click((event) => {
let myID = event.currentTarget.attributes['data-id'].value;
const item = this.actor.getEmbeddedDocuments('Item', myID);
const item = this.actor.getEmbeddedDocument('Item', myID);
item.sheet.render(true);
});
// Info sort
html.find('.case-label a').click((event) => {
let myID = event.currentTarget.attributes['data-id'].value;
const item = this.actor.getEmbeddedDocuments('Item', myID);
const item = this.actor.getEmbeddedDocument('Item', myID);
item.sheet.render(true);
});

View File

@ -87,7 +87,7 @@ export class RdDActorVehiculeSheet extends ActorSheet {
// Update Inventory Item
html.find('.item-edit').click(ev => {
const li = $(ev.currentTarget).parents(".item");
const item = this.actor.getEmbeddedDocuments('Item', li.data("itemId"));
const item = this.actor.getEmbeddedDocument('Item', li.data("itemId"));
item.sheet.render(true);
});
// Delete Inventory Item

View File

@ -343,13 +343,11 @@ export class RdDActor extends Actor {
async _recupereChance() {
// On ne récupère un point de chance que si aucun appel à la chance dans la journée
if (this.getFlag('foundryvtt-reve-de-dragon', 'utilisationChance')) {
// Nouveau jour, suppression du flag
await this.unsetFlag('foundryvtt-reve-de-dragon', 'utilisationChance');
}
else {
await this.chanceActuelleIncDec(1);
if (this.getChanceActuel() < this.getChance() && !this.getFlag('foundryvtt-reve-de-dragon', 'utilisationChance')) {
await this.chanceActuelleIncDec(1);
}
// Nouveau jour, suppression du flag
await this.unsetFlag('foundryvtt-reve-de-dragon', 'utilisationChance');
}
/* -------------------------------------------- */
@ -651,14 +649,14 @@ export class RdDActor extends Actor {
return;
}
}
const actorData = Misc.data(this);
const tplData = Misc.templateData(this);
if (caracName == "reve") {
if (caracValue > Misc.toInt(actorData.data.reve.seuil.value)) {
if (caracValue > Misc.toInt(tplData.reve.seuil.value)) {
this.setPointsDeSeuil(caracValue);
}
}
if (caracName == "chance") {
if (caracValue > Misc.toInt(actorData.data.compteurs.chance.value)) {
if (caracValue > Misc.toInt(tplData.compteurs.chance.value)) {
this.setPointsDeChance(caracValue);
}
}
@ -1435,22 +1433,21 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
async moralIncDec(ajustementMoral) {
let actorData
let tplData = Misc.templateData(this);
if (ajustementMoral != 0) {
actorData = Misc.data(this);
let moral = Misc.toInt(actorData.data.compteurs.moral.value) + ajustementMoral
let moral = Misc.toInt(tplData.compteurs.moral.value) + ajustementMoral
if (moral > 3) { // exaltation
const exaltation = Misc.toInt(actorData.data.compteurs.exaltation.value) + moral - 3;
const exaltation = Misc.toInt(tplData.compteurs.exaltation.value) + moral - 3;
await this.updateCompteurValue('exaltation', exaltation);
}
if (moral < -3) { // dissolution
const dissolution = Misc.toInt(actorData.data.compteurs.dissolution.value) + 3 - moral;
const dissolution = Misc.toInt(tplData.compteurs.dissolution.value) + 3 - moral;
await this.updateCompteurValue('dissolution', dissolution);
}
moral = Math.max(-3, Math.min(moral, 3));
await this.updateCompteurValue('moral', moral);
}
return actorData.data.compteurs.moral.value;
return tplData.compteurs.moral.value;
}
/* -------------------------------------------- */
@ -2261,9 +2258,6 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
async rollAppelChance(onSuccess = () => { }, onEchec = () => { }) {
// Stocke si utilisation de la chance
await this.unsetFlag('foundryvtt-reve-de-dragon', 'utilisationChance');
await this.setFlag('foundryvtt-reve-de-dragon', 'utilisationChance', true);
let rollData = { selectedCarac: this.getCaracByName('chance-actuelle'), surprise: '' };
const dialog = await RdDRoll.create(this, rollData,
{ html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html' },
@ -2283,6 +2277,7 @@ export class RdDActor extends Actor {
async _appelChanceResult(rollData, onSuccess = () => { }, onEchec = () => { }) {
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-appelchance.html')
if (rollData.rolled.isSuccess) {
await this.setFlag('foundryvtt-reve-de-dragon', 'utilisationChance', true);
await this.chanceActuelleIncDec(-1);
onSuccess();
}
@ -2292,11 +2287,8 @@ export class RdDActor extends Actor {
}
/* -------------------------------------------- */
async chanceActuelleIncDec(value, limit = true) {
chance = Math.max(Misc.templateData(this).compteurs.chance.value + value, 0);
if (limit) {
chance = Math.min(chance.value, this.getChance())
}
async chanceActuelleIncDec(value) {
const chance = Math.min(this.getChance(), Math.max(this.getChanceActuel() + value, 0));
await this.updateCompteurValue("chance", chance);
}
@ -2532,7 +2524,7 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
getArmeParade(armeParadeId) {
const item = armeParadeId ? this.getEmbeddedDocuments('Item', armeParadeId) : undefined;
const item = armeParadeId ? this.getEmbeddedDocument('Item', armeParadeId) : undefined;
return RdDItemArme.getArmeData(item);
}
@ -2549,9 +2541,9 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
async equiperObjet(itemID) {
let item = this.getEmbeddedDocuments('Item', itemID);
if (item?.data?.data) {
let itemData = Misc.itemData(item);
let item = this.getEmbeddedDocument('Item', itemID);
let itemData = Misc.data(item);
if (itemData?.data) {
const isEquipe = !itemData.data.equipe;
let update = { _id: item._id, "data.equipe": isEquipe };
await this.updateEmbeddedDocuments('Item', [update]);
@ -2567,7 +2559,8 @@ export class RdDActor extends Actor {
let dmg = (attackerRoll.dmg.dmgArme ?? 0) + (attackerRoll.dmg.dmgActor ?? 0);
let armeData = attackerRoll.arme;
let protection = 0;
const armures = this.data.items.filter(it => it.type == "armure" && it.data.equipe);
const armures = this.items.map(it => Misc.data(it))
.filter(it => it.type == "armure" && it.data.equipe);
for (const itemData of armures) {
protection += new Roll(itemData.data.protection.toString()).roll().total;
if (dmg > 0) {
@ -2575,7 +2568,7 @@ export class RdDActor extends Actor {
dmg = 0;
}
}
const penetration = armeData ? Misc.toInt(armeData.data.penetration) : 0;
const penetration = Misc.toInt(armeData?.data.penetration ?? 0);
protection = Math.max(protection - penetration, 0);
protection += this.getProtectionNaturelle();
// Gestion des cas particuliers sur la fenêtre d'encaissement
@ -2865,7 +2858,7 @@ export class RdDActor extends Actor {
}
let updates = []
for (const [valeur, nombre] of Object.entries(fortune)) {
updates.push( { _id: parValeur[valeur]._id, 'data.quantite': nombre });
updates.push({ _id: parValeur[valeur]._id, 'data.quantite': nombre });
}
await this.updateEmbeddedDocuments('Item', updates);
}
@ -3149,7 +3142,7 @@ export class RdDActor extends Actor {
}
}
async onPreUpdateItem(item, change, options, id) {
async onPreUpdateItem(item, change, options, id) {
const itemData = Misc.data(item);
if (itemData.type == 'competence' && itemData.data.defaut_carac && itemData.data.xp) {
await this.checkCompetenceXP(itemData.name, itemData.data.xp);

View File

@ -5,8 +5,8 @@ export class RdDItemCompetenceCreature extends Item {
/* -------------------------------------------- */
static setRollDataCreature(rollData) {
rollData.competence = Misc.data(rollData.competence);
rollData.carac = { "carac_creature": { label: rollData.competence.name, value: rollData.competence.data.carac_value } };
rollData.competence = duplicate(rollData.competence);
rollData.competence.data.defaut_carac = "carac_creature";
rollData.competence.data.categorie = "creature";
rollData.selectedCarac = rollData.carac.carac_creature;

View File

@ -97,19 +97,8 @@ export class Misc {
return [...new Set(array)];
}
static actorData(actor) {
return Misc.data(actor);
}
static itemData(item) {
return Misc.data(item);
}
static data(it) {
if (it instanceof Item) {
return it.data;
}
if (it instanceof Actor) {
if (it instanceof Actor || it instanceof Item || it instanceof Combatant) {
return it.data;
}
return it;

View File

@ -143,18 +143,20 @@ export class RdDCombatManager extends Combat {
// Gestion des armes 1/2 mains
let armesEquipe = [];
for (const arme of armes) {
if (arme.data.equipe) {
armesEquipe.push(arme);
let comp = competences.find(c => c.name == arme.data.competence);
arme.data.initiative = RdDCombatManager.calculInitiative(arme.data.niveau, carac[comp.data.defaut_carac].value);
let armeData = Misc.data(arme);
if (armeData.data.equipe) {
let compData = competences.map(c => Misc.data(c)).find(c => c.name == armeData.data.competence);
armesEquipe.push(armeData);
armeData.data.initiative = RdDCombatManager.calculInitiative(armeData.data.niveau, carac[compData.data.defaut_carac].value);
// Dupliquer les armes pouvant être à 1 main et 2 mains en patchant la compétence
if (arme.data.unemain && !arme.data.deuxmains) {
arme.data.mainInfo = "(1m)";
} else if (!arme.data.unemain && arme.data.deuxmains) {
arme.data.mainInfo = "(2m)";
} else if (arme.data.unemain && arme.data.deuxmains) {
arme.data.mainInfo = "(1m)";
let arme2main = duplicate(arme);
if (armeData.data.unemain && !armeData.data.deuxmains) {
armeData.data.mainInfo = "(1m)";
} else if (!armeData.data.unemain && armeData.data.deuxmains) {
armeData.data.mainInfo = "(2m)";
} else if (armeData.data.unemain && armeData.data.deuxmains) {
armeData.data.mainInfo = "(1m)";
let arme2main = duplicate(armeData);
arme2main.data.mainInfo = "(2m)";
arme2main.data.dommages = arme2main.data.dommages.split("/")[1]; // Existence temporaire uniquement dans la liste des armes, donc OK
arme2main.data.competence = arme2main.data.competence.replace(" 1 main", " 2 mains"); // Replace !
@ -182,7 +184,6 @@ export class RdDCombatManager extends Combat {
} else {
// Recupération des items 'arme'
let armes = items.filter(it => RdDItemArme.isArmeUtilisable(it))
.map(arme => duplicate(arme)) /* pas de changements aux armes d'origine */
.concat(RdDItemArme.mainsNues());
let competences = items.filter(it => it.type == 'competence');

View File

@ -7,17 +7,23 @@ export class RdDEncaisser extends Dialog {
/* -------------------------------------------- */
constructor(html, actor) {
// Common conf
const buttonsCreatures = {
"mortel": { label: "mortel", callback: html => this.performEncaisser("mortel") },
"non-mortel": { label: "non-mortel", callback: html => this.performEncaisser("non-mortel") },
};
const buttonsEntitesCauchemar = {
"cauchemar": { label: "cauchemar", callback: html => this.performEncaisser("cauchemar") }
};
const buttons = actor.isEntiteCauchemar() ? buttonsEntitesCauchemar : buttonsCreatures;
let dialogConf = {
title: "Jet d'Encaissement",
content: html,
buttons: {
"mortel": { label: "mortel", callback: html => this.performEncaisser(html, "mortel") },
"non-mortel": { label: "non-mortel", callback: html => this.performEncaisser(html, "non-mortel") },
"cauchemar": { label: "cauchemar", callback: html => this.performEncaisser(html, "cauchemar") }
},
buttons: buttons,
default: "coupMortel"
}
let dialogOptions = {
classes: ["rdddialog"],
width: 320,
@ -32,13 +38,15 @@ export class RdDEncaisser extends Dialog {
this.encaisserSpecial = "aucun";
}
/* -------------------------------------------- */
performEncaisser(html, mortalite = "mortel") {
performEncaisser(mortalite) {
this.actor.encaisserDommages({
dmg:{
dmg: {
total: Number(this.modifier),
encaisserSpecial: this.encaisserSpecial,
loc: { result: 0, label: "Corps" },
loc: { result: 0, label: "" },
mortalite: mortalite
}
});

View File

@ -1,5 +1,6 @@
/* -------------------------------------------- */
import { HtmlUtility } from "./html-utility.js";
import { Misc } from "./misc.js";
import { RdDCombatManager } from "./rdd-combat.js";
import { RdDUtility } from "./rdd-utility.js";
@ -24,7 +25,7 @@ export class RdDTokenHud {
let token = canvas.tokens.get(tokenId);
let actor = token.actor;
let combatant = game.combat.data.combatants.find(c => c.tokenId == token.data._id);
let combatant = game.combat.combatants.find(c => Misc.data(c).tokenId == tokenId);
app.hasExtension = true;
let armesList = RdDCombatManager.buildListeActionsCombat(combatant) ;

View File

@ -197,7 +197,7 @@
{{!-- Equipment Tab --}}
<div class="tab items" data-group="primary" data-tab="items">
<span class="item-name">Encombrement total/max : {{numberFormat calc.encTotal decimals=2}} / {{data.attributs.encombrement.value}} <b>{{calc.surEncombrementMessage}}</b></span> -
<span class="item-name"><a id="creer-un-objet">Créer un objet</a></span>
<span class="item-name"><a class="creer-un-objet">Créer un objet</a></span>
{{#if options.isGM}}
<span class="item-name"> - <a id="nettoyer-conteneurs">Vider tout les conteneurs</a></span>
{{/if}}

View File

@ -461,6 +461,7 @@
{{!-- Connaissances Tab --}}
<div class="tab connaissances" data-group="primary" data-tab="connaissances">
<span class="item-name"><a class="creer-une-oeuvre">Créer une oeuvre</a></span>
<h3>Oeuvres diverses :</h3>
<ul class="item-list alterne-list">
{{#each chants as |chant id|}}
@ -526,7 +527,7 @@
</li>
{{/each}}
</ul>
<h3>Tâches</h3><a id='creer-tache'>Créer une nouvelle Tâche</a>
<h3>Tâches</h3><a class='creer-tache'>Créer une nouvelle Tâche</a>
<ul class="item-list alterne-list">
{{#each taches as |tache id|}}
<li class="item flexrow list-item" data-item-id="{{tache._id}}"><span class="competence-title tache-label"><a>{{tache.name}} ({{tache.data.points_de_tache_courant}}/{{tache.data.points_de_tache}})</a></span>
@ -723,7 +724,7 @@
<span class="item-name">Estimation de l'équipement : {{numberFormat calc.prixTotalEquipement decimals=2}} Sols</span>
</div>
<div>
<span class="item-name"><a id="creer-un-objet">Créer un objet</a></span>
<span class="item-name"><a class="creer-un-objet">Créer un objet</a></span>
{{#if options.isGM}}
<span class="item-name"> - <a id="nettoyer-conteneurs">Vider tout les conteneurs</a></span>
{{/if}}

View File

@ -69,7 +69,7 @@
{{!-- Equipment Tab --}}
<div class="tab items" data-group="primary" data-tab="items">
<span class="item-name">Encombrement total/max : {{numberFormat calc.encTotal decimals=2}} / {{data.capacite_encombrement}} <b>{{calc.surEncombrementMessage}}</b></span> -
<span class="item-name"><a id="creer-un-objet">Créer un objet</a></span>
<span class="item-name"><a class="creer-un-objet">Créer un objet</a></span>
{{#if options.isGM}}
<span class="item-name"> - <a id="nettoyer-conteneurs">Vider tout les conteneurs</a></span>
{{/if}}

View File

@ -17,9 +17,9 @@
</h4>
<div>
Je d'encaissement de {{roll.total}}
{{#unless (eq armure 0)}}, l'armure a protègé de {{armure}} {{#unless (eq penetration 0)}}(pénétration de {{penetration}})
{{/unless}}
{{/unless}}, total: <span class="rdd-roll-echec">{{total}}</span>
{{#unless (eq armure 0)}}, l'armure a protègé de {{armure}}
{{~#unless (eq penetration 0)}} (pénétration de {{penetration}}){{/unless}}
{{~/unless}}, total: <span class="rdd-roll-echec">{{total}}</span>
<br>
{{alias}}
{{#if (eq dmg.mortalite 'cauchemar')}}subit le coup
@ -29,10 +29,14 @@
{{else if critiques}}subit une blessure critique
{{else if mort}}vient de mourir
{{else}}s'en sort sans une égratignure
{{/if}}
({{dmg.loc.label}})
{{#if (gt endurance 0)}}
{{#if hasPlayerOwner}}, a perdu {{endurance}} points d'endurance
{{~/if~}}
{{~#unless (eq dmg.mortalite 'cauchemar')}}
{{#if dmg.loc.label}}
{{#if (gt roll.total 0)}}({{dmg.loc.label}}){{/if}}
{{/if}}
{{/unless~}}
{{~#if (gt endurance 0)}}
{{~#if hasPlayerOwner}}, a perdu {{endurance}} points d'endurance
{{#if (ne vie 0)}}, <span class="rdd-roll-echec">{{vie}} points de vie</span>{{/if}}
{{/if}}
{{#if (ne dmg.mortalite 'cauchemar')}}