implemented first version of attribute rolls including chat-messages

feature/attribute-rolls
Jendrik 2025-09-28 17:19:58 +02:00
parent 3ec419ae26
commit d84aec7ffa
7 changed files with 150 additions and 22 deletions

View File

@ -1,3 +1,5 @@
import {rollAttributeForActor} from "../utils/rolls/rollEngine.mjs";
export class CharacterSheet extends ActorSheet {
/**@override */
static get defaultOptions() {
@ -165,17 +167,10 @@ export class CharacterSheet extends ActorSheet {
_onAttributeRoll(event) {
event.preventDefault();
const dataset = event.currentTarget.dataset;
if (dataset.roll) {
let label = dataset.label ? `[Attribut] ${dataset.label}` : '';
let roll = new Roll(dataset.roll, this.actor.getRollData());
roll.toMessage({
speaker: ChatMessage.getSpeaker({ actor: this.actor }),
flavor: label,
rollMode: game.settings.get('core', 'rollMode'),
});
return roll;
}
let actor = this.actor
let dataset = event.currentTarget.dataset
let attribute = this.getData().attributes.find(item => item.eigenschaft === dataset.shortForm)
rollAttributeForActor(actor, attribute, "+0")
}
activateListeners(html) {

View File

@ -0,0 +1,63 @@
/**
* Rolls an attribute Check
* @param actor the actor that performs the roll
* @param attribute the attribute to check against
* @param modifier the modifier that is applied to the check in good old-fashioned DSA-Notation (+X for more difficulty, -X to make it easier)
* @param mode the mode as described in [foundry.CONFIG.Dice.rollModes]
*/
export async function rollAttributeForActor(actor, attribute, modifier, mode = foundry.CONFIG.Dice.rollModes.publicroll) {
let result = await rollDice("1d20", mode)
let resultRoll = result.results[0]
let success = attribute.wert >= resultRoll
let message = await foundry.applications.handlebars.renderTemplate("templates/chatMessage/attributeCheckMessage.hbs", {
attribute: {
name: attribute.name,
value: attribute.wert,
},
mod: modifier,
result: resultRoll,
success: success,
rest: attribute.wert - resultRoll,
})
let chatData = {
speaker: ChatMessage.getSpeaker({actor: actor}),
content: message
}
ChatMessage.create(chatData, {})
}
async function rollDice(check, mode = foundry.CONFIG.Dice.rollModes.publicroll) {
let roll = new Roll(check)
// This is used to roll via Dice so Nice without writing any specific code
// and to prevent the ugly total rolled section in the message from appearing
let message = await roll.toMessage({}, {rollMode: mode, create: true})
message.delete()
let results = []
for (let term in roll.terms) {
term = roll.terms[term]
for (let value in term.results) {
value = term.results[value]
results.push(value.result)
}
}
return new RollResult(
check,
results
)
}
/**
* Stores the check and the results for the check
* @param check the chack that has been rolled
* @param result the results for the check as an array
*/
class RollResult {
constructor(check, results) {
this.check = check;
this.results = results;
}
}

View File

@ -0,0 +1,55 @@
.attribute-check-message {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: auto auto auto 1fr;
div {
text-align: center;
align-content: center;
}
.headline {
grid-row: 1;
grid-column: 1;
}
.result {
grid-row: 2;
grid-column: 1;
background-color: rgb(255 255 255 / 35%);
padding: 10px 0;
.success {
color: #008800;
margin: 0;
}
.failure {
color: #880000;
margin: 0;
}
}
.result-message {
grid-row: 3;
grid-column: 1;
}
.roll-result {
grid-row: 4;
grid-column: 1;
display: grid;
grid-template-rows: 1fr;
grid-template-columns: auto 1fr auto;
.roll {
grid-row: 1;
grid-column: 1;
}
.attribute-value {
grid-row: 1;
grid-column: 3;
}
}
}

View File

@ -1,5 +1,7 @@
$bgcolor: FFF;
@use 'chat-messages';
html {
background-color: $bgcolor;
}

View File

@ -8,7 +8,7 @@
<h1 class="charname"><input name="name" type="text" value="{{actor.name}}" placeholder="Name"/></h1>
<div class="attribute">
{{#each attributes}}
<button class="attribut rollable" data-label="{{this.name}}" data-roll="1d20cs<=@{{this.eigenschaft}}">
<button class="attribut rollable" data-label="{{this.name}}" data-short-form="{{this.eigenschaft}}">
<span class="attribut-wert">
{{this.wert}}
</span>

View File

@ -0,0 +1,23 @@
<div class="attribute-check-message">
<div class="headline">
<h2>{{attribute.name}}-Probe ({{mod}})</h2>
</div>
<div class="result {{#if success}}success{{else}}failure{{/if}}">
{{#if success}}
<h2 class="success">Gelungen</h2>
{{else}}
<h2 class="failure">Misslungen</h2>
{{/if}}
</div>
<div class="result-message">
{{#if success}}
<span>Es sind noch {{rest}} Punkte übrig</span>
{{else}}
<span>Es fehlen {{rest}} Punkte</span>
{{/if}}
</div>
<div class="roll-result">
<div class="roll">{{result}}</div>
<div class="attribute-value">{{attribute.value}}</div>
</div>
</div>

View File

@ -1,10 +0,0 @@
<form class="flexcol" autocomplete="off">
<header class="sheet-header">
<div class="header-fields">
<h1 class="charname">{{actor.name}}</h1>
</div>
</header>
<section class="sheet-body">
<textarea readonly>{{formatCharacter actor}}</textarea>
</section>
</form>