feature/rollable-character-talents (#38)
Pull Request Check / testing (pull_request) Successful in 17s Details

Hinterlegt bei den Talenten nun die Würfel mechanik. Fügt bei dieser auch hinzu, dass die Schwelle zum Patzer (Tollpatsch,...) reduziert werden könne, sodass Patzerschwelle, Meisterliche schwelle in anzahl und Wert angepasst werden kann.

Basistalente werden nun beim anlegen des Actors hinzugefügt, diese müssen entsprechend bereits aus dem Kompendium importiert sein.

**Das muss aber besser und automatischer gehen können.**

Co-authored-by: macniel <yuna.baehr@proton.me>
Reviewed-on: #38
pull/37/head
macniel 2025-09-28 12:19:21 +02:00
parent 531bb4ae39
commit 109682b415
6 changed files with 131 additions and 15 deletions

View File

@ -43,7 +43,8 @@ export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel {
so: new NumberField({ required: true, integer: true }),
gilde: new StringField(),
}),
talente: new ArrayField ( new ForeignDocumentField(Item) ),
talente: new ArrayField ( new SchemaField(
{taw: new NumberField(), talent: new ForeignDocumentField(Item) })),
zauber: new ArrayField ( new ForeignDocumentField(Item) ),
}
}
@ -52,4 +53,49 @@ export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel {
super._initialize(options);
}
_onCreate(data, options, userId) {
// prepare base talents
const talentsByName = [
"Athletik", "Klettern", "Körperbeherrschung", "Schleichen", "Schwimmen", "Selbstbeherrschung", "Sich Verstecken", "Singen", "Sinnenschärfe", "Tanzen", "Zechen",
"Menschenkenntnis", "Überreden",
"Fährtensuchen", "Orientierung", "Wildnisleben",
"Götter/Kulte", "Rechnen", "Sagen/Legenden",
"Heilkunde: Wunden", "Holzbearbeitung", "Kochen", "Lederverarbeitung", "Malen/Zeichnen", "Schneidern"
]
const talente = []
talentsByName.forEach( talentName => {
const talent = game.items.getName(talentName);
console.log(talent);
if (talent) {
talente.push({
taw: 0,
talent
})
} else {
console.error(`${talentName} not found in items`)
}
})
// push base talents
game.actors.getName(data.name).update({system: {talente}})
const startEigenschaften = {
"mu": 10,
"kl": 10,
"in": 10,
"ch": 10,
"ff": 10,
"ge": 10,
"ko": 10,
"kk": 10,
}
game.actors.getName(data.name).update({system: {attribute: startEigenschaften}})
super._onCreate(data, options, userId);
}
}

View File

