finalises missing sidebutton tabs

pull/65/head
macniel 2025-11-16 11:41:35 +01:00
parent 46b6ed8f2a
commit 692867f2ac
9 changed files with 574 additions and 8 deletions

8
package-lock.json generated
View File

@ -12,7 +12,7 @@
"gulp-json-modify": "^1.0.2"
},
"devDependencies": {
"@foundryvtt/foundryvtt-cli": "^3.0.0",
"@foundryvtt/foundryvtt-cli": "^3.0.2",
"cb": "^0.1.1",
"del": "^8.0.1",
"fvtt-types": "npm:@league-of-foundry-developers/foundry-vtt-types@^13.346.0-beta.20250812191140",
@ -209,9 +209,9 @@
}
},
"node_modules/@foundryvtt/foundryvtt-cli": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@foundryvtt/foundryvtt-cli/-/foundryvtt-cli-3.0.0.tgz",
"integrity": "sha512-OiF4HtnYg5An1ivVxB68mOj5LO5gMHd4uHmC5nWdD8IYxpK0pSYw3t+cHrUYDp+Tic78uwFuHxLyc+ZNeZXulA==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@foundryvtt/foundryvtt-cli/-/foundryvtt-cli-3.0.2.tgz",
"integrity": "sha512-coh4Cf4FD/GHxk2QMsd+3wLMivNeih4rfkbZy8CaYjdlpo6iciFQwxLqznZWtn+5p06zekvS2xLUF55NnbXQDw==",
"dev": true,
"dependencies": {
"chalk": "^5.4.1",

View File

@ -14,7 +14,7 @@
"installToFoundry": "node installToFoundry.mjs"
},
"devDependencies": {
"@foundryvtt/foundryvtt-cli": "^3.0.0",
"@foundryvtt/foundryvtt-cli": "^3.0.2",
"cb": "^0.1.1",
"del": "^8.0.1",
"fvtt-types": "npm:@league-of-foundry-developers/foundry-vtt-types@^13.346.0-beta.20250812191140",

View File

@ -0,0 +1,152 @@
import {LiturgyData} from "../../data/miracle/liturgyData.mjs";
const {HandlebarsApplicationMixin, DocumentSheetV2} = foundry.applications.api
const {ActorSheetV2} = foundry.applications.sheets
export class StandaloneLiturgies extends HandlebarsApplicationMixin(ActorSheetV2) {
/** @inheritDoc */
static DEFAULT_OPTIONS = {
position: {width: 520, height: 480},
classes: ['dsa41', 'sheet', 'actor', 'character', 'standalone', 'liturgies'],
tag: 'form',
actions: {
openEmbeddedDocument: StandaloneLiturgies.#openEmbeddedDocument,
openLiturgyDialog: StandaloneLiturgies.#openLiturgyDialog,
}
}
/** @inheritDoc */
static PARTS = {
form: {
template: `systems/DSA_4-1/templates/actor/character/standalone/liturgies.hbs`
}
}
_actor = null
constructor(actor) {
super(actor)
this._actor = actor
this.render(true)
}
static async #openEmbeddedDocument(event, target) {
this._actor?.sheet.options.actions.openEmbeddedDocument.bind(this)(event, target)
}
static async #openLiturgyDialog(event, target) {
this._actor?.sheet.options.actions.openLiturgyDialog.bind(this)(event, target)
}
_configureRenderOptions(options) {
super._configureRenderOptions(options)
options.window.title = `${this.document.name}: Segnungen und Liturgien`
return options
}
async _prepareContext(context, options, object) {
const actorData = this.document
context.system = actorData.system
context.flags = actorData.flags
context.derived = this.document.system
context.originalName = actorData.name
context.name = context.derived.name ?? actorData.name
context.effects = actorData.effects ?? []
context.liturgies = [];
context.blessings = [];
actorData.itemTypes.Blessing.forEach((item, index) => {
context.blessings.push({
deity: item.system.gottheit,
value: item.system.wert
})
})
actorData.itemTypes.Liturgy.forEach((item, index) => {
context.blessings.forEach(({deity, value}) => {
let insertObject = context.liturgies.find(p => p.deity === deity);
if (!insertObject) {
insertObject = {
deity: deity,
lkp: value,
O: [],
I: [],
II: [],
III: [],
IV: [],
V: [],
VI: [],
VII: [],
VIII: [],
"NA": [],
countO: 1,
countI: 1,
countII: 1,
countIII: 1,
countIV: 1,
countV: 1,
countVI: 1,
countVII: 1,
countVIII: 1,
countNA: 0,
total: 3,
}
context.liturgies.push(insertObject);
}
// sort by rank
const rankData = LiturgyData.getRankOfLiturgy(item.system, deity)
if (rankData) {
console.log(rankData)
let {index, name, lkp, mod, costKaP} = rankData;
insertObject["count" + name] = insertObject["count" + name] + 1;
insertObject[name]?.push({
id: item._id,
name: item.name,
lkpReq: lkp,
lkpMod: mod,
costKaP,
fav: item.getFlag("DSA_4-1", "favourite"),
rank: index, // get effective liturgy rank based on deity
liturgiekenntnis: deity,
})
insertObject.total = insertObject.total + 2;
}
})
})
// clean up counter
Object.values(context.liturgies).forEach((litObject) => {
if (litObject.I.length === 0) litObject.countI = false;
if (litObject.II.length === 0) litObject.countII = false;
if (litObject.III.length === 0) litObject.countIII = false;
if (litObject.IV.length === 0) litObject.countIV = false;
if (litObject.V.length === 0) litObject.countV = false;
if (litObject.VI.length === 0) litObject.countVI = false;
if (litObject.VII.length === 0) litObject.countVII = false;
if (litObject.VIII.length === 0) litObject.countVIII = false;
if (litObject.NA.length === 0) litObject.countNA = false;
})
context.hasLiturgies = context.blessings.length > 0;
return context
}
_onRender(context, options) {
}
}

