Merge remote-tracking branch 'origin/main'

pull/58/head
Poppy 2025-10-15 18:15:20 +02:00
commit 217eb654df
19 changed files with 104 additions and 52 deletions

View File

@ -23,7 +23,7 @@ import {ActiveEffectDataModel} from "./module/data/activeeffect.mjs";
import {Trefferzone, Wunde, Zonenruestung, Zonenwunde} from "./module/data/Trefferzone.js";
async function preloadHandlebarsTemplates() {
return loadTemplates([
return foundry.applications.handlebars.loadTemplates([
// ui partials.
'systems/DSA_4-1/templates/ui/partial-rollable-button.hbs',
'systems/DSA_4-1/templates/ui/partial-rollable-weaponskill-button.hbs',
@ -79,55 +79,55 @@ Hooks.once("init", () => {
console.log("DSA 4.1 is ready for development!")
Actors.registerSheet('dsa41.character', CharacterSheet, {
foundry.documents.collections.Actors.registerSheet('dsa41.character', CharacterSheet, {
types: ["character"],
makeDefault: true,
label: 'DSA41.CharacterLabels.Item'
})
Actors.registerSheet('dsa41.creature', CreatureSheet, {
foundry.documents.collections.Actors.registerSheet('dsa41.creature', CreatureSheet, {
types: ["creature"],
makeDefault: true,
label: 'DSA41.CreatureLabel.Item'
})
Actors.registerSheet('dsa41.group', GroupSheet, {
foundry.documents.collections.Actors.registerSheet('dsa41.group', GroupSheet, {
types: ["group"],
makeDefault: true,
label: 'DSA41.GroupLabel.Item'
})
// Register sheet application classes
Items.registerSheet('dsa41.skill', SkillSheet, {
foundry.documents.collections.Items.registerSheet('dsa41.skill', SkillSheet, {
types: ["Skill"],
makeDefault: true,
label: 'DSA41.SkillLabels.Item',
});
Items.registerSheet('dsa41.spell', SpellSheet, {
foundry.documents.collections.Items.registerSheet('dsa41.spell', SpellSheet, {
types: ["Spell"],
makeDefault: true,
label: 'DSA41.SpellLabels.Item',
});
Items.registerSheet('dsa41.advantage', VornachteilSheet, {
foundry.documents.collections.Items.registerSheet('dsa41.advantage', VornachteilSheet, {
types: ["Advantage"],
makeDefault: true,
label: 'DSA41.VornachteilLabels.Item'
})
Items.registerSheet('dsa41.equipment', AusruestungSheet, {
foundry.documents.collections.Items.registerSheet('dsa41.equipment', AusruestungSheet, {
types: ["Equipment"],
makeDefault: false,
label: 'DSA41.AusruestungLabels.Item'
})
Items.registerSheet('dsa41.liturgy', LiturgySheet, {
foundry.documents.collections.Items.registerSheet('dsa41.liturgy', LiturgySheet, {
types: ["SpecialAbility"],
makeDefault: true,
label: 'DSA41.SpecialAbilityLabels.Item'
})
Items.registerSheet('dsa41.specialAbility', SpecialAbilitySheet, {
foundry.documents.collections.Items.registerSheet('dsa41.specialAbility', SpecialAbilitySheet, {
types: ["Liturgy"],
makeDefault: true,
label: 'DSA41.LiturgyLabels.Item'
})
Items.registerSheet('dsa41.activeEffect', ActiveEffectSheet, {
foundry.documents.collections.Items.registerSheet('dsa41.activeEffect', ActiveEffectSheet, {
types: ['ActiveEffect'],
makeDefault: true,
label: 'DSA41.ActiveEffectLabels.ActiveFfect'

View File

@ -1,6 +1,14 @@
import BaseItem from "./base-item.mjs";
const {BooleanField, ArrayField, NumberField, SchemaField, StringField, HTMLField} = foundry.data.fields;
const {
BooleanField,
DocumentIdField,
ArrayField,
NumberField,
SchemaField,
StringField,
HTMLField
} = foundry.data.fields;
export class SkillDataModel extends BaseItem {
@ -13,9 +21,9 @@ export class SkillDataModel extends BaseItem {
pa: new NumberField({required: false, integer: true, nullable: true, initial: 0}),
probe: new ArrayField(new StringField(), {exact: 3}), // References one of the eight attributes by name
voraussetzung: new SchemaField({
talent: new StringField({model: SkillDataModel}),
wert: new NumberField({}),
}), // Required skills at a given level
talent: new DocumentIdField(),
wert: new NumberField(),
}, {required: false}), // Required skills at a given level
talent: new HTMLField({required: true}),
behinderung: new NumberField({required: false}), // BE-X
komplexität: new NumberField({required: false}), // In case of languages

View File

@ -1,6 +1,6 @@
import BaseItem from "./base-item.mjs";
const {ArrayField, NumberField, StringField, HTMLField} = foundry.data.fields;
const {ArrayField, BooleanField, NumberField, StringField, HTMLField} = foundry.data.fields;
export class VornachteileDataModel extends BaseItem {
@ -8,9 +8,11 @@ export class VornachteileDataModel extends BaseItem {
return {
name: new StringField({required: true}),
description: new HTMLField(),
nachteil: new BooleanField({required: true, initialValue: false}),
schlechteEigenschaft: new BooleanField({required: true, initialValue: false}),
// Optional Fields
value: new ArrayField(new StringField(), {required: false}),
value: new StringField({required: false, nullable: true}),
regenerationASP: new ArrayField(new NumberField({integer: true}), {required: false}),
regenerationLEP: new ArrayField(new NumberField({integer: true}), {required: false}),
inRollRegeneration: new ArrayField(new NumberField({integer: true}), {required: false}),

View File

@ -1,4 +1,4 @@
export class ActiveEffectSheet extends ItemSheet {
export class ActiveEffectSheet extends foundry.appv1.sheets.ItemSheet {
/**@override */
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {

View File

@ -3,7 +3,7 @@ import {ActionManager} from "./actions/action-manager.mjs";
import {LiturgyData} from "../data/miracle/liturgydata.mjs";
import {ModifyLiturgy} from "../dialog/modify-liturgy.mjs";
export class CharacterSheet extends ActorSheet {
export class CharacterSheet extends foundry.appv1.sheets.ActorSheet {
/**@override */
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
@ -322,6 +322,9 @@ export class CharacterSheet extends ActorSheet {
value: item.system.value,
options: item.system.auswahl,
description: item.system.description,
isAdvantage: !item.system.nachteil,
isDisadvantage: item.system.nachteil,
isBadAttribute: item.system.schlechteEigenschaft
});
}
}
@ -841,7 +844,7 @@ export class CharacterSheet extends ActorSheet {
activateListeners(html) {
super.activateListeners(html);
const tabs = new Tabs({
const tabs = new foundry.applications.ux.Tabs({
navSelector: ".paperdoll-tabs.tabs",
contentSelector: ".sheet-body.paperdoll-sets",
initial: "set" + (this.object.system.setEquipped + 1)
@ -926,7 +929,7 @@ export class CharacterSheet extends ActorSheet {
}
})
new ContextMenu(html, '.talent.rollable', [
new foundry.applications.ux.ContextMenu(html[0], '.talent.rollable', [
{
name: "Entfernen",
icon: '<i class="fa-solid fa-trash"></i>',
@ -935,10 +938,12 @@ export class CharacterSheet extends ActorSheet {
},
condition: () => true
}
]);
], {
jQuery: false
});
new ContextMenu(html, '.attribute.rollable', [
new foundry.applications.ux.ContextMenu(html[0], '.attribute.rollable', [
{
name: "Anpassen",
icon: '<i class="fa-solid fa-pen"></i>',
@ -947,7 +952,9 @@ export class CharacterSheet extends ActorSheet {
},
condition: () => true
}
]);
], {
jQuery: false
});
let handler = evt => {
const talentId = evt.target.dataset.id
@ -965,7 +972,7 @@ export class CharacterSheet extends ActorSheet {
li.addEventListener("dragstart", handler, false);
});
new ContextMenu(html, '.equipment', [
new foundry.applications.ux.ContextMenu(html[0], '.equipment', [
{
name: "Aus dem Inventar entfernen",
icon: '<i class="fa-solid fa-trash"></i>',
@ -975,9 +982,11 @@ export class CharacterSheet extends ActorSheet {
},
condition: () => true
}
]);
], {
jQuery: false
});
new ContextMenu(html, '.equipped', [
new foundry.applications.ux.ContextMenu(html[0], '.equipped', [
{
name: "Gegenstand vom Set entfernen",
callback: (event) => {
@ -990,7 +999,9 @@ export class CharacterSheet extends ActorSheet {
},
condition: () => true
}
]);
], {
jQuery: false
});
html.on('click', '[data-operation="addWounds"]', async (evt) => {
const {value} = evt.currentTarget.dataset

View File

@ -1,4 +1,4 @@
export class AusruestungSheet extends ItemSheet {
export class AusruestungSheet extends foundry.appv1.sheets.ItemSheet {
/**@override */
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {

View File

@ -1,4 +1,4 @@
export class GroupSheet extends ActorSheet {
export class GroupSheet extends foundry.appv1.sheets.ActorSheet {
/**@override */
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {

View File

@ -1,4 +1,4 @@
export class LiturgySheet extends ItemSheet {
export class LiturgySheet extends foundry.appv1.sheets.ItemSheet {
/**@override */
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {

View File

@ -1,4 +1,4 @@
export class SkillSheet extends ItemSheet {
export class SkillSheet extends foundry.appv1.sheets.ItemSheet {
/**@override */
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
@ -9,7 +9,7 @@ export class SkillSheet extends ItemSheet {
{
navSelector: '.sheet-tabs',
contentSelector: '.sheet-body',
initial: 'description',
initial: 'meta',
},
],
});
@ -40,11 +40,16 @@ export class SkillSheet extends ItemSheet {
Gesellschaft: "Gesellschaft",
Natur: "Natur",
Wissen: "Wissen",
Sprachen: "Sprache",
Sprachen: "Sprachen",
Schriften: "Schriften",
Handwerk: "Handwerk"
}
context.isCombat = context.system.gruppe === "Kampf"
context.isTalent = context.system.gruppe !== "Kampf"
context.isLanguage = context.system.gruppe === "Sprachen" || context.system.gruppe === "Schriften"
context.hasRequirement = context.system.voraussetzung.talent != null
return context;
}
@ -52,7 +57,9 @@ export class SkillSheet extends ItemSheet {
super.activateListeners(html);
// Everything below here is only needed if the sheet is editable
if (!this.isEditable) return;
if (!this.isEditable) {
}
}
}

View File

@ -1,4 +1,4 @@
export class SpecialAbilitySheet extends ItemSheet {
export class SpecialAbilitySheet extends foundry.appv1.sheets.ItemSheet {
/**@override */
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {

View File

@ -1,4 +1,4 @@
export class VornachteilSheet extends ItemSheet {
export class VornachteilSheet extends foundry.appv1.sheets.ItemSheet {
/**@override */
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
@ -34,13 +34,12 @@ export class VornachteilSheet extends ItemSheet {
// Add the actor's data to context.data for easier access, as well as flags.
context.system = advantageData.system;
context.flags = advantageData.flags;
context.hasChoices = context.system.auswahl.length > 0;
context.choices = {}
context.system.auswahl.forEach(a => {
context.choices[a] = a
})
context.hasChoices = context.system.auswahl.length > 0;
context.hasModality = context.system.value == null
context.hasModality = context.system.value != null
return context;
}

View File

@ -1,4 +1,5 @@
{
"name": "Guter Ruf",
"value": 0,
"description": "Der Held ist bekannt für seine Freigiebigkeit, seine Gerechtigkeit, Hilfsbereitschaft oder dergleichen positive Charakterzüge, was sich darin niederschlägt, dass andere Menschen positiv und freundlich auf ihn reagieren. Je 2 Punkte, die der Held in Guten Ruf investiert, erleichtern (passende) Talentproben in gesellschaftlichen Talenten um 1 Punkt. Je nach Situation kann auch ein Drittel der GP für Guten Ruf als Ersatz für fehlenden Sozialstatus verwendet werden (z.B. wenn es um Audienzen oder die Einladungen zu Hofbällen geht). Guter Ruf gilt nur für Begegnungen mit Personen der eigenen Kultur, eingeschränkt (nach Meis terentscheid) auch in benachbarten oder verwandten Kulturen. Ein Guter Ruf in einer Kultur, die nicht die heimatliche ist, erfordert ebenso die Zustimmung des Spielleiters wie das Erwerben eines Guten Rufs in mehreren Kulturen."
}

View File

@ -0,0 +1,17 @@
{
"name": "Neugier",
"schlechteEigenschaft": true,
"nachteil": true,
"value": "5",
"auswahl": [
"5",
"6",
"7",
"8",
"9",
"10",
"11",
"12"
],
"description": "Dieser Nachteil bringt den Helden dazu, alles, was irgendwie interessant wirkt, näher untersuchen zu wollen und zwar unabhängig von eventuellen Risiken, die das mit sich bringen könnte. Neugier ist ein typischer Fall für eine Schlechte Eigenschaft, die weniger Nachteile bei anderen Handlungen mit sich bringt, als dass sie den Helden zu einer bestimmten Aktion zwingt."
}

View File

@ -1,4 +1,5 @@
{
"name": "Verbindungen",
"value": 0,
"description": "Der Held hat einen guten Bekannten, den er in schwierigen Situationen um Hilfe bitten kann. Welcher Art diese Hilfe ist und wie häufig der Bekannte sie zu geben bereit ist, hängt von dessen Charakter und Profession ab und ist Meisterentscheid. So ist die Straßenbande, die der alanfanische Streuner kennt (6 Schläger mit SO 2 und ein Anführer mit SO 5 für insgesamt 6 GP) sicherlich in Festum nicht von Nutzen, ebenso wie die Bekanntschaft mit einem mittelreichischen Grafen (SO 15 entsprechend 5 GP) einen Magier nicht zwangsläufig aus den Kerkern der Inquisition befreit. Jeder Bekannte kostet ein Drittel so viele GP, wie dessen Sozialstatus beträgt, und muss aus einem Rahmen vom eigenen SO +/5 (Maximum SO 15) ausgewählt werden. Der Meister sollte je nach Art der geplanten Kampagne die Kosten für diesen Vorteil modifizieren. Dieser Vorteil kann mehrfach gewählt werden. Verbindungen sind bei Helden, die ihre Profession an einer Akademie oder einer anderen Institution gelernt haben (Magier, Krieger etc.), häufiger zu finden; meist bezogen auf ehemalige Mitschüler und / oder Lieblingslehrer."
}

View File

@ -224,7 +224,7 @@
margin-left: 8px;
}
&.nachteil {
&.disadvantage {
font-style: italic;
&::after {

View File

@ -26,7 +26,7 @@
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: auto 1fr;
.statistics > label {
& > label {
grid-column: 1/4;
text-align: center;
}

View File

@ -10,7 +10,7 @@
<div class="tab advantage {{#if hasModality}}modality{{/if}}" data-group="primary" data-tab="advantage">
<div>
<label>Name</label>
<input name="item.name" value="{{item.name}}"/>
<input name="system.name" value="{{system.name}}"/>
</div>
{{#if hasModality}}
@ -21,7 +21,7 @@
{{selectOptions choices selected=system.auswahl inverted=true}}
</select>
{{else}}
<input name="actor.system.value" value="{{actor.system.value}}"/>
<input name="system.value" value="{{system.value}}"/>
{{/if}}
</div>
{{/if}}

View File

@ -23,9 +23,9 @@
value="{{system.taw}}"/>
</label>
</div>
{{#if isTalent}}
<div class="statistics">
<label>Probe</label>
<label class="throw">Probe</label>
<div>
<label>
<input type="text" name="system.probe.0"
@ -43,17 +43,20 @@
</label>
</div>
</div>
{{/if}}
<div class="ebe">
<label>Effektive Behinderung
<input type="text" name="system.behinderung" value="{{system.behinderung}}"/>
</label>
</div>
{{#if isLanguage}}
<div class="language-statistics">
<label>Sprachenkomplexizität
<input type="text" name="system.komplexität" value="{{system.komplexität}}"/>
</label>
</div>
{{/if}}
{{#if isCombat}}
<div class="attack-statistics">
<div>
<label>Attacke
@ -66,6 +69,7 @@
</label>
</div>
</div>
{{/if}}
</div>
<div class="tab description" data-group="primary" data-tab="description">
@ -73,17 +77,19 @@
<label>Beschreibungstext</label>
{{editor system.talent target="system.talent" button=true owner=owner editable=editable}}
</div>
{{#if hasRequirement}}
<div>
<label>Voraussetzung</label>
<ul>
{{#each system.voraussetzung as |pair key|}}
{{#each system.voraussetzung}}
<li>
<input type="text" name="system.vorraussetzung.{{key}}.wert" value="{{pair.wert}}"/>
<input type="text" name="system.vorraussetzung.{{key}}.talent" value="{{pair.talent}}"/>
<input type="text" name="system.vorraussetzung.{{@key}}.wert" value="{{this}}"/>
<input type="text" name="system.vorraussetzung.{{@key}}.talent" value="{{this}}"/>
</li>
{{/each}}
</ul>
</div>
{{/if}}
</div>
</div>

View File

@ -1,3 +1,3 @@
<div class="advantage">
<span class="name" data-id="{{this.id}}">{{this.name}}</span>
<div class="advantage {{#if isDisadvantage}}disadvantage{{/if}}">
<span class="name" data-id="{{this.id}}">{{this.name}} {{#if this.value}}: {{this.value}}{{/if}}</span>
</div>