Compare commits

...

8 Commits

13 changed files with 120 additions and 74 deletions

View File

@ -1,9 +1,13 @@
# v11.2
## v11.2.2 - Les tendres moments d'Akarlikarlikar
- On peut maintenant avoir des points de cœur pour des suivants/compagnons
# 11.2
## 11.2.6 - Les réveils difficiles d'Akarlikarlikar
- Les changements de points de Cœur sont temporaires jusqu'à fin Château Dormant
- Fix: tous les petits fixes (feuille qui s'ouvre plus, compagnons animaux, potions qui bloquent Château Dormant, ...)
## 11.2.2 - Les tendres moments d'Akarlikarlikar
- On peut maintenant avoir des points de Cœur pour des suivants/compagnons
- diminuer les points de coeurs fait perdre du moral
- on peut proposer un tendre moment
- les jets de volonté peuvent être ajustés selon les points de cœur
- les jets de volonté peuvent être ajustés selon les points de Cœur
- Fixes
- La résistance est de 1 par défaut pour les équipements
- Les armes de créatures sont de nouveau utilisables depuis les tokens

View File

@ -120,6 +120,18 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
HtmlUtility.showControlWhen(this.html.find(".appliquerFatigue"), ReglesOptionnelles.isUsing("appliquer-fatigue"));
this.html.find('.subacteur-open').click(async event => {
const subActorId = RdDSheetUtility.getEventItemData(event, 'subactor-id');
this.openSubActeur(subActorId);
})
this.html.find('.show-hide-competences').click(async event => {
this.options.showCompNiveauBase = !this.options.showCompNiveauBase;
this.render(true);
});
this.html.find('.visu-tmr').click(async event => this.actor.displayTMR("visu"))
// Everything below here is only needed if the sheet is editable
if (!this.options.editable) return;
@ -130,32 +142,18 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
this.html.find('.subacteur-coeur-toggle a').click(async event => {
const subActorIdactorId = RdDSheetUtility.getEventItemData(event, 'subactor-id')
const coeurNombre = $(event.currentTarget).data('coeur-nombre')
const coeurNombre = $(event.currentTarget).data('numero-coeur')
RdDCoeur.toggleSubActeurCoeur(this.actor.id, subActorIdactorId, coeurNombre)
})
this.html.find('.subacteur-tendre-moment').click(async event => {
const subActorId = RdDSheetUtility.getEventItemData(event, 'subactor-id')
RdDCoeur.startSubActeurTendreMoment(this.actor.id, subActorId)
})
this.html.find('.subacteur-open').click(async event => {
const subActorId = RdDSheetUtility.getEventItemData(event, 'subactor-id');
this.openSubActeur(subActorId);
})
this.html.find('.subacteur-delete').click(async event => {
const li = RdDSheetUtility.getEventElement(event);
const subActorId = li.data("subactor-id");
this.deleteSubActeur(subActorId, li);
})
this.html.find('.experiencelog-delete').click(async event => {
const li = this.html.find(event.currentTarget)?.parents(".experiencelog");
const key = Number(li.data("key") ?? -1);
await this.actor.deleteExperienceLog(key, 1);
});
this.html.find('.experiencelog-delete-previous').click(async event => {
const li = this.html.find(event.currentTarget)?.parents(".experiencelog");
const key = Number(li.data("key") ?? -1);
await this.actor.deleteExperienceLog(0, key + 1);
});
this.html.find("input.derivee-value[name='system.compteurs.stress.value']").change(async event => {
this.actor.updateCompteurValue("stress", parseInt(event.target.value));
});
@ -204,7 +202,18 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
this.html.find('.recettecuisine-label a').click(async event => this.actor.rollRecetteCuisine(RdDSheetUtility.getItemId(event)))
if (game.user.isGM) {
// Boutons spéciaux MJs
// experience log
this.html.find('.experiencelog-delete').click(async event => {
const li = this.html.find(event.currentTarget)?.parents(".experiencelog");
const key = Number(li.data("key") ?? -1);
await this.actor.deleteExperienceLog(key, 1);
});
this.html.find('.experiencelog-delete-previous').click(async event => {
const li = this.html.find(event.currentTarget)?.parents(".experiencelog");
const key = Number(li.data("key") ?? -1);
await this.actor.deleteExperienceLog(0, key + 1);
});
// Boutons spéciaux MJs
this.html.find('.forcer-tmr-aleatoire').click(async event => this.actor.reinsertionAleatoire("Action MJ"))
this.html.find('.afficher-tmr').click(async event => this.actor.changeTMRVisible())
}
@ -226,7 +235,6 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
});
// Display TMR
this.html.find('.visu-tmr').click(async event => this.actor.displayTMR("visu"))
this.html.find('.monte-tmr').click(async event => this.actor.displayTMR("normal"))
this.html.find('.monte-tmr-rapide').click(async event => this.actor.displayTMR("rapide"))
@ -264,12 +272,6 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
this.html.find('.nouvelle-incarnation').click(async event => this.actor.nouvelleIncarnation())
}
this.html.find('.show-hide-competences').click(async event => {
this.options.showCompNiveauBase = !this.options.showCompNiveauBase;
this.render(true);
});
// On pts de reve change
this.html.find('.pointsreve-value').change(async event => this.actor.update({ "system.reve.reve.value": event.currentTarget.value }))
this.html.find('.seuil-reve-value').change(async event => this.actor.setPointsDeSeuil(event.currentTarget.value))

