implements deity model and sheet.

the model includes stats important for clerics as it contains miracle Plus and miracle Minus.
pull/65/head 0.5.0-rc2
macniel 2025-11-08 14:21:24 +01:00
parent 7b0f407239
commit 97fe0fa9a6
9 changed files with 521 additions and 1 deletions

View File

@ -0,0 +1,35 @@
import BaseItem from "./baseItem.mjs";
import {Liturgy} from "../documents/liturgy.mjs";
const {
ArrayField,
NumberField,
StringField,
HTMLField,
SchemaField,
DocumentIdField,
} = foundry.data.fields;
export class DeityDataModel extends BaseItem {
static defineSchema() {
return {
alias: new ArrayField(new StringField()),
description: new HTMLField(),
miracleMinus: new ArrayField(new StringField()),
miraclePlus: new ArrayField(new StringField()),
karmicEnergy: new NumberField({integer: true}),
liturgies: new SchemaField({
rank0: new ArrayField(new StringField()),
rank1: new ArrayField(new StringField()),
rank2: new ArrayField(new StringField()),
rank3: new ArrayField(new StringField()),
rank4: new ArrayField(new StringField()),
rank5: new ArrayField(new StringField()),
rank6: new ArrayField(new StringField()),
rank7: new ArrayField(new StringField()),
rank8: new ArrayField(new StringField()),
}),
}
}
}

View File

@ -0,0 +1,9 @@
export class Deity extends Item {
/**
* Augment the basic Item data model with additional dynamic data.
*/
prepareData() {
super.prepareData();
}
}

View File

@ -19,6 +19,7 @@ import {BattleDialog} from "../dialog/battleDialog.mjs";
import {Talent} from "../data/talent.mjs"; import {Talent} from "../data/talent.mjs";
import {Character} from "../documents/character.mjs"; import {Character} from "../documents/character.mjs";
import {currency} from "../handlebar-helpers/currency.mjs"; import {currency} from "../handlebar-helpers/currency.mjs";
import {DeityDataModel} from "../data/deity.mjs";
function initGlobalAccess() { function initGlobalAccess() {
@ -59,6 +60,7 @@ function initDataModels(config) {
Profession: ProfessionDataModel, Profession: ProfessionDataModel,
Spezies: SpeciesDataModel, Spezies: SpeciesDataModel,
Kultur: CultureDataModel, Kultur: CultureDataModel,
Deity: DeityDataModel,
} }
} }

View File

