Compare commits

..

2 Commits

Author SHA1 Message Date
9836bd50e6 Resultat impari sur D20 dans messages et corrections diverses
All checks were successful
Release Creation / build (release) Successful in 46s
2026-03-10 21:37:33 +01:00
6b909b192b Resultat impari sur D20 dans messages et corrections diverses 2026-03-10 21:37:20 +01:00
43 changed files with 53 additions and 39 deletions

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
.history/
node_modules
.github/

View File

@@ -43,6 +43,7 @@
"MNBL.disarm": "Disarm",
"MNBL.doubleD20": "Double d20 (1 Shard Point)",
"MNBL.dramaticfailure": "Dramatic Failure",
"MNBL.oddresult": "Odd result — the die counts as 0",
"MNBL.duration": "Duration",
"MNBL.easy": "Easy (5)",
"MNBL.eclat": "Shard",

View File

@@ -161,6 +161,7 @@
"MNBL.failure": "Echec",
"MNBL.heroicsuccess": "Succés Héroïque",
"MNBL.dramaticfailure": "Echec Dramatique",
"MNBL.oddresult": "Résultat impair — le dé compte pour 0",
"MNBL.attackmountbonus": "Attaquant monté vs def. au sol (+5)",
"MNBL.targetdefense": "Défense adversaire",

View File

@@ -132,7 +132,7 @@ export default class MournbladeItemSheet extends HandlebarsApplicationMixin(foun
payload: chatData,
})
const html = await renderTemplate('systems/fvtt-mournblade/templates/post-item.hbs', chatData)
const html = await foundry.applications.handlebars.renderTemplate('systems/fvtt-mournblade/templates/post-item.hbs', chatData)
const chatOptions = {
user: game.user.id,
content: html,

View File

@@ -11,7 +11,22 @@ export default class CompetenceDataModel extends foundry.abstract.TypeDataModel
attribut2: new fields.StringField({ initial: "" }),
attribut3: new fields.StringField({ initial: "" }),
doublebonus: new fields.BooleanField({ initial: false }),
predilections: new fields.ArrayField(new fields.StringField(), { initial: [] })
predilections: new fields.ArrayField(
new fields.SchemaField({
name: new fields.StringField({ initial: "" }),
used: new fields.BooleanField({ initial: false })
}),
{ initial: [] }
)
};
}
static migrateData(source) {
if (Array.isArray(source.predilections)) {
source.predilections = source.predilections.map(pred =>
typeof pred === "string" ? { name: pred, used: false } : pred
);
}
return super.migrateData(source);
}
}

View File

