Basic dice roll support

This commit is contained in:
LeRatierBretonnien 2024-12-17 15:47:36 +01:00
parent 2c29acd56c
commit 4d3c15a2a8
14 changed files with 173 additions and 67 deletions

BIN
assets/fonts/broadw.ttf Normal file

Binary file not shown.

BIN
assets/fonts/broadway.woff2 Normal file

Binary file not shown.

View File

@ -1,10 +1,39 @@
@font-face {
font-family: "Georama";
src: url("../assets/fonts/georama.woff2") format("woff2");
}
@font-face {
font-family: "Broadway";
src: url("../assets/fonts/broadway.woff2") format("woff2");
}
@font-face {
font-family: "Caslon";
src: url("../fonts/caslonpro-regular.otf") format("truetype");
}
@font-face {
font-family: "Caslon Bold";
src: url("../fonts/caslonpro-bold.otf") format("truetype");
}
@font-face {
font-family: "Caslon Bold Italic";
src: url("../fonts/caslonpro-bolditalic.otf") format("truetype");
}
@font-face {
font-family: "Caslon Italic";
src: url("../fonts/caslonpro-italic.otf") format("truetype");
}
:root { :root {
--font-size-standard: 0.9rem; --font-size-standard: 0.9rem;
--background-image-base: linear-gradient(rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.8)), url("../assets/ui/jazzage_background_main.webp"); --background-image-base: linear-gradient(rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.8)), url("../assets/ui/jazzage_background_main.webp");
/*--background-image-base: url("../assets/ui/jazzage_background_main.webp");*/ /*--background-image-base: url("../assets/ui/jazzage_background_main.webp");*/
--font-primary: "Georama"; --font-primary: "Georama";
--font-secondary: "Georama"; --font-secondary: "Georama";
--font-title: "Broadway";
--logo-standard: url("../assets/logos/reanimated-ce-logo.webp"); --logo-standard: url("../assets/logos/reanimated-ce-logo.webp");
--color-success: darkgreen;
--color-failure: darkred;
--color-critical-success: lightgreen;
--color-critical-failure: lightcoral;
} }
.era-icon-color { .era-icon-color {
/*filter: invert(90%) sepia(10%) saturate(1215%) hue-rotate(55deg) brightness(93%) contrast(89%);*/ /*filter: invert(90%) sepia(10%) saturate(1215%) hue-rotate(55deg) brightness(93%) contrast(89%);*/
@ -50,7 +79,8 @@ i.fvtt-cthulhu-eternal {
.chat-message.whisper { .chat-message.whisper {
font-family: var(--font-primary); font-family: var(--font-primary);
background-image: var(--background-image-base); background-image: var(--background-image-base);
background-repeat: no-repeat; background-repeat: repeat-y;
background-position: 0%;
background-size: 100% 100%; background-size: 100% 100%;
} }
.fvtt-cthulhu-eternal .protagonist-sheet-common label { .fvtt-cthulhu-eternal .protagonist-sheet-common label {
@ -179,6 +209,8 @@ i.fvtt-cthulhu-eternal {
display: flex; display: flex;
} }
.fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-right .protagonist-name input { .fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-right .protagonist-name input {
font-family: var(--font-title);
font-size: calc(var(--font-size-standard) * 1.4);
width: 400px; width: 400px;
} }
.fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-right .protagonist-infos { .fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-right .protagonist-infos {
@ -1285,6 +1317,38 @@ i.fvtt-cthulhu-eternal {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
.dice-roll .intro-chat .intro-right ul {
list-style-type: none;
padding: 0;
margin: 0;
justify-content: center;
align-items: center;
}
.dice-roll .intro-chat .intro-right ul li {
margin: 0 10px;
font-family: var(--font-primary);
font-size: calc(var(--font-size-standard) * 1);
}
.dice-roll .intro-chat .intro-right ul .result-success {
color: var(--color-success);
font-family: var(--font-title);
font-size: calc(var(--font-size-standard) * 1.2);
}
.dice-roll .intro-chat .intro-right ul .result-critical-success {
color: var(--color-critical-success);
font-family: var(--font-title);
font-size: calc(var(--font-size-standard) * 1.2);
}
.dice-roll .intro-chat .intro-right ul .result-failure {
color: var(--color-failure);
font-family: var(--font-title);
font-size: calc(var(--font-size-standard) * 1.2);
}
.dice-roll .intro-chat .intro-right ul .result-critical-failure {
color: var(--color-critical-failure);
font-family: var(--font-title);
font-size: calc(var(--font-size-standard) * 1.2);
}
.dice-roll .intro-chat .intro-right .introText { .dice-roll .intro-chat .intro-right .introText {
font-family: var(--font-secondary); font-family: var(--font-secondary);
font-size: calc(var(--font-size-standard) * 1.2); font-size: calc(var(--font-size-standard) * 1.2);

View File

@ -29,3 +29,4 @@ exports.default = gulp.series(
watchUpdates watchUpdates
); );
exports.css = css; exports.css = css;
exports.watchUpdates = watchUpdates;

View File

@ -250,7 +250,13 @@
"breakingPoint": "Breaking Point", "breakingPoint": "Breaking Point",
"willpower": "Willpower", "willpower": "Willpower",
"totalScore": "Total Score", "totalScore": "Total Score",
"exhausted": "Exhausted" "exhausted": "Exhausted",
"skillRoll": "Skill Roll",
"finalScore": "Final Score",
"failure": "Failure",
"success": "Success",
"criticalSuccess": "Critical Success",
"criticalFailure": "Critical Failure"
}, },
"Edit": "Edit", "Edit": "Edit",
"Delete": "Delete", "Delete": "Delete",

View File

@ -5,7 +5,7 @@ export default class CthulhuEternalProtagonistSheet extends CthulhuEternalActorS
static DEFAULT_OPTIONS = { static DEFAULT_OPTIONS = {
classes: ["protagonist"], classes: ["protagonist"],
position: { position: {
width: 820, width: 840,
height: 620, height: 620,
}, },
window: { window: {

View File

@ -34,14 +34,6 @@ export default class CthulhuEternalRoll extends Roll {
return this.options.actorImage return this.options.actorImage
} }
get introText() {
return this.options.introText
}
get introTextTooltip() {
return this.options.introTextTooltip
}
get help() { get help() {
return this.options.help return this.options.help
} }
@ -82,37 +74,6 @@ export default class CthulhuEternalRoll extends Roll {
return this.options.realDamage return this.options.realDamage
} }
/**
* Generates introductory text based on the roll type.
*
* @returns {string} The formatted introductory text for the roll.
*/
_createIntroText() {
let text
switch (this.type) {
case "skill":
const skillLabel = game.i18n.localize(`CTHULHUETERNAL.Character.FIELDS.caracteristiques.${this.target}.valeur.label`)
text = game.i18n.format("CTHULHUETERNAL.Roll.skill", { skill: "skill" })
text = text.concat("<br>").concat(`Seuil : ${this.treshold}`)
break
}
return text
}
/**
* Generates an introductory text tooltip with characteristics and modifiers.
*
* @returns {string} A formatted string containing the value, help, hindrance, and modifier.
*/
_createIntroTextTooltip() {
let tooltip = game.i18n.format("CTHULHUETERNAL.Tooltip.saveIntroTextTooltip", { value: this.value, help: this.help, gene: this.gene, modifier: this.modifier })
if (this.hasTarget) {
tooltip = tooltip.concat(`<br>Target : ${this.targetName}`)
}
return tooltip
}
/** /**
* Prompt the user with a dialog to configure and execute a roll. * Prompt the user with a dialog to configure and execute a roll.
* *
@ -132,13 +93,13 @@ export default class CthulhuEternalRoll extends Roll {
switch (options.rollType) { switch (options.rollType) {
case "skill": case "skill":
console.log(options.rollItem) console.log(options.rollItem)
options.targetScore = options.rollItem.system.computeScore() options.initialScore = options.rollItem.system.computeScore()
break break
case "characteristic": case "characteristic":
options.targetScore = options.rollItem.value * 5 options.initialScore = options.rollItem.value * 5
break break
default: default:
options.targetScore = 50 options.initialScore = 50
break break
} }
@ -167,7 +128,8 @@ export default class CthulhuEternalRoll extends Roll {
let dialogContext = { let dialogContext = {
rollType: options.rollType, rollType: options.rollType,
rollItem: foundry.utils.duplicate(options.rollItem), // Object only, no class rollItem: foundry.utils.duplicate(options.rollItem), // Object only, no class
targetScore: options.targetScore, initialScore: options.initialScore,
targetScore: options.initialScore,
rollModes, rollModes,
fieldRollMode, fieldRollMode,
choiceModifier, choiceModifier,
@ -213,6 +175,7 @@ export default class CthulhuEternalRoll extends Roll {
actorImage: options.actorImage, actorImage: options.actorImage,
rollMode: rollContext.visibility, rollMode: rollContext.visibility,
hasTarget: options.hasTarget, hasTarget: options.hasTarget,
initialScore: options.initialScore,
targetName, targetName,
targetArmor, targetArmor,
targetMalus, targetMalus,
@ -220,7 +183,7 @@ export default class CthulhuEternalRoll extends Roll {
} }
// Update target score // Update target score
rollData.targetScore = options.targetScore + Number(rollData.modifier) rollData.targetScore = Math.min( Math.max(options.initialScore + Number(rollData.modifier), 0), 100)
/** /**
* A hook event that fires before the roll is made. * A hook event that fires before the roll is made.
@ -230,14 +193,27 @@ export default class CthulhuEternalRoll extends Roll {
const roll = new this(formula, options.data, rollData) const roll = new this(formula, options.data, rollData)
await roll.evaluate() await roll.evaluate()
let resultType = "failure" // Compute the result quality
let resultType = "failure"
let dec = Math.floor(roll.total/10)
let unit = roll.total - (dec*10)
if (roll.total <= rollData.targetScore) { if (roll.total <= rollData.targetScore) {
resultType = "success" resultType = "success"
// Detect if decimal == unit in the dire total result
if (dec === unit || roll.total == 1) {
resultType = "successCritical"
}
} else {
// Detect if decimal == unit in the dire total result
if (dec === unit || roll.total == 100) {
resultType = "failureCritical"
}
} }
roll.options.resultType = resultType roll.options.resultType = resultType
roll.options.introText = roll._createIntroText() roll.options.isSuccess = resultType === "success" || resultType === "successCritical"
roll.options.introTextTooltip = roll._createIntroTextTooltip() roll.options.isFailure = resultType === "failure" || resultType === "failureCritical"
roll.options.isCritical = resultType === "successCritical" || resultType === "failureCritical"
/** /**
* A hook event that fires after the roll has been made. * A hook event that fires after the roll has been made.
@ -284,8 +260,6 @@ export default class CthulhuEternalRoll extends Roll {
* @property {string} actorId - The ID of the actor performing the roll. * @property {string} actorId - The ID of the actor performing the roll.
* @property {string} actingCharName - The name of the character performing the roll. * @property {string} actingCharName - The name of the character performing the roll.
* @property {string} actingCharImg - The image of the character performing the roll. * @property {string} actingCharImg - The image of the character performing the roll.
* @property {string} introText - Introductory text for the roll.
* @property {string} introTextTooltip - Tooltip for the introductory text.
* @property {string} resultType - The type of result (e.g., success, failure). * @property {string} resultType - The type of result (e.g., success, failure).
* @property {boolean} hasTarget - Indicates if the roll has a target. * @property {boolean} hasTarget - Indicates if the roll has a target.
* @property {string} targetName - The name of the target. * @property {string} targetName - The name of the target.
@ -302,16 +276,18 @@ export default class CthulhuEternalRoll extends Roll {
diceTotal: this.dice.reduce((t, d) => t + d.total, 0), diceTotal: this.dice.reduce((t, d) => t + d.total, 0),
isGM: game.user.isGM, isGM: game.user.isGM,
rollItem: this.options.rollItem, rollItem: this.options.rollItem,
initialScore: this.options.initialScore,
targetScore: this.options.targetScore, targetScore: this.options.targetScore,
rollType: this.options.rollType, rollType: this.options.rollType,
modifier: this.options.modifier,
formula: this.formula, formula: this.formula,
total: this.total, total: this.total,
isFailure: this.isFailure, isSuccess: this.options.isSuccess,
isFailure: this.options.isFailure,
isCritical: this.options.isCritical,
actorId: this.actorId, actorId: this.actorId,
actingCharName: this.actorName, actingCharName: this.actorName,
actingCharImg: this.actorImage, actingCharImg: this.actorImage,
introText: this.introText,
introTextTooltip: this.introTextTooltip,
resultType: this.resultType, resultType: this.resultType,
hasTarget: this.hasTarget, hasTarget: this.hasTarget,
targetName: this.targetName, targetName: this.targetName,
@ -338,8 +314,6 @@ export default class CthulhuEternalRoll extends Roll {
super.toMessage( super.toMessage(
{ {
isFailure: this.resultType === "failure", isFailure: this.resultType === "failure",
introText: this.introText,
introTextTooltip: this.introTextTooltip,
actingCharName: this.actorName, actingCharName: this.actorName,
actingCharImg: this.actorImage, actingCharImg: this.actorImage,
hasTarget: this.hasTarget, hasTarget: this.hasTarget,

View File

@ -3,6 +3,11 @@
src: url("../assets/fonts/georama.woff2") format("woff2"); src: url("../assets/fonts/georama.woff2") format("woff2");
} }
@font-face {
font-family: "Broadway";
src: url("../assets/fonts/broadway.woff2") format("woff2");
}
@font-face { @font-face {
font-family: "Caslon"; font-family: "Caslon";
src: url("../fonts/caslonpro-regular.otf") format("truetype"); src: url("../fonts/caslonpro-regular.otf") format("truetype");

View File

@ -1,3 +1,4 @@
@import "fonts.less";
@import "global.less"; @import "global.less";
.fvtt-cthulhu-eternal { .fvtt-cthulhu-eternal {

View File

@ -5,7 +5,12 @@
/*--background-image-base: url("../assets/ui/jazzage_background_main.webp");*/ /*--background-image-base: url("../assets/ui/jazzage_background_main.webp");*/
--font-primary: "Georama"; --font-primary: "Georama";
--font-secondary: "Georama"; --font-secondary: "Georama";
--font-title: "Broadway";
--logo-standard: url("../assets/logos/reanimated-ce-logo.webp"); --logo-standard: url("../assets/logos/reanimated-ce-logo.webp");
--color-success: darkgreen;
--color-failure: darkred;
--color-critical-success: lightgreen;
--color-critical-failure: lightcoral;
} }
.era-icon-color { .era-icon-color {
@ -57,6 +62,7 @@ i.fvtt-cthulhu-eternal {
.chat-message.whisper { .chat-message.whisper {
font-family: var(--font-primary); font-family: var(--font-primary);
background-image: var(--background-image-base); background-image: var(--background-image-base);
background-repeat: no-repeat; background-repeat:repeat-y;
background-position: 0%;
background-size: 100% 100%; background-size: 100% 100%;
} }

View File

@ -62,6 +62,8 @@
.protagonist-name { .protagonist-name {
display: flex; display: flex;
input { input {
font-family: var(--font-title);
font-size: calc(var(--font-size-standard) * 1.4);
width: 400px; width: 400px;
} }
} }

View File

@ -75,6 +75,38 @@
.intro-right { .intro-right {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
ul {
list-style-type: none;
padding: 0;
margin: 0;
justify-content: center;
align-items: center;
li {
margin: 0 10px;
font-family: var(--font-primary);
font-size: calc(var(--font-size-standard) * 1.0);
}
.result-success {
color: var(--color-success);
font-family: var(--font-title);
font-size: calc(var(--font-size-standard) * 1.2);
}
.result-critical-success {
color: var(--color-critical-success);
font-family: var(--font-title);
font-size: calc(var(--font-size-standard) * 1.2);
}
.result-failure {
color: var(--color-failure);
font-family: var(--font-title);
font-size: calc(var(--font-size-standard) * 1.2);
}
.result-critical-failure {
color: var(--color-critical-failure);
font-family: var(--font-title);
font-size: calc(var(--font-size-standard) * 1.2);
}
}
.introText { .introText {
font-family: var(--font-secondary); font-family: var(--font-secondary);
font-size: calc(var(--font-size-standard) * 1.2); font-size: calc(var(--font-size-standard) * 1.2);

View File

@ -4,19 +4,34 @@
<div class="intro-img"> <div class="intro-img">
<img src="{{actingCharImg}}" data-tooltip="{{actingCharName}}" /> <img src="{{actingCharImg}}" data-tooltip="{{actingCharName}}" />
</div> </div>
<div class="intro-right"> <div class="intro-right">
<p class="introText" {{#if isSave}}data-tooltip="{{introTextTooltip}}"{{/if}}>{{{introText}}} <ul>
{{#if (eq rollType "skill")}} {{#if (eq rollType "skill")}}
<span>{{rollItem.name}} : {{targetScore}}</span> <li><strong>{{localize "CTHULHUETERNAL.Label.skillRoll"}} {{rollItem.name}} : {{initialScore}}</strong></li>
<span>Modifier : {{modifier}}</span> <li>{{localize "CTHULHUETERNAL.Label.modifier"}} : {{modifier}}</li>
{{/if}} <li>{{localize "CTHULHUETERNAL.Label.finalScore"}} : {{targetScore}}</li>
</p> {{/if}}
{{#if isSuccess}}
{{#if isCritical}}
<li class="result-critical-success">{{localize "CTHULHUETERNAL.Label.criticalSuccess"}}</li>
{{else}}
<li class="result-success">{{localize "CTHULHUETERNAL.Label.success"}}</li>
{{/if}}
{{/if}}
{{#if isFailure}}
{{#if isCritical}}
<li class="result-critical-failure">{{localize "CTHULHUETERNAL.Label.criticalFailure"}}</li>
{{else}}
<li class="result-failure">{{localize "CTHULHUETERNAL.Label.failure"}}</li>
{{/if}}
{{/if}}
</ul>
</div> </div>
</div> </div>
{{#if isDamage}} {{#if isDamage}}
<div> <div>
{{#if (and isGM hasTarget)}} {{#if (and isGM hasTarget)}}
{{{localize "TENEBRIS.Roll.displayArmor" targetName=targetName targetArmor=targetArmor realDamage=realDamage}}} {{{localize "CTHULHUETERNAL.Roll.displayArmor" targetName=targetName targetArmor=targetArmor realDamage=realDamage}}}
{{/if}} {{/if}}
</div> </div>
{{/if}} {{/if}}

View File

@ -3,7 +3,7 @@
{{#if (eq rollType "skill")}} {{#if (eq rollType "skill")}}
<fieldSet> <fieldSet>
<legend>{{localize "CTHULHUETERNAL.Label.skill"}}</legend> <legend>{{localize "CTHULHUETERNAL.Label.skill"}}</legend>
<div class="dialog-skill">{{rollItem.name}} : {{targetScore}}</div> <div class="dialog-skill">{{rollItem.name}} : {{initialScore}}</div>
</fieldSet> </fieldSet>
<fieldSet class="dialog-modifier"> <fieldSet class="dialog-modifier">
<legend>{{localize "CTHULHUETERNAL.Label.modifier"}}</legend> <legend>{{localize "CTHULHUETERNAL.Label.modifier"}}</legend>