@ -12,6 +12,7 @@ import {CultureSheet} from "../sheets/cultureSheet.mjs";
import {SpeciesSheet} from "../sheets/SpeciesSheet.mjs"; import {SpeciesSheet} from "../sheets/SpeciesSheet.mjs";
import {ProfessionSheet} from "../sheets/professionSheet.mjs"; import {ProfessionSheet} from "../sheets/professionSheet.mjs";
import {MerchantSheet} from "../sheets/merchantSheet.mjs"; import {MerchantSheet} from "../sheets/merchantSheet.mjs";
import {DeitySheet} from "../sheets/deitySheet.mjs";
function setUpActorSheets(registry) { function setUpActorSheets(registry) {
@ -88,6 +89,11 @@ function setUpItemSheets(registry) {
makeDefault: true, makeDefault: true,
}) })
registry.registerSheet('dsa41.deity', DeitySheet, {
types: ['Deity'],
makeDefault: true,
})
} }
export { export {

View File

@ -0,0 +1,228 @@
const {DocumentSheetV2, HandlebarsApplicationMixin} = foundry.applications.api
export class DeitySheet extends HandlebarsApplicationMixin(DocumentSheetV2) {
/** @inheritDoc */
static DEFAULT_OPTIONS = {
position: {width: 520, height: 848},
classes: ['dsa41', 'sheet', 'item', 'deity'],
tag: 'form',
form: {
submitOnChange: true,
closeOnSubmit: false,
handler: DeitySheet.#onSubmitForm
},
window: {
resizable: true,
},
actions: {
editImage: DocumentSheetV2.DEFAULT_OPTIONS.actions.editImage,
openLiturgy: DeitySheet.#openLiturgySheet,
removeLiturgy: DeitySheet.#removeLiturgy,
}
}
/** @inheritDoc */
static PARTS = {
form: {
template: `systems/DSA_4-1/templates/item/deity-sheet.hbs`
},
}
/**
* Handle form submission
* @this {SpeciesSheet}
* @param {SubmitEvent} event
* @param {HTMLFormElement} form
* @param {FormDataExtended} formData
*/
static async #onSubmitForm(event, form, formData) {
event.preventDefault()
formData.object["system.miraclePlus"] = formData.object.miraclePlus.split(",")
formData.object["system.miracleMinus"] = formData.object.miracleMinus.split(",")
delete formData.object.miraclePlus
delete formData.object.miracleMinus
await this.document.update(formData.object) // Note: formData.object
}
static async #openLiturgySheet(event, target) {
const {rank, liturgyId} = target.dataset
if (liturgyId && rank) {
this.document.system.liturgies["rank" + rank].find(p => p._id === liturgyId)?.sheet.render(true, {editable: false})
}
}
static async #removeLiturgy(event, target) {
const {rank, liturgyId} = target.dataset
if (liturgyId && rank) {
const idx = this.document.system.liturgies["rank" + rank].findIndex(p => p._id === liturgyId)
this.document.system.liturgies["rank" + rank].splice(idx, 1)
const thisUpdateObject = {}
thisUpdateObject["system.liturgies.rank" + rank] = this.document.system.liturgies
this.document.update(thisUpdateObject)
this.render({parts: ["form"]})
}
}
_configureRenderOptions(options) {
super._configureRenderOptions(options)
if (options.window) {
options.window.title = this.document.name
}
return options
}
/** @override */
async _prepareContext(options) {
// const context = await super._prepareContext(options)
context.system = this.document.system
context.name = this.document.name
context.img = this.document.img
context.description = this.document.description
context.liturgies = {
rank0: [],
rank1: [],
rank2: [],
rank3: [],
rank4: [],
rank5: [],
rank6: [],
rank7: [],
rank8: [],
}
context.miraclePlus = this.document.system.miraclePlus?.join(",")
context.miracleMinus = this.document.system.miracleMinus?.join(",")
this.document.system.liturgies.rank0.forEach(liturgyUuid => {
fromUuid(liturgyUuid).then(liturgy => {
context.liturgies.rank0.push({
id: liturgy._id,
name: liturgy.name,
})
})
})
this.document.system.liturgies.rank1.forEach(liturgyUuid => {
fromUuid(liturgyUuid).then(liturgy => {
context.liturgies.rank1.push({
id: liturgy._id,
name: liturgy.name,
})
})
})
this.document.system.liturgies.rank2.forEach(liturgyUuid => {
fromUuid(liturgyUuid).then(liturgy => {
context.liturgies.rank2.push({
id: liturgy._id,
name: liturgy.name,
})
})
})
this.document.system.liturgies.rank3.forEach(liturgyUuid => {
fromUuid(liturgyUuid).then(liturgy => {
context.liturgies.rank3.push({
id: liturgy._id,
name: liturgy.name,
})
})
})
this.document.system.liturgies.rank4.forEach(liturgyUuid => {
fromUuid(liturgyUuid).then(liturgy => {
context.liturgies.rank4.push({
id: liturgy._id,
name: liturgy.name,
})
})
})
this.document.system.liturgies.rank5.forEach(liturgyUuid => {
fromUuid(liturgyUuid).then(liturgy => {
context.liturgies.rank5.push({
id: liturgy._id,
name: liturgy.name,
})
})
})
this.document.system.liturgies.rank6.forEach(liturgyUuid => {
fromUuid(liturgyUuid).then(liturgy => {
context.liturgies.rank6.push({
id: liturgy._id,
name: liturgy.name,
})
})
})
this.document.system.liturgies.rank7.forEach(liturgyUuid => {
fromUuid(liturgyUuid).then(liturgy => {
context.liturgies.rank7.push({
id: liturgy._id,
name: liturgy.name,
})
})
})
this.document.system.liturgies.rank8.forEach(liturgyUuid => {
fromUuid(liturgyUuid).then(liturgy => {
context.liturgies.rank8.push({
id: liturgy._id,
name: liturgy.name,
})
})
})
return context
}
async _canDragDrop() {
return true
}
_onRender(context, options) {
new foundry.applications.ux.DragDrop.implementation({
dropSelector: ".liturgy-drops",
permissions: {
drop: this._canDragDrop.bind(this)
},
callbacks: {
drop: this._onDrop.bind(this)
}
}).bind(this.element);
}
async _onDrop(event, target) {
const data = TextEditor.implementation.getDragEventData(event);
const documentClass = foundry.utils.getDocumentClass(data.type)
if (documentClass) {
const document = await documentClass.fromDropData(data);
if (document.type === "Liturgy") {
// process and drop it rightly
const {rank} = event.target.dataset
if (rank) {
let rankData = this.document.system.liturgies["rank" + rank]
rankData.push(document.uuid)
const updateData = {}
updateData["system.liturgies.rank" + rank] = rankData
this.document.update(updateData)
this.render({parts: ["form"]})
}
}
}
}
}