View File

@ -0,0 +1,98 @@
const {HandlebarsApplicationMixin, DocumentSheetV2} = foundry.applications.api
const {ActorSheetV2} = foundry.applications.sheets
export class StandaloneSpells extends HandlebarsApplicationMixin(ActorSheetV2) {
/** @inheritDoc */
static DEFAULT_OPTIONS = {
position: {width: 520, height: 480},
classes: ['dsa41', 'sheet', 'actor', 'character', 'standalone', 'spells'],
tag: 'form',
actions: {
openEmbeddedDocument: StandaloneSpells.#openEmbeddedDocument,
}
}
/** @inheritDoc */
static PARTS = {
form: {
template: `systems/DSA_4-1/templates/actor/character/standalone/spells.hbs`
}
}
_actor = null
constructor(actor) {
super(actor)
this._actor = actor
this.render(true)
}
static async #openEmbeddedDocument(event, target) {
this._actor?.sheet.options.actions.openEmbeddedDocument.bind(this)(event, target)
}
_configureRenderOptions(options) {
super._configureRenderOptions(options)
options.window.title = `${this.document.name}: Zauber und Rituale`
return options
}
async _prepareContext(context, options, object) {
const actorData = this.document
context.spells = []
context.system = actorData.system
context.flags = actorData.flags
context.derived = this.document.system
context.originalName = actorData.name
context.name = context.derived.name ?? actorData.name
context.effects = actorData.effects ?? []
const cleanUpMerkmal = (merkmale) => {
return merkmale.split(",").map((merkmal) => merkmal.trim())
}
const prepareEigenschaftRoll = (actorData, name) => {
if (name && name !== "*") {
return actorData.system.attribute[name.toLowerCase()].aktuell
} else {
return 0
}
}
actorData.itemTypes["Spell"].forEach((item, index) => {
const eigenschaften = item.system.probe;
const werte = [
{name: eigenschaften[0], value: prepareEigenschaftRoll(actorData, eigenschaften[0])},
{name: eigenschaften[1], value: prepareEigenschaftRoll(actorData, eigenschaften[1])},
{name: eigenschaften[2], value: prepareEigenschaftRoll(actorData, eigenschaften[2])}
]
context.spells.push({
id: item._id,
name: item.name,
zfw: item.system.zfw,
hauszauber: item.system.hauszauber,
merkmal: 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,
fav: item.getFlag("DSA_4-1", "favourite")
})
})
context.hasSpells = context.spells.length > 0
return context
}
_onRender(context, options) {
}
}

