v11 #645

Merged
uberwald merged 3 commits from VincentVk/foundryvtt-reve-de-dragon:v11 into v11 2023-05-25 20:37:02 +02:00
8 changed files with 185 additions and 108 deletions

View File

@ -1,6 +1,9 @@
---
# v10.7 - L'os de Semolosse
## v10.7.13 - l'armure de Semolosse
- Fix: en cas d'armure variable, la détérioration diminue le dé d'armure
## v10.7.12
- Fix: si le MJ gère les changements de jours, l'option "sieste" de la fenêtre de repos est prise par défaut si chateau dormant n'est pas passé

View File

@ -3149,8 +3149,8 @@ export class RdDActor extends RdDBaseActor {
const armures = this.items.filter(it => it.type == "armure" && it.system.equipe);
for (const armure of armures) {
protection += await RdDDice.rollTotal(armure.system.protection.toString());
if (dmg > 0) {
this._deteriorerArmure(armure, dmg);
if (dmg > 0 && attackerRoll.dmg.encaisserSpecial != "noarmure") {
armure.deteriorerArmure(dmg);
dmg = 0;
}
}
@ -3168,35 +3168,6 @@ export class RdDActor extends RdDBaseActor {
return protection;
}
/* -------------------------------------------- */
_deteriorerArmure(armure, dmg) {
armure = duplicate(armure);
if (!ReglesOptionelles.isUsing('deteriorationArmure') || armure.system.protection == '0') {
return;
}
armure.system.deterioration = (armure.system.deterioration ?? 0) + dmg;
if (armure.system.deterioration >= 10) {
armure.system.deterioration -= 10;
let res = /(\d+)?d(\d+)(\-\d+)?/.exec(armure.system.protection);
if (res) {
let malus = Misc.toInt(res[3]) - 1;
let armure = Misc.toInt(res[2]);
if (armure + malus <= 0) {
armure.system.protection = 0;
} else {
armure.system.protection = '' + (res[1] ?? '1') + 'd' + armure + malus;
}
}
else if (/\d+/.exec(armure.system.protection)) {
armure.system.protection = "1d" + armure.system.protection;
}
else {
ui.notifications.warn(`La valeur d'armure de votre ${armure.name} est incorrecte`);
}
ChatMessage.create({ content: "Votre armure s'est détériorée, elle protège maintenant de " + armure.system.protection });
}
this.updateEmbeddedDocuments('Item', [armure]);
}
/* -------------------------------------------- */
async encaisser() {

View File

@ -7,34 +7,71 @@ import { RdDUtility } from "./rdd-utility.js";
import { SystemCompendiums } from "./settings/system-compendiums.js";
import { RdDRaretes } from "./item/raretes.js";
export const TYPES = {
competence: 'competence',
competencecreature: 'competencecreature',
arme: 'arme',
armure: 'armure',
conteneur: 'conteneur',
sort: 'sort',
herbe: 'herbe',
faune: 'faune',
ingredient: 'ingredient',
livre: 'livre',
potion: 'potion',
rencontre: 'rencontre',
queue: 'queue',
ombre: 'ombre',
souffle: 'souffle',
tete: 'tete',
meditation: 'meditation',
recettealchimique: 'recettealchimique',
chant: 'chant',
danse: 'danse',
jeu: 'jeu',
recettecuisine: 'recettecuisine',
musique: 'musique',
maladie: 'maladie',
poison: 'poison',
oeuvre: 'oeuvre',
nourritureboisson: 'nourritureboisson',
service: 'service',
signedraconique: 'signedraconique',
gemme: 'gemme',
possession: 'possession',
sortreserve: 'sortreserve',
extraitpoetique: 'extraitpoetique',
tarot: 'tarot',
empoignade: 'empoignade'
}
const typesInventaireMateriel = [
"arme",
"armure",
"conteneur",
"faune",
"gemme",
"herbe",
"plante",
"ingredient",
"livre",
"monnaie",
"munition",
"nourritureboisson",
"objet",
"potion",
TYPES.arme,
TYPES.armure,
TYPES.conteneur,
TYPES.faune,
TYPES.gemme,
TYPES.herbe,
TYPES.plante,
TYPES.ingredient,
TYPES.livre,
TYPES.monnaie,
TYPES.munition,
TYPES.nourritureboisson,
TYPES.objet,
TYPES.potion,
]
const typesInventaire = {
materiel: typesInventaireMateriel,
all: ['service'].concat(typesInventaireMateriel),
}
const typesObjetsOeuvres = ["oeuvre", "recettecuisine", "musique", "chant", "danse", "jeu"]
const typesObjetsDraconiques = ["queue", "ombre", "souffle", "tete", "signedraconique", "sortreserve", "rencontre"]
const typesObjetsConnaissance = ["meditation", "recettealchimique", "sort"]
const typesObjetsEffet = ["possession", "poison", "maladie", "blessure"]
const typesObjetsCompetence = ["competence", "competencecreature"]
const typesObjetsTemporels = ["blessure", "poison", "maladie", "queue", "ombre", "souffle", "signedraconique", "rencontre"]
const typesObjetsEquipable = ['arme', 'armure', 'objet'];
const typesObjetsOeuvres = [TYPES.oeuvre, TYPES.recettecuisine, TYPES.musique, TYPES.chant, TYPES.danse, TYPES.jeu]
const typesObjetsDraconiques = [TYPES.queue, TYPES.ombre, TYPES.souffle, TYPES.tete, TYPES.signedraconique, TYPES.sortreserve, TYPES.rencontre]
const typesObjetsConnaissance = [TYPES.meditation, TYPES.recettealchimique, TYPES.sort]
const typesObjetsEffet = [TYPES.possession, TYPES.poison, TYPES.maladie, TYPES.blessure]
const typesObjetsCompetence = [TYPES.competence, TYPES.competencecreature]
const typesObjetsTemporels = [TYPES.blessure, TYPES.poison, TYPES.maladie, TYPES.queue, TYPES.ombre, TYPES.souffle, TYPES.signedraconique, TYPES.rencontre]
const typesObjetsEquipable = [TYPES.arme, TYPES.armure, TYPES.objet];
const typesEnvironnement = typesInventaireMateriel;
const encBrin = 0.00005; // un brin = 1 décigramme = 1/10g = 1/10000kg = 1/20000 enc
const encPepin = 0.0007; /* un pépin de gemme = 1/10 cm3 = 1/1000 l = 3.5/1000 kg = 7/2000 kg = 7/1000 enc
@ -93,12 +130,12 @@ export class RdDItem extends Item {
static isFieldInventaireModifiable(type, field) {
switch (field) {
case 'quantite':
if (['conteneur'].includes(type)) {
if ([TYPES.conteneur].includes(type)) {
return false;
}
break;
case 'cout':
if (['monnaie'].includes(type)) {
if ([TYPES.monnaie].includes(type)) {
return game.user.isGM;
}
break;
@ -146,15 +183,15 @@ export class RdDItem extends Item {
getUniteQuantite() {
switch (this.type) {
case "monnaie": return "(Pièces)"
case "herbe":
case TYPES.monnaie: return "(Pièces)"
case TYPES.herbe:
switch (this.system.categorie) {
case 'Alchimie': case 'Repos': case 'Soin':
return "(Brins)"
case 'Cuisine': return '';
}
return '';
case "ingredient": return "(Pépins ou Brins)"
case TYPES.ingredient: return "(Pépins ou Brins)"
}
return '';
}
@ -163,26 +200,27 @@ export class RdDItem extends Item {
return typesObjetsEquipable.includes(this.type)
}
isCompetencePersonnage() { return this.type == 'competence' }
isCompetenceCreature() { return this.type == 'competencecreature' }
isConteneur() { return this.type == 'conteneur'; }
isMonnaie() { return this.type == 'monnaie'; }
isPotion() { return this.type == 'potion'; }
isNourritureBoisson() { return this.type == 'nourritureboisson'; }
isService() { return this.type == 'service'; }
isCompetencePersonnage() { return this.type == TYPES.competence }
isCompetenceCreature() { return this.type == TYPES.competencecreature }
isConteneur() { return this.type == TYPES.conteneur; }
isMonnaie() { return this.type == TYPES.monnaie; }
isPotion() { return this.type == TYPES.potion; }
isNourritureBoisson() { return this.type == TYPES.nourritureboisson; }
isService() { return this.type == TYPES.service; }
isCompetence() { return typesObjetsCompetence.includes(this.type) }
isTemporel() { return typesObjetsTemporels.includes(this.type) }
isOeuvre() { return typesObjetsOeuvres.includes(this.type) }
isDraconique() { return RdDItem.getItemTypesDraconiques().includes(this.type) }
isQueueDragon() { return [TYPES.queue, TYPES.ombre].includes(this.type) }
isEffet() { return typesObjetsEffet.includes(this.type) }
isConnaissance() { return typesObjetsConnaissance.includes(this.type) }
isInventaire(mode = 'materiel') { return RdDItem.getItemTypesInventaire(mode).includes(this.type); }
isBoisson() { return this.isNourritureBoisson() && this.system.boisson; }
isAlcool() { return this.isNourritureBoisson() && this.system.boisson && this.system.alcoolise; }
isHerbeAPotion() { return this.type == 'herbe' && (this.system.categorie == 'Soin' || this.system.categorie == 'Repos'); }
isBlessure() { return this.type == 'blessure' }
isHerbeAPotion() { return this.type == TYPES.herbe && (this.system.categorie == 'Soin' || this.system.categorie == 'Repos'); }
isBlessure() { return this.type == TYPES.blessure }
isPresentDansMilieux(milieux) {
return this.getEnvironnements(milieux).length > 0
@ -267,15 +305,15 @@ export class RdDItem extends Item {
getUtilisation() {
switch (this.type) {
case 'potion':
case TYPES.potion:
switch (this.system.categorie) {
case 'Alchimie': case 'AlchimieEnchante': case 'AlchimieAutre': return 'alchimie'
case 'Cuisine': return 'cuisine'
case 'Remede': case 'Repos': case 'ReposEnchante': case 'Soin': case 'SoinEnchante': return 'soins'
}
return '';
case 'nourritureboisson': return 'cuisine';
case 'herbe': case 'faune': case 'ingredient': case 'plante':
case TYPES.nourritureboisson: return 'cuisine';
case TYPES.herbe: case TYPES.faune: case TYPES.ingredient: case TYPES.plante:
switch (this.system.categorie) {
case 'Cuisine': return 'cuisine';
case 'Toxique': case 'Poison': return 'poison';
@ -290,9 +328,9 @@ export class RdDItem extends Item {
getUtilisationCuisine() {
if (this.getUtilisation() == 'cuisine') {
switch (this.type) {
case 'nourritureboisson':
case TYPES.nourritureboisson:
return 'pret';
case 'herbe': case 'faune': case 'ingredient': case 'plante':
case TYPES.herbe: case TYPES.faune: case TYPES.ingredient: case TYPES.plante:
return 'brut';
}
}
@ -300,7 +338,7 @@ export class RdDItem extends Item {
}
isCristalAlchimique() {
return this.type == 'objet' && Grammar.toLowerCaseNoAccent(this.name) == 'cristal alchimique' && this.system.quantite > 0;
return this.type == TYPES.objet && Grammar.includesLowerCaseNoAccent(this.name, 'cristal alchimique') && this.system.quantite > 0;
}
isMagique() {
@ -328,11 +366,11 @@ export class RdDItem extends Item {
getEnc() {
switch (this.type) {
case 'service':
case TYPES.service:
return 0;
case 'herbe':
case TYPES.herbe:
return this.getEncHerbe();
case 'gemme':
case TYPES.gemme:
return encPepin * this.system.taille;
}
return Math.max(this.system.encombrement ?? 0, 0);
@ -388,7 +426,7 @@ export class RdDItem extends Item {
getActionPrincipale(options = { warnIfNot: true }) {
switch (this.type) {
case 'conteneur': return 'Ouvrir';
case TYPES.conteneur: return 'Ouvrir';
}
if (this.actor?.isPersonnage()) {
const warn = options.warnIfNot;
@ -396,11 +434,11 @@ export class RdDItem extends Item {
return 'Utiliser';
}
switch (this.type) {
case 'nourritureboisson': return this._actionOrWarnQuantiteZero(this.system.boisson ? 'Boire' : 'Manger', warn);
case 'potion': return this._actionOrWarnQuantiteZero('Boire', warn);
case 'livre': return this._actionOrWarnQuantiteZero('Lire', warn);
case 'herbe': return this.isHerbeAPotion() ? this._actionOrWarnQuantiteZero('Décoction', warn) : undefined;
case 'queue': case 'ombre': return this.system.refoulement > 0 ? 'Refouler' : undefined;
case TYPES.nourritureboisson: return this._actionOrWarnQuantiteZero(this.system.boisson ? 'Boire' : 'Manger', warn);
case TYPES.potion: return this._actionOrWarnQuantiteZero('Boire', warn);
case TYPES.livre: return this._actionOrWarnQuantiteZero('Lire', warn);
case TYPES.herbe: return this.isHerbeAPotion() ? this._actionOrWarnQuantiteZero('Décoction', warn) : undefined;
case TYPES.queue: case TYPES.ombre: return this.system.refoulement > 0 ? 'Refouler' : undefined;
}
}
return undefined;
@ -415,11 +453,11 @@ export class RdDItem extends Item {
return;
}
switch (this.type) {
case 'potion': return await actor.consommerPotion(this, onActionItem);
case 'livre': return await actor.actionLire(this);
case 'conteneur': return await this.sheet.render(true);
case 'herbe': return await actor.actionHerbe(this, onActionItem);
case 'queue': case 'ombre': return await actor.actionRefoulement(this);
case TYPES.potion: return await actor.consommerPotion(this, onActionItem);
case TYPES.livre: return await actor.actionLire(this);
case TYPES.conteneur: return await this.sheet.render(true);
case TYPES.herbe: return await actor.actionHerbe(this, onActionItem);
case TYPES.queue: case TYPES.ombre: return await actor.actionRefoulement(this);
}
}

51
module/item/armure.js Normal file
View File

@ -0,0 +1,51 @@
import { RdDItem } from "../item.js";
import { Misc } from "../misc.js";
import { ReglesOptionelles } from "../settings/regles-optionelles.js";
export class RdDItemArmure extends RdDItem {
static get defaultIcon() {
return "systems/foundryvtt-reve-de-dragon/icons/armes_armures/armure_plaques.webp";
}
deteriorerArmure(dmg) {
if (!ReglesOptionelles.isUsing('deteriorationArmure') || this.system.protection == '0') {
return;
}
let deterioration = (this.system.deterioration ?? 0) + dmg;
let protection = this.system.protection;
if (deterioration >= 10) {
deterioration -= 10;
protection = this.calculProtectionDeterioree();
ChatMessage.create({ content: `Votre armure ${this.name} s'est détériorée, elle protège maintenant de ${protection}` });
}
this.update({
system: {
deterioration: deterioration,
protection: protection
}
});
}
calculProtectionDeterioree() {
const protectionCourante = this.system.protection;
let res = /(\d+)?d(\d+)(\-\d+)?/.exec(protectionCourante);
if (res) {
let protection = Misc.toInt(res[2]);
let malus = Misc.toInt(res[3]) - 1;
if (protection + malus <= 0) {
return 0;
} else {
return `1d${protection}${malus}`;
}
}
else if (/\d+/.exec(protectionCourante)) {
return `1d${protectionCourante}`;
}
else {
ui.notifications.warn(`La valeur d'armure de votre ${this.name} est incorrecte`);
return undefined;
}
}
}

View File

@ -58,6 +58,7 @@ import { RdDConteneurItemSheet } from "./item/sheet-conteneur.js";
import { RdDSigneDraconiqueItemSheet } from "./item/sheet-signedraconique.js";
import { RdDItemInventaireSheet } from "./item/sheet-base-inventaire.js";
import { AppAstrologie } from "./sommeil/app-astrologie.js";
import { RdDItemArmure } from "./item/armure.js";
/**
* RdD system
@ -76,6 +77,7 @@ export class SystemReveDeDragon {
this.RdDUtility = RdDUtility;
this.RdDHotbar = RdDHotbar;
this.itemClasses = {
armure: RdDItemArmure,
blessure: RdDItemBlessure,
maladie: RdDItemMaladie,
ombre: RdDItemOmbre,

View File

@ -1,4 +1,4 @@
import { Misc } from "../misc.js";
import { TYPES } from "../item.js";
import { TMRUtility } from "../tmr-utility.js";
import { PixiTMR } from "./pixi-tmr.js";
@ -9,10 +9,10 @@ const registeredEffects = [
* Définition des informations d'une "draconique" (queue, ombre, tête, souffle) qui influence les TMR
*/
export class Draconique {
static isCaseTMR(item) { return item.type == 'casetmr'; }
static isQueueDragon(item) { return item.type == 'queue' || item.type == 'ombre'; }
static isSouffleDragon(item) { return item.type == 'souffle'; }
static isTeteDragon(item) { return item.type == 'tete'; }
static isCaseTMR(item) { return item.type == TYPES.casetmr; }
static isQueueDragon(item) { return item.isQueueDragon(); }
static isSouffleDragon(item) {return item.type == TYPES.souffle; }
static isTeteDragon(item) { return item.type == TYPES.tete; }
static isQueueSouffle(item) { return Draconique.isQueueDragon(item) || Draconique.isSouffleDragon(item); }
tmrLabel(linkData) { return TMRUtility.getTMRLabel(linkData.system.coord); }

View File

@ -18,6 +18,7 @@ import { Periple } from "./periple.js";
import { UrgenceDraconique } from "./urgence-draconique.js";
import { Grammar } from "../grammar.js";
import { AugmentationSeuil } from "./augmentation-seuil.js";
import { TYPES } from "../item.js";
export class EffetsDraconiques {
@ -114,46 +115,57 @@ export class EffetsDraconiques {
);
}
static filterItems(actor, filter, name) {
return actor.filterItems(filter)
.filter(it => Grammar.includesLowerCaseNoAccent(it.name, name));
static tetesDragon(actor, name) {
return actor.itemTypes[TYPES.tete].filter(it => Grammar.includesLowerCaseNoAccent(it.name, name));
}
static soufflesDragon(actor, name) {
return actor.itemTypes[TYPES.souffle].filter(it => Grammar.includesLowerCaseNoAccent(it.name, name));
}
static queuesDragon(actor, name) {
return actor.filterItems(it => it.isQueueDragon() && Grammar.includesLowerCaseNoAccent(it.name, name));
}
static queuesSoufflesDragon(actor, name) {
return actor.filterItems(it => [TYPES.queue, TYPES.ombre, TYPES.souffle].includes(it.type) && Grammar.includesLowerCaseNoAccent(it.name, name));
}
static countAugmentationSeuil(actor) {
return EffetsDraconiques.filterItems(actor, Draconique.isTeteDragon, 'Augmentation du seuil de rêve').length;
return EffetsDraconiques.tetesDragon(actor, 'Augmentation du seuil de rêve').length;
}
static isDonDoubleReve(actor) {
return EffetsDraconiques.filterItems(actor, Draconique.isTeteDragon, 'Don de double-rêve').length>0;
return EffetsDraconiques.tetesDragon(actor, 'Don de double-rêve').length > 0;
}
static isConnaissanceFleuve(actor) {
return EffetsDraconiques.filterItems(actor, Draconique.isTeteDragon, 'connaissance du fleuve').length>0;
return EffetsDraconiques.tetesDragon(actor, 'connaissance du fleuve').length > 0;
}
static isReserveEnSecurite(actor) {
return EffetsDraconiques.filterItems(actor, Draconique.isTeteDragon, 'réserve en sécurité').length>0;
return EffetsDraconiques.tetesDragon(actor, 'réserve en sécurité').length > 0;
}
static isDeplacementAccelere(actor) {
return EffetsDraconiques.filterItems(actor, Draconique.isTeteDragon, ' déplacement accéléré').length>0;
return EffetsDraconiques.tetesDragon(actor, 'déplacement accéléré').length > 0;
}
static isDoubleResistanceFleuve(actor) {
return EffetsDraconiques.filterItems(actor, Draconique.isSouffleDragon, 'résistance du fleuve').length>0;
return EffetsDraconiques.soufflesDragon(actor, 'résistance du fleuve').length > 0;
}
static countInertieDraconique(actor) {
return EffetsDraconiques.filterItems(actor, Draconique.isQueueDragon, 'inertie draconique').length;
return EffetsDraconiques.queuesDragon(actor, 'inertie draconique').length;
}
static countMonteeLaborieuse(actor) {
return EffetsDraconiques.filterItems(actor, Draconique.isQueueSouffle, 'montée laborieuse').length;
return EffetsDraconiques.queuesSoufflesDragon(actor, 'montée laborieuse').length;
}
static mauvaiseRencontre(actor) {
const mauvaisesRencontres = EffetsDraconiques.filterItems(actor, Draconique.isQueueSouffle, 'mauvaise rencontre');
return mauvaisesRencontres.length>0 ? mauvaisesRencontres[0] : undefined;
const mauvaisesRencontres = EffetsDraconiques.queuesSoufflesDragon(actor, 'mauvaise rencontre');
return mauvaisesRencontres.length > 0 ? mauvaisesRencontres[0] : undefined;
}
static isPontImpraticable(actor) {
@ -165,11 +177,11 @@ export class EffetsDraconiques {
}
static isSujetInsomnie(actor) {
return actor.items.find(it => ['queue', 'ombre'].includes(it.type) && Grammar.includesLowerCaseNoAccent(it.name, 'Insomnie')) ? true : false;
return EffetsDraconiques.queuesDragon(actor, 'Insomnie').length > 0 ? true : false;
}
static isPeage(actor) {
return EffetsDraconiques.filterItems(actor, Draconique.isSouffleDragon, 'péage').length > 0;
return EffetsDraconiques.soufflesDragon(actor, 'péage').length > 0;
}

View File

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