Compare commits

..

8 Commits

Author SHA1 Message Date
da4e18dc3c Gestion de l'empoignade 2023-04-22 07:55:26 +02:00
154a9b7a37 Gestion de l'empoignade 2023-04-21 23:09:40 +02:00
fb8189606b Merge pull request 'v10: pinaillages mineurs' (#642) from VincentVk/foundryvtt-reve-de-dragon:v10 into v10
Reviewed-on: public/foundryvtt-reve-de-dragon#642
2023-04-21 23:08:10 +02:00
cfbfad27bd cleanup Empoignade 2023-04-21 22:30:21 +02:00
f541849306 Centralisation du message empoignade
Déplacement dans le module empoignade du message et de
la vérification d'empoignade en cours.

Le message est donc centralisé (possible de le modifier une fois pour
toutes les utilisations)
2023-04-21 22:30:21 +02:00
d2d1891838 cleanup itemTypes
Utilisation de itemTypes plutôt que de méthode listItems ou de
filtrer les items par type.

Potentiellement, itemTypes peut être précalculé par Foundry
C'est aussi un peu plus lisibles (conditions du filter moins longues,
et le filtrage par type est mis en avant en premier)
2023-04-21 22:30:21 +02:00
5580b6d59c Debug: à la recherche de l'Item qui ne se vend pas 2023-04-21 21:38:21 +02:00
40c45c30de Equiper des vêtements, bijoux, ...
Permettre d'équiper les objets "de base" en plus des armes et armures
2023-04-21 21:38:21 +02:00
11 changed files with 83 additions and 95 deletions

View File