View File

@ -0,0 +1,73 @@
.dsa41.item.deity {
.deity {
.head {
display: grid;
grid-template-columns: 52px 1fr 80px;
height: 52px;
gap: 8px;
img {
width: 52px;
height: 52px;
}
margin-bottom: 8px;
}
fieldset {
padding: 8px 0;
}
.miracles {
display: flex;
gap: 8px;
}
table {
tr th:first-child {
width: 64px;
}
div.liturgy {
border: 1px solid #333;
background-color: darkgrey;
box-shadow: 1px 1px 1px black;
height: 24px;
display: inline-block;
position: relative;
padding-left: 4px;
padding-right: 24px;
span {
line-height: 24px;
height: 24px;
vertical-align: middle;
}
button.mini {
border: unset;
background: unset;
width: 24px;
height: 24px;
padding: unset;
margin: unset;
text-align: center;
position: absolute;
right: 0;
top: -2px;
}
}
}
}
}

View File

@ -35,3 +35,4 @@
@use "organisms/battle-dialog"; @use "organisms/battle-dialog";
@use "organisms/liturgy-sheet"; @use "organisms/liturgy-sheet";
@use "organisms/dialog"; @use "organisms/dialog";
@use "organisms/deity-sheet";

View File

@ -308,6 +308,7 @@
}, },
"Blessing": {}, "Blessing": {},
"Liturgy": {}, "Liturgy": {},
"Deity": {},
"Spell": { "Spell": {
"stringFields": [ "stringFields": [
"name", "name",

View File

@ -0,0 +1,165 @@
<section class="deity">
<div class="head">
<img class="img" src="{{img}}" data-action="editImage" data-edit="img" title="{{name}}"/>
<label>Name
<input type="text" name="name" value="{{this.name}}"/>
</label>
<label>Karma
<input type="number" name="system.karmicEnergy" value="{{system.karmicEnergy}}"/>
</label>
</div>
<div class="editor">
<label>Beschreibung</label>
<prose-mirror
name="system.description"
button="false"
editable="{{editable}}"
toggled="true"
value="{{system.description}}">
{{{description}}}
</prose-mirror>
</div>
<fieldset>
<legend>Mirakel</legend>
<div class="miracles">
<div><label><span>Mirakel+</span>
<input type="text" name="miraclePlus" value="{{miraclePlus}}"/>
</label></div>
<div><label><span>Mirakel-</span>
<input type="text" name="miracleMinus" value="{{miracleMinus}}"/>
</label></div>
</div>
</fieldset>
<fieldset>
<legend>Liturgien</legend>
<table>
<thead>
<tr>
<th>Grad</th>
<th>Liturgien</th>
</tr>
</thead>
<tbody>
<tr class="liturgy-drops" data-rank="0">
<th data-rank="0">0</th>
<td data-rank="0">
{{#each liturgies.rank0}}
<div class="liturgy" data-action="openLiturgy" data-rank="0" data-liturgy-id="{{this.id}}">
<span>{{this.name}}</span>
<button data-action="removeLiturgy" data-rank="0" data-liturgy-id="{{this.id}}"
class="mini"><i class="fa fa-xmark"></i></button>
</div>
{{/each}}
</td>
</tr>
<tr class="liturgy-drops" data-rank="1">
<th data-rank="1">I</th>
<td data-rank="1">
{{#each liturgies.rank1}}
<div class="liturgy" data-action="openLiturgy" data-rank="1" data-liturgy-id="{{this.id}}">
<span>{{this.name}}</span>
<button data-action="removeLiturgy" data-rank="1" data-liturgy-id="{{this.id}}"
class="mini"><i class="fa fa-xmark"></i></button>
</div>
{{/each}}
</td>
</tr>
<tr class="liturgy-drops" data-rank="2">
<th data-rank="2">II</th>
<td data-rank="2">
{{#each liturgies.rank2}}
<div class="liturgy" data-action="openLiturgy" data-rank="2" data-liturgy-id="{{this.id}}">
<span>{{this.name}}</span>
<button data-action="removeLiturgy" data-rank="2" data-liturgy-id="{{this.id}}"
class="mini"><i class="fa fa-xmark"></i></button>
</div>
{{/each}}
</td>
</tr>
<tr class="liturgy-drops" data-rank="3">
<th data-rank="3">III</th>
<td data-rank="3">
{{#each liturgies.rank3}}
<div class="liturgy" data-action="openLiturgy" data-rank="3" data-liturgy-id="{{this.id}}">
<span>{{this.name}}</span>
<button data-action="removeLiturgy" data-rank="3" data-liturgy-id="{{this.id}}"
class="mini"><i class="fa fa-xmark"></i></button>
</div>
{{/each}}
</td>
</tr>
<tr class="liturgy-drops" data-rank="4">
<th data-rank="4">IV</th>
<td data-rank="4">
{{#each liturgies.rank4}}
<div class="liturgy" data-action="openLiturgy" data-rank="4" data-liturgy-id="{{this.id}}">
<span>{{this.name}}</span>
<button data-action="removeLiturgy" data-rank="4" data-liturgy-id="{{this.id}}"
class="mini"><i class="fa fa-xmark"></i></button>
</div>
{{/each}}
</td>
</tr>
<tr class="liturgy-drops" data-rank="5">
<th data-rank="5">V</th>
<td data-rank="5">
{{#each liturgies.rank5}}
<div class="liturgy" data-action="openLiturgy" data-rank="5" data-liturgy-id="{{this.id}}">
<span>{{this.name}}</span>
<button data-action="removeLiturgy" data-rank="5" data-liturgy-id="{{this.id}}"
class="mini"><i class="fa fa-xmark"></i></button>
</div>
{{/each}}
</td>
</tr>
<tr class="liturgy-drops" data-rank="6">
<th data-rank="6">VI</th>
<td data-rank="6">
{{#each liturgies.rank6}}
<div class="liturgy" data-action="openLiturgy" data-rank="6" data-liturgy-id="{{this.id}}">
<span>{{this.name}}</span>
<button data-action="removeLiturgy" data-rank="6" data-liturgy-id="{{this.id}}"
class="mini"><i class="fa fa-xmark"></i></button>
</div>
{{/each}}
</td>
</tr>
<tr class="liturgy-drops" data-rank="7">
<th data-rank="7">VII</th>
<td data-rank="7">
{{#each liturgies.rank7}}
<div class="liturgy" data-action="openLiturgy" data-rank="7" data-liturgy-id="{{this.id}}">
<span>{{this.name}}</span>
<button data-action="removeLiturgy" data-rank="7" data-liturgy-id="{{this.id}}"
class="mini"><i class="fa fa-xmark"></i></button>
</div>
{{/each}}
</td>
</tr>
<tr class="liturgy-drops" data-rank="8">
<th data-rank="8">VIII</th>
<td data-rank="8">
{{#each liturgies.rank8}}
<div class="liturgy" data-action="openLiturgy" data-rank="8" data-liturgy-id="{{this.id}}">
<span>{{this.name}}</span>
<button data-action="removeLiturgy" data-rank="8" data-liturgy-id="{{this.id}}"
class="mini"><i class="fa fa-xmark"></i></button>
</div>
{{/each}}
</td>
</tr>
</tbody>
</table>
</fieldset>
</section>