View File

@ -19,6 +19,8 @@ import * as EquipmentDocument from "../documents/equipment.mjs";
import {StandaloneADVSF} from "./character-standalone/advsf.mjs";
import {StandaloneSkills} from "./character-standalone/skills.mjs";
import {Bagpack} from "./character-standalone/bagpack.mjs";
import {StandaloneSpells} from "./character-standalone/spells.mjs";
import {StandaloneLiturgies} from "./character-standalone/liturgies.mjs";
const {HandlebarsApplicationMixin, DocumentSheetV2} = foundry.applications.api
const {ActorSheetV2} = foundry.applications.sheets
@ -62,7 +64,9 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
toggleFav: CharacterSheet.toggleFav,
openStandaloneADVSF: CharacterSheet.#openStandaloneADVSF,
openStandaloneSkills: CharacterSheet.#openStandaloneSkills,
openBagpack: CharacterSheet.#openBagpack
openBagpack: CharacterSheet.#openBagpack,
openStandaloneSpells: CharacterSheet.#openStandaloneSpells,
openStandaloneLiturgies: CharacterSheet.#openStandaloneLiturgies,
}
}

View File

@ -87,4 +87,61 @@
padding: 0 4px;
}
}
}
.mini-spells {
height: 100%;
display: flex;
flex-direction: column;
.table-header {
display: grid;
grid-template-columns: 1fr 100px 30px;
padding: 0 8px;
font-weight: bold;
}
.scrollable-table {
overflow-x: hidden;
overflow-y: auto;
thead {
display: none;
}
tr {
td:nth-child(1) {
width: 32px;
}
td:nth-child(3) {
width: 100px;
}
td:nth-child(4) {
width: 30px;
}
.spell.rollable {
position: relative;
svg {
position: absolute;
width: 32px;
height: 32px;
z-index: 2;
top: 0;
left: -4px;
path {
fill: colour.$zauber-color;
}
}
}
}
}
}

View File