@@ -18,6 +18,12 @@ export class MournbladeActor extends Actor {
// Calculate derived attributes
const data = this.system;
if (this.type == 'personnage') {
// Compute base health and max soul from attributes (derived, no DB write needed)
data.sante.base = data.sante.bonus + (data.attributs.pui.value + data.attributs.tre.value) * 2 + 5;
data.ame.fullmax = (data.attributs.cla.value + data.attributs.tre.value) * data.biodata.amemultiplier + 5;
}
// Calculate total health
data.sante.total = data.sante.base + data.sante.bonus;
@@ -32,7 +38,7 @@ export class MournbladeActor extends Actor {
}
prepareDerivedData() {
this.prepareData();
super.prepareDerivedData();
}
/* -------------------------------------------- */
@@ -299,25 +305,6 @@ export class MournbladeActor extends Actor {
return combat
}
/* -------------------------------------------- */
prepareDerivedData() {
if (this.type == 'personnage') {
let newSante = this.system.sante.bonus + (this.system.attributs.pui.value + this.system.attributs.tre.value) * 2 + 5
if (this.system.sante.base != newSante && this._id) {
// Only update if the actor already exists (has an _id)
this.update({ 'system.sante.base': newSante })
}
let newAme = (this.system.attributs.cla.value + this.system.attributs.tre.value) * this.system.biodata.amemultiplier + 5
if (this.system.ame.fullmax != newAme && this._id) {
// Only update if the actor already exists (has an _id)
this.update({ 'system.ame.fullmax': newAme })
}
}
super.prepareDerivedData()
}
/* -------------------------------------------- */
_preUpdate(changed, options, user) {
@@ -583,8 +570,8 @@ export class MournbladeActor extends Actor {
this.update({ 'system.ressources': ressources })
ChatMessage.create({
content: "L'utilisation de la capacité/arme a dépensé " + arme.system.nbressources + " ressources.",
whisper: game.user._id,
user: game.user._id
whisper: game.user.id,
user: game.user.id
});
} else {
ui.notifications.warn("Points de ressources insuffisants.")
@@ -735,7 +722,7 @@ export class MournbladeActor extends Actor {
let arme = this.items.get(armeId)
if (arme) {
MournbladeUtility.createChatWithRollMode("GM", {
content: await renderTemplate(`systems/fvtt-mournblade/templates/chat-display-description.hbs`, arme)
content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-mournblade/templates/chat-display-description.hbs`, arme)
}, arme)
this.depenseRessources(arme)
}
@@ -751,7 +738,7 @@ export class MournbladeActor extends Actor {
arme = this.prepareBouclier(arme)
}
//Unused rollData.degatsFormula = arme.system.totalDegats
let roll = await new Roll(arme.system.totalDegats).roll()
let roll = await new Roll(arme.system.totalDegats).evaluate()
await MournbladeUtility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
let rollData = {
degatsFormula:arme.system.totalDegats,

View File

@@ -10,7 +10,7 @@ export class MournbladeCombat extends Combat {
const c = this.combatants.get(ids[cId]);
let id = c._id || c.id;
let initBonus = c.actor ? c.actor.getInitiativeScore() : 0
let roll = new Roll("1d10 + "+initBonus).roll({ async: false})
let roll = await new Roll("1d10 + "+initBonus).evaluate()
await MournbladeUtility.showDiceSoNice(roll, game.settings.get("core", "rollMode"))
//console.log("Init bonus", initBonus, roll.total)
await this.updateEmbeddedDocuments("Combatant", [ { _id: id, initiative: roll.total } ]);

View File

@@ -89,7 +89,7 @@ export class MournbladeCommands {
if (command && command.func) {
const result = command.func(content, msg, params);
if (result == false) {
RdDCommands._chatAnswer(msg, command.descr);
MournbladeCommands._chatAnswer(msg, command.descr);
}
return true;
}
@@ -98,8 +98,8 @@ export class MournbladeCommands {
/* -------------------------------------------- */
async createChar(msg) {
game.system.Mournblade.creator = new MournbladeActorCreate();
game.system.Mournblade.creator.start();
game.system.mournblade.creator = new MournbladeActorCreate();
game.system.mournblade.creator.start();
}
/* -------------------------------------------- */

View File

@@ -106,7 +106,7 @@ export class MournbladeItemSheet extends foundry.appv1.sheets.ItemSheet {
payload: chatData,
});
renderTemplate('systems/fvtt-mournblade/templates/post-item.hbs', chatData).then(html => {
foundry.applications.handlebars.renderTemplate('systems/fvtt-mournblade/templates/post-item.hbs', chatData).then(html => {
let chatOptions = MournbladeUtility.chatDataSetup(html);
ChatMessage.create(chatOptions)
});

View File

@@ -44,7 +44,7 @@ Hooks.once("init", async function () {
};
/* -------------------------------------------- */
game.socket.on("system.fvtt-mournblade-rpg", data => {
game.socket.on("system.fvtt-mournblade", data => {
MournbladeUtility.onSocketMesssage(data);
});
@@ -119,7 +119,7 @@ Hooks.once("init", async function () {
/* -------------------------------------------- */
async function welcomeMessage() {
const templateData = {};
const html = await renderTemplate("systems/fvtt-mournblade/templates/chat-welcome-message.hbs", templateData);
const html = await foundry.applications.handlebars.renderTemplate("systems/fvtt-mournblade/templates/chat-welcome-message.hbs", templateData);
ChatMessage.create({
user: game.user.id,
@@ -154,14 +154,14 @@ Hooks.once("ready", function () {
ui.notifications.info("Attention ! Aucun personnage n'est relié au joueur !");
ChatMessage.create({
content: "<b>ATTENTION</b> Le joueur " + game.user.name + " n'est relié à aucun personnage !",
user: game.user._id
user: game.user.id
});
}
if (!game.user.isGM && game.user.character && !game.user.character.prototypeToken.actorLink) {
ui.notifications.info("Le token de du joueur n'est pas connecté à l'acteur !");
ChatMessage.create({
content: "<b>ATTENTION</b> Le token du joueur " + game.user.name + " n'est pas connecté à l'acteur !",
user: game.user._id
user: game.user.id
});
}

View File

@@ -154,7 +154,7 @@ export class MournbladeUtility {
if (game.user.isGM) {
MournbladeUtility.applyDegatsFromAttaque(rollData)
} else {
game.socket.emit("system.fvtt-mournblade", { name: "msg_apply_damage", data: { rolLData: rollData } })
game.socket.emit("system.fvtt-mournblade", { name: "msg_apply_damage", data: { rollData: rollData } })
}
})
}
@@ -294,6 +294,7 @@ export class MournbladeUtility {
if (diceValue % 2 == 1) {
//console.log("PAIR/IMP2", diceValue)
rollData.finalResult -= rollData.roll.terms[0].results[0].result // Substract value
rollData.isImpair = true
if (diceValue == 1 || diceValue == 11) {
rollData.isDramatique = true
rollData.isSuccess = false
@@ -312,6 +313,7 @@ export class MournbladeUtility {
rollData.isDramatique = ((rollData.finalResult - rollData.difficulte) <= -10)
rollData.isPureSuccess = (rollData.isSuccess && !rollData.isHeroique)
}
rollData.isEchec = !rollData.isSuccess
}
/* -------------------------------------------- */
@@ -608,7 +610,7 @@ export class MournbladeUtility {
chatGM.whisper = this.getUsers(user => user.isGM);
chatGM.content = "Blinde message of " + game.user.name + "<br>" + chatOptions.content;
console.log("blindMessageToGM", chatGM);
game.socket.emit("system.fvtt-weapons-of-the-gods", { msg: "msg_gm_chat_message", data: chatGM });
game.socket.emit("system.fvtt-mournblade", { msg: "msg_gm_chat_message", data: chatGM });
}
/* -------------------------------------------- */
@@ -682,7 +684,7 @@ export class MournbladeUtility {
let target = MournbladeUtility.getTarget()
if (target) {
rollData.defenderTokenId = target.id
let defender = game.canvas.tokens.get(rollData.defenderTokenId).actor
let defender = game.canvas.tokens.get(rollData.defenderTokenId)?.actor
rollData.defenderCombatValues = defender.getCombatValues()
rollData.defender = defender.toObject() // Simpler
rollData.defenderDefense = defender.getBestDefenseValue()

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -698,7 +698,7 @@
</li>
<li class="flexrow item">
<label class="label-name">{{localize "MNBL.exp"}}</label>
<input type="number" class="" name="system.experience" {{#if isPlayMode}}disabled{{/if}} value="{{system.experience}}" data-dtype="Number" />
<input type="number" class="" name="system.experience.value" {{#if isPlayMode}}disabled{{/if}} value="{{system.experience.value}}" data-dtype="Number" />
</li>
</ul>
</div>

View File

@@ -64,6 +64,13 @@
{{/if}}
</div>
{{!-- Résultat impair --}}
{{#if isImpair}}
<div class="result-warning">
<i class="fas fa-circle-half-stroke"></i> {{localize "MNBL.oddresult"}}
</div>
{{/if}}
{{!-- Détails du jet --}}
<div class="result-details">
<div class="details-section">