foundryvtt-reve-de-dragon/module/coeur/rdd-coeur.js

169 lines
6.5 KiB
JavaScript

import { RdDBaseActor } from "../actor/base-actor.js";
import { ChatUtility } from "../chat-utility.js";
import { ReglesOptionnelles } from "../settings/regles-optionnelles.js";
const INFO_COEUR = 'info-coeur';
export class RdDCoeur {
static registerChatCallbacks(html) {
html.on("click", 'a.accepter-tendre-moment', event => {
RdDCoeur.accepterTendreMoment(RdDCoeur.extractInfoCoeur(event))
})
html.on("click", 'a.refuser-tendre-moment', event => {
RdDCoeur.refuserTendreMoment(RdDCoeur.extractInfoCoeur(event))
})
html.on("click", 'a.perdre-point-coeur-douceur', event => {
RdDCoeur.perdreEnDouceur(
RdDCoeur.extractInfoCoeur(event),
event.currentTarget.attributes['data-actor-id'].value)
})
}
static addTagsInfoCoeur(infoCoeur, chatMessage = undefined) {
if (chatMessage) {
infoCoeur.chatMessageId = chatMessage.id
}
else {
chatMessage = game.messages.get(infoCoeur.chatMessageId)
}
ChatUtility.setMessageData(chatMessage, INFO_COEUR, infoCoeur);
}
static extractInfoCoeur(event) {
return ChatUtility.getMessageData(ChatUtility.getChatMessage(event), INFO_COEUR)
}
static getInfoCoeur(sourceActorId, targetActorId) {
const sourceActor = game.actors.get(sourceActorId)
const targetActor = game.actors.get(targetActorId)
if (sourceActor && targetActor) {
return {
source: {
actor: RdDBaseActor.extractActorMin(sourceActor),
coeur: sourceActor.getPointsCoeur(targetActorId),
},
target: {
actor: RdDBaseActor.extractActorMin(targetActor),
coeur: targetActor.getPointsCoeur(sourceActorId),
}
}
}
return {}
}
static async toggleSubActeurCoeur(actorId, subActorId, toggleCoeur) {
const actor = game.actors.get(actorId)
const amoureux = actor.getSuivant(subActorId)
if (toggleCoeur <= amoureux.coeur) {
if (toggleCoeur > amoureux.prochainCoeur) {
toggleCoeur = amoureux.coeur
}
else {
toggleCoeur = amoureux.coeur - 1
}
}
else if (toggleCoeur <= amoureux.prochainCoeur) {
toggleCoeur = Math.max(amoureux.coeur, toggleCoeur - 1)
}
actor.setPointsCoeur(subActorId, Math.max(0, Math.min(toggleCoeur, 4)))
}
static async applyCoeurChateauDormant(actor, message) {
const newSuivants = foundry.utils.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 });
}
}
static async startSubActeurTendreMoment(actorId, subActeurId) {
const infoCoeur = RdDCoeur.getInfoCoeur(actorId, subActeurId)
if (infoCoeur.target?.actor.id) {
// TODO: passer par une fenêtre pour saisir sa proposition (lieu, heure, ...)
const chatHtml = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/coeur/chat-proposer-tendre-moment.hbs`, infoCoeur)
const chatMessage = await ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(infoCoeur.target?.actor.name),
content: chatHtml
})
RdDCoeur.addTagsInfoCoeur(infoCoeur, chatMessage)
}
}
static async accepterTendreMoment(infoCoeur) {
const target = game.actors.get(infoCoeur.target.actor.id)
if (!target.isOwner) {
ui.notifications.warn(`vous ne pouvez pas accepter pour ${infoCoeur.target.actor.name}`)
return
}
ChatUtility.removeChatMessageId(infoCoeur.chatMessageId)
infoCoeur.target.jetTendre = (await (new Roll('1d6').evaluate({ async: true }))).total
infoCoeur.source.jetTendre = (await (new Roll('1d6').evaluate({ async: true }))).total
const diff = Math.abs(infoCoeur.source.jetTendre - infoCoeur.target.jetTendre)
for (let amoureux of [infoCoeur.source, infoCoeur.target]) {
const actorAmoureux = game.actors.get(amoureux.actor.id);
amoureux.situation = diff <= amoureux.coeur ? 'heureux' : 'neutre'
amoureux.gainMoral = await actorAmoureux.jetDeMoral(amoureux.situation)
}
const chatHtml = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/coeur/chat-accepter-tendre-moment.hbs`, infoCoeur)
const chatMessage = await ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(infoCoeur.source?.actor.name, infoCoeur.target?.actor.name),
content: chatHtml
})
RdDCoeur.addTagsInfoCoeur(infoCoeur, chatMessage)
}
static async refuserTendreMoment(infoCoeur) {
const target = game.actors.get(infoCoeur.target.actor.id)
if (!target.isOwner) {
ui.notifications.warn(`vous ne pouvez pas refuser pour ${infoCoeur.target.actor.name}`)
return
}
ChatUtility.removeChatMessageId(infoCoeur.chatMessageId)
const chatHtml = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/coeur/chat-refuser-tendre-moment.hbs`, infoCoeur)
await ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(infoCoeur.source?.actor.name, infoCoeur.target?.actor.name),
content: chatHtml
});
}
static async perdreEnDouceur(infoCoeur, actorId) {
const [amoureux, partenaire] = (infoCoeur.source.actor.id == actorId
? [infoCoeur.source, infoCoeur.target]
: (infoCoeur.target.actor.id == actorId
? [infoCoeur.target, infoCoeur.source]
: [undefined, undefined]))
if (amoureux.perteCoeur) {
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(partenaire?.actor.id, amoureux.coeur - 1, { immediat: true })
amoureux.perteCoeur = true
RdDCoeur.addTagsInfoCoeur(infoCoeur)
}
}
}
}