@ -135,9 +135,9 @@
<button data-action="openStandaloneSkills">Talente</button>
<button data-action="openBagpack">Inventar</button>
{{#if this.hasLiturgies}}
<button data-action="openLiturgies">Liturgien</button>{{/if}}
<button data-action="openStandaloneLiturgies">Liturgien</button>{{/if}}
{{#if this.hasSpells}}
<button data-action="openSpells">Zauber</button>{{/if}}
<button data-action="openStandaloneSpells">Zauber</button>{{/if}}
</div>
</div>

View File

@ -0,0 +1,204 @@
<div class="mini-liturgies">
<div class="tab-resources">
<div class="karmapoints">
<label>KaP:</label>
<input type="number" name="system.kap.aktuell" value="{{system.kap.aktuell}}"/>
<span class="inline">von</span>
<input type="number" disabled value="{{derived.kap.max}}"/>
</div>
</div>
<div class="scroll-y">
{{#each this.liturgies}}
<table class="{{this.deity}}">
<thead class="liturgy-header">
<tr class="liturgy-header">
<th style="width: 0"></th>
<th class="banner-top" style="width: 90px"><img
src="systems/DSA_4-1/assets/deities/{{this.deity}}.png"/></th>
<th class="lkp" colspan="2">Liturgiekenntnis: {{this.lkp}}</th>
</tr>
</thead>
<tbody>
<tr>
<th rowspan="{{this.total}}" class="background"></th>
<th class="banner-mid" rowspan="{{countO}}">
<div>
<div class="rank-label">{{#if this.count0}}0{{/if}}</div>
</div>
</th>
</tr>
{{#each this.O}}
<tr>
<td class="liturgy rollable" data-action="openLiturgyDialog" data-id="{{this.id}}"
data-rank="{{this.rank}}"
data-lkp="{{../lkp}}" data-deity="{{../deity}}">
{{> 'systems/DSA_4-1/templates/ui/partial-die.hbs' }}
</td>
<td class="clickable" data-id="{{this.id}}" data-action="openEmbeddedDocument">
{{this.name}}</td>
<td></td>
</tr>
{{/each}}
{{#if this.countI}}
<tr>
<th class="banner-mid" rowspan="{{countI}}">
<div>
<div class="rank-label">{{#if this.countI}}I{{/if}}</div>
</div>
</th>
</tr>
{{#each this.I}}
<tr>
<td class="liturgy rollable" data-action="openLiturgyDialog" data-id="{{this.id}}"
data-rank="{{this.rank}}"
data-lkp="{{../lkp}}" data-deity="{{../deity}}">
{{> 'systems/DSA_4-1/templates/ui/partial-die.hbs' }}
</td>
<td class="clickable" data-id="{{this.id}}" data-action="openEmbeddedDocument">
{{this.name}}</td>
<td></td>
</tr>
{{/each}}
{{/if}}
{{#if this.countII}}
<tr>
<th class="banner-mid" rowspan="{{countII}}">
<div>
<div class="rank-label">{{#if this.countII}}II{{/if}}</div>
</div>
</th>
</tr>
{{#each this.II}}
<tr>
<td class="liturgy rollable" data-action="openLiturgyDialog" data-id="{{this.id}}"
data-rank="{{this.rank}}"
data-lkp="{{../lkp}}" data-deity="{{../deity}}">
{{> 'systems/DSA_4-1/templates/ui/partial-die.hbs' }}
</td>
<td class="clickable" data-id="{{this.id}}"
data-action="openEmbeddedDocument">{{this.name}}</td>
</tr>
{{/each}}
{{/if}}
{{#if this.countIII}}
<tr>
<th class="banner-mid" rowspan="{{countIII}}">
<div>
<div class="rank-label">{{#if this.countIII}}III{{/if}}</div>
</div>
</th>
</tr>
{{#each this.III}}
<tr>
<td class="liturgy rollable" data-action="openLiturgyDialog" data-id="{{this.id}}"
data-rank="{{this.rank}}"
data-lkp="{{../lkp}}" data-deity="{{../deity}}">
{{> 'systems/DSA_4-1/templates/ui/partial-die.hbs' }}
</td>
<td class="clickable" data-id="{{this.id}}"
data-action="openEmbeddedDocument">{{this.name}}</td>
</tr>
{{/each}}
{{/if}}
{{#if this.countIV}}
<tr>
<th class="banner-mid" rowspan="{{countIV}}">
<div>
<div class="rank-label">{{#if this.countIV}}IV{{/if}}</div>
</div>
</th>
</tr>
{{#each this.IV}}
<tr>
<td class="liturgy rollable" data-action="openLiturgyDialog" data-id="{{this.id}}"
data-rank="{{this.rank}}"
data-lkp="{{../lkp}}" data-deity="{{../deity}}">
{{> 'systems/DSA_4-1/templates/ui/partial-die.hbs' }}
</td>
<td class="clickable" data-id="{{this.id}}"
data-action="openEmbeddedDocument">{{this.name}}</td>
</tr>
{{/each}}{{/if}}
{{#if this.countV}}
<tr>
<th class="banner-mid" rowspan="{{countV}}">
<div>
<div class="rank-label">{{#if this.countV}}V{{/if}}</div>
</div>
</th>
</tr>
{{#each this.V}}
<tr>
<td class="liturgy rollable" data-action="openLiturgyDialog" data-id="{{this.id}}"
data-rank="{{this.rank}}"
data-lkp="{{../lkp}}" data-deity="{{../deity}}">
{{> 'systems/DSA_4-1/templates/ui/partial-die.hbs' }}
</td>
<td class="clickable" data-id="{{this.id}}"
data-action="openEmbeddedDocument">{{this.name}}</td>
</tr>
{{/each}}
{{/if}}
{{#if this.countVI}}
<tr>
<th class="banner-mid" rowspan="{{countVI}}">
<div>
<div class="rank-label">{{#if this.countVI}}VI{{/if}}</div>
</div>
</th>
</tr>
{{#each this.VI}}
<tr>
<td class="liturgy rollable" data-action="openLiturgyDialog" data-id="{{this.id}}"
data-rank="{{this.rank}}"
data-lkp="{{../lkp}}" data-deity="{{../deity}}">
{{> 'systems/DSA_4-1/templates/ui/partial-die.hbs' }}
</td>
<td class="clickable" data-id="{{this.id}}"
data-action="openEmbeddedDocument">{{this.name}}</td>
</tr>
{{/each}}
{{/if}}{{#if this.countVII}}
<tr>
<th class="banner-mid" rowspan="{{countVII}}">
<div>
<div class="rank-label">{{#if this.countVII}}VII{{/if}}</div>
</div>
</th>
</tr>
{{#each this.VII}}
<tr>
<td class="liturgy rollable" data-action="openLiturgyDialog" data-id="{{this.id}}"
data-rank="{{this.rank}}"
data-lkp="{{../lkp}}" data-deity="{{../deity}}">
{{> 'systems/DSA_4-1/templates/ui/partial-die.hbs' }}
</td>
<td class="clickable" data-id="{{this.id}}"
data-action="openEmbeddedDocument">{{this.name}}</td>
</tr>
{{/each}}
{{/if}}{{#if this.countVIII}}
<tr>
<th class="banner-mid" rowspan="{{countVIII}}">
<div>
<div class="rank-label">{{#if this.countVIII}}VIII{{/if}}</div>
</div>
</th>
</tr>
{{#each this.VIII}}
<tr>
<td class="liturgy rollable" data-action="openLiturgyDialog" data-id="{{this.id}}"
data-rank="{{this.rank}}"
data-lkp="{{../lkp}}" data-deity="{{../deity}}">
{{> 'systems/DSA_4-1/templates/ui/partial-die.hbs' }}
</td>
<td class="clickable" data-id="{{this.id}}"
data-action="openEmbeddedDocument">{{this.name}}</td>
</tr>
{{/each}}
{{/if}}
</tbody>
</table>
{{/each}}
</div>

View File

@ -0,0 +1,51 @@
<div class="mini-spells">
<div class="tab-resources">
<div class="astralpoints">
<label>AsP:</label>
<input type="number" name="system.asp.aktuell" value="{{system.asp.aktuell}}"/>
<span class="inline">von</span>
<input type="number" disabled value="{{derived.asp.max}}"/>
</div>
<div class="mr">
<label>MR: </label>
<input type="number" disabled value="{{derived.mr.aktuell}}"/>
</div>
</div>
<div class="table-header">
<span class="die-and-name">
Zaubername
</span>
<span>
Probe
</span>
<span>ZfW</span>
</div>
<div class="scrollable-table">
<table>
<thead aria-hidden="false">
<tr>
<th class="die-column"></th>
<th>Zaubername</th>
<th>Probe</th>
<th>ZfW</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-item-id="{{this.id}}" data-action="openEmbeddedDocument">
<span>{{this.name}}</span></td>
<td>{{this.eigenschaft1}} {{this.eigenschaft2}} {{this.eigenschaft3}}</td>
<td>{{this.zfw}}</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
</div>