initial draft of spells

pull/53/head
macniel 2025-10-05 15:59:45 +02:00
parent 651029f751
commit ff9e59078f
7 changed files with 173 additions and 27 deletions

View File

@ -7,9 +7,11 @@ export class SpellDataModel extends BaseItem {
static defineSchema() {
return {
seite: new NumberField(),
zfw: new NumberField(),
name: new StringField({required: true}),
probe: new ArrayField(new StringField(), {required: true, exact: 3}),
probeMod: new StringField(),
hauszauber: new BooleanField(),
technik: new StringField(),
zauberdauer: new StringField(),
wirkung: new StringField(),

View File

@ -41,6 +41,7 @@ export class CharacterSheet extends ActorSheet {
this.#addEquipmentsToContext(context)
await this.#addCombatStatistics(context)
this.#addActionsToContext(context)
this.#addSpellsToContext(context)
return context;
}
@ -96,6 +97,38 @@ export class CharacterSheet extends ActorSheet {
);
}
#cleanUpMerkmal(merkmale) {
return merkmale.split(",").map((merkmal) => merkmal.trim())
}
#addSpellsToContext(context) {
const actorData = context.data;
context.spells = [];
Object.values(actorData.items).forEach((item, index) => {
if (item.type === "Spell") {
const eigenschaften = item.system.probe;
const werte = [
{name: eigenschaften[0], value: this.prepareEigenschaftRoll(actorData, eigenschaften[0])},
{name: eigenschaften[1], value: this.prepareEigenschaftRoll(actorData, eigenschaften[1])},
{name: eigenschaften[2], value: this.prepareEigenschaftRoll(actorData, eigenschaften[2])}
]
context.spells.push({
id: item._id,
name: item.name,
zfw: item.system.zfw,
hauszauber: item.system.hauszauber,
merkmal: this.#cleanUpMerkmal(item.system.merkmal),
rollEigenschaft1: werte[0].value,
rollEigenschaft2: werte[1].value,
rollEigenschaft3: werte[2].value,
eigenschaft1: werte[0].name,
eigenschaft2: werte[1].name,
eigenschaft3: werte[2].name,
})
}
})
}
#addAttributesToContext(context) {
const actorData = context.data;
context.attributes = [
@ -267,7 +300,7 @@ export class CharacterSheet extends ActorSheet {
}
prepareEigenschaftRoll(actorData, name) {
if (name) {
if (name && name !== "*") {
return actorData.system.attribute[name.toLowerCase()].aktuell
} else {
return 0
@ -555,21 +588,32 @@ export class CharacterSheet extends ActorSheet {
this._onRoll(evt);
});
// TODO: merge into click.clickable handler
html.on('click', '.talent .name', (evt) => {
this.openEmbeddedDocument(evt.target.dataset.id);
evt.stopPropagation();
})
// TODO: merge into click.clickable handler
html.on('click', '.advantage .name', (evt) => {
this.openEmbeddedDocument(evt.target.dataset.id);
evt.stopPropagation();
})
// TODO: merge into click.clickable handler
html.on('click', '.equipment', (evt) => {
this.openEmbeddedDocument(evt.target.parentElement.dataset.id);
evt.stopPropagation();
})
html.on('click', '.clickable', async (evt) => {
const {id, operation} = evt.currentTarget.dataset;
if (operation === "openActorSheet") {
this.openEmbeddedDocument(id);
evt.stopPropagation();
}
})
html.on('dragstart', '.equipment', (evt) => {
evt.originalEvent.dataTransfer.setData("application/json", JSON.stringify({
documentId: evt.currentTarget.dataset.id

View File

@ -102,6 +102,23 @@ async function addAdvantageFromCompendiumByNameToActor(advantageName, advantageV
}
}
async function addSpellsFromCompendiumByNameToActor(spellName, zfw, representation, hauszauber, actor) {
const compendiumOfSpells = game.packs.get('DSA_4-1.spells');
const SCREAMING_NAME = spellName.toUpperCase()
const spellId = compendiumOfSpells.index.find(spell => spell.name === SCREAMING_NAME)
if (spellId) {
const spell = await compendiumOfSpells.getDocument(spellId._id);
try {
const embeddedDocument = (await actor.createEmbeddedDocuments('Item', [spell]))[0]
embeddedDocument.update({system: {zfw: zfw, hauszauber: hauszauber, repräsentation: representation}});
} catch (error) {
console.error(`${spell} not found in items`, error)
}
}
}
/**
* gets the text content of a file
* @param file the file with the desired content
@ -147,6 +164,13 @@ function mapAdvantages(actor, held) {
}
}
function mapSpells(actor, held) {
for (let spell in held.zauberliste.zauber) {
spell = held.zauberliste.zauber[spell]
addSpellsFromCompendiumByNameToActor(spell.name, spell.value, spell.repraesentation, spell.hauszauber === "true", actor)
}
}
/**
* parses a json into a fitting character-json
* @param rawJson the json parsed from the Helden-Software XML
@ -266,19 +290,7 @@ function mapRawJson(actor, rawJson) {
json.liturgien = liturgies
mapSkills(actor, held)
let spells = []
/*for (let spell in held.zauberliste.zauber) {
spell = held.zauberliste.zauber[spell]
spells.push({
name: spell.name,
rep: spell.repraesentation,
hauszauber: spell.hauszauber === "true",
zfw: spell.value,
anmerkungen: spell.zauberkommentar,
komplexitaet: spell.k,
})
}*/
json.zauber = spells
mapSpells(actor, held)
let combatValues = []
for (let combatValue in held.kampf.kampfwerte) {
combatValue = held.kampf.kampfwerte[combatValue]

View File

@ -1,3 +1,8 @@
@use "sass:color";
@use "_numbers";
@use "_colours" as colour;
.dsa41.sheet.actor.character {
.window-header.flexrow.draggable.resizable {
@ -127,6 +132,58 @@
}
.tab.spells {
.spell.rollable svg {
width: 24px;
height: 24px;
.border {
fill: #0000;
}
$color: #05f;
.center {
fill: $color;
stroke: colour.$rollable-die-border-color;
}
.topleft {
fill: color.adjust($color, $lightness: numbers.$lighter_factor);
stroke: colour.$rollable-die-border-color;
}
.bottomleft {
fill: color.adjust($color, $lightness: numbers.$lightest_factor);
stroke: colour.$rollable-die-border-color;
}
.topright {
fill: color.adjust($color, $lightness: numbers.$darken_factor);
stroke: colour.$rollable-die-border-color;
}
.bottomright, .bottom {
fill: color.adjust($color, $lightness: numbers.$darkest_factor);
stroke: colour.$rollable-die-border-color;
}
}
.merkmal-list {
list-style: none;
margin: 0;
padding: 0;
text-indent: 0;
li {
display: inline-block;
padding: 0 4px;
}
}
}
}
}

View File

@ -109,34 +109,35 @@
svg {
stroke-width: 0.5;
$color: #f30;
.border {
fill: colour.$harm-fill-color;
stroke: colour.$harm-border-color;
fill: #0000;
}
.center {
fill: colour.$harm-fill-color;
stroke: colour.$harm-border-color;
fill: $color;
stroke: colour.$rollable-die-border-color;
}
.topleft {
fill: color.adjust(colour.$harm-fill-color, $lightness: numbers.$lighter_factor);
stroke: colour.$harm-border-color;
fill: color.adjust($color, $lightness: numbers.$lighter_factor);
stroke: colour.$rollable-die-border-color;
}
.bottomleft {
fill: color.adjust(colour.$harm-fill-color, $lightness: numbers.$lightest_factor);
stroke: colour.$harm-border-color;
fill: color.adjust($color, $lightness: numbers.$lightest_factor);
stroke: colour.$rollable-die-border-color;
}
.topright {
fill: color.adjust(colour.$harm-fill-color, $lightness: numbers.$darken_factor);
stroke: colour.$harm-border-color;
fill: color.adjust($color, $lightness: numbers.$darken_factor);
stroke: colour.$rollable-die-border-color;
}
.bottomright, .bottom {
fill: color.adjust(colour.$harm-fill-color, $lightness: numbers.$darkest_factor);
stroke: colour.$harm-border-color;
fill: color.adjust($color, $lightness: numbers.$darkest_factor);
stroke: colour.$rollable-die-border-color;
}
}

View File

@ -34,7 +34,7 @@
"private": false
},
{
"name": "Spell",
"name": "spells",
"label": "Basiszauber",
"system": "DSA_4-1",
"type": "Item",

View File

@ -255,6 +255,36 @@
</div>
<div class="tab spells" data-group="primary" data-tab="spells">
<table>
<thead>
<tr>
<th></th>
<th>Zaubername</th>
<th colspan="3">Probe</th>
<th>ZfW</th>
<th>Merkmale</th>
</tr>
</thead>
<tbody>
{{#each this.spells}}
<tr>
<td class="spell rollable">
{{> 'systems/DSA_4-1/templates/ui/partial-die.hbs' }}
</td>
<td class="clickable" data-id="{{this.id}}" data-operation="openActorSheet">{{this.name}}</td>
<td>{{this.eigenschaft1}}</td>
<td>{{this.eigenschaft2}}</td>
<td>{{this.eigenschaft3}}</td>
<td>{{this.zfw}}</td>
<td>
<ul class="merkmal-list">{{#each this.merkmal}}
<li>{{this}}</li>{{/each}}</ul>
</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
<div class="tab miracles" data-group="primary" data-tab="miracles">