View File

@ -34,6 +34,7 @@ import { RdDEmpoignade } from "./rdd-empoignade.js";
import { ExperienceLog, XP_TOPIC } from "./actor/experience-log.js";
import { TYPES } from "./item.js";
import { RdDBaseActorSang } from "./actor/base-actor-sang.js";
import { RdDCoeur } from "./coeur/rdd-coeur.js";
export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre']
@ -153,7 +154,7 @@ export class RdDActor extends RdDBaseActorSang {
let potions = this.itemTypes[TYPES.potion]
.filter(it => it.system.categorie.toLowerCase().includes('enchant') && !potion.system.prpermanent)
const potionUpdates = Promise.all(potions.map(async potion => {
const potionUpdates = await Promise.all(potions.map(async potion => {
console.log(potion)
let nouveauReve = (potion.system.pr > 0) ? potion.system.pr - 1 : 0;
const message = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-potionenchantee-chateaudormant.html`, {
@ -270,6 +271,7 @@ export class RdDActor extends RdDBaseActorSang {
await this.setBonusPotionSoin(0);
await this.retourSust(message);
await this.$perteRevePotionsEnchantees();
await RdDCoeur.applyCoeurChateauDormant(this, message)
if (message.content != "") {
message.content = `A la fin Chateau Dormant, ${message.content}<br>Un nouveau jour se lève`;
ChatMessage.create(message);
@ -2636,7 +2638,8 @@ export class RdDActor extends RdDBaseActorSang {
static $transformSubActeurSuivant = (suivant, link) => {
return mergeObject(RdDBaseActor.extractActorMin(suivant), {
ephemere: !suivant.prototypeToken.actorLink,
coeur: link.coeur ?? 0
coeur: link.coeur ?? 0,
prochainCoeur: link.prochainCoeur ?? link.coeur ?? 0
})
};
@ -2646,23 +2649,23 @@ export class RdDActor extends RdDBaseActorSang {
)
}
getSuivant(actorId) {
const suivant = this.system.subacteurs.suivants.find(it => it.id == actorId);
getSuivant(subActorId) {
const suivant = this.system.subacteurs.suivants.find(it => it.id == subActorId);
if (suivant) {
return RdDActor.$transformSubActeurSuivant(game.actors.get(actorId), suivant);
return RdDActor.$transformSubActeurSuivant(game.actors.get(suivant.id), suivant);
}
return undefined
}
getPointsCoeur(actorId) {
return this.getSuivant(actorId)?.coeur ?? 0;
getPointsCoeur(subActorId) {
return this.getSuivant(subActorId)?.coeur ?? 0;
}
async setPointsCoeur(actorId, coeur) {
const amoureux = this.getSuivant(actorId);
async setPointsCoeur(subActorId, coeurs, options = { immediat: false }) {
const newSuivants = duplicate(this.system.subacteurs.suivants)
const amoureux = newSuivants.find(it => it.id == subActorId);
if (amoureux) {
const suivants = this.system.subacteurs.suivants;
let newSuivants = [...suivants.filter(it => it.id != actorId), { id: actorId, coeur: coeur }]
amoureux[options.immediat ? 'coeur' : 'prochainCoeur'] = coeurs
await this.update({ 'system.subacteurs.suivants': newSuivants });
}
}
@ -2679,7 +2682,7 @@ export class RdDActor extends RdDBaseActorSang {
}
/* -------------------------------------------- */
static $transformSubActeurCreature = (actor, link) => RdDBaseActor.extractActorMin(actor.id)
static $transformSubActeurCreature = (actor, link) => RdDBaseActor.extractActorMin(actor)
listeMontures() {
return RdDActor.$buildSubActorLinks(this.system.subacteurs.montures, RdDActor.$transformSubActeurCreature);

View File

@ -131,20 +131,14 @@ export class RdDBaseActorSheet extends ActorSheet {
super.activateListeners(html);
this.html = html;
if (!this.options.editable) return;
this.html.find('.item-action').click(async event => {
const item = RdDSheetUtility.getItem(event, this.actor);
item?.actionPrincipale(this.actor, async () => this.render())
});
this.html.find('.conteneur-name a').click(async event => {
RdDUtility.toggleAfficheContenu(this.getItemId(event));
this.render(true);
});
this.html.find('.actor-montrer').click(async event => this.actor.postActorToChat());
this.html.find('.item-edit').click(async event => this.getItem(event)?.sheet.render(true))
this.html.find('.item-montrer').click(async event => this.getItem(event)?.postItemToChat());
this.html.find('.actor-montrer').click(async event => this.actor.postActorToChat());
this.html.find('.recherche')
.each((index, field) => {
this._rechercheSelectArea(field);
@ -152,9 +146,16 @@ export class RdDBaseActorSheet extends ActorSheet {
.keyup(async event => this._rechercherKeyup(event))
.change(async event => this._rechercherKeyup(event));
this.html.find('.recherche').prop("disabled", false);
// Everything below here is only needed if the sheet is editable
if (!this.options.editable) return;
this.html.find('.item-action').click(async event => {
const item = RdDSheetUtility.getItem(event, this.actor);
item?.actionPrincipale(this.actor, async () => this.render())
});
this.html.find('.item-split').click(async event => {
const item = this.getItem(event);
RdDSheetUtility.splitItem(item, this.actor);

View File

@ -53,22 +53,46 @@ export class RdDCoeur {
static async toggleSubActeurCoeur(actorId, subActorId, toggleCoeur) {
const actor = game.actors.get(actorId)
if (ReglesOptionnelles.isUsing("chateau-dormant-gardien") && !actor.system.sommeil.nouveaujour) {
ui.notifications.warn(`Les changements de points de coeur se font juste avant de gérer Château Dormant, juste avant de passer à un nouveau jour`)
return
const amoureux = actor.getSuivant(subActorId)
if (toggleCoeur <= amoureux.coeur) {
if (toggleCoeur > amoureux.prochainCoeur) {
toggleCoeur = amoureux.coeur
}
else {
toggleCoeur = amoureux.coeur - 1
}
}
const coeur = actor.getPointsCoeur(subActorId);
if (toggleCoeur <= coeur) {
// TODO: validation?
await actor.moralIncDec(-4);
actor.setPointsCoeur(subActorId, Math.max(0, coeur - 1));
ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(actor.name),
content: `Perte de points de coeur arbitraire: ${actor.name} perd 4 points de moral, pour finir à ${actor.getMoralTotal()}.`
});
else if (toggleCoeur <= amoureux.prochainCoeur) {
toggleCoeur = Math.max(amoureux.coeur, toggleCoeur - 1)
}
else {
actor.setPointsCoeur(subActorId, Math.min(4, toggleCoeur));
actor.setPointsCoeur(subActorId, Math.max(0, Math.min(toggleCoeur, 4)))
}
static async applyCoeurChateauDormant(actor, message) {
const newSuivants = duplicate(actor.system.subacteurs.suivants)
let count = 0
newSuivants.forEach(async link => {
const suivant = game.actors.get(link.id)
const prochainCoeur = link.prochainCoeur ?? 0;
const coeurCourant = link.coeur ?? 0;
const diff = prochainCoeur - coeurCourant
if (diff < 0) {
await actor.moralIncDec(-4);
link.coeur = Math.max(0, coeurCourant - 1)
link.prochainCoeur = link.coeur
message.content += `<br>Votre c&oelig;ur brisé pour ${suivant.name} vous fait perdre 4 points de moral, il vous reste ${link.coeur} points de C&oelig;ur.`
count++
}
else if (diff > 0) {
link.coeur = Math.min(prochainCoeur, 4)
message.content += `<br>Votre c&oelig;ur bat fort, vous avez maintenant ${link.coeur} points de C&oelig;ur pour ${suivant.name}.`
link.prochainCoeur = link.coeur
count++
}
}
)
if (count > 0) {
await actor.update({ 'system.subacteurs.suivants': newSuivants });
}
}
@ -130,14 +154,13 @@ export class RdDCoeur {
? [infoCoeur.target, infoCoeur.source]
: [undefined, undefined]))
const subActorId = partenaire?.actor.id;
if (amoureux.perteCoeur) {
ui.notifications.warn(`Un point de coeur a déjà été perdu`)
ui.notifications.warn(`Le point de c&oelig;ur a déjà été perdu`)
}
else if (amoureux.coeur > 0) {
const actor = game.actors.get(actorId)
if (actor.isOwner) {
await actor.setPointsCoeur(subActorId, amoureux.coeur - 1)
await actor.setPointsCoeur(partenaire?.actor.id, amoureux.coeur - 1, { immediat: true })
amoureux.perteCoeur = true
RdDCoeur.addTagsInfoCoeur(infoCoeur)
}

View File

@ -53,7 +53,7 @@ export class RdDSheetUtility {
targetActorId: actor.id,
itemId: item.id,
sourceActorId: item.actor?.id,
sourceTokenId: item.actor.token?.id,
sourceTokenId: item.actor?.token?.id,
srcId: objetVersConteneur[item.id],
onEnleverConteneur: () => { delete objetVersConteneur[item.id]; },
onAjouterDansConteneur: (itemId, conteneurId) => { objetVersConteneur[itemId] = conteneurId; }

View File

@ -205,6 +205,7 @@ export class RdDUtility {
'systems/foundryvtt-reve-de-dragon/templates/enum-tmr-type.html',
// Partials
'systems/foundryvtt-reve-de-dragon/templates/coeur/chat-effet-tendre-moment.hbs',
'systems/foundryvtt-reve-de-dragon/templates/coeur/afficher-coeur.hbs',
'systems/foundryvtt-reve-de-dragon/templates/tirage/liste-resultats-recherche.hbs',
'systems/foundryvtt-reve-de-dragon/templates/time/horloge.hbs',
'systems/foundryvtt-reve-de-dragon/templates/common/timestamp.hbs',

View File

@ -83,7 +83,7 @@ export const referenceAjustements = {
coeur: {
isVisible: (rollData, actor) => actor.isPersonnage() && RdDCarac.isVolonte(rollData.selectedCarac),
isUsed: (rollData, actor) => rollData.use.coeur != undefined,
getLabel: (rollData, actor) => 'Ajustement de coeur',
getLabel: (rollData, actor) => 'Ajustement de c&oelig;ur',
getValue: (rollData, actor) => -2 * (rollData.use.coeur?.coeur ?? 0)
},
moralTotal: {

View File

@ -1,8 +1,8 @@
{
"id": "foundryvtt-reve-de-dragon",
"title": "Rêve de Dragon",
"version": "11.2.4",
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-v11.2.4.zip",
"version": "11.2.6",
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-11.2.6.zip",
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v11/system.json",
"changelog": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/branch/v11/changelog.md",
"compatibility": {

View File

@ -11,10 +11,10 @@
<span></span>
{{else}}
<span class="competence-title subacteur-coeur-toggle">
<a data-coeur-nombre="1"><i class="{{#if (gte suivant.coeur 1)}}fa-solid{{else}}fa-regular{{/if}} fa-heart"></i></a>
<a data-coeur-nombre="2"><i class="{{#if (gte suivant.coeur 2)}}fa-solid{{else}}fa-regular{{/if}} fa-heart"></i></a>
<a data-coeur-nombre="3"><i class="{{#if (gte suivant.coeur 3)}}fa-solid{{else}}fa-regular{{/if}} fa-heart"></i></a>
<a data-coeur-nombre="4"><i class="{{#if (gte suivant.coeur 4)}}fa-solid{{else}}fa-regular{{/if}} fa-heart"></i></a>
{{>'systems/foundryvtt-reve-de-dragon/templates/coeur/afficher-coeur.hbs' numero=1 courant=suivant.coeur prochain=suivant.prochainCoeur}}
{{>'systems/foundryvtt-reve-de-dragon/templates/coeur/afficher-coeur.hbs' numero=2 courant=suivant.coeur prochain=suivant.prochainCoeur}}
{{>'systems/foundryvtt-reve-de-dragon/templates/coeur/afficher-coeur.hbs' numero=3 courant=suivant.coeur prochain=suivant.prochainCoeur}}
{{>'systems/foundryvtt-reve-de-dragon/templates/coeur/afficher-coeur.hbs' numero=4 courant=suivant.coeur prochain=suivant.prochainCoeur}}
</span>
<span class="competence-title subacteur-label">
{{#if (gte suivant.coeur 1)}}

View File

@ -0,0 +1,12 @@
{{log 'C&oelig;ur' numero courant prochain}}
<a data-numero-coeur="{{numero}}">
{{#if (and (lte numero courant) (lte numero prochain))}}
<i class="fa-solid fa-heart"></i>
{{else if (and (lte numero courant) (gt numero prochain))}}
<i class="fa-solid fa-heart-crack"></i>
{{else if (and (gt numero courant) (lte numero prochain))}}
<i class="fa-solid fa-hand-holding-heart"></i>
{{else if (and (gt numero courant) (gt numero prochain))}}
<i class="fa-regular fa-heart"></i>
{{/if}}
</a>

View File

@ -4,7 +4,7 @@
{{#if (gt gainMoral 0)}}a apprécié ce tendre moment et gagné du moral
{{else}}n'a pas gagné de moral{{#if (gte coeur 1)}} et peut
<span class="chat-card-button-area">
<a class="perdre-point-coeur-douceur chat-card-button" data-actor-id="{{actor.id}}">perdre un point de coeur</a>
<a class="perdre-point-coeur-douceur chat-card-button" data-actor-id="{{actor.id}}">perdre un point de c&oelig;ur</a>
</span>
{{/if}}.
{{/if}}

View File

@ -1,5 +1,5 @@
<div class="flexrow utilisation-coeur">
<label class="">Ajustement de Coeur</label>
<label class="">Ajustement de C&oelig;ur</label>
<div class="select-suivant">
<img class="sheet-competence-img selected-suivant-coeur" src="{{use.coeur.img}}" title="{{use.coeur.name}}" />
<select name="select-suivant-coeur" class="select-suivant-coeur" data-dtype="String">