12.0.7 - La propriété d'Astrobazzarh #709
13
changelog.md
13
changelog.md
@ -1,4 +1,17 @@
|
||||
# 12.0
|
||||
## 12.0.7 - La propriété d'Astrobazzarh
|
||||
- correction des opérations faites à la création d'un Item:
|
||||
- la durée des queues/rencontres/souffles
|
||||
- les effets draconiques d'un souffle/queue
|
||||
- mise à jour des points de tâche des blessures lors des soins
|
||||
- pas d'expérience sur les particulières quand aucun MJ n'est connecté
|
||||
- Le drag&drop d'un acteur depuis la liste des acteurs sur la fiche
|
||||
d'une entité incarnée permet d'accorder le personnage
|
||||
- Les messages pour résister aux possessions/conjuration sont envoyées
|
||||
au défenseur
|
||||
- Les messages pour résister aux empoignades sont envoyées au défenseur
|
||||
- la commande /voyage affiche maintenant le total de fatigue pour chaque voyageur
|
||||
- la commande /voyage affiche maintenant les compétences liées au terrain
|
||||
|
||||
## 12.0.6 - Le bazar d'Astrobazzarh
|
||||
- Corrections de l'inventaire en bazar:
|
||||
|
@ -1548,6 +1548,9 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async appliquerAjoutExperience(rollData, hideChatMessage = 'show') {
|
||||
if (!Misc.firstConnectedGM()){
|
||||
return
|
||||
}
|
||||
hideChatMessage = hideChatMessage == 'hide' || (Misc.isRollModeHiddenToPlayer() && !game.user.isGM)
|
||||
let xpData = await this._appliquerExperience(rollData.rolled, rollData.selectedCarac.label, rollData.competence, rollData.jetResistance);
|
||||
if (xpData.length) {
|
||||
|
@ -508,8 +508,8 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
||||
|
||||
isEntiteAccordee(attacker) { return true }
|
||||
|
||||
async setEntiteReveAccordee(attacker) {
|
||||
ui.notifications.error("Impossible de s'accorder à " + this.name + ": ce n'est pas une entite de cauchemer/rêve");
|
||||
async setEntiteReveAccordee(actor) {
|
||||
ui.notifications.error("Impossible de s'accorder à " + this.name + ": ce n'est pas une entité incarnée");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -33,27 +33,4 @@ export class RdDCreature extends RdDBaseActorSang {
|
||||
}
|
||||
}
|
||||
|
||||
isEntiteAccordee(attacker) {
|
||||
if (this.isEntite([ENTITE_INCARNE])) {
|
||||
let resonnance = this.system.sante.resonnance
|
||||
return (resonnance.actors.find(it => it == attacker.id))
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async setEntiteReveAccordee(attacker) {
|
||||
if (this.isEntite([ENTITE_INCARNE])) {
|
||||
let resonnance = foundry.utils.duplicate(this.system.sante.resonnance);
|
||||
if (resonnance.actors.find(it => it == attacker.id)) {
|
||||
// déjà accordé
|
||||
return;
|
||||
}
|
||||
await this.update({ "system.sante.resonnance": [...resonnance, attacker.id] });
|
||||
}
|
||||
else {
|
||||
super.setEntiteReveAccordee(attacker)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -54,6 +54,12 @@ export class RdDActorEntiteSheet extends RdDBaseActorReveSheet {
|
||||
});
|
||||
}
|
||||
|
||||
async _onDropActor(event, dragData) {
|
||||
const dropActor = fromUuidSync(dragData.uuid)
|
||||
await this.actor.setEntiteReveAccordee(dropActor)
|
||||
super._onDropActor(event, dragData)
|
||||
}
|
||||
|
||||
async deleteSubActeur(actorId) {
|
||||
let newResonances = this.actor.system.sante.resonnance.actors.filter(id => id != actorId);
|
||||
await this.actor.update({ 'system.sante.resonnance.actors': newResonances }, { renderSheet: false });
|
||||
|
@ -67,7 +67,7 @@ export class RdDEntite extends RdDBaseActorReve {
|
||||
if (this.isNonIncarnee()) {
|
||||
return
|
||||
}
|
||||
await RdDEncaisser.encaisser(this)
|
||||
await RdDEncaisser.encaisser(this)
|
||||
}
|
||||
|
||||
isEffectAllowed(effectId) {
|
||||
@ -91,20 +91,16 @@ export class RdDEntite extends RdDBaseActorReve {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async setEntiteReveAccordee(attacker) {
|
||||
async setEntiteReveAccordee(actor) {
|
||||
if (this.isEntite([ENTITE_INCARNE])) {
|
||||
let resonnance = foundry.utils.duplicate(this.system.sante.resonnance);
|
||||
if (resonnance.actors.find(it => it == attacker.id)) {
|
||||
if (this.system.sante.resonnance.actors.find(it => it == actor.id)) {
|
||||
// déjà accordé
|
||||
return;
|
||||
return
|
||||
}
|
||||
resonnance.actors.push(attacker.id);
|
||||
await this.update({ "system.sante.resonnance": resonnance });
|
||||
await this.update({ "system.sante.resonnance.actors": [...this.system.sante.resonnance.actors, actor.id] })
|
||||
}
|
||||
else {
|
||||
super.setEntiteReveAccordee(attacker)
|
||||
super.setEntiteReveAccordee(actor)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -166,11 +166,12 @@ export class Misc {
|
||||
}
|
||||
|
||||
static firstConnectedGM() {
|
||||
if (game.users?.activeGM) {
|
||||
return game.users.activeGM
|
||||
if (foundry.utils.isNewerVersion(game.release.version, '12.0')) {
|
||||
return game.users.activeGM
|
||||
}
|
||||
return game.users.sort(Misc.ascending(u => u.id)).find(u => u.isGM && u.active);
|
||||
return game.users.find(u => u.isGM && u.active);
|
||||
}
|
||||
|
||||
static connectedGMs() {
|
||||
return game.users.filter(u => u.isGM && u.active);
|
||||
}
|
||||
@ -188,16 +189,20 @@ export class Misc {
|
||||
* and there is no connected GM
|
||||
*/
|
||||
static documentIfResponsible(document) {
|
||||
if (document instanceof Document) {
|
||||
if (Misc.isUniqueConnectedGM() || (Misc.connectedGMs().length == 0 && Misc.isOwnerPlayer(document))) {
|
||||
if (foundry.utils.isNewerVersion(game.release.version, '12.0')) {
|
||||
if (game.users.activeGM || (Misc.connectedGMs().length == 0 && Misc.isOwnerPlayer(document)))
|
||||
{
|
||||
return document
|
||||
}
|
||||
}
|
||||
else if (Misc.isUniqueConnectedGM() || (Misc.connectedGMs().length == 0 && Misc.isOwnerPlayer(document))) {
|
||||
return document
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
static isOwnerPlayer(actor) {
|
||||
return actor.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)
|
||||
static isOwnerPlayer(document) {
|
||||
return document.testUserPermission && document.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)
|
||||
}
|
||||
|
||||
static isOwnerPlayerOrUniqueConnectedGM(actor) {
|
||||
|
@ -248,7 +248,7 @@ export class RdDEmpoignade {
|
||||
if (rollData.rolled.isPart) {
|
||||
rollData.particuliere = "finesse";
|
||||
}
|
||||
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-resultat.html');
|
||||
let msg = await RdDResolutionTable.displayRollData(rollData, defender, 'chat-empoignade-resultat.html');
|
||||
RdDEmpoignade.$storeRollEmpoignade(msg, rollData);
|
||||
}
|
||||
|
||||
|
@ -131,7 +131,7 @@ export class RdDPossession {
|
||||
}
|
||||
const possession = (rollData.isECNIDefender ? rollData.attacker : rollData.defender).getPossession(rollData.possession.system.possessionid)
|
||||
RdDPossession.storePossessionAttaque(possession, rollData)
|
||||
await RdDResolutionTable.displayRollData(rollData, rollData.attacker, 'chat-resultat-possession.html');
|
||||
await RdDResolutionTable.displayRollData(rollData, rollData.defender, 'chat-resultat-possession.html');
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -171,7 +171,7 @@ export class RdDPossession {
|
||||
rollData.possession = possession
|
||||
RdDPossession.$updateEtatPossession(rollData.possession)
|
||||
|
||||
await RdDResolutionTable.displayRollData(rollData, rollData.defender, 'chat-resultat-possession.html')
|
||||
await RdDResolutionTable.displayRollData(rollData, rollData.attacker, 'chat-resultat-possession.html')
|
||||
if (rollData.possession.isPosseder || rollData.possession.isConjurer) {
|
||||
// conjuration
|
||||
victime.deleteEmbeddedDocuments("Item", [rollData.possession._id])
|
||||
|
@ -97,7 +97,7 @@ export class RdDResolutionTable {
|
||||
}
|
||||
|
||||
static actorChatName(actor) {
|
||||
return actor?.userName ?? game.user.name;
|
||||
return actor?.name ?? game.user.name;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { TYPES } from "../item.js"
|
||||
import { RdDItemCompetence } from "../item-competence.js"
|
||||
import { ChatUtility } from "../chat-utility.js"
|
||||
import { Misc } from "../misc.js"
|
||||
|
||||
const CODES_COMPETENCES_VOYAGE = ['Extérieur', 'Forêt', 'Montagne', 'Marais', 'Glace', 'Equitation']
|
||||
const TABLEAU_FATIGUE_MARCHE = [
|
||||
@ -36,7 +37,7 @@ export class DialogFatigueVoyage extends Dialog {
|
||||
const parameters = {
|
||||
tableauFatigueMarche: TABLEAU_FATIGUE_MARCHE,
|
||||
playerActors: game.actors.filter(actor => actor.isPersonnageJoueur())
|
||||
.map(actor => DialogFatigueVoyage.prepareActor(actor)),
|
||||
.map(actor => DialogFatigueVoyage.prepareActorParameters(actor)),
|
||||
nombreHeures: 1,
|
||||
}
|
||||
DialogFatigueVoyage.setModeDeplacement(parameters, undefined, undefined)
|
||||
@ -53,21 +54,37 @@ export class DialogFatigueVoyage extends Dialog {
|
||||
parameters.typeTerrain = ligneFatigueMarche
|
||||
parameters.vitesseDeplacement = rythme.vitesse
|
||||
parameters.fatigueHoraire = rythme.fatigue
|
||||
parameters.playerActors.forEach(voyageur =>
|
||||
DialogFatigueVoyage.selectSurvie(voyageur, parameters.typeTerrain.code)
|
||||
)
|
||||
}
|
||||
|
||||
static prepareActor(actor) {
|
||||
const competencesVoyage = {}
|
||||
CODES_COMPETENCES_VOYAGE.forEach(codeSurvie =>
|
||||
competencesVoyage[codeSurvie] = RdDItemCompetence.findCompetence(actor.itemTypes[TYPES.competence], codeSurvie, { onMessage: () => { } })
|
||||
)
|
||||
return {
|
||||
static prepareActorParameters(actor) {
|
||||
const actorParameters = {
|
||||
id: actor.id,
|
||||
actor: actor,
|
||||
selected: true,
|
||||
ajustementFatigue: 0,
|
||||
competencesVoyage: competencesVoyage
|
||||
survies: {}
|
||||
}
|
||||
const competencesVoyage = {}
|
||||
CODES_COMPETENCES_VOYAGE.forEach(codeSurvie => {
|
||||
competencesVoyage[codeSurvie] = RdDItemCompetence.findCompetence(actor.itemTypes[TYPES.competence], codeSurvie, { onMessage: () => { } })
|
||||
})
|
||||
TABLEAU_FATIGUE_MARCHE.forEach(terrain => {
|
||||
actorParameters.survies[terrain.code] = Misc.join(
|
||||
terrain.survies.map(survie => {
|
||||
const niveau = competencesVoyage[survie]?.system.niveau
|
||||
return `${survie}: ${niveau}`
|
||||
}),
|
||||
', ')
|
||||
})
|
||||
return actorParameters
|
||||
}
|
||||
|
||||
static selectSurvie(actorParameters, code) {
|
||||
actorParameters.survieCourante = actorParameters.survies[code]
|
||||
}
|
||||
|
||||
constructor(html, parameters) {
|
||||
const options = {
|
||||
@ -97,6 +114,7 @@ export class DialogFatigueVoyage extends Dialog {
|
||||
this.html.find('select[name="code-terrain"]').change(event => this.changeParameters())
|
||||
this.html.find('select[name="vitesse-deplacement"]').change(event => this.changeParameters())
|
||||
this.html.find('input[name="nombre-heures"]').change(event => this.changeParameters())
|
||||
this.html.find('.list-item input[name="ajustement-fatigue"]').change(event => this.changeParameters())
|
||||
this.html.find('button[name="appliquer-fatigue"]').click(event => this.appliquerFatigue())
|
||||
}
|
||||
|
||||
@ -118,6 +136,10 @@ export class DialogFatigueVoyage extends Dialog {
|
||||
selectVitesseDeplacement.append(await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/voyage/option-vitesse-fatigue.hbs', rythme))
|
||||
})
|
||||
selectVitesseDeplacement.val(this.parameters.vitesseDeplacement).change()
|
||||
|
||||
Promise.all(this.getActorRows()
|
||||
.map(async row => row.find('label.voyage-liste-survies').text(this.$extractActorParameters(row).survieCourante)
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,16 +154,24 @@ export class DialogFatigueVoyage extends Dialog {
|
||||
}
|
||||
|
||||
async setFatigue() {
|
||||
this.html.find('input[name="base-fatigue"]').val(this.parameters.nombreHeures * this.parameters.fatigueHoraire)
|
||||
const baseFatigue = this.parameters.nombreHeures * this.parameters.fatigueHoraire
|
||||
this.html.find('input[name="base-fatigue"]').val(baseFatigue)
|
||||
this.updateActorTotalFatigue(baseFatigue)
|
||||
}
|
||||
|
||||
async updateActorTotalFatigue(baseFatigue) {
|
||||
Promise.all(this.getActorRows()
|
||||
.map(async row => {
|
||||
const actor = this.$extractActorParameters(row)
|
||||
row.find('input[name="total-fatigue"]').val(actor.ajustement + baseFatigue)
|
||||
}))
|
||||
}
|
||||
|
||||
async appliquerFatigue() {
|
||||
const fatigueBase = parseInt(this.html.find('input[name="base-fatigue"]').val() ?? 0)
|
||||
const actors = jQuery.map(
|
||||
this.html.find('div.fatigue-actors-list li.list-item'),
|
||||
it => this.$extractActor(this.html.find(it))
|
||||
)
|
||||
actors.filter(it => it.selected)
|
||||
this.getActorRows()
|
||||
.map(row => this.$extractActorParameters(row))
|
||||
.filter(it => it.selected)
|
||||
.forEach(async it => {
|
||||
const perteFatigue = fatigueBase + it.ajustement
|
||||
ChatMessage.create({
|
||||
@ -161,16 +191,24 @@ export class DialogFatigueVoyage extends Dialog {
|
||||
})
|
||||
}
|
||||
|
||||
$extractActor(actorRow) {
|
||||
const actor = game.actors.get(actorRow.data('actor-id'))
|
||||
getActorRows() {
|
||||
return jQuery.map(
|
||||
this.html.find('div.fatigue-actors-list li.list-item'),
|
||||
it => this.html.find(it))
|
||||
}
|
||||
|
||||
|
||||
$extractActorParameters(actorRow) {
|
||||
const actorId = actorRow.data('actor-id')
|
||||
const actorParameters = this.parameters.playerActors.find(it => it.id == actorId)
|
||||
const actor = game.actors.get(actorId)
|
||||
if (!actor) {
|
||||
ui.notifications.warn(`Acteur ${it.actorId} introuvable`)
|
||||
return {}
|
||||
}
|
||||
return {
|
||||
actor: actor,
|
||||
ajustement: parseInt(actorRow.find('input[name="ajustement-fatigue"]').val() ?? 0),
|
||||
selected: actor && actorRow.find('input[name="selectionner-acteur"]').is(':checked')
|
||||
}
|
||||
actorParameters.ajustement = parseInt(actorRow.find('input[name="ajustement-fatigue"]').val() ?? 0)
|
||||
actorParameters.selected = actor && actorRow.find('input[name="selectionner-acteur"]').is(':checked')
|
||||
return actorParameters
|
||||
}
|
||||
|
||||
async close() {
|
||||
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"id": "foundryvtt-reve-de-dragon",
|
||||
"title": "Rêve de Dragon",
|
||||
"version": "12.0.6",
|
||||
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-12.0.6.zip",
|
||||
"version": "12.0.7",
|
||||
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-12.0.7.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": {
|
||||
|
@ -42,7 +42,8 @@
|
||||
<li class="competence-header flexrow">
|
||||
<span class="flex-grow-2">Personnage</span>
|
||||
<span class="flex-grow-2">Survies</span>
|
||||
<span class="flex-grow-1" data-tooltip="Ajustements à appliquer pour les personnages se reposant (par exemple, à cheval)">Ajustements</span>
|
||||
<span class="flex-grow-1" data-tooltip="Ajustements à appliquer (par exemple, repos à cheval)">Ajustements</span>
|
||||
<span class="flex-grow-1" data-tooltip="Total de fatigue pour le voyageur">Total</span>
|
||||
</li>
|
||||
{{#each playerActors as |selected|}}
|
||||
{{>'systems/foundryvtt-reve-de-dragon/templates/voyage/fatigue-actor.hbs' voyageur=selected survies=@root.typeTerrain.survies}}
|
||||
|
@ -8,16 +8,13 @@
|
||||
</span>
|
||||
<span class="flex-grow-2">
|
||||
<div class="flexcol ">
|
||||
<label class="voyage-liste-survies">
|
||||
{{#each voyageur.competencesVoyage as |comp key|}}
|
||||
{{#if (array-includes ../survies key)}}
|
||||
{{key}} {{comp.system.niveau}},
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</label>
|
||||
<label class="voyage-liste-survies">{{voyageur.survieCourante}}</label>
|
||||
</div>
|
||||
</span>
|
||||
<span class="flex-grow-1">
|
||||
<input type="number" name="ajustement-fatigue" class="number-x2 ajustement-fatigue" data-dtype="Number" value="{{voyageur.ajustementFatigue}}" min="-6" max="6"/>
|
||||
</span>
|
||||
<span class="flex-grow-1">
|
||||
<input type="number" name="total-fatigue" class="number-x2 total-fatigue" data-dtype="Number" value="1" min="0" max="24" disabled/>
|
||||
</span>
|
||||
</li>
|
||||
|
Loading…
Reference in New Issue
Block a user