@ -1,6 +1,5 @@
import { BaseItem } from "./base-item.mjs";
export class Skill extends BaseItem {
export class Skill extends Item {
/**
* Augment the basic Item data model with additional dynamic data.
*/

View File

@ -1,6 +1,4 @@
import { BaseItem } from "./base-item.mjs";
export class Spell extends BaseItem {
export class Spell extends Item {
/**
* Augment the basic Item data model with additional dynamic data.
*/

View File

@ -80,11 +80,17 @@ export class CharacterSheet extends ActorSheet {
context.skills = [];
if ( context.system.talente?.length >= 0) {
context.system.talente.forEach(talent => {
const tempTalent = talent();
console.log(tempTalent.system.probe);
console.log(talent);
const taw = talent.taw;
const talentObjekt = game.items.get(talent.talent);
const eigenschaften = Object.values(talentObjekt.system.probe);
context.skills.push({
talentName: tempTalent.name,
probe: `ROLLDATA(${Object.values(tempTalent.system.probe).join("/")})`
talentName: talentObjekt.name,
taw: taw,
rollEigenschaft1: this.prepareEigenschaftRoll(actorData, eigenschaften[0]),
rollEigenschaft2: this.prepareEigenschaftRoll(actorData, eigenschaften[1]),
rollEigenschaft3: this.prepareEigenschaftRoll(actorData, eigenschaften[2]),
probe: `(${eigenschaften.join("/")})`
});
})
@ -94,13 +100,74 @@ export class CharacterSheet extends ActorSheet {
return context;
}
_onRoll(event) {
prepareEigenschaftRoll(actorData, name) {
return actorData.system.attribute[name.toLowerCase()]
}
async _onTalentRoll(event) {
event.preventDefault();
const dataset = event.currentTarget.dataset;
console.log(dataset)
if (dataset.rolleigenschaft1) {
let roll1 = new Roll("3d20", this.actor.getRollData());
let evaluated1 = (await roll1.evaluate())
const dsaDieRollEvaluated = this._evaluateRoll(evaluated1.terms[0].results, {
taw: dataset.taw,
werte: [dataset.rolleigenschaft1, dataset.rolleigenschaft2, dataset.rolleigenschaft3],
})
if (dsaDieRollEvaluated.tap >= 0) { // erfolg
evaluated1.toMessage({
speaker: ChatMessage.getSpeaker({actor: this.actor}),
flavor: ` ${dsaDieRollEvaluated.meisterlich?'Meisterlich geschafft':'Geschafft'} mit ${dsaDieRollEvaluated.tap} Punkten übrig`,
rollMode: game.settings.get('core', 'rollMode'),
})
} else { // misserfolg
evaluated1.toMessage({
speaker: ChatMessage.getSpeaker({actor: this.actor}),
flavor: ` ${dsaDieRollEvaluated.meisterlich?'Gepatzt':''} mit ${Math.abs(dsaDieRollEvaluated.tap)} Punkten daneben`,
rollMode: game.settings.get('core', 'rollMode'),
})
}
}
}
_evaluateRoll(rolledDice, { taw, lowerThreshold = 1, upperThreshold = 20, countToMeisterlich = 3, countToPatzer = 3, werte = [] } ) {
let tap = taw;
let meisterlichCounter = 0;
let patzerCounter = 0;
let failCounter = 0;
rolledDice.forEach( (rolledDie, index) => {
if (tap < 0 && rolledDie.result > werte[index]) {
tap -= rolledDie.result - werte[index];
if (tap <0) { // konnte nicht vollständig ausgeglichen werden
failCounter++;
}
} else if (rolledDie.result > werte[index]) { // taw ist bereits aufgebraucht und wert kann nicht ausgeglichen werden
tap -= rolledDie.result - werte[index];
failCounter++;
}
if (rolledDie.result <= lowerThreshold) meisterlichCounter++;
if (rolledDie.result > upperThreshold) patzerCounter++;
})
return {
tap,
meisterlich: meisterlichCounter === countToMeisterlich,
patzer: patzerCounter === countToPatzer,
}
}
_onAttributeRoll(event) {
event.preventDefault();
const dataset = event.currentTarget.dataset;
if (dataset.roll) {
let label = dataset.label ? `[Attribut] ${dataset.label}` : '';
console.log(this.actor.getRollData());
let roll = new Roll(dataset.roll, this.actor.getRollData());
roll.toMessage({
speaker: ChatMessage.getSpeaker({ actor: this.actor }),
@ -116,7 +183,12 @@ export class CharacterSheet extends ActorSheet {
html.on('click', '.attribut.rollable', (evt) => {
console.log(evt);
this._onRoll(evt);
this._onAttributeRoll(evt);
});
html.on('click', '.talent.rollable', (evt) => {
console.log(evt);
this._onTalentRoll(evt);
});
// Everything below here is only needed if the sheet is editable

View File

@ -2,7 +2,7 @@
"_id": "o1nYjhmMP0Zzlcw6",
"_key": "!items!o1nYjhmMP0Zzlcw6",
"type": "Skill",
"name": "Sich verstecken",
"name": "Sich Verstecken",
"system": {
"gruppe": "Körperlich",
"probe": [

View File

@ -46,9 +46,10 @@
<div class="tab skills" data-group="primary" data-tab="skills">
<ul>
{{#each skills}}
<li><div class="talent rollable" data-roll="1d20cs<=@{{this.p1}}">
<li><div class="talent rollable" data-taw="{{this.taw}}" data-rollEigenschaft1="{{this.rollEigenschaft1}}" data-rollEigenschaft2="{{this.rollEigenschaft2}}" data-rollEigenschaft3="{{this.rollEigenschaft3}}">
<b>{{this.talentName}}</b>
{{this.probe}}
TAW: {{this.taw}}
</div></li>
{{/each}}
</ul>