@@ -84,7 +84,7 @@ export class RdDActorSheet extends RdDBaseActorSheet {
RdDItemArme.ajoutCorpsACorps(formData.combat, formData.competences, formData.system.carac);
formData.esquives = this.actor.getCompetences("Esquive");
formData.combat = RdDCombatManager.listActionsArmes(formData.combat, formData.competences, formData.system.carac);
formData.empoignades = this.actor.getEmpoignades("Esquive");
formData.empoignades = this.actor.getEmpoignades();
this.armesList = formData.combat;

View File

@@ -98,7 +98,7 @@ export class RdDActor extends RdDBaseActor {
/* -------------------------------------------- */
async cleanupConteneurs() {
let updates = this.listItems('conteneur')
let updates = this.itemTypes['conteneur']
.filter(c => c.system.contenu.filter(id => this.getItem(id) == undefined).length > 0)
.map(c => { return { _id: c._id, 'system.contenu': c.system.contenu.filter(id => this.getItem(id) != undefined) } });
if (updates.length > 0) {
@@ -333,18 +333,12 @@ export class RdDActor extends RdDBaseActor {
/* -------------------------------------------- */
hasArmeeMeleeEquipee() { // Return true si l'acteur possède au moins 1 arme de mêlée équipée
let melee = this.items.filter(it => it.type == "arme" && it.system.equipe && it.system.competence != "")
return (melee.length > 0)
}
isEmpoignadeEnCours() {
return this.items.find(it => it.type == "empoignade" && it.system.pointsemp > 0)
return this.itemTypes['arme'].find(it => it.system.equipe && it.system.competence != "")
}
/* -------------------------------------------- */
async roll() {
if (this.isEmpoignadeEnCours()) {
ui.notifications.warn("Une empoignade est en cours ! Normalement, vous ne pouvez rien faire d'autre que continuer l'empoignade ou la rompre.")
}
RdDEmpoignade.checkEmpoignadeEnCours(this)
const carac = mergeObject(duplicate(this.system.carac),
{
@@ -1101,16 +1095,12 @@ export class RdDActor extends RdDBaseActor {
/* -------------------------------------------- */
computeIsHautRevant() {
if (this.isPersonnage()) {
this.system.attributs.hautrevant.value = this.hasItemNamed('tete', 'don de haut-reve')
this.system.attributs.hautrevant.value = this.itemTypes['tete'].find(it => Grammar.equalsInsensitive(it.name, 'don de haut-reve'))
? "Haut rêvant"
: "";
}
}
hasItemNamed(type, name) {
name = Grammar.toLowerCaseNoAccent(name);
return this.listItems(type).find(it => Grammar.toLowerCaseNoAccent(it.name) == name);
}
/* -------------------------------------------- */
async computeMalusArmure() {
@@ -1672,9 +1662,9 @@ export class RdDActor extends RdDBaseActor {
await this.rollTache(tache.id);
}
}
async actionHerbe(item, onActionItem = async () => {}) {
async actionHerbe(item, onActionItem = async () => { }) {
if (item.isHerbeAPotion()) {
return DialogFabriquerPotion.create(this, item, onActionItem);
return DialogFabriquerPotion.create(this, item, onActionItem);
}
return;
}
@@ -2076,16 +2066,13 @@ export class RdDActor extends RdDBaseActor {
/* -------------------------------------------- */
async rollUnSort(coord) {
if (this.isEmpoignadeEnCours()) {
ui.notifications.warn("Une empoignade est en cours ! Normalement, vous ne pouvez rien faire d'autre que continuer l'empoignade ou la rompre.")
}
RdDEmpoignade.checkEmpoignadeEnCours(this)
if (EffetsDraconiques.isSortImpossible(this)) {
ui.notifications.error("Une queue ou un souffle vous empèche de lancer de sort!");
return;
}
// Duplication car les pts de reve sont modifiés dans le sort
let sorts = duplicate(this.$filterSortList(this.getSortList(), coord));
let sorts = duplicate(this.$filterSortList(this.itemTypes['sort'], coord));
if (sorts.length == 0) {
ui.notifications.info(`Aucun sort disponible en ${TMRUtility.getTMR(coord).label} !`);
return;
@@ -2219,10 +2206,7 @@ export class RdDActor extends RdDBaseActor {
/* -------------------------------------------- */
async rollCarac(caracName, jetResistance = undefined) {
if (this.isEmpoignadeEnCours()) {
ui.notifications.warn("Une empoignade est en cours ! Normalement, vous ne pouvez rien faire d'autre que continuer l'empoignade ou la rompre.")
}
RdDEmpoignade.checkEmpoignadeEnCours(this)
let selectedCarac = this.getCaracByName(caracName)
await this._openRollDialog({
name: 'jet-' + caracName,
@@ -2290,10 +2274,7 @@ export class RdDActor extends RdDBaseActor {
/* -------------------------------------------- */
async rollCompetence(idOrName, options = { tryTarget: true }) {
if (this.isEmpoignadeEnCours()) {
ui.notifications.warn("Une empoignade est en cours ! Normalement, vous ne pouvez rien faire d'autre que continuer l'empoignade ou la rompre.")
}
RdDEmpoignade.checkEmpoignadeEnCours(this)
let rollData = {
carac: this.system.carac,
competence: this.getCompetence(idOrName)
@@ -2365,7 +2346,7 @@ export class RdDActor extends RdDBaseActor {
async getTacheBlessure(blesse, blessure) {
const gravite = blessure?.system.gravite ?? 0;
if (gravite > 0) {
const tache = this.listItems('tache').find(it => it.system.itemId == blessure.id)
const tache = this.itemTypes['tache'].find(it => it.system.itemId == blessure.id)
?? await RdDItemBlessure.createTacheSoinBlessure(this, gravite);
await blessure?.updateTacheSoinBlessure(tache);
return tache
@@ -2374,10 +2355,7 @@ export class RdDActor extends RdDBaseActor {
}
async rollCaracCompetence(caracName, compName, diff, options = { title: "" }) {
if (this.isEmpoignadeEnCours()) {
ui.notifications.warn("Une empoignade est en cours ! Normalement, vous ne pouvez rien faire d'autre que continuer l'empoignade ou la rompre.")
}
RdDEmpoignade.checkEmpoignadeEnCours(this)
const competence = this.getCompetence(compName);
await this._openRollDialog({
name: 'jet-competence',
@@ -2398,10 +2376,7 @@ export class RdDActor extends RdDBaseActor {
/* -------------------------------------------- */
async rollTache(id, options = {}) {
if (this.isEmpoignadeEnCours()) {
ui.notifications.warn("Une empoignade est en cours ! Normalement, vous ne pouvez rien faire d'autre que continuer l'empoignade ou la rompre.")
}
RdDEmpoignade.checkEmpoignadeEnCours(this)
const tacheData = this.getTache(id)
const compData = this.getCompetence(tacheData.system.competence)
compData.system.defaut_carac = tacheData.system.carac; // Patch !
@@ -2668,7 +2643,7 @@ export class RdDActor extends RdDBaseActor {
/* -------------------------------------------- */
_getSignesDraconiques(coord) {
const type = TMRUtility.getTMRType(coord);
return this.listItems("signedraconique").filter(it => it.system.typesTMR.includes(type));
return this.itemTypes["signedraconique"].filter(it => it.system.typesTMR.includes(type));
}
/* -------------------------------------------- */
@@ -2875,8 +2850,7 @@ export class RdDActor extends RdDBaseActor {
/* -------------------------------------------- */
async resetNombresAstraux() {
let toDelete = this.listItems('nombreastral');
const deletions = toDelete.map(it => it._id);
const deletions = this.itemTypes['nombreastral'].map(it => it._id);
await this.deleteEmbeddedDocuments("Item", deletions);
}
@@ -2900,7 +2874,7 @@ export class RdDActor extends RdDBaseActor {
async supprimerAnciensNombresAstraux() {
const calendrier = game.system.rdd.calendrier;
if (calendrier) {
const toDelete = this.listItems('nombreastral')
const toDelete = this.itemTypes['nombreastral']
.filter(it => calendrier.isAfterIndexDate(it.system.jourindex))
.map(it => it._id);
await this.deleteEmbeddedDocuments("Item", toDelete);
@@ -2958,11 +2932,6 @@ export class RdDActor extends RdDBaseActor {
return entry && entry.length > 0 ? carac[entry[0]] : undefined;
}
/* -------------------------------------------- */
getSortList() {
return this.listItems("sort");
}
/* -------------------------------------------- */
countMonteeLaborieuse() { // Return +1 par queue/ombre/souffle Montée Laborieuse présente
let countMonteeLaborieuse = EffetsDraconiques.countMonteeLaborieuse(this);
@@ -3022,8 +2991,8 @@ export class RdDActor extends RdDBaseActor {
mode: mode,
fatigue: RdDUtility.calculFatigueHtml(fatigue, endurance),
draconic: this.getDraconicList(),
sort: this.getSortList(),
signes: this.listItems("signedraconique"),
sort: this.itemTypes['sort'],
signes: this.itemTypes['signedraconique'],
caracReve: this.system.carac.reve.value,
pointsReve: this.getReveActuel(),
isRapide: isRapide,
@@ -3163,7 +3132,7 @@ export class RdDActor extends RdDBaseActor {
/* -------------------------------------------- */
async equiperObjet(itemID) {
let item = this.getEmbeddedDocument('Item', itemID);
if (item && ['arme', 'armure'].includes(item.type)) {
if (item?.isEquipable()) {
const isEquipe = !item.system.equipe;
await this.updateEmbeddedDocuments('Item', [{ _id: item.id, "system.equipe": isEquipe }]);
this.computeEncTotal(); // Mise à jour encombrement

View File

@@ -32,7 +32,7 @@ export class RdDBaseActor extends Actor {
case "msg_refresh_nombre_astral":
Hooks.callAll(APP_ASTROLOGIE_REFRESH);
return;
}
}
}
static remoteActorCall(callData, userId = undefined) {
@@ -109,7 +109,6 @@ export class RdDBaseActor extends Actor {
isEntite() { return this.type == 'entite'; }
isPersonnage() { return this.type == 'personnage'; }
isVehicule() { return this.type == 'vehicule'; }
getItem(id, type = undefined) {
const item = this.items.get(id);
if (type == undefined || (item?.type == type)) {
@@ -119,7 +118,7 @@ export class RdDBaseActor extends Actor {
}
listItems(type = undefined) { return (type ? this.itemTypes[type] : this.items); }
filterItems(filter, type = undefined) { return this.listItems(type)?.filter(filter) ?? []; }
filterItems(filter, type = undefined) { return type ? this.itemTypes[type]?.filter(filter) ?? [] : []; }
findItemLike(idOrName, type) {
return this.getItem(idOrName, type)
?? Misc.findFirstLike(idOrName, this.listItems(type), { description: Misc.typeName('Item', type) });
@@ -244,12 +243,16 @@ export class RdDBaseActor extends Actor {
});
return;
}
console.log('achatVente', achat);
const cout = Number(achat.prixTotal ?? 0);
const vendeur = achat.vendeurId ? game.actors.get(achat.vendeurId) : undefined;
const acheteur = achat.acheteurId ? game.actors.get(achat.acheteurId) : undefined;
const quantite = (achat.choix.nombreLots ?? 1) * (achat.vente.tailleLot);
const itemVendu = vendeur?.getItem(achat.vente.item._id);
const itemVendu = vendeur?.getItem(achat.vente.item._id) ?? game.items.get(achat.vente.item._id) ?? achat.vente.item;
if (!itemVendu) {
ui.notifications.warn("Erreur sur achat: rien à acheter<br>Si possible, transmettez les logs de la console aux développeurs");
console.log('Erreur sur achat: rien à acheter', achat);
return;
}
if (!this.verifierQuantite(vendeur, itemVendu, quantite)) {
ChatUtility.notifyUser(achat.userId, 'warn', `Le vendeur n'a pas assez de ${itemVendu.name} !`);
return

View File

@@ -18,7 +18,7 @@ export class DialogItemAchat extends Dialog {
}
return {
item: (json ? JSON.parse(json) : undefined),
item: JSON.parse(json),
vendeur,
acheteur,
nbLots: parseInt(chatButton.attributes['data-quantiteNbLots']?.value),
@@ -34,7 +34,6 @@ export class DialogItemAchat extends Dialog {
const venteData = {
item,
actingUserId: game.user.id,
vendeurId: vendeur?.id,
vendeur,
acheteur,
tailleLot,

View File

@@ -34,6 +34,7 @@ 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 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
@@ -81,6 +82,10 @@ export const defaultItemImg = {
/* -------------------------------------------- */
export class RdDItem extends Item {
static get defaultIcon() {
return undefined;
}
static getDefaultImg(itemType) {
return game.system.rdd.itemClasses[itemType]?.defaultIcon ?? defaultItemImg[itemType];
}
@@ -139,10 +144,6 @@ export class RdDItem extends Item {
super(docData, context);
}
static get defaultIcon() {
return undefined;
}
getUniteQuantite() {
switch (this.type) {
case "monnaie": return "(Pièces)"
@@ -158,6 +159,10 @@ export class RdDItem extends Item {
return '';
}
isEquipable() {
return typesObjetsEquipable.includes(this.type)
}
isCompetencePersonnage() { return this.type == 'competence' }
isCompetenceCreature() { return this.type == 'competencecreature' }
isConteneur() { return this.type == 'conteneur'; }
@@ -367,6 +372,7 @@ export class RdDItem extends Item {
}
this.system.actionPrincipale = this.getActionPrincipale({ warnIfNot: false });
}
this.equipable = this.isEquipable();
}
prepareDataPotion() {

View File

@@ -96,15 +96,15 @@ export class RdDCombatManager extends Combat {
let compName = "Corps à corps"
if (armeCombat) {
if (armeCombat.system.competence != "") {
compName = armeCombat.system.competence
compName = armeCombat.system.competence
}
if (armeCombat.system.lancer != "") {
compName = armeCombat.system.lancer
compName = armeCombat.system.lancer
}
if (armeCombat.system.tir != "") {
compName = armeCombat.system.tir
compName = armeCombat.system.tir
}
}
}
const competence = RdDItemCompetence.findCompetence(combatant.actor.items, compName);
if (competence && competence.system.defaut_carac) {
const carac = combatant.actor.system.carac[competence.system.defaut_carac].value;
@@ -756,9 +756,7 @@ export class RdDCombat {
RdDEmpoignade.onAttaqueEmpoignade(this.attacker, this.defender)
return;
}
if ( this.attacker.isEmpoignadeEnCours() ) {
ui.notifications.warn("Une empoignade est en cours ! Normalement, vous ne pouvez rien faire d'autre que continuer l'empoignade ou la rompre.")
}
RdDEmpoignade.checkEmpoignadeEnCours(this.attacker)
let rollData = this._prepareAttaque(competence, arme);
console.log("RdDCombat.attaque >>>", rollData);

View File

@@ -1,10 +1,9 @@
/* -------------------------------------------- */
import { RdDCombat } from "./rdd-combat.js";
import { RdDResolutionTable } from "./rdd-resolution-table.js";
import { RdDRoll } from "./rdd-roll.js";
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
import { ChatUtility } from "./chat-utility.js";
import { STATUSES, StatusEffects } from "./settings/status-effects.js";
import { STATUSES } from "./settings/status-effects.js";
/* -------------------------------------------- */
@@ -15,22 +14,37 @@ export class RdDEmpoignade {
static init() {
}
/* -------------------------------------------- */
static checkEmpoignadeEnCours(actor) {
// TODO: autoriser la perception? la comédie/séduction?
if (RdDEmpoignade.isEmpoignadeEnCours(actor)) {
ui.notifications.warn("Une empoignade est en cours ! Normalement, vous ne pouvez rien faire d'autre que continuer l'empoignade ou la rompre.")
return true;
}
return false;
}
/* -------------------------------------------- */
static isEmpoignadeEnCours(actor) {
return actor.itemTypes['empoignade'].find(it => it.system.pointsemp > 0)
}
/* -------------------------------------------- */
static getEmpoignadeById(actor, id) {
let emp = actor.items.find(emp => emp.type == 'empoignade' && emp.system.empoignadeid == id)
let emp = actor.itemTypes['empoignade'].find(it => it.system.empoignadeid == id)
return emp && duplicate(emp) || undefined;
}
/* -------------------------------------------- */
static getEmpoignade(attacker, defender) {
let emp = attacker.items.find(emp => emp.type == 'empoignade' && emp.system.empoigneurid == attacker.id && emp.system.empoigneid == defender.id)
let emp = attacker.itemTypes['empoignade'].find(it => it.system.empoigneurid == attacker.id && it.system.empoigneid == defender.id)
if (!emp) {
emp = attacker.items.find(emp => emp.type == 'empoignade' && emp.system.empoigneurid == defender.id && emp.system.empoigneid == attacker.id)
emp = attacker.itemTypes['empoignade'].find(it => it.system.empoigneurid == defender.id && it.system.empoigneid == attacker.id)
}
if (emp) {
// TODO ? central storage ?
return duplicate(emp);
}
return emp && duplicate(emp) || undefined;
return undefined;
}
/* -------------------------------------------- */
static getMalusTaille(emp, attacker, defender) {
@@ -210,9 +224,9 @@ export class RdDEmpoignade {
let emp = RdDEmpoignade.getEmpoignadeById(defender, empoignade.system.empoignadeid)
await defender.deleteEmbeddedDocuments('Item', [emp._id])
let attacker = game.actors.get(empoignade.system.empoigneurid)
emp = RdDEmpoignade.getEmpoignadeById(attacker, empoignade.system.empoignadeid)
await attacker.deleteEmbeddedDocuments('Item', [emp._id])
//let attacker = game.actors.get(empoignade.system.empoigneurid)
//emp = RdDEmpoignade.getEmpoignadeById(attacker, empoignade.system.empoignadeid)
//await attacker.deleteEmbeddedDocuments('Item', [emp._id])
}
/* -------------------------------------------- */
@@ -249,19 +263,19 @@ export class RdDEmpoignade {
let defender = game.actors.get(rollData.defenderId)
let empoignade = this.getEmpoignade(attacker, defender)
console.log("Perte d'endurance :!!!", perteMode)
//console.log("Perte d'endurance :!!!", perteMode)
let endValue = defender.system.sante.endurance.value
if (perteMode == "end0") {
await defender.santeIncDec("endurance", -defender.system.sante.endurance.value);
await defender.santeIncDec("endurance", -endValue);
}
if (perteMode == "end1") {
await defender.santeIncDec("endurance", -(defender.system.sante.endurance.value - 1));
await defender.santeIncDec("endurance", -(endValue - 1));
}
if (perteMode == "endmoitie") {
await defender.santeIncDec("endurance", -Math.floor(defender.system.sante.endurance.value / 2));
await defender.santeIncDec("endurance", -Math.floor(endValue / 2));
}
if (perteMode == "endquart") {
await defender.santeIncDec("endurance", -(3 * Math.floor(defender.system.sante.endurance.value / 4)));
await defender.santeIncDec("endurance", -(3 * Math.floor(endValue / 4)));
}
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-perte-endurance.html');
ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
@@ -270,13 +284,11 @@ export class RdDEmpoignade {
/* -------------------------------------------- */
static async deleteAllEmpoignades() {
for (let actor of game.actors) {
let empList = actor.items.filter(it => it.type == "empoignade")
for (let emp of empList) {
await actor.deleteEmbeddedDocuments('Item', [emp.id])
}
let empIds = actor.itemTypes["empoignade"].map(it => it.id)
await actor.deleteEmbeddedDocuments('Item', empIds)
}
}
/* -------------------------------------------- */
static async deleteLinkedEmpoignade(actorId, empoignade) {
let actorDeleteId = (actorId == empoignade.system.empoigneurid) ? empoignade.system.empoigneid : empoignade.system.empoigneurid
@@ -290,7 +302,8 @@ export class RdDEmpoignade {
/* -------------------------------------------- */
static async createEmpoignade(attacker, defender) {
return await Item.create({
name: "Empoignade en cours de " + attacker.name + ' sur ' + defender.name, type: 'empoignade',
name: "Empoignade en cours de " + attacker.name + ' sur ' + defender.name,
type: 'empoignade',
img: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp",
system: { description: "", empoignadeid: randomID(16), compteempoigne: 0, empoigneurid: attacker.id, empoigneid: defender.id, ptsemp: 0, empoigneurname: attacker.name, empoignename: defender.name }
},

View File

@@ -57,7 +57,7 @@ export class AppAstrologie extends Application {
if (this.actor) {
return {
actor: this.actor,
nombres: this._organizeNombresAstraux(this.actor.listItems('nombreastral')),
nombres: this._organizeNombresAstraux(this.actor.itemTypes['nombreastral']),
ajustements: CONFIG.RDD.difficultesLibres,
etat: this.actor.getEtatGeneral(),
astrologie: this.actor.getCompetence('Astrologie')

View File

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

View File

@@ -692,7 +692,7 @@
"capacite": 0
},
"objet": {
"templates": ["description", "inventaire"]
"templates": ["description", "equipement", "inventaire"]
},
"monnaie": {
"templates": ["description", "inventaire"]

View File

@@ -28,7 +28,7 @@
<span class="equipement-actions item-controls">
{{#if options.isOwner}}
{{#unless item.estContenu}}
{{#if (or (eq item.type 'arme') (eq item.type 'armure') )}}
{{#if item.equipable}}
<a class="item-equip" title="Equiper">{{#if item.system.equipe}}<i class="fas fa-hand-rock"></i>{{else}}<i class="far fa-hand-paper"></i>{{/if}}</a>
{{/if}}
{{/unless}}