Adds Rollable Talents

pull/38/head
macniel 2025-09-28 11:50:07 +02:00
parent 531bb4ae39
commit e6525